diff --git a/go.mod b/go.mod index 80a59f3091..26e28fd03e 100644 --- a/go.mod +++ b/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-0.20241211105841-27dbf493c70e github.com/containerd/containerd v1.7.24 github.com/containerd/platforms v0.2.1 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index eece3a3ed2..3c6d268f4e 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,8 @@ github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8E github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= 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-0.20241211105841-27dbf493c70e h1:MpISkSqxiD7QsuQT1wRQYQ4LZwvugiiyZjGHBwJ6vk0= +github.com/compose-spec/compose-go/v2 v2.4.6-0.20241211105841-27dbf493c70e/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= diff --git a/pkg/compose/watch.go b/pkg/compose/watch.go index fc501a330a..cc22106f4a 100644 --- a/pkg/compose/watch.go +++ b/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