Skip to content

Commit 54b967e

Browse files
committed
Add support for multiple platforms in docker image save
Signed-off-by: Cesar Talledo <[email protected]>
1 parent 83f7690 commit 54b967e

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

cli/command/image/save.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@ import (
1010
"github.com/docker/cli/cli/command/completion"
1111
"github.com/docker/docker/client"
1212
"github.com/moby/sys/atomicwriter"
13+
v1 "github.com/opencontainers/image-spec/specs-go/v1"
1314
"github.com/pkg/errors"
1415
"github.com/spf13/cobra"
1516
)
1617

1718
type saveOptions struct {
1819
images []string
1920
output string
20-
platform string
21+
platform []string
2122
}
2223

2324
// NewSaveCommand creates a new `docker save` command
@@ -41,7 +42,7 @@ func NewSaveCommand(dockerCli command.Cli) *cobra.Command {
4142
flags := cmd.Flags()
4243

4344
flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT")
44-
flags.StringVar(&opts.platform, "platform", "", `Save only the given platform variant. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
45+
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")`)
4546
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
4647

4748
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
@@ -51,13 +52,17 @@ func NewSaveCommand(dockerCli command.Cli) *cobra.Command {
5152
// runSave performs a save against the engine based on the specified options
5253
func runSave(ctx context.Context, dockerCLI command.Cli, opts saveOptions) error {
5354
var options []client.ImageSaveOption
54-
if opts.platform != "" {
55-
p, err := platforms.Parse(opts.platform)
55+
56+
platformList := []v1.Platform{}
57+
for _, p := range opts.platform {
58+
pp, err := platforms.Parse(p)
5659
if err != nil {
5760
return errors.Wrap(err, "invalid platform")
5861
}
59-
// TODO(thaJeztah): change flag-type to support multiple platforms.
60-
options = append(options, client.ImageSaveWithPlatforms(p))
62+
platformList = append(platformList, pp)
63+
}
64+
if len(platformList) > 0 {
65+
options = append(options, client.ImageSaveWithPlatforms(platformList...))
6166
}
6267

6368
var output io.Writer

cli/command/image/save_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,26 @@ func TestNewSaveCommandSuccess(t *testing.T) {
111111
return io.NopCloser(strings.NewReader("")), nil
112112
},
113113
},
114+
{
115+
args: []string{"--platform", "linux/amd64,linux/arm64/v8,linux/riscv64", "arg1"},
116+
isTerminal: false,
117+
imageSaveFunc: func(images []string, options ...client.ImageSaveOption) (io.ReadCloser, error) {
118+
assert.Assert(t, is.Len(images, 1))
119+
assert.Check(t, is.Equal("arg1", images[0]))
120+
assert.Check(t, len(options) > 0) // can be 1 or 2 depending on whether a terminal is attached :/
121+
return io.NopCloser(strings.NewReader("")), nil
122+
},
123+
},
124+
{
125+
args: []string{"--platform", "linux/amd64", "--platform", "linux/arm64/v8", "--platform", "linux/riscv64", "arg1"},
126+
isTerminal: false,
127+
imageSaveFunc: func(images []string, options ...client.ImageSaveOption) (io.ReadCloser, error) {
128+
assert.Assert(t, is.Len(images, 1))
129+
assert.Check(t, is.Equal("arg1", images[0]))
130+
assert.Check(t, len(options) > 0) // can be 1 or 2 depending on whether a terminal is attached :/
131+
return io.NopCloser(strings.NewReader("")), nil
132+
},
133+
},
114134
}
115135
for _, tc := range testCases {
116136
t.Run(strings.Join(tc.args, " "), func(t *testing.T) {

0 commit comments

Comments
 (0)