diff options
author | Daniel J Walsh <dwalsh@redhat.com> | 2020-11-25 15:40:46 -0500 |
---|---|---|
committer | Daniel J Walsh <dwalsh@redhat.com> | 2020-11-26 06:08:11 -0500 |
commit | 88f8d96ed8e7edcb4dfdb3de707034036bab27ff (patch) | |
tree | d018dd03e19b30ac0e2e5330f5fc6b031c90c950 | |
parent | 397e9a9f1b146617120690243a89fa9541f0854c (diff) | |
download | podman-88f8d96ed8e7edcb4dfdb3de707034036bab27ff.tar.gz podman-88f8d96ed8e7edcb4dfdb3de707034036bab27ff.tar.bz2 podman-88f8d96ed8e7edcb4dfdb3de707034036bab27ff.zip |
Add support for --platform
For docker compatibility we need to support --platform
flag.
podman create --platform
podman run --platform
podman pull --platform
Since we have --override-os and --override-arch already
this can be done just by modifying the client to split
the --platform call into os and arch and then pass those
options to the server side.
Fixes: https://github.com/containers/podman/issues/6244
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
-rw-r--r-- | cmd/podman/common/create.go | 8 | ||||
-rw-r--r-- | cmd/podman/common/create_opts.go | 1 | ||||
-rw-r--r-- | cmd/podman/containers/create.go | 16 | ||||
-rw-r--r-- | cmd/podman/images/pull.go | 20 | ||||
-rw-r--r-- | docs/source/markdown/podman-create.1.md | 5 | ||||
-rw-r--r-- | docs/source/markdown/podman-pull.1.md | 5 | ||||
-rw-r--r-- | docs/source/markdown/podman-run.1.md | 5 | ||||
-rw-r--r-- | test/e2e/create_test.go | 32 | ||||
-rw-r--r-- | test/e2e/pull_test.go | 28 |
9 files changed, 120 insertions, 0 deletions
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go index 599b430ea..14086ace4 100644 --- a/cmd/podman/common/create.go +++ b/cmd/podman/common/create.go @@ -513,6 +513,14 @@ func DefineCreateFlags(cmd *cobra.Command, cf *ContainerCLIOpts) { ) _ = cmd.RegisterFlagCompletionFunc(pidsLimitFlagName, completion.AutocompleteNone) + platformFlagName := "platform" + createFlags.StringVar( + &cf.Platform, + platformFlagName, "", + "Specify the platform for selecting the image. (Conflicts with override-arch and override-os)", + ) + _ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone) + podFlagName := "pod" createFlags.StringVar( &cf.Pod, diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go index 6dc43dbc6..24ede4885 100644 --- a/cmd/podman/common/create_opts.go +++ b/cmd/podman/common/create_opts.go @@ -78,6 +78,7 @@ type ContainerCLIOpts struct { OverrideVariant string PID string PIDsLimit *int64 + Platform string Pod string PodIDFile string PreserveFDs uint diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go index db920554e..3d87c71a9 100644 --- a/cmd/podman/containers/create.go +++ b/cmd/podman/containers/create.go @@ -18,6 +18,7 @@ import ( "github.com/containers/podman/v2/pkg/specgen" "github.com/containers/podman/v2/pkg/util" "github.com/pkg/errors" + "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -236,6 +237,21 @@ func pullImage(imageName string) (string, error) { imageMissing = !br.Value } + if cliVals.Platform != "" { + if cliVals.OverrideArch != "" || cliVals.OverrideOS != "" { + return "", errors.Errorf("--platform option can not be specified with --overide-arch or --override-os") + } + split := strings.SplitN(cliVals.Platform, "/", 2) + cliVals.OverrideOS = split[0] + if len(split) > 1 { + cliVals.OverrideArch = split[1] + } + if pullPolicy != config.PullImageAlways { + logrus.Info("--platform causes the pull policy to be \"always\"") + pullPolicy = config.PullImageAlways + } + } + if imageMissing || pullPolicy == config.PullImageAlways { if pullPolicy == config.PullImageNever { return "", errors.Wrapf(define.ErrNoSuchImage, "unable to find a name and tag match for %s in repotags", imageName) diff --git a/cmd/podman/images/pull.go b/cmd/podman/images/pull.go index a6f41688c..f8e1ee226 100644 --- a/cmd/podman/images/pull.go +++ b/cmd/podman/images/pull.go @@ -3,6 +3,7 @@ package images import ( "fmt" "os" + "strings" "github.com/containers/common/pkg/auth" "github.com/containers/common/pkg/completion" @@ -11,6 +12,7 @@ import ( "github.com/containers/podman/v2/cmd/podman/registry" "github.com/containers/podman/v2/pkg/domain/entities" "github.com/containers/podman/v2/pkg/util" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -94,6 +96,10 @@ func pullFlags(cmd *cobra.Command) { flags.StringVar(&pullOptions.OverrideVariant, overrideVariantFlagName, "", " use VARIANT instead of the running architecture variant for choosing images") _ = cmd.RegisterFlagCompletionFunc(overrideVariantFlagName, completion.AutocompleteNone) + platformFlagName := "platform" + flags.String(platformFlagName, "", "Specify the platform for selecting the image. (Conflicts with override-arch and override-os)") + _ = cmd.RegisterFlagCompletionFunc(platformFlagName, completion.AutocompleteNone) + flags.Bool("disable-content-trust", false, "This is a Docker specific option and is a NOOP") flags.BoolVarP(&pullOptions.Quiet, "quiet", "q", false, "Suppress output information when pulling images") flags.StringVar(&pullOptions.SignaturePolicy, "signature-policy", "", "`Pathname` of signature policy file (not usually used)") @@ -127,6 +133,20 @@ func imagePull(cmd *cobra.Command, args []string) error { return err } } + platform, err := cmd.Flags().GetString("platform") + if err != nil { + return err + } + if platform != "" { + if pullOptions.OverrideArch != "" || pullOptions.OverrideOS != "" { + return errors.Errorf("--platform option can not be specified with --overide-arch or --override-os") + } + split := strings.SplitN(platform, "/", 2) + pullOptions.OverrideOS = split[0] + if len(split) > 1 { + pullOptions.OverrideArch = split[1] + } + } if pullOptions.CredentialsCLI != "" { creds, err := util.ParseRegistryCreds(pullOptions.CredentialsCLI) diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md index eb73609d4..5e73804ab 100644 --- a/docs/source/markdown/podman-create.1.md +++ b/docs/source/markdown/podman-create.1.md @@ -647,6 +647,11 @@ Default is to create a private PID namespace for the container Tune the container's pids limit. Set `0` to have unlimited pids for the container. (default "4096" on systems that support PIDS cgroups). +#### **--platform**=*OS/ARCH* + +Specify the platform for selecting the image. (Conflicts with override-arch and override-os) +The `--platform` option can be used to override the current architecture and operating system. + #### **--pod**=*name* Run container in an existing pod. If you want Podman to make the pod for you, preference the pod name with `new:`. diff --git a/docs/source/markdown/podman-pull.1.md b/docs/source/markdown/podman-pull.1.md index 130c54ba9..b28d34c64 100644 --- a/docs/source/markdown/podman-pull.1.md +++ b/docs/source/markdown/podman-pull.1.md @@ -89,6 +89,11 @@ Override the OS, defaults to hosts, of the image to be pulled. For example, `win Use _VARIANT_ instead of the default architecture variant of the container image. Some images can use multiple variants of the arm architectures, such as arm/v5 and arm/v7. +#### **--platform**=*OS/ARCH* + +Specify the platform for selecting the image. (Conflicts with override-arch and override-os) +The `--platform` option can be used to override the current architecture and operating system. + #### **--quiet**, **-q** Suppress output information when pulling images diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md index 184c12acd..897210749 100644 --- a/docs/source/markdown/podman-run.1.md +++ b/docs/source/markdown/podman-run.1.md @@ -675,6 +675,11 @@ The efault is to create a private PID namespace for the container. Tune the container's pids limit. Set to **0** to have unlimited pids for the container. The default is **4096** on systems that support "pids" cgroup controller. +#### **--platform**=*OS/ARCH* + +Specify the platform for selecting the image. (Conflicts with override-arch and override-os) +The `--platform` option can be used to override the current architecture and operating system. + #### **--pod**=*name* Run container in an existing pod. If you want Podman to make the pod for you, prefix the pod name with **new:**. diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go index 760345a67..aaf089d97 100644 --- a/test/e2e/create_test.go +++ b/test/e2e/create_test.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "os" "path/filepath" + "runtime" "strings" . "github.com/containers/podman/v2/test/utils" @@ -644,4 +645,35 @@ var _ = Describe("Podman create", func() { Expect(session.ErrorToString()).To(ContainSubstring("unknown flag")) }) + It("podman create --platform", func() { + session := podmanTest.Podman([]string{"create", "--platform=linux/bogus", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + expectedError := "no image found in manifest list for architecture bogus" + Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) + + session = podmanTest.Podman([]string{"create", "--platform=linux/arm64", "--override-os", "windows", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + expectedError = "--platform option can not be specified with --overide-arch or --override-os" + Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) + + session = podmanTest.Podman([]string{"create", "-q", "--platform=linux/arm64", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + setup := podmanTest.Podman([]string{"container", "inspect", session.OutputToString()}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + data := setup.InspectContainerToJSON() + setup = podmanTest.Podman([]string{"image", "inspect", data[0].Image}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + idata := setup.InspectImageJSON() // returns []inspect.ImageData + Expect(len(idata)).To(Equal(1)) + Expect(idata[0].Os).To(Equal(runtime.GOOS)) + Expect(idata[0].Architecture).To(Equal("arm64")) + }) }) diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go index f1b055d6d..c572fc5ac 100644 --- a/test/e2e/pull_test.go +++ b/test/e2e/pull_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "runtime" "strings" . "github.com/containers/podman/v2/test/utils" @@ -494,4 +495,31 @@ var _ = Describe("Podman pull", func() { Expect(data[0].ID).To(Equal(image1)) } }) + + It("podman pull --platform", func() { + session := podmanTest.Podman([]string{"pull", "--platform=linux/bogus", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + expectedError := "no image found in manifest list for architecture bogus" + Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) + + session = podmanTest.Podman([]string{"pull", "--platform=linux/arm64", "--override-os", "windows", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(125)) + expectedError = "--platform option can not be specified with --overide-arch or --override-os" + Expect(session.ErrorToString()).To(ContainSubstring(expectedError)) + + session = podmanTest.Podman([]string{"pull", "-q", "--platform=linux/arm64", ALPINE}) + session.WaitWithDefaultTimeout() + Expect(session.ExitCode()).To(Equal(0)) + + setup := podmanTest.Podman([]string{"image", "inspect", session.OutputToString()}) + setup.WaitWithDefaultTimeout() + Expect(setup.ExitCode()).To(Equal(0)) + + data := setup.InspectImageJSON() // returns []inspect.ImageData + Expect(len(data)).To(Equal(1)) + Expect(data[0].Os).To(Equal(runtime.GOOS)) + Expect(data[0].Architecture).To(Equal("arm64")) + }) }) |