Skip to content

Commit

Permalink
Add --pull option to build command
Browse files Browse the repository at this point in the history
Signed-off-by: David Son <[email protected]>
  • Loading branch information
sondavidb committed Jun 10, 2024
1 parent a5e8b64 commit c5f5be4
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cmd/nerdctl/builder_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ If Dockerfile is not present and -f is not specified, it will look for Container
buildCommand.Flags().StringP("output", "o", "", "Output destination (format: type=local,dest=path)")
buildCommand.Flags().String("progress", "auto", "Set type of progress output (auto, plain, tty). Use plain to show container output")
buildCommand.Flags().String("provenance", "", "Shorthand for \"--attest=type=provenance\"")
buildCommand.Flags().String("pull", "", "On true, always attempt to pull latest image version from remote. Default uses buildkit's default.")
buildCommand.Flags().StringArray("secret", nil, "Secret file to expose to the build: id=mysecret,src=/local/secret")
buildCommand.Flags().StringArray("allow", nil, "Allow extra privileged entitlement, e.g. network.host, security.insecure")
buildCommand.RegisterFlagCompletionFunc("allow", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
Expand Down Expand Up @@ -133,6 +134,10 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
if err != nil {
return types.BuilderBuildOptions{}, err
}
pull, err := cmd.Flags().GetString("pull")
if err != nil {
return types.BuilderBuildOptions{}, err
}
secret, err := cmd.Flags().GetStringArray("secret")
if err != nil {
return types.BuilderBuildOptions{}, err
Expand Down Expand Up @@ -205,6 +210,7 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
BuildArgs: buildArgs,
Label: label,
NoCache: noCache,
Pull: pull,
Secret: secret,
Allow: allow,
Attest: attest,
Expand Down
84 changes: 84 additions & 0 deletions cmd/nerdctl/builder_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package main
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"

Expand Down Expand Up @@ -592,3 +594,85 @@ func TestBuildAttestation(t *testing.T) {
t.Fatal(err)
}
}

func TestBuildWithPull(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Windows is not supported for this test right now")
}

testutil.RequiresBuild(t)

oldImage := "ubuntu:18.04"
oldImageSha := "152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98"
newImage := "ubuntu:latest"

buildkitConfig := fmt.Sprintf(`[worker.oci]
enabled = false
[worker.containerd]
enabled = true
namespace = "%s"`, testutil.Namespace)

cleanup := useBuildkitConfig(t, buildkitConfig)
defer cleanup()

testCases := []struct {
name string
pull string
}{
{
name: "build with local image",
pull: "false",
},
{
name: "build with newest image",
pull: "true",
},
}

for _, tc := range testCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
base := testutil.NewBase(t)
defer base.Cmd("builder", "prune").AssertOK()
base.Cmd("image", "prune", "--force", "--all").AssertOK()

base.Cmd("pull", oldImage).Run()
base.Cmd("tag", oldImage, newImage).Run()

dockerfile := fmt.Sprintf(`FROM %s`, newImage)
tmpDir := t.TempDir()
err := os.WriteFile(filepath.Join(tmpDir, "Dockerfile"), []byte(dockerfile), 0644)
assert.NilError(t, err)

buildCtx := createBuildContext(t, dockerfile)

buildCmd := []string{"build", buildCtx}
switch tc.pull {
case "false":
buildCmd = append(buildCmd, "--pull=false")
base.Cmd(buildCmd...).AssertErrContains(oldImageSha)
case "true":
buildCmd = append(buildCmd, "--pull=true")
base.Cmd(buildCmd...).AssertErrNotContains(oldImageSha)
}
})
}
}

func useBuildkitConfig(t *testing.T, config string) (cleanup func()) {
buildkitConfigPath := "/etc/buildkit/buildkitd.toml"

currConfig, err := exec.Command("cat", buildkitConfigPath).Output()
assert.NilError(t, err)

os.WriteFile(buildkitConfigPath, []byte(config), 0644)
_, err = exec.Command("systemctl", "restart", "buildkit").Output()
assert.NilError(t, err)

return func() {
assert.NilError(t, os.WriteFile(buildkitConfigPath, currConfig, 0644))
_, err = exec.Command("systemctl", "restart", "buildkit").Output()
assert.NilError(t, err)
}
}
1 change: 1 addition & 0 deletions docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,7 @@ Flags:
- :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)
- :whale: `--progress=(auto|plain|tty)`: Set type of progress output (auto, plain, tty). Use plain to show container output
- :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
- :whale: `--pull=(true|false)`: On true, always attempt to pull latest image version from remote. Default uses buildkit's default.
- :whale: `--secret`: Secret file to expose to the build: id=mysecret,src=/local/secret
- :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)
- :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
Expand Down
3 changes: 3 additions & 0 deletions pkg/api/types/builder_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ type BuilderBuildOptions struct {
ExtendedBuildContext []string
// NetworkMode mode for the build context
NetworkMode string
// Pull determines if we should attempt to pull the latest image from remote.
// "true" will pull from remote while "false" will always use locally cached image
Pull string
}

// BuilderPruneOptions specifies options for `nerdctl builder prune`.
Expand Down
7 changes: 7 additions & 0 deletions pkg/cmd/builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,13 @@ func generateBuildctlArgs(ctx context.Context, client *containerd.Client, option
buildctlArgs = append(buildctlArgs, "--no-cache")
}

switch options.Pull {
case "true":
buildctlArgs = append(buildctlArgs, "--opt=image-resolve-mode=pull")
case "false":
buildctlArgs = append(buildctlArgs, "--opt=image-resolve-mode=local")
}

for _, s := range strutil.DedupeStrSlice(options.Secret) {
buildctlArgs = append(buildctlArgs, "--secret="+s)
}
Expand Down

0 comments on commit c5f5be4

Please sign in to comment.