diff --git a/api/compose/api.go b/api/compose/api.go index aab686da1..dfd919333 100644 --- a/api/compose/api.go +++ b/api/compose/api.go @@ -67,10 +67,14 @@ type Service interface { // CreateOptions group options of the Create API type CreateOptions struct { + // Services defines the services user interacts with + Services []string // Remove legacy containers for services that are not defined in the project RemoveOrphans bool // Recreate define the strategy to apply on existing containers Recreate string + // RecreateDependencies define the strategy to apply on dependencies services + RecreateDependencies string // Inherit reuse anonymous volumes from previous container Inherit bool } diff --git a/cli/cmd/compose/up.go b/cli/cmd/compose/up.go index 763be0952..4416f91b4 100644 --- a/cli/cmd/compose/up.go +++ b/cli/cmd/compose/up.go @@ -56,7 +56,9 @@ type upOptions struct { removeOrphans bool forceRecreate bool noRecreate bool + recreateDeps bool noStart bool + noDeps bool cascadeStop bool exitCodeFrom string scale []string @@ -64,7 +66,6 @@ type upOptions struct { noPrefix bool timeChanged bool timeout int - noDeps bool noInherit bool } @@ -78,6 +79,16 @@ func (o upOptions) recreateStrategy() string { return compose.RecreateDiverged } +func (o upOptions) dependenciesRecreateStrategy() string { + if o.noRecreate { + return compose.RecreateNever + } + if o.recreateDeps { + return compose.RecreateForce + } + return compose.RecreateDiverged +} + func upCommand(p *projectOptions, contextType string) *cobra.Command { opts := upOptions{ composeOptions: &composeOptions{ @@ -103,6 +114,9 @@ func upCommand(p *projectOptions, contextType string) *cobra.Command { if opts.forceRecreate && opts.noRecreate { return fmt.Errorf("--force-recreate and --no-recreate are incompatible") } + if opts.recreateDeps && opts.noRecreate { + return fmt.Errorf("--always-recreate-deps and --no-recreate are incompatible") + } return runCreateStart(cmd.Context(), opts, args) default: return runUp(cmd.Context(), opts, args) @@ -130,6 +144,7 @@ func upCommand(p *projectOptions, contextType string) *cobra.Command { flags.StringVar(&opts.exitCodeFrom, "exit-code-from", "", "Return the exit code of the selected service container. Implies --abort-on-container-exit") flags.IntVarP(&opts.timeout, "timeout", "t", 10, "Use this timeout in seconds for container shutdown when attached or when containers are already running.") flags.BoolVar(&opts.noDeps, "no-deps", false, "Don't start linked services.") + flags.BoolVar(&opts.recreateDeps, "always-recreate-deps", false, "Recreate dependent containers. Incompatible with --no-recreate.") flags.BoolVarP(&opts.noInherit, "renew-anon-volumes", "V", false, "Recreate anonymous volumes instead of retrieving data from the previous containers.") } @@ -192,9 +207,11 @@ func runCreateStart(ctx context.Context, opts upOptions, services []string) erro _, err = progress.Run(ctx, func(ctx context.Context) (string, error) { err := c.ComposeService().Create(ctx, project, compose.CreateOptions{ - RemoveOrphans: opts.removeOrphans, - Recreate: opts.recreateStrategy(), - Inherit: !opts.noInherit, + Services: services, + RemoveOrphans: opts.removeOrphans, + Recreate: opts.recreateStrategy(), + RecreateDependencies: opts.dependenciesRecreateStrategy(), + Inherit: !opts.noInherit, }) if err != nil { return "", err diff --git a/local/compose/create.go b/local/compose/create.go index 61b774932..123502030 100644 --- a/local/compose/create.go +++ b/local/compose/create.go @@ -42,6 +42,10 @@ import ( ) func (s *composeService) Create(ctx context.Context, project *types.Project, opts compose.CreateOptions) error { + if len(opts.Services) == 0 { + opts.Services = project.ServiceNames() + } + err := s.ensureImagesExists(ctx, project) if err != nil { return err @@ -97,7 +101,10 @@ func (s *composeService) Create(ctx context.Context, project *types.Project, opt prepareNetworkMode(project) return InDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error { - return s.ensureService(c, project, service, opts.Recreate, opts.Inherit) + if contains(opts.Services, service.Name) { + return s.ensureService(c, project, service, opts.Recreate, opts.Inherit) + } + return s.ensureService(c, project, service, opts.RecreateDependencies, opts.Inherit) }) }