Browse Source

add sync+restart action to watch attribute

Signed-off-by: Guillaume Lours <[email protected]>
Guillaume Lours 2 years ago
parent
commit
818bc3c34a
6 changed files with 43 additions and 5 deletions
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 11 0
      pkg/compose/watch.go
  4. 6 0
      pkg/e2e/fixtures/watch/compose.yaml
  5. 1 0
      pkg/e2e/fixtures/watch/config/file.config
  6. 22 2
      pkg/e2e/watch_test.go

+ 1 - 1
go.mod

@@ -7,7 +7,7 @@ require (
 	github.com/Microsoft/go-winio v0.6.1
 	github.com/adrg/xdg v0.4.0
 	github.com/buger/goterm v1.0.4
-	github.com/compose-spec/compose-go v1.19.0
+	github.com/compose-spec/compose-go v1.20.0
 	github.com/containerd/console v1.0.3
 	github.com/containerd/containerd v1.7.7
 	github.com/davecgh/go-spew v1.1.1

+ 2 - 2
go.sum

@@ -139,8 +139,8 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g
 github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
 github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
 github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
-github.com/compose-spec/compose-go v1.19.0 h1:t68gAcwStDg0hy2kFvqHJIksf6xkqRnlSKfL45/ETqo=
-github.com/compose-spec/compose-go v1.19.0/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM=
+github.com/compose-spec/compose-go v1.20.0 h1:h4ZKOst1EF/DwZp7dWkb+wbTVE4nEyT9Lc89to84Ol4=
+github.com/compose-spec/compose-go v1.20.0/go.mod h1:+MdqXV4RA7wdFsahh/Kb8U0pAJqkg7mr4PM9tFKU8RM=
 github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
 github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
 github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw=

+ 11 - 0
pkg/compose/watch.go

@@ -415,6 +415,7 @@ func (t tarDockerClient) Exec(ctx context.Context, containerID string, cmd []str
 
 func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Project, serviceName string, build api.BuildOptions, batch []fileEvent, syncer sync.Syncer) error {
 	pathMappings := make([]sync.PathMapping, len(batch))
+	restartService := false
 	for i := range batch {
 		if batch[i].Action == types.WatchActionRebuild {
 			fmt.Fprintf(
@@ -441,6 +442,9 @@ func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Pr
 			}
 			return nil
 		}
+		if batch[i].Action == types.WatchActionSyncRestart {
+			restartService = true
+		}
 		pathMappings[i] = batch[i].PathMapping
 	}
 
@@ -453,6 +457,13 @@ func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Pr
 	if err := syncer.Sync(ctx, service, pathMappings); err != nil {
 		return err
 	}
+	if restartService {
+		return s.Restart(ctx, project.Name, api.RestartOptions{
+			Services: []string{serviceName},
+			Project:  project,
+			NoDeps:   false,
+		})
+	}
 	return nil
 }
 

+ 6 - 0
pkg/e2e/fixtures/watch/compose.yaml

@@ -6,6 +6,9 @@ x-dev: &x-dev
       ignore:
         - '*.foo'
         - ./ignored
+    - action: sync+restart
+      path: ./config
+      target: /app/config
 
 services:
   alpine:
@@ -13,6 +16,7 @@ services:
       dockerfile_inline: |-
         FROM alpine
         RUN mkdir -p /app/data
+        RUN mkdir -p /app/config
     init: true
     command: sleep infinity
     develop: *x-dev
@@ -21,6 +25,7 @@ services:
       dockerfile_inline: |-
         FROM busybox
         RUN mkdir -p /app/data
+        RUN mkdir -p /app/config
     init: true
     command: sleep infinity
     develop: *x-dev
@@ -29,6 +34,7 @@ services:
       dockerfile_inline: |-
         FROM debian
         RUN mkdir -p /app/data
+        RUN mkdir -p /app/config
     init: true
     command: sleep infinity
     develop: *x-dev

+ 1 - 0
pkg/e2e/fixtures/watch/config/file.config

@@ -0,0 +1 @@
+This is a config file

+ 22 - 2
pkg/e2e/watch_test.go

@@ -59,13 +59,18 @@ func TestWatch(t *testing.T) {
 func doTest(t *testing.T, svcName string, tarSync bool) {
 	tmpdir := t.TempDir()
 	dataDir := filepath.Join(tmpdir, "data")
-	writeDataFile := func(name string, contents string) {
+	configDir := filepath.Join(tmpdir, "config")
+
+	writeTestFile := func(name, contents, sourceDir string) {
 		t.Helper()
-		dest := filepath.Join(dataDir, name)
+		dest := filepath.Join(sourceDir, name)
 		require.NoError(t, os.MkdirAll(filepath.Dir(dest), 0o700))
 		t.Logf("writing %q to %q", contents, dest)
 		require.NoError(t, os.WriteFile(dest, []byte(contents+"\n"), 0o600))
 	}
+	writeDataFile := func(name, contents string) {
+		writeTestFile(name, contents, dataDir)
+	}
 
 	composeFilePath := filepath.Join(tmpdir, "compose.yaml")
 	CopyFile(t, filepath.Join("fixtures", "watch", "compose.yaml"), composeFilePath)
@@ -195,5 +200,20 @@ func doTest(t *testing.T, svcName string, tarSync bool) {
 			Err:      "No such file or directory",
 		})
 
+	t.Logf("Sync and restart use case")
+	require.NoError(t, os.Mkdir(configDir, 0o700))
+	writeTestFile("file.config", "This is an updated config file", configDir)
+	checkRestart := func(state string) poll.Check {
+		return func(pollLog poll.LogT) poll.Result {
+			if strings.Contains(r.Combined(), state) {
+				return poll.Success()
+			}
+			return poll.Continue(r.Combined())
+		}
+	}
+	poll.WaitOn(t, checkRestart(fmt.Sprintf("%s-1  Restarting", svcName)))
+	poll.WaitOn(t, checkRestart(fmt.Sprintf("%s-1  Started", svcName)))
+	poll.WaitOn(t, checkFileContents("/app/config/file.config", "This is an updated config file"))
+
 	testComplete.Store(true)
 }