summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/common/create.go8
-rw-r--r--cmd/podman/common/create_opts.go1
-rw-r--r--cmd/podman/containers/create.go16
-rw-r--r--cmd/podman/images/pull.go20
-rw-r--r--docs/source/markdown/podman-create.1.md5
-rw-r--r--docs/source/markdown/podman-pull.1.md5
-rw-r--r--docs/source/markdown/podman-run.1.md5
-rw-r--r--test/e2e/create_test.go32
-rw-r--r--test/e2e/pull_test.go28
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 41611d1aa..af53a3b67 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 ab390447e..843e2b22f 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -689,6 +689,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 4495cec3a..44a7e83b6 100644
--- a/docs/source/markdown/podman-pull.1.md
+++ b/docs/source/markdown/podman-pull.1.md
@@ -106,6 +106,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 13b586e17..83aaa33e8 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -717,6 +717,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"))
+ })
})