Skip to content

Commit

Permalink
3432: Support --pull flag in nerdctl compose up
Browse files Browse the repository at this point in the history
Signed-off-by: Manu Gupta <[email protected]>
  • Loading branch information
manugupt1 committed Dec 10, 2024
1 parent 00f6acd commit 7b8d0f7
Show file tree
Hide file tree
Showing 6 changed files with 49 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", "missing", "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
35 changes: 35 additions & 0 deletions cmd/nerdctl/compose/compose_up_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,38 @@ services:
assert.NilError(t, err)
assert.Equal(t, "hi\n", string(testB))
}

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", 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", 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)
})
}
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 7b8d0f7

Please sign in to comment.