Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add network flag to nerdctl build #2383

Merged
merged 1 commit into from
Jul 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion cmd/nerdctl/builder_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@ If Dockerfile is not present and -f is not specified, it will look for Container
buildCommand.Flags().StringArray("cache-from", nil, "External cache sources (eg. user/app:cache, type=local,src=path/to/dir)")
buildCommand.Flags().StringArray("cache-to", nil, "Cache export destinations (eg. user/app:cache, type=local,dest=path/to/dir)")
buildCommand.Flags().Bool("rm", true, "Remove intermediate containers after a successful build")

buildCommand.Flags().String("network", "default", "Set type of network for build (format:network=default|none|host)")
buildCommand.RegisterFlagCompletionFunc("network", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"default", "host", "none"}, cobra.ShellCompDirectiveNoFileComp
})
// #region platform flags
// platform is defined as StringSlice, not StringArray, to allow specifying "--platform=amd64,arm64"
buildCommand.Flags().StringSlice("platform", []string{}, "Set target platform for build (e.g., \"amd64\", \"arm64\")")
Expand Down Expand Up @@ -153,6 +156,10 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
if err != nil {
return types.BuilderBuildOptions{}, err
}
network, err := cmd.Flags().GetString("network")
if err != nil {
return types.BuilderBuildOptions{}, err
}
return types.BuilderBuildOptions{
GOptions: globalOptions,
BuildKitHost: buildKitHost,
Expand All @@ -176,6 +183,7 @@ func processBuildCommandFlag(cmd *cobra.Command, args []string) (types.BuilderBu
Stdout: cmd.OutOrStdout(),
Stderr: cmd.OutOrStderr(),
Stdin: cmd.InOrStdin(),
NetworkMode: network,
}, nil
}

Expand Down
46 changes: 46 additions & 0 deletions cmd/nerdctl/builder_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,49 @@ CMD ["cat", "/source-date-epoch"]
base.Cmd("build", "-t", imageName, "--build-arg", "SOURCE_DATE_EPOCH="+sourceDateEpochArgStr, buildCtx).AssertOK()
base.Cmd("run", "--rm", imageName).AssertOutExactly(sourceDateEpochArgStr + "\n")
}

func TestBuildNetwork(t *testing.T) {
testutil.RequiresBuild(t)
base := testutil.NewBase(t)
defer base.Cmd("builder", "prune").AssertOK()

dockerfile := fmt.Sprintf(`FROM %s
RUN apk add --no-cache curl
RUN curl -I http://google.com
`, testutil.CommonImage)
buildCtx, err := createBuildContext(dockerfile)
assert.NilError(t, err)
defer os.RemoveAll(buildCtx)

validCases := []struct {
name string
network string
exitCode int
}{
// When network=none, can't connect to internet, therefore cannot download packages in the dockerfile
// Order is important here, test fails for `-test.target=docker` in CI
{"test_with_no_network", "none", 1},
{"test_with_empty_network", "", 0},
{"test_with_default_network", "default", 0},
}

for _, tc := range validCases {
tc := tc
t.Run(tc.name, func(t *testing.T) {
// --no-cache is intentional here for `-test.target=docker`
base.Cmd("build", buildCtx, "-t", tc.name, "--no-cache", "--network", tc.network).AssertExitCode(tc.exitCode)
if tc.exitCode != 1 {
defer base.Cmd("rmi", tc.name).AssertOK()
}
})
}
}

func TestBuildNetworkShellCompletion(t *testing.T) {
testutil.DockerIncompatible(t)
base := testutil.NewBase(t)
const gsc = "__complete"
// Tests with build network
networkName := "default"
base.Cmd(gsc, "build", "--network", "").AssertOutContains(networkName)
}
2 changes: 1 addition & 1 deletion cmd/nerdctl/completion_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestCompletion(t *testing.T) {
base.Cmd(gsc, "run", "-it", "").AssertOutContains(testutil.AlpineImage)
base.Cmd(gsc, "run", "-it", "--rm", "").AssertOutContains(testutil.AlpineImage)

// Tests with an network
// Tests with a network
testNetworkName := "nerdctl-test-completion"
defer base.Cmd("network", "rm", testNetworkName).Run()
base.Cmd("network", "create", testNetworkName).AssertOK()
Expand Down
3 changes: 2 additions & 1 deletion docs/command-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -655,8 +655,9 @@ Flags:
- :whale: `--iidfile=FILE`: Write the image ID to the file
- :nerd_face: `--ipfs`: Build image with pulling base images from IPFS. See [`ipfs.md`](./ipfs.md) for details.
- :whale: `--label`: Set metadata for an image
- :whale: `--network=(default|host|none)`: Set the networking mode for the RUN instructions during build.(compatible with `buildctl build`)

Unimplemented `docker build` flags: `--add-host`, `--network`, `--squash`
Unimplemented `docker build` flags: `--add-host`, `--squash`

### :whale: nerdctl commit

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 @@ -61,6 +61,8 @@ type BuilderBuildOptions struct {
Label []string
// BuildContext is the build context
BuildContext string
// NetworkMode mode for the build context
NetworkMode string
}

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

if options.NetworkMode != "" {
switch options.NetworkMode {
case "none":
buildctlArgs = append(buildctlArgs, "--opt=force-network-mode="+options.NetworkMode)
case "host":
buildctlArgs = append(buildctlArgs, "--opt=force-network-mode="+options.NetworkMode, "--allow=network.host", "--allow=security.insecure")
case "", "default":
default:
logrus.Debugf("ignoring network build arg %s", options.NetworkMode)
}
}

return buildctlBinary, buildctlArgs, needsLoading, metaFile, tags, cleanup, nil
}

Expand Down