mirror of https://github.com/docker/cli.git
Merge pull request #5331 from vvoland/c8d-saveload-platform
c8d: Add `--platform` flag to history, save and load
This commit is contained in:
commit
f483aacd6b
|
@ -3,17 +3,20 @@ package image
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/containerd/platforms"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
"github.com/docker/cli/cli/command/formatter"
|
"github.com/docker/cli/cli/command/formatter"
|
||||||
flagsHelper "github.com/docker/cli/cli/flags"
|
flagsHelper "github.com/docker/cli/cli/flags"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
type historyOptions struct {
|
type historyOptions struct {
|
||||||
image string
|
image string
|
||||||
|
platform string
|
||||||
|
|
||||||
human bool
|
human bool
|
||||||
quiet bool
|
quiet bool
|
||||||
|
@ -45,12 +48,24 @@ func NewHistoryCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only show image IDs")
|
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only show image IDs")
|
||||||
flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
|
flags.BoolVar(&opts.noTrunc, "no-trunc", false, "Don't truncate output")
|
||||||
flags.StringVar(&opts.format, "format", "", flagsHelper.FormatHelp)
|
flags.StringVar(&opts.format, "format", "", flagsHelper.FormatHelp)
|
||||||
|
flags.StringVar(&opts.platform, "platform", "", `Show history for the given platform. Formatted as "os[/arch[/variant]]" (e.g., "linux/amd64")`)
|
||||||
|
_ = flags.SetAnnotation("platform", "version", []string{"1.48"})
|
||||||
|
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHistory(ctx context.Context, dockerCli command.Cli, opts historyOptions) error {
|
func runHistory(ctx context.Context, dockerCli command.Cli, opts historyOptions) error {
|
||||||
history, err := dockerCli.Client().ImageHistory(ctx, opts.image, image.HistoryOptions{})
|
var options image.HistoryOptions
|
||||||
|
if opts.platform != "" {
|
||||||
|
p, err := platforms.Parse(opts.platform)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "invalid platform")
|
||||||
|
}
|
||||||
|
options.Platform = &p
|
||||||
|
}
|
||||||
|
|
||||||
|
history, err := dockerCli.Client().ImageHistory(ctx, opts.image, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,10 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,6 +35,11 @@ func TestNewHistoryCommandErrors(t *testing.T) {
|
||||||
return []image.HistoryResponseItem{{}}, errors.Errorf("something went wrong")
|
return []image.HistoryResponseItem{{}}, errors.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid platform",
|
||||||
|
args: []string{"--platform", "<invalid>", "arg1"},
|
||||||
|
expectedError: `invalid platform`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
@ -89,6 +96,17 @@ func TestNewHistoryCommandSuccess(t *testing.T) {
|
||||||
}}, nil
|
}}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "platform",
|
||||||
|
args: []string{"--platform", "linux/amd64", "image:tag"},
|
||||||
|
imageHistoryFunc: func(img string, options image.HistoryOptions) ([]image.HistoryResponseItem, error) {
|
||||||
|
assert.Check(t, is.DeepEqual(ocispec.Platform{OS: "linux", Architecture: "amd64"}, *options.Platform))
|
||||||
|
return []image.HistoryResponseItem{{
|
||||||
|
ID: "1234567890123456789",
|
||||||
|
Created: time.Now().Unix(),
|
||||||
|
}}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/containerd/platforms"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
|
@ -15,8 +16,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type loadOptions struct {
|
type loadOptions struct {
|
||||||
input string
|
input string
|
||||||
quiet bool
|
quiet bool
|
||||||
|
platform string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewLoadCommand creates a new `docker load` command
|
// NewLoadCommand creates a new `docker load` command
|
||||||
|
@ -40,7 +42,10 @@ func NewLoadCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
|
|
||||||
flags.StringVarP(&opts.input, "input", "i", "", "Read from tar archive file, instead of STDIN")
|
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.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.SetAnnotation("platform", "version", []string{"1.48"})
|
||||||
|
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,12 +68,20 @@ func runLoad(ctx context.Context, dockerCli command.Cli, opts loadOptions) error
|
||||||
return errors.Errorf("requested load from stdin, but stdin is empty")
|
return errors.Errorf("requested load from stdin, but stdin is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
var loadOpts image.LoadOptions
|
var options image.LoadOptions
|
||||||
if opts.quiet || !dockerCli.Out().IsTerminal() {
|
if opts.quiet || !dockerCli.Out().IsTerminal() {
|
||||||
loadOpts.Quiet = true
|
options.Quiet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err := dockerCli.Client().ImageLoad(ctx, input, loadOpts)
|
if opts.platform != "" {
|
||||||
|
p, err := platforms.Parse(opts.platform)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "invalid platform")
|
||||||
|
}
|
||||||
|
options.Platform = &p
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := dockerCli.Client().ImageLoad(ctx, input, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,10 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
|
is "gotest.tools/v3/assert/cmp"
|
||||||
"gotest.tools/v3/golden"
|
"gotest.tools/v3/golden"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,6 +42,14 @@ func TestNewLoadCommandErrors(t *testing.T) {
|
||||||
return image.LoadResponse{}, errors.Errorf("something went wrong")
|
return image.LoadResponse{}, errors.Errorf("something went wrong")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid platform",
|
||||||
|
args: []string{"--platform", "<invalid>"},
|
||||||
|
expectedError: `invalid platform`,
|
||||||
|
imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
|
||||||
|
return image.LoadResponse{}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
@ -96,6 +106,14 @@ func TestNewLoadCommandSuccess(t *testing.T) {
|
||||||
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
|
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "with platform",
|
||||||
|
args: []string{"--platform", "linux/amd64"},
|
||||||
|
imageLoadFunc: func(input io.Reader, options image.LoadOptions) (image.LoadResponse, error) {
|
||||||
|
assert.Check(t, is.DeepEqual(ocispec.Platform{OS: "linux", Architecture: "amd64"}, *options.Platform))
|
||||||
|
return image.LoadResponse{Body: io.NopCloser(strings.NewReader("Success"))}, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/containerd/platforms"
|
||||||
"github.com/docker/cli/cli"
|
"github.com/docker/cli/cli"
|
||||||
"github.com/docker/cli/cli/command"
|
"github.com/docker/cli/cli/command"
|
||||||
"github.com/docker/cli/cli/command/completion"
|
"github.com/docker/cli/cli/command/completion"
|
||||||
|
@ -13,8 +14,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type saveOptions struct {
|
type saveOptions struct {
|
||||||
images []string
|
images []string
|
||||||
output string
|
output string
|
||||||
|
platform string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSaveCommand creates a new `docker save` command
|
// NewSaveCommand creates a new `docker save` command
|
||||||
|
@ -38,7 +40,10 @@ func NewSaveCommand(dockerCli command.Cli) *cobra.Command {
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
|
|
||||||
flags.StringVarP(&opts.output, "output", "o", "", "Write to a file, instead of STDOUT")
|
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.SetAnnotation("platform", "version", []string{"1.48"})
|
||||||
|
|
||||||
|
_ = cmd.RegisterFlagCompletionFunc("platform", completion.Platforms)
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +57,16 @@ func RunSave(ctx context.Context, dockerCli command.Cli, opts saveOptions) error
|
||||||
return errors.Wrap(err, "failed to save image")
|
return errors.Wrap(err, "failed to save image")
|
||||||
}
|
}
|
||||||
|
|
||||||
responseBody, err := dockerCli.Client().ImageSave(ctx, opts.images, image.SaveOptions{})
|
var options image.SaveOptions
|
||||||
|
if opts.platform != "" {
|
||||||
|
p, err := platforms.Parse(opts.platform)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "invalid platform")
|
||||||
|
}
|
||||||
|
options.Platform = &p
|
||||||
|
}
|
||||||
|
|
||||||
|
responseBody, err := dockerCli.Client().ImageSave(ctx, opts.images, options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/docker/cli/internal/test"
|
"github.com/docker/cli/internal/test"
|
||||||
"github.com/docker/docker/api/types/image"
|
"github.com/docker/docker/api/types/image"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
is "gotest.tools/v3/assert/cmp"
|
is "gotest.tools/v3/assert/cmp"
|
||||||
|
@ -51,6 +52,11 @@ func TestNewSaveCommandErrors(t *testing.T) {
|
||||||
args: []string{"-o", "/dev/null", "arg1"},
|
args: []string{"-o", "/dev/null", "arg1"},
|
||||||
expectedError: "failed to save image: invalid output path: \"/dev/null\" must be a directory or a regular file",
|
expectedError: "failed to save image: invalid output path: \"/dev/null\" must be a directory or a regular file",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "invalid platform",
|
||||||
|
args: []string{"--platform", "<invalid>", "arg1"},
|
||||||
|
expectedError: `invalid platform`,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
@ -95,6 +101,16 @@ func TestNewSaveCommandSuccess(t *testing.T) {
|
||||||
return io.NopCloser(strings.NewReader("")), nil
|
return io.NopCloser(strings.NewReader("")), nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
args: []string{"--platform", "linux/amd64", "arg1"},
|
||||||
|
isTerminal: false,
|
||||||
|
imageSaveFunc: func(images []string, options image.SaveOptions) (io.ReadCloser, error) {
|
||||||
|
assert.Assert(t, is.Len(images, 1))
|
||||||
|
assert.Check(t, is.Equal("arg1", images[0]))
|
||||||
|
assert.Check(t, is.DeepEqual(ocispec.Platform{OS: "linux", Architecture: "amd64"}, *options.Platform))
|
||||||
|
return io.NopCloser(strings.NewReader("")), nil
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
IMAGE CREATED CREATED BY SIZE COMMENT
|
||||||
|
123456789012 Less than a second ago 0B
|
|
@ -0,0 +1 @@
|
||||||
|
Success
|
|
@ -14,6 +14,7 @@ Show the history of an image
|
||||||
| `--format` | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
|
| `--format` | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
|
||||||
| `-H`, `--human` | `bool` | `true` | Print sizes and dates in human readable format |
|
| `-H`, `--human` | `bool` | `true` | Print sizes and dates in human readable format |
|
||||||
| `--no-trunc` | `bool` | | Don't truncate output |
|
| `--no-trunc` | `bool` | | Don't truncate output |
|
||||||
|
| `--platform` | `string` | | Show history for the given platform. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||||
| `-q`, `--quiet` | `bool` | | Only show image IDs |
|
| `-q`, `--quiet` | `bool` | | Only show image IDs |
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,12 +9,13 @@ Show the history of an image
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:----------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|:--------------------------|:---------|:--------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| [`--format`](#format) | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
|
| [`--format`](#format) | `string` | | Format output using a custom template:<br>'table': Print output in table format with column headers (default)<br>'table TEMPLATE': Print output in table format using the given Go template<br>'json': Print in JSON format<br>'TEMPLATE': Print output using the given Go template.<br>Refer to https://docs.docker.com/go/formatting/ for more information about formatting output with templates |
|
||||||
| `-H`, `--human` | `bool` | `true` | Print sizes and dates in human readable format |
|
| `-H`, `--human` | `bool` | `true` | Print sizes and dates in human readable format |
|
||||||
| `--no-trunc` | `bool` | | Don't truncate output |
|
| `--no-trunc` | `bool` | | Don't truncate output |
|
||||||
| `-q`, `--quiet` | `bool` | | Only show image IDs |
|
| [`--platform`](#platform) | `string` | | Show history for the given platform. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||||
|
| `-q`, `--quiet` | `bool` | | Only show image IDs |
|
||||||
|
|
||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
@ -76,3 +77,54 @@ $ docker history --format "{{.ID}}: {{.CreatedSince}}" busybox
|
||||||
f6e427c148a7: 4 weeks ago
|
f6e427c148a7: 4 weeks ago
|
||||||
<missing>: 4 weeks ago
|
<missing>: 4 weeks ago
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name="platform"></a> Show history for a specific platform (--platform)
|
||||||
|
|
||||||
|
The `--platform` option allows you to specify which platform variant to show
|
||||||
|
history for if multiple platforms are present. By default, `docker history`
|
||||||
|
shows the history for the daemon's native platform or if not present, the
|
||||||
|
first available platform.
|
||||||
|
|
||||||
|
If the local image store has multiple platform variants of an image, the
|
||||||
|
`--platform` option selects which variant to show the history for. An error
|
||||||
|
is produced if the given platform is not present in the local image cache.
|
||||||
|
|
||||||
|
The platform option takes the `os[/arch[/variant]]` format; for example,
|
||||||
|
`linux/amd64` or `linux/arm64/v8`. Architecture and variant are optional,
|
||||||
|
and if omitted falls back to the daemon's defaults.
|
||||||
|
|
||||||
|
|
||||||
|
The following example pulls the RISC-V variant of the `alpine:latest` image
|
||||||
|
and shows its history.
|
||||||
|
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker image pull --quiet --platform=linux/riscv64 alpine
|
||||||
|
docker.io/library/alpine:latest
|
||||||
|
|
||||||
|
$ docker image history --platform=linux/s390x alpine
|
||||||
|
IMAGE CREATED CREATED BY SIZE COMMENT
|
||||||
|
beefdbd8a1da 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B
|
||||||
|
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:ba2637314e600db5a… 8.46MB
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example attempts to show the history for a platform variant of
|
||||||
|
`alpine:latest` that doesn't exist in the local image store, resulting in
|
||||||
|
an error.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker image ls --tree
|
||||||
|
IMAGE ID DISK USAGE CONTENT SIZE IN USE
|
||||||
|
alpine:latest beefdbd8a1da 10.6MB 3.37MB
|
||||||
|
├─ linux/riscv64 80cde017a105 10.6MB 3.37MB
|
||||||
|
├─ linux/amd64 33735bd63cf8 0B 0B
|
||||||
|
├─ linux/arm/v6 50f635c8b04d 0B 0B
|
||||||
|
├─ linux/arm/v7 f2f82d424957 0B 0B
|
||||||
|
├─ linux/arm64/v8 9cee2b382fe2 0B 0B
|
||||||
|
├─ linux/386 b3e87f642f5c 0B 0B
|
||||||
|
├─ linux/ppc64le c7a6800e3dc5 0B 0B
|
||||||
|
└─ linux/s390x 2b5b26e09ca2 0B 0B
|
||||||
|
|
||||||
|
$ docker image history --platform=linux/s390x alpine
|
||||||
|
Error response from daemon: image with reference alpine:latest was found but does not match the specified platform: wanted linux/s390x
|
||||||
|
```
|
||||||
|
|
|
@ -9,10 +9,11 @@ Load an image from a tar archive or STDIN
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:------------------------------------|:---------|:--------|:---------------------------------------------|
|
|:------------------------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||||
| [`-i`](#input), [`--input`](#input) | `string` | | Read from tar archive file, instead of STDIN |
|
| [`-i`](#input), [`--input`](#input) | `string` | | Read from tar archive file, instead of STDIN |
|
||||||
| `-q`, `--quiet` | `bool` | | Suppress the load output |
|
| [`--platform`](#platform) | `string` | | Load only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||||
|
| `-q`, `--quiet` | `bool` | | Suppress the load output |
|
||||||
|
|
||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
@ -58,3 +59,32 @@ fedora 20 58394af37342 7 weeks ago
|
||||||
fedora heisenbug 58394af37342 7 weeks ago 385.5 MB
|
fedora heisenbug 58394af37342 7 weeks ago 385.5 MB
|
||||||
fedora latest 58394af37342 7 weeks ago 385.5 MB
|
fedora latest 58394af37342 7 weeks ago 385.5 MB
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### <a name="platform"></a> Load a specific platform (--platform)
|
||||||
|
|
||||||
|
The `--platform` option allows you to specify which platform variant of the
|
||||||
|
image to load. By default, `docker load` loads all platform variants that
|
||||||
|
are present in the archive. Use the `--platform` option to specify which
|
||||||
|
platform variant of the image to load. An error is produced if the given
|
||||||
|
platform is not present in the archive.
|
||||||
|
|
||||||
|
The platform option takes the `os[/arch[/variant]]` format; for example,
|
||||||
|
`linux/amd64` or `linux/arm64/v8`. Architecture and variant are optional,
|
||||||
|
and default to the daemon's native architecture if omitted.
|
||||||
|
|
||||||
|
The following example loads the `linux/amd64` variant of an `alpine` image
|
||||||
|
from an archive that contains multiple platform variants.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker image load -i image.tar --platform=linux/amd64
|
||||||
|
Loaded image: alpine:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example attempts to load a `linux/ppc64le` image from an
|
||||||
|
archive, but the given platform is not present in the archive;
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker image load -i image.tar --platform=linux/ppc64le
|
||||||
|
requested platform (linux/ppc64le) not found: image might be filtered out
|
||||||
|
```
|
||||||
|
|
|
@ -9,9 +9,10 @@ Save one or more images to a tar archive (streamed to STDOUT by default)
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:-----------------|:---------|:--------|:-----------------------------------|
|
|:--------------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||||
| `-o`, `--output` | `string` | | Write to a file, instead of STDOUT |
|
| `-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`) |
|
||||||
|
|
||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
@ -59,3 +60,52 @@ You can even cherry-pick particular tags of an image repository.
|
||||||
```console
|
```console
|
||||||
$ docker save -o ubuntu.tar ubuntu:lucid ubuntu:saucy
|
$ docker save -o ubuntu.tar ubuntu:lucid ubuntu:saucy
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### <a name="platform"></a> Save a specific platform (--platform)
|
||||||
|
|
||||||
|
The `--platform` option allows you to specify which platform variant of the
|
||||||
|
image to save. By default, `docker save` saves all platform variants that
|
||||||
|
are present in the daemon's image store. Use the `--platform` option
|
||||||
|
to specify which platform variant of the image to save. An error is produced
|
||||||
|
if the given platform is not present in the local image store.
|
||||||
|
|
||||||
|
The platform option takes the `os[/arch[/variant]]` format; for example,
|
||||||
|
`linux/amd64` or `linux/arm64/v8`. Architecture and variant are optional,
|
||||||
|
and default to the daemon's native architecture if omitted.
|
||||||
|
|
||||||
|
The following example pulls the RISC-V variant of the `alpine:latest` image
|
||||||
|
and saves it to a tar archive.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker pull --platform=linux/riscv64 alpine:latest
|
||||||
|
latest: Pulling from library/alpine
|
||||||
|
8c4a05189a5f: Download complete
|
||||||
|
Digest: sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d
|
||||||
|
Status: Downloaded newer image for alpine:latest
|
||||||
|
docker.io/library/alpine:latest
|
||||||
|
|
||||||
|
$ docker image save --platform=linux/riscv64 -o alpine-riscv.tar alpine:latest
|
||||||
|
|
||||||
|
$ ls -lh image.tar
|
||||||
|
-rw------- 1 thajeztah staff 3.9M Oct 7 11:06 alpine-riscv.tar
|
||||||
|
```
|
||||||
|
|
||||||
|
The following example attempts to save a platform variant of `alpine:latest`
|
||||||
|
that doesn't exist in the local image store, resulting in an error.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ docker image ls --tree
|
||||||
|
IMAGE ID DISK USAGE CONTENT SIZE IN USE
|
||||||
|
alpine:latest beefdbd8a1da 10.6MB 3.37MB
|
||||||
|
├─ linux/riscv64 80cde017a105 10.6MB 3.37MB
|
||||||
|
├─ linux/amd64 33735bd63cf8 0B 0B
|
||||||
|
├─ linux/arm/v6 50f635c8b04d 0B 0B
|
||||||
|
├─ linux/arm/v7 f2f82d424957 0B 0B
|
||||||
|
├─ linux/arm64/v8 9cee2b382fe2 0B 0B
|
||||||
|
├─ linux/386 b3e87f642f5c 0B 0B
|
||||||
|
├─ linux/ppc64le c7a6800e3dc5 0B 0B
|
||||||
|
└─ linux/s390x 2b5b26e09ca2 0B 0B
|
||||||
|
|
||||||
|
$ docker image save --platform=linux/s390x -o alpine-s390x.tar alpine:latest
|
||||||
|
Error response from daemon: no suitable export target found for platform linux/s390x
|
||||||
|
```
|
||||||
|
|
|
@ -9,10 +9,11 @@ Load an image from a tar archive or STDIN
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:----------------|:---------|:--------|:---------------------------------------------|
|
|:----------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||||
| `-i`, `--input` | `string` | | Read from tar archive file, instead of STDIN |
|
| `-i`, `--input` | `string` | | Read from tar archive file, instead of STDIN |
|
||||||
| `-q`, `--quiet` | `bool` | | Suppress the load output |
|
| `--platform` | `string` | | Load only the given platform variant. Formatted as `os[/arch[/variant]]` (e.g., `linux/amd64`) |
|
||||||
|
| `-q`, `--quiet` | `bool` | | Suppress the load output |
|
||||||
|
|
||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
|
|
@ -9,9 +9,10 @@ Save one or more images to a tar archive (streamed to STDOUT by default)
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
|
|
||||||
| Name | Type | Default | Description |
|
| Name | Type | Default | Description |
|
||||||
|:-----------------|:---------|:--------|:-----------------------------------|
|
|:-----------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
|
||||||
| `-o`, `--output` | `string` | | Write to a file, instead of STDOUT |
|
| `-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`) |
|
||||||
|
|
||||||
|
|
||||||
<!---MARKER_GEN_END-->
|
<!---MARKER_GEN_END-->
|
||||||
|
|
Loading…
Reference in New Issue