Browse Source

introduce watch restart action

Signed-off-by: Nicolas De Loof <[email protected]>
Nicolas De Loof 11 months ago
parent
commit
df9e420ddd
3 changed files with 41 additions and 26 deletions
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 38 23
      pkg/compose/watch.go

+ 1 - 1
go.mod

@@ -9,7 +9,7 @@ require (
 	github.com/Microsoft/go-winio v0.6.2
 	github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
 	github.com/buger/goterm v1.0.4
-	github.com/compose-spec/compose-go/v2 v2.4.6-0.20241203131247-9a9cc5d9c345
+	github.com/compose-spec/compose-go/v2 v2.4.6
 	github.com/containerd/containerd v1.7.24
 	github.com/containerd/platforms v0.2.1
 	github.com/davecgh/go-spew v1.1.1

+ 2 - 2
go.sum

@@ -79,8 +79,8 @@ github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e
 github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
 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/v2 v2.4.6-0.20241203131247-9a9cc5d9c345 h1:oLm7hga9jjaDedg+dqsWiI1GeRrcGLBPxu8W0VfpiKA=
-github.com/compose-spec/compose-go/v2 v2.4.6-0.20241203131247-9a9cc5d9c345/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
+github.com/compose-spec/compose-go/v2 v2.4.6 h1:QiqXQ2L/f0OCbAl41bPpeiGAWVRIQ+GEDrYxO+dRPhQ=
+github.com/compose-spec/compose-go/v2 v2.4.6/go.mod h1:lFN0DrMxIncJGYAXTfWuajfwj5haBJqrBkarHcnjJKc=
 github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
 github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
 github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=

+ 38 - 23
pkg/compose/watch.go

@@ -472,11 +472,17 @@ func (t tarDockerClient) Untar(ctx context.Context, id string, archive io.ReadCl
 func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Project, serviceName string, options api.WatchOptions, batch []fileEvent, syncer sync.Syncer) error {
 	pathMappings := make([]sync.PathMapping, len(batch))
 	restartService := false
+	syncService := false
 	for i := range batch {
-		if batch[i].Trigger.Action == types.WatchActionRebuild {
+		switch batch[i].Trigger.Action {
+		case types.WatchActionRebuild:
 			return s.rebuild(ctx, project, serviceName, options)
-		}
-		if batch[i].Trigger.Action == types.WatchActionSyncRestart {
+		case types.WatchActionSync, types.WatchActionSyncExec:
+			syncService = true
+		case types.WatchActionSyncRestart:
+			restartService = true
+			syncService = true
+		case types.WatchActionRestart:
 			restartService = true
 		}
 		pathMappings[i] = batch[i].PathMapping
@@ -488,8 +494,10 @@ func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Pr
 	if err != nil {
 		return err
 	}
-	if err := syncer.Sync(ctx, service, pathMappings); err != nil {
-		return err
+	if syncService {
+		if err := syncer.Sync(ctx, service, pathMappings); err != nil {
+			return err
+		}
 	}
 	if restartService {
 		err = s.restart(ctx, project.Name, api.RestartOptions{
@@ -507,32 +515,39 @@ func (s *composeService) handleWatchBatch(ctx context.Context, project *types.Pr
 	eg, ctx := errgroup.WithContext(ctx)
 	for _, b := range batch {
 		if b.Trigger.Action == types.WatchActionSyncExec {
-			containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, serviceName)
+			err := s.exec(ctx, project, serviceName, b.Trigger.Exec, eg)
 			if err != nil {
 				return err
 			}
-			x := b.Trigger.Exec
-			for _, c := range containers {
-				eg.Go(func() error {
-					exec := ccli.NewExecOptions()
-					exec.User = x.User
-					exec.Privileged = x.Privileged
-					exec.Command = x.Command
-					exec.Workdir = x.WorkingDir
-					for _, v := range x.Environment.ToMapping().Values() {
-						err := exec.Env.Set(v)
-						if err != nil {
-							return err
-						}
-					}
-					return ccli.RunExec(ctx, s.dockerCli, c.ID, exec)
-				})
-			}
 		}
 	}
 	return eg.Wait()
 }
 
+func (s *composeService) exec(ctx context.Context, project *types.Project, serviceName string, x types.ServiceHook, eg *errgroup.Group) error {
+	containers, err := s.getContainers(ctx, project.Name, oneOffExclude, false, serviceName)
+	if err != nil {
+		return err
+	}
+	for _, c := range containers {
+		eg.Go(func() error {
+			exec := ccli.NewExecOptions()
+			exec.User = x.User
+			exec.Privileged = x.Privileged
+			exec.Command = x.Command
+			exec.Workdir = x.WorkingDir
+			for _, v := range x.Environment.ToMapping().Values() {
+				err := exec.Env.Set(v)
+				if err != nil {
+					return err
+				}
+			}
+			return ccli.RunExec(ctx, s.dockerCli, c.ID, exec)
+		})
+	}
+	return nil
+}
+
 func (s *composeService) rebuild(ctx context.Context, project *types.Project, serviceName string, options api.WatchOptions) error {
 	options.LogTo.Log(api.WatchLogger, fmt.Sprintf("Rebuilding service %q after changes were detected...", serviceName))
 	// restrict the build to ONLY this service, not any of its dependencies