Skip to content

Commit

Permalink
Merge pull request #3745 from manugupt1/docker-compose-up-pull
Browse files Browse the repository at this point in the history
3432: Support --pull flag in nerdctl compose up
  • Loading branch information
AkihiroSuda authored Dec 11, 2024
2 parents cc9a3fc + e3b231e commit 580d47c
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 4 deletions.
6 changes: 6 additions & 0 deletions cmd/nerdctl/compose/compose_up.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func newComposeUpCommand() *cobra.Command {
composeUpCommand.Flags().Bool("force-recreate", false, "Recreate containers even if their configuration and image haven't changed.")
composeUpCommand.Flags().Bool("no-recreate", false, "Don't recreate containers if they exist, conflict with --force-recreate.")
composeUpCommand.Flags().StringArray("scale", []string{}, "Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present.")
composeUpCommand.Flags().String("pull", "", "Pull image before running (\"always\"|\"missing\"|\"never\")")
return composeUpCommand
}

Expand Down Expand Up @@ -96,6 +97,10 @@ func composeUpAction(cmd *cobra.Command, services []string) error {
if err != nil {
return err
}
pull, err := cmd.Flags().GetString("pull")
if err != nil {
return err
}
removeOrphans, err := cmd.Flags().GetBool("remove-orphans")
if err != nil {
return err
Expand Down Expand Up @@ -154,6 +159,7 @@ func composeUpAction(cmd *cobra.Command, services []string) error {
QuietPull: quietPull,
RemoveOrphans: removeOrphans,
Scale: scale,
Pull: pull,
ForceRecreate: forceRecreate,
NoRecreate: noRecreate,
}
Expand Down
54 changes: 54 additions & 0 deletions cmd/nerdctl/compose/compose_up_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -579,3 +579,57 @@ services:
}
c.Assert(expected)
}

func TestComposeUpPull(t *testing.T) {
base := testutil.NewBase(t)

var dockerComposeYAML = fmt.Sprintf(`
services:
test:
image: %s
command: sh -euxc "echo hi"
`, testutil.CommonImage)

comp := testutil.NewComposeDir(t, dockerComposeYAML)
defer comp.CleanUp()

// Cases where pull is required
for _, pull := range []string{"missing", "always"} {
t.Run(fmt.Sprintf("pull=%s", pull), func(t *testing.T) {
base.Cmd("rmi", "-f", testutil.CommonImage).Run()
base.Cmd("images").AssertOutNotContains(testutil.CommonImage)
t.Cleanup(func() {
base.ComposeCmd("-f", comp.YAMLFullPath(), "down").AssertOK()
})
base.ComposeCmd("-f", comp.YAMLFullPath(), "up", "--pull", pull).AssertOutContains("hi")
})
}

t.Run("pull=never, no pull", func(t *testing.T) {
base.Cmd("rmi", "-f", testutil.CommonImage).Run()
base.Cmd("images").AssertOutNotContains(testutil.CommonImage)
t.Cleanup(func() {
base.ComposeCmd("-f", comp.YAMLFullPath(), "down").AssertOK()
})
base.ComposeCmd("-f", comp.YAMLFullPath(), "up", "--pull", "never").AssertExitCode(1)
})
}

func TestComposeUpServicePullPolicy(t *testing.T) {
base := testutil.NewBase(t)

var dockerComposeYAML = fmt.Sprintf(`
services:
test:
image: %s
command: sh -euxc "echo hi"
pull_policy: "never"
`, testutil.CommonImage)

comp := testutil.NewComposeDir(t, dockerComposeYAML)
defer comp.CleanUp()

base.Cmd("rmi", "-f", testutil.CommonImage).Run()
base.Cmd("images").AssertOutNotContains(testutil.CommonImage)
base.ComposeCmd("-f", comp.YAMLFullPath(), "up").AssertExitCode(1)
}
1 change: 1 addition & 0 deletions docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,7 @@ Flags:
- :whale: `--remove-orphans`: Remove containers for services not defined in the Compose file
- :whale: `--force-recreate`: force Compose to stop and recreate all containers
- :whale: `--no-recreate`: force Compose to reuse existing containers
- :whale: `--pull`: Pull image before running ("always"|"missing"|"never")

Unimplemented `docker-compose up` (V1) flags: `--no-deps`, `--always-recreate-deps`,
`--no-start`, `--abort-on-container-exit`, `--attach-dependencies`, `--timeout`, `--renew-anon-volumes`, `--exit-code-from`
Expand Down
2 changes: 1 addition & 1 deletion pkg/composer/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ func (c *Composer) Create(ctx context.Context, opt CreateOptions, services []str
return err
}
for _, ps := range parsedServices {
if err := c.ensureServiceImage(ctx, ps, !opt.NoBuild, opt.Build, BuildOptions{}, false); err != nil {
if err := c.ensureServiceImage(ctx, ps, !opt.NoBuild, opt.Build, BuildOptions{}, false, ""); err != nil {
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/composer/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func (c *Composer) runServices(ctx context.Context, parsedServices []*servicepar

// TODO: parallelize loop for ensuring images (make sure not to mess up tty)
for _, ps := range parsedServices {
if err := c.ensureServiceImage(ctx, ps, !ro.NoBuild, ro.ForceBuild, BuildOptions{}, ro.QuietPull); err != nil {
if err := c.ensureServiceImage(ctx, ps, !ro.NoBuild, ro.ForceBuild, BuildOptions{}, ro.QuietPull, ""); err != nil {
return err
}
}
Expand Down
1 change: 1 addition & 0 deletions pkg/composer/up.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type UpOptions struct {
ForceRecreate bool
NoRecreate bool
Scale map[string]int // map of service name to replicas
Pull string
}

func (opts UpOptions) recreateStrategy() string {
Expand Down
7 changes: 5 additions & 2 deletions pkg/composer/up_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (c *Composer) upServices(ctx context.Context, parsedServices []*servicepars

// TODO: parallelize loop for ensuring images (make sure not to mess up tty)
for _, ps := range parsedServices {
if err := c.ensureServiceImage(ctx, ps, !uo.NoBuild, uo.ForceBuild, BuildOptions{}, uo.QuietPull); err != nil {
if err := c.ensureServiceImage(ctx, ps, !uo.NoBuild, uo.ForceBuild, BuildOptions{}, uo.QuietPull, uo.Pull); err != nil {
return err
}
}
Expand Down Expand Up @@ -101,7 +101,7 @@ func (c *Composer) upServices(ctx context.Context, parsedServices []*servicepars
return nil
}

func (c *Composer) ensureServiceImage(ctx context.Context, ps *serviceparser.Service, allowBuild, forceBuild bool, bo BuildOptions, quiet bool) error {
func (c *Composer) ensureServiceImage(ctx context.Context, ps *serviceparser.Service, allowBuild, forceBuild bool, bo BuildOptions, quiet bool, pullModeArg string) error {
if ps.Build != nil && allowBuild {
if ps.Build.Force || forceBuild {
return c.buildServiceImage(ctx, ps.Image, ps.Build, ps.Unparsed.Platform, bo)
Expand All @@ -117,6 +117,9 @@ func (c *Composer) ensureServiceImage(ctx context.Context, ps *serviceparser.Ser
}

log.G(ctx).Infof("Ensuring image %s", ps.Image)
if pullModeArg != "" {
return c.EnsureImage(ctx, ps.Image, pullModeArg, ps.Unparsed.Platform, ps, quiet)
}
return c.EnsureImage(ctx, ps.Image, ps.PullMode, ps.Unparsed.Platform, ps, quiet)
}

Expand Down

0 comments on commit 580d47c

Please sign in to comment.