Skip to content

Commit 4d44b73

Browse files
committed
Add --pull option to build command
Signed-off-by: David Son <[email protected]>
1 parent a5e8b64 commit 4d44b73

File tree

5 files changed

+90
-0
lines changed

5 files changed

+90
-0
lines changed

cmd/nerdctl/builder_build.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ If Dockerfile is not present and -f is not specified, it will look for Container
5151
buildCommand.Flags().StringP("output", "o", "", "Output destination (format: type=local,dest=path)")
5252
buildCommand.Flags().String("progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
5353
buildCommand.Flags().String("provenance", "", "Shorthand for \"--attest=type=provenance\"")
54+
buildCommand.Flags().String("pull", "", "On true, always attempt to pull latest image version from remote. Default uses buildkit's default.")
5455
buildCommand.Flags().StringArray("secret", nil, "Secret file to expose to the build: id=mysecret,src=/local/secret")
5556
buildCommand.Flags().StringArray("allow", nil, "Allow extra privileged entitlement, e.g. network.host, security.insecure")
5657
buildCommand.RegisterFlagCompletionFunc("allow", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
@@ -133,6 +134,10 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
133134
if err != nil {
134135
return types.BuilderBuildOptions{}, err
135136
}
137+
pull, err := cmd.Flags().GetString("pull")
138+
if err != nil {
139+
return types.BuilderBuildOptions{}, err
140+
}
136141
secret, err := cmd.Flags().GetStringArray("secret")
137142
if err != nil {
138143
return types.BuilderBuildOptions{}, err
@@ -205,6 +210,7 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
205210
BuildArgs: buildArgs,
206211
Label: label,
207212
NoCache: noCache,
213+
Pull: pull,
208214
Secret: secret,
209215
Allow: allow,
210216
Attest: attest,

cmd/nerdctl/builder_build_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package main
1919
import (
2020
"fmt"
2121
"os"
22+
"os/exec"
2223
"path/filepath"
2324
"strings"
2425
"testing"
@@ -592,3 +593,75 @@ func TestBuildAttestation(t *testing.T) {
592593
t.Fatal(err)
593594
}
594595
}
596+
597+
func TestBuildWithPull(t *testing.T) {
598+
testutil.RequiresBuild(t)
599+
600+
oldImage := "ubuntu:18.04"
601+
oldImageSha := "152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98"
602+
newImage := "ubuntu:latest"
603+
604+
buildkitConfigPath := "/etc/buildkit/buildkitd.toml"
605+
606+
currConfig, err := exec.Command("cat", buildkitConfigPath).Output()
607+
assert.NilError(t, err)
608+
609+
defer func() {
610+
assert.NilError(t, os.WriteFile(buildkitConfigPath, currConfig, 0644))
611+
_, err = exec.Command("systemctl", "restart", "buildkit").Output()
612+
assert.NilError(t, err)
613+
}()
614+
615+
buildkitConfig := fmt.Sprintf(`[worker.oci]
616+
enabled = false
617+
618+
[worker.containerd]
619+
enabled = true
620+
namespace = "%s"`, testutil.Namespace)
621+
os.WriteFile(buildkitConfigPath, []byte(buildkitConfig), 0644)
622+
_, err = exec.Command("systemctl", "restart", "buildkit").Output()
623+
assert.NilError(t, err)
624+
625+
testCases := []struct {
626+
name string
627+
pull string
628+
}{
629+
{
630+
name: "build with local image",
631+
pull: "false",
632+
},
633+
{
634+
name: "build with newest image",
635+
pull: "true",
636+
},
637+
}
638+
639+
for _, tc := range testCases {
640+
tc := tc
641+
t.Run(tc.name, func(t *testing.T) {
642+
base := testutil.NewBase(t)
643+
defer base.Cmd("builder", "prune").AssertOK()
644+
base.Cmd("image", "prune", "--force", "--all").AssertOK()
645+
646+
base.Cmd("pull", oldImage).Run()
647+
base.Cmd("tag", oldImage, newImage).Run()
648+
649+
dockerfile := fmt.Sprintf(`FROM %s`, newImage)
650+
tmpDir := t.TempDir()
651+
err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644)
652+
assert.NilError(t, err)
653+
654+
buildCtx := createBuildContext(t, dockerfile)
655+
656+
buildCmd := []string{"build", buildCtx}
657+
switch tc.pull {
658+
case "false":
659+
buildCmd = append(buildCmd, "--pull=false")
660+
base.Cmd(buildCmd...).AssertErrContains(oldImageSha)
661+
case "true":
662+
buildCmd = append(buildCmd, "--pull=true")
663+
base.Cmd(buildCmd...).AssertErrNotContains(oldImageSha)
664+
}
665+
})
666+
}
667+
}

docs/command-reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ Flags:
692692
- :whale: `type=image,name=example.com/image,push=true`: Push to a registry (see [`buildctl build`](https://github.com/moby/buildkit/tree/v0.9.0#imageregistry) documentation)
693693
- :whale: `--progress=(auto|plain|tty)`: Set type of progress output (auto, plain, tty). Use plain to show container output
694694
- :whale: `--provenance`: Shorthand for \"--attest=type=provenance\", see [`buildx_build.md`](https://github.com/docker/buildx/blob/v0.12.1/docs/reference/buildx_build.md#provenance) documentation
695+
- :whale: `--pull=(true|false)`: On true, always attempt to pull latest image version from remote. Default uses buildkit's default.
695696
- :whale: `--secret`: Secret file to expose to the build: id=mysecret,src=/local/secret
696697
- :whale: `--allow`: Allow extra privileged entitlement, e.g. network.host, security.insecure (It’s required to configure the buildkitd to enable the feature, see [`buildkitd.toml`](https://github.com/moby/buildkit/blob/master/docs/buildkitd.toml.md) documentation)
697698
- :whale: `--attest`: Attestation parameters (format: "type=sbom,generator=image"), see [`buildx_build.md`](https://github.com/docker/buildx/blob/v0.12.1/docs/reference/buildx_build.md#attest) documentation

pkg/api/types/builder_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ type BuilderBuildOptions struct {
6969
ExtendedBuildContext []string
7070
// NetworkMode mode for the build context
7171
NetworkMode string
72+
// Pull determines if we should attempt to pull the latest image from remote.
73+
// "true" will pull from remote while "false" will always use locally cached image
74+
Pull string
7275
}
7376

7477
// BuilderPruneOptions specifies options for `nerdctl builder prune`.

pkg/cmd/builder/build.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,13 @@ func generateBuildctlArgs(ctx context.Context, client *containerd.Client, option
367367
buildctlArgs = append(buildctlArgs, "--no-cache")
368368
}
369369

370+
switch options.Pull {
371+
case "true":
372+
buildctlArgs = append(buildctlArgs, "--opt=image-resolve-mode=pull")
373+
case "false":
374+
buildctlArgs = append(buildctlArgs, "--opt=image-resolve-mode=local")
375+
}
376+
370377
for _, s := range strutil.DedupeStrSlice(options.Secret) {
371378
buildctlArgs = append(buildctlArgs, "--secret="+s)
372379
}

0 commit comments

Comments
 (0)