Skip to content
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
13 changes: 8 additions & 5 deletions cli/command/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ import (
)

type createOptions struct {
name string
name string
platform string
}

// NewCreateCommand creates a new cobra.Command for `docker create`
Expand Down Expand Up @@ -51,6 +52,7 @@ func NewCreateCommand(dockerCli command.Cli) *cobra.Command {
// with hostname
flags.Bool("help", false, "Print usage")

command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
copts = addFlags(flags)
return cmd
Expand All @@ -62,15 +64,15 @@ func runCreate(dockerCli command.Cli, flags *pflag.FlagSet, opts *createOptions,
reportError(dockerCli.Err(), "create", err.Error(), true)
return cli.StatusError{StatusCode: 125}
}
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts.name)
response, err := createContainer(context.Background(), dockerCli, containerConfig, opts.name, opts.platform)
if err != nil {
return err
}
fmt.Fprintln(dockerCli.Out(), response.ID)
return nil
}

func pullImage(ctx context.Context, dockerCli command.Cli, image string, out io.Writer) error {
func pullImage(ctx context.Context, dockerCli command.Cli, image string, platform string, out io.Writer) error {
ref, err := reference.ParseNormalizedNamed(image)
if err != nil {
return err
Expand All @@ -90,6 +92,7 @@ func pullImage(ctx context.Context, dockerCli command.Cli, image string, out io.

options := types.ImageCreateOptions{
RegistryAuth: encodedAuth,
Platform: platform,
}

responseBody, err := dockerCli.Client().ImageCreate(ctx, image, options)
Expand Down Expand Up @@ -155,7 +158,7 @@ func newCIDFile(path string) (*cidFile, error) {
return &cidFile{path: path, file: f}, nil
}

func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, name string) (*container.ContainerCreateCreatedBody, error) {
func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig *containerConfig, name string, platform string) (*container.ContainerCreateCreatedBody, error) {
config := containerConfig.Config
hostConfig := containerConfig.HostConfig
networkingConfig := containerConfig.NetworkingConfig
Expand Down Expand Up @@ -198,7 +201,7 @@ func createContainer(ctx context.Context, dockerCli command.Cli, containerConfig
fmt.Fprintf(stderr, "Unable to find image '%s' locally\n", reference.FamiliarString(namedRef))

// we don't want to write to stdout anything apart from container.ID
if err := pullImage(ctx, dockerCli, config.Image, stderr); err != nil {
if err := pullImage(ctx, dockerCli, config.Image, platform, stderr); err != nil {
return nil, err
}
if taggedRef, ok := namedRef.(reference.NamedTagged); ok && trustedRef != nil {
Expand Down
3 changes: 2 additions & 1 deletion cli/command/container/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"io/ioutil"
"os"
"runtime"
"strings"
"testing"

Expand Down Expand Up @@ -106,7 +107,7 @@ func TestCreateContainerPullsImageIfMissing(t *testing.T) {
},
HostConfig: &container.HostConfig{},
}
body, err := createContainer(context.Background(), cli, config, "name")
body, err := createContainer(context.Background(), cli, config, "name", runtime.GOOS)
require.NoError(t, err)
expected := container.ContainerCreateCreatedBody{ID: containerID}
assert.Equal(t, expected, *body)
Expand Down
4 changes: 3 additions & 1 deletion cli/command/container/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type runOptions struct {
sigProxy bool
name string
detachKeys string
platform string
}

// NewRunCommand create a new `docker run` command
Expand Down Expand Up @@ -62,6 +63,7 @@ func NewRunCommand(dockerCli command.Cli) *cobra.Command {
// with hostname
flags.Bool("help", false, "Print usage")

command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)
copts = addFlags(flags)
return cmd
Expand Down Expand Up @@ -160,7 +162,7 @@ func runContainer(dockerCli command.Cli, opts *runOptions, copts *containerOptio

ctx, cancelFun := context.WithCancel(context.Background())

createResponse, err := createContainer(ctx, dockerCli, containerConfig, opts.name)
createResponse, err := createContainer(ctx, dockerCli, containerConfig, opts.name, opts.platform)
if err != nil {
reportError(stderr, cmdPath, err.Error(), true)
return runStartContainerErr(err)
Expand Down
3 changes: 3 additions & 0 deletions cli/command/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ type buildOptions struct {
target string
imageIDFile string
stream bool
platform string
}

// dockerfileFromStdin returns true when the user specified that the Dockerfile
Expand Down Expand Up @@ -135,6 +136,7 @@ func NewBuildCommand(dockerCli command.Cli) *cobra.Command {
flags.StringVar(&options.imageIDFile, "iidfile", "", "Write the image ID to the file")

command.AddTrustVerificationFlags(flags)
command.AddPlatformFlag(flags, &options.platform)

flags.BoolVar(&options.squash, "squash", false, "Squash newly built layers into a single new layer")
flags.SetAnnotation("squash", "experimental", nil)
Expand Down Expand Up @@ -374,6 +376,7 @@ func runBuild(dockerCli command.Cli, options buildOptions) error {
ExtraHosts: options.extraHosts.GetAll(),
Target: options.target,
RemoteContext: remote,
Platform: options.platform,
}

if s != nil {
Expand Down
11 changes: 7 additions & 4 deletions cli/command/image/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (
)

type pullOptions struct {
remote string
all bool
remote string
all bool
platform string
}

// NewPullCommand creates a new `docker pull` command
Expand All @@ -35,6 +36,8 @@ func NewPullCommand(dockerCli command.Cli) *cobra.Command {
flags := cmd.Flags()

flags.BoolVarP(&opts.all, "all-tags", "a", false, "Download all tagged images in the repository")

command.AddPlatformFlag(flags, &opts.platform)
command.AddTrustVerificationFlags(flags)

return cmd
Expand Down Expand Up @@ -63,9 +66,9 @@ func runPull(cli command.Cli, opts pullOptions) error {
// Check if reference has a digest
_, isCanonical := distributionRef.(reference.Canonical)
if command.IsTrusted() && !isCanonical {
err = trustedPull(ctx, cli, imgRefAndAuth)
err = trustedPull(ctx, cli, imgRefAndAuth, opts.platform)
} else {
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all)
err = imagePullPrivileged(ctx, cli, imgRefAndAuth, opts.all, opts.platform)
}
if err != nil {
if strings.Contains(err.Error(), "when fetching 'plugin'") {
Expand Down
8 changes: 4 additions & 4 deletions cli/command/image/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ func imagePushPrivileged(ctx context.Context, cli command.Cli, authConfig types.
}

// trustedPull handles content trust pulling of an image
func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth) error {
func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, platform string) error {
refs, err := getTrustedPullTargets(cli, imgRefAndAuth)
if err != nil {
return err
Expand All @@ -202,7 +202,7 @@ func trustedPull(ctx context.Context, cli command.Cli, imgRefAndAuth trust.Image
if err != nil {
return err
}
if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, false); err != nil {
if err := imagePullPrivileged(ctx, cli, updatedImgRefAndAuth, false, platform); err != nil {
return err
}

Expand Down Expand Up @@ -268,7 +268,7 @@ func getTrustedPullTargets(cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth)
}

// imagePullPrivileged pulls the image and displays it to the output
func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, all bool) error {
func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth trust.ImageRefAndAuth, all bool, platform string) error {
ref := reference.FamiliarString(imgRefAndAuth.Reference())

encodedAuth, err := command.EncodeAuthToBase64(*imgRefAndAuth.AuthConfig())
Expand All @@ -280,8 +280,8 @@ func imagePullPrivileged(ctx context.Context, cli command.Cli, imgRefAndAuth tru
RegistryAuth: encodedAuth,
PrivilegeFunc: requestPrivilege,
All: all,
Platform: platform,
}

responseBody, err := cli.Client().ImagePull(ctx, ref, options)
if err != nil {
return err
Expand Down
8 changes: 8 additions & 0 deletions cli/command/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/pkg/system"
"github.com/spf13/pflag"
)

// CopyToFile writes the content of the reader to the specified file
Expand Down Expand Up @@ -117,3 +118,10 @@ func PruneFilters(dockerCli Cli, pruneFilters filters.Args) filters.Args {

return pruneFilters
}

// AddPlatformFlag adds `platform` to a set of flags for API version 1.32 and later.
func AddPlatformFlag(flags *pflag.FlagSet, target *string) {
flags.StringVar(target, "platform", os.Getenv("DOCKER_DEFAULT_PLATFORM"), "Set platform if server is multi-platform capable")
flags.SetAnnotation("platform", "version", []string{"1.32"})
flags.SetAnnotation("platform", "experimental", nil)
}