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 17, 2024
1 parent a5e8b64 commit 819f183
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 0 deletions.
10 changes: 10 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().Bool("pull", true, "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,14 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
if err != nil {
return types.BuilderBuildOptions{}, err
}
var pull *bool
if cmd.Flags().Changed("pull") {
pullFlag, err := cmd.Flags().GetBool("pull")
if err != nil {
return types.BuilderBuildOptions{}, err
}
pull = &pullFlag
}
secret, err := cmd.Flags().GetStringArray("secret")
if err != nil {
return types.BuilderBuildOptions{}, err
Expand Down Expand Up @@ -205,6 +214,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
90 changes: 90 additions & 0 deletions cmd/nerdctl/builder_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ package main
import (
"bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/containerd/nerdctl/v2/pkg/testutil"
"gotest.tools/v3/assert"
)

func TestBuilderDebug(t *testing.T) {
Expand All @@ -36,3 +40,89 @@ CMD ["echo", "nerdctl-builder-debug-test-string"]

base.Cmd("builder", "debug", buildCtx).CmdOption(testutil.WithStdin(bytes.NewReader([]byte("c\n")))).AssertOK()
}

func TestBuildWithPull(t *testing.T) {
testutil.DockerIncompatible(t)
testutil.RequiresBuild(t)

oldImage := testutil.BusyboxImage
oldImageSha := "141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47"
newImage := testutil.AlpineImage

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",
},
{
name: "build with buildkit default",
// buildkit default pulls from remote
pull: "default",
},
}

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)
case "default":
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
2 changes: 2 additions & 0 deletions pkg/api/types/builder_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ type BuilderBuildOptions struct {
ExtendedBuildContext []string
// NetworkMode mode for the build context
NetworkMode string
// Pull determines if we should try to pull latest image from remote. Default is buildkit's default.
Pull *bool
}

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

if options.Pull != nil {
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 819f183

Please sign in to comment.