mirror of
https://github.com/docker/cli.git
synced 2025-08-01 04:26:55 +03:00
Merge pull request #6126 from ctalledo/fix-for-moby-48759
Add support for multiple platform options in image load and save
This commit is contained in:
@ -11,6 +11,7 @@ import (
|
||||
"github.com/docker/cli/internal/jsonstream"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/sys/sequential"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -18,7 +19,7 @@ import (
|
||||
type loadOptions struct {
|
||||
input string
|
||||
quiet bool
|
||||
platform string
|
||||
platform []string
|
||||
}
|
||||
|
||||
// NewLoadCommand creates a new `docker load` command
|
||||
@ -42,7 +43,7 @@ func NewLoadCommand(dockerCli command.Cli) *cobra.Command {
|
||||
|
||||
flags.StringVarP(&opts.input, "input", "i", "", "Read from tar archive file, instead of STDIN")
|
||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Suppress the load output")
|
||||
flags.StringVar(&opts.platform, "platform", "", `Load only the given platform variant. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
|
||||
flags.StringSliceVar(&opts.platform, "platform", []string{}, `Load only the given platform(s). Formatted as a comma-separated list of "os[/arch[/variant]]" (e.g., "linux/amd64,linux/arm64/v8").`)
|
||||
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||
@ -76,13 +77,16 @@ func runLoad(ctx context.Context, dockerCli command.Cli, opts loadOptions) error
|
||||
options = append(options, client.ImageLoadWithQuiet(true))
|
||||
}
|
||||
|
||||
if opts.platform != "" {
|
||||
p, err := platforms.Parse(opts.platform)
|
||||
platformList := []ocispec.Platform{}
|
||||
for _, p := range opts.platform {
|
||||
pp, err := platforms.Parse(p)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid platform")
|
||||
}
|
||||
// TODO(thaJeztah): change flag-type to support multiple platforms.
|
||||
options = append(options, client.ImageLoadWithPlatforms(p))
|
||||
platformList = append(platformList, pp)
|
||||
}
|
||||
if len(platformList) > 0 {
|
||||
options = append(options, client.ImageLoadWithPlatforms(platformList...))
|
||||
}
|
||||
|
||||
response, err := dockerCli.Client().ImageLoad(ctx, input, options...)
|
||||
|
@ -104,7 +104,7 @@ func TestNewLoadCommandSuccess(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with platform",
|
||||
name: "with-single-platform",
|
||||
args: []string{"--platform", "linux/amd64"},
|
||||
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
|
||||
// FIXME(thaJeztah): need to find appropriate way to test the result of "ImageHistoryWithPlatform" being applied
|
||||
@ -113,6 +113,22 @@ func TestNewLoadCommandSuccess(t *testing.T) {
|
||||
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with-comma-separated-platforms",
|
||||
args: []string{"--platform", "linux/amd64,linux/arm64/v8,linux/riscv64"},
|
||||
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
|
||||
assert.Check(t, len(options) > 0) // can be 1 or two depending on whether a terminal is attached :/
|
||||
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with-multiple-platform-options",
|
||||
args: []string{"--platform", "linux/amd64", "--platform", "linux/arm64/v8", "--platform", "linux/riscv64"},
|
||||
imageLoadFunc: func(input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
|
||||
assert.Check(t, len(options) > 0) // can be 1 or two depending on whether a terminal is attached :/
|
||||
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/docker/cli/cli/command/completion"
|
||||
"github.com/moby/moby/client"
|
||||
"github.com/moby/sys/atomicwriter"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -17,7 +18,7 @@ import (
|
||||
type saveOptions struct {
|
||||
images []string
|
||||
output string
|
||||
platform string
|
||||
platform []string
|
||||
}
|
||||
|
||||
// NewSaveCommand creates a new `docker save` command
|
||||
@ -41,7 +42,7 @@ func NewSaveCommand(dockerCli command.Cli) *cobra.Command {
|
||||
flags := cmd.Flags()
|
||||
|
||||
flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT")
|
||||
flags.StringVar(&opts.platform, "platform", "", `Save only the given platform variant. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
|
||||
flags.StringSliceVar(&opts.platform, "platform", []string{}, `Save only the given platform(s). Formatted as a comma-separated list of "os[/arch[/variant]]" (e.g., "linux/amd64,linux/arm64/v8")`)
|
||||
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
|
||||
|
||||
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||
@ -51,13 +52,17 @@ func NewSaveCommand(dockerCli command.Cli) *cobra.Command {
|
||||
// runSave performs a save against the engine based on the specified options
|
||||
func runSave(ctx context.Context, dockerCLI command.Cli, opts saveOptions) error {
|
||||
var options []client.ImageSaveOption
|
||||
if opts.platform != "" {
|
||||
p, err := platforms.Parse(opts.platform)
|
||||
|
||||
platformList := []ocispec.Platform{}
|
||||
for _, p := range opts.platform {
|
||||
pp, err := platforms.Parse(p)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "invalid platform")
|
||||
}
|
||||
// TODO(thaJeztah): change flag-type to support multiple platforms.
|
||||
options = append(options, client.ImageSaveWithPlatforms(p))
|
||||
platformList = append(platformList, pp)
|
||||
}
|
||||
if len(platformList) > 0 {
|
||||
options = append(options, client.ImageSaveWithPlatforms(platformList...))
|
||||
}
|
||||
|
||||
var output io.Writer
|
||||
|
@ -111,6 +111,26 @@ func TestNewSaveCommandSuccess(t *testing.T) {
|
||||
return io.NopCloser(strings.NewReader("")), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
args: []string{"--platform", "linux/amd64,linux/arm64/v8,linux/riscv64", "arg1"},
|
||||
isTerminal: false,
|
||||
imageSaveFunc: func(images []string, options ...client.ImageSaveOption) (io.ReadCloser, error) {
|
||||
assert.Assert(t, is.Len(images, 1))
|
||||
assert.Check(t, is.Equal("arg1", images[0]))
|
||||
assert.Check(t, len(options) > 0) // can be 1 or 2 depending on whether a terminal is attached :/
|
||||
return io.NopCloser(strings.NewReader("")), nil
|
||||
},
|
||||
},
|
||||
{
|
||||
args: []string{"--platform", "linux/amd64", "--platform", "linux/arm64/v8", "--platform", "linux/riscv64", "arg1"},
|
||||
isTerminal: false,
|
||||
imageSaveFunc: func(images []string, options ...client.ImageSaveOption) (io.ReadCloser, error) {
|
||||
assert.Assert(t, is.Len(images, 1))
|
||||
assert.Check(t, is.Equal("arg1", images[0]))
|
||||
assert.Check(t, len(options) > 0) // can be 1 or 2 depending on whether a terminal is attached :/
|
||||
return io.NopCloser(strings.NewReader("")), nil
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(strings.Join(tc.args, " "), func(t *testing.T) {
|
||||
|
1
cli/command/image/testdata/load-command-success.with-multiple-platform-options.golden
vendored
Normal file
1
cli/command/image/testdata/load-command-success.with-multiple-platform-options.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
Success
|
1
cli/command/image/testdata/load-command-success.with-single-platform.golden
vendored
Normal file
1
cli/command/image/testdata/load-command-success.with-single-platform.golden
vendored
Normal file
@ -0,0 +1 @@
|
||||
Success
|
@ -10,9 +10,9 @@ Load an image from a tar archive or STDIN
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:------------------------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||
|:------------------------------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| [`-i`](#input), [`--input`](#input) | `string` | | Read from tar archive file, instead of STDIN |
|
||||
| [`--platform`](#platform) | `string` | | Load only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||
| [`--platform`](#platform) | `stringSlice` | | Load only the given platform(s). Formatted as a comma-separated list of `os[/arch[/variant]]` (e.g., `linux/amd64,linux/arm64/v8`). |
|
||||
| `-q`, `--quiet` | `bool` | | Suppress the load output |
|
||||
|
||||
|
||||
|
@ -10,9 +10,9 @@ Save one or more images to a tar archive (streamed to STDOUT by default)
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:--------------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||
|:--------------------------|:--------------|:--------|:-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `-o`, `--output` | `string` | | Write to a file, instead of STDOUT |
|
||||
| [`--platform`](#platform) | `string` | | Save only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||
| [`--platform`](#platform) | `stringSlice` | | Save only the given platform(s). Formatted as a comma-separated list of `os[/arch[/variant]]` (e.g., `linux/amd64,linux/arm64/v8`) |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
@ -10,9 +10,9 @@ Load an image from a tar archive or STDIN
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:----------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||
|:----------------|:--------------|:--------|:------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `-i`, `--input` | `string` | | Read from tar archive file, instead of STDIN |
|
||||
| `--platform` | `string` | | Load only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||
| `--platform` | `stringSlice` | | Load only the given platform(s). Formatted as a comma-separated list of `os[/arch[/variant]]` (e.g., `linux/amd64,linux/arm64/v8`). |
|
||||
| `-q`, `--quiet` | `bool` | | Suppress the load output |
|
||||
|
||||
|
||||
|
@ -10,9 +10,9 @@ Save one or more images to a tar archive (streamed to STDOUT by default)
|
||||
### Options
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|:-----------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||
|:-----------------|:--------------|:--------|:-----------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `-o`, `--output` | `string` | | Write to a file, instead of STDOUT |
|
||||
| `--platform` | `string` | | Save only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||
| `--platform` | `stringSlice` | | Save only the given platform(s). Formatted as a comma-separated list of `os[/arch[/variant]]` (e.g., `linux/amd64,linux/arm64/v8`) |
|
||||
|
||||
|
||||
<!---MARKER_GEN_END-->
|
||||
|
Reference in New Issue
Block a user