aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xAPI.md21
-rw-r--r--cmd/podman/attach.go2
-rw-r--r--cmd/podman/build.go3
-rw-r--r--cmd/podman/checkpoint.go9
-rw-r--r--cmd/podman/cleanup.go8
-rw-r--r--cmd/podman/commands.go4
-rw-r--r--cmd/podman/commands_remoteclient.go2
-rw-r--r--cmd/podman/common.go23
-rw-r--r--cmd/podman/cp.go34
-rw-r--r--cmd/podman/exec.go2
-rw-r--r--cmd/podman/exists.go5
-rw-r--r--cmd/podman/inspect.go2
-rw-r--r--cmd/podman/kill.go8
-rw-r--r--cmd/podman/logs.go1
-rw-r--r--cmd/podman/main.go1
-rw-r--r--cmd/podman/mount.go4
-rw-r--r--cmd/podman/pod.go2
-rw-r--r--cmd/podman/pod_inspect.go11
-rw-r--r--cmd/podman/pod_kill.go8
-rw-r--r--cmd/podman/pod_pause.go8
-rw-r--r--cmd/podman/pod_ps.go2
-rw-r--r--cmd/podman/pod_restart.go8
-rw-r--r--cmd/podman/pod_rm.go8
-rw-r--r--cmd/podman/pod_start.go8
-rw-r--r--cmd/podman/pod_stats.go1
-rw-r--r--cmd/podman/pod_stop.go8
-rw-r--r--cmd/podman/pod_unpause.go8
-rw-r--r--cmd/podman/port.go4
-rw-r--r--cmd/podman/ps.go1
-rw-r--r--cmd/podman/pull.go9
-rw-r--r--cmd/podman/restart.go4
-rw-r--r--cmd/podman/restore.go8
-rw-r--r--cmd/podman/rm.go8
-rw-r--r--cmd/podman/runlabel.go4
-rw-r--r--cmd/podman/save.go21
-rw-r--r--cmd/podman/start.go1
-rw-r--r--cmd/podman/stats.go4
-rw-r--r--cmd/podman/stop.go8
-rw-r--r--cmd/podman/top.go1
-rw-r--r--cmd/podman/umount.go7
-rw-r--r--cmd/podman/utils.go16
-rw-r--r--cmd/podman/varlink/io.podman.varlink10
-rw-r--r--cmd/podman/wait.go1
-rw-r--r--docs/podman-attach.1.md2
-rw-r--r--docs/podman-build.1.md6
-rw-r--r--docs/podman-container-checkpoint.1.md2
-rw-r--r--docs/podman-container-cleanup.1.md3
-rw-r--r--docs/podman-container-restore.1.md2
-rw-r--r--docs/podman-diff.1.md6
-rw-r--r--docs/podman-exec.1.md2
-rw-r--r--docs/podman-inspect.1.md2
-rw-r--r--docs/podman-kill.1.md2
-rw-r--r--docs/podman-load.1.md4
-rw-r--r--docs/podman-logs.1.md7
-rw-r--r--docs/podman-mount.1.md2
-rw-r--r--docs/podman-pod-inspect.1.md1
-rw-r--r--docs/podman-pod-kill.1.md2
-rw-r--r--docs/podman-pod-pause.1.md2
-rw-r--r--docs/podman-pod-ps.1.md2
-rw-r--r--docs/podman-pod-restart.1.md2
-rw-r--r--docs/podman-pod-rm.1.md2
-rw-r--r--docs/podman-pod-start.1.md2
-rw-r--r--docs/podman-pod-stop.1.md2
-rw-r--r--docs/podman-pod-top.1.md2
-rw-r--r--docs/podman-pod-unpause.1.md2
-rw-r--r--docs/podman-port.1.md2
-rw-r--r--docs/podman-ps.1.md2
-rw-r--r--docs/podman-restart.1.md2
-rw-r--r--docs/podman-rm.1.md2
-rw-r--r--docs/podman-start.1.md1
-rw-r--r--docs/podman-stats.1.md2
-rw-r--r--docs/podman-stop.1.md2
-rw-r--r--docs/podman-top.1.md2
-rw-r--r--docs/podman-umount.1.md2
-rw-r--r--docs/podman-wait.1.md4
-rw-r--r--libpod/adapter/pods.go16
-rw-r--r--libpod/adapter/pods_remote.go60
-rw-r--r--libpod/container_commit.go2
-rw-r--r--libpod/options.go1
-rw-r--r--pkg/rootless/rootless_linux.c28
-rw-r--r--pkg/varlinkapi/pods.go17
-rw-r--r--test/e2e/libpod_suite_test.go4
-rw-r--r--test/e2e/rootless_test.go45
-rw-r--r--test/utils/podmantest_test.go2
-rw-r--r--test/utils/utils.go12
-rw-r--r--vendor.conf4
-rw-r--r--vendor/github.com/containers/buildah/buildah.go7
-rw-r--r--vendor/github.com/containers/buildah/imagebuildah/build.go19
-rw-r--r--vendor/github.com/containers/buildah/new.go68
-rw-r--r--vendor/github.com/containers/buildah/pkg/cli/common.go10
-rw-r--r--vendor/github.com/containers/buildah/pkg/parse/parse.go6
-rw-r--r--vendor/github.com/containers/buildah/pull.go117
-rw-r--r--vendor/github.com/containers/buildah/unshare/unshare.c140
-rw-r--r--vendor/github.com/containers/buildah/unshare/unshare.go6
-rw-r--r--vendor/github.com/containers/buildah/util/util.go56
-rw-r--r--vendor/github.com/containers/buildah/vendor.conf24
-rw-r--r--vendor/github.com/openshift/imagebuilder/README.md2
-rw-r--r--vendor/github.com/openshift/imagebuilder/builder.go31
-rw-r--r--vendor/github.com/openshift/imagebuilder/dispatchers.go13
99 files changed, 761 insertions, 317 deletions
diff --git a/API.md b/API.md
index dd950e9fc..c4f23c9bd 100755
--- a/API.md
+++ b/API.md
@@ -89,12 +89,16 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in
[func ListPods() ListPodData](#ListPods)
+[func LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) MoreResponse](#LoadImage)
+
[func MountContainer(name: string) string](#MountContainer)
[func PauseContainer(name: string) string](#PauseContainer)
[func PausePod(name: string) string](#PausePod)
+[func PodStateData(name: string) string](#PodStateData)
+
[func PullImage(name: string, certDir: string, creds: string, signaturePolicy: string, tlsVerify: ) MoreResponse](#PullImage)
[func PushImage(name: string, tag: string, tlsverify: , signaturePolicy: string, creds: string, certDir: string, compress: bool, format: string, removeSignatures: bool, signBy: string) MoreResponse](#PushImage)
@@ -537,7 +541,9 @@ $ varlink call unix:/run/podman/io.podman/io.podman.GetPodStats '{"name": "7f62b
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method GetPodsByContext(all: [bool](https://godoc.org/builtin#bool), latest: [bool](https://godoc.org/builtin#bool), args: [[]string](#[]string)) [[]string](#[]string)</div>
-
+GetPodsByContext allows you to get a list pod ids depending on all, latest, or a list of
+pod names. The definition of latest pod means the latest by creation date. In a multi-
+user environment, results might differ from what you expect.
### <a name="GetVersion"></a>func GetVersion
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -573,7 +579,7 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ImageExists '{"name": "im
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ImageSave(options: [ImageSaveOptions](#ImageSaveOptions)) [MoreResponse](#MoreResponse)</div>
-
+ImageSave allows you to save an image from the local image storage to a tarball
### <a name="ImagesPrune"></a>func ImagesPrune
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -734,6 +740,11 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.ListPods
]
}
~~~
+### <a name="LoadImage"></a>func LoadImage
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+
+method LoadImage(name: [string](https://godoc.org/builtin#string), inputFile: [string](https://godoc.org/builtin#string), quiet: [bool](https://godoc.org/builtin#bool), deleteFile: [bool](https://godoc.org/builtin#bool)) [MoreResponse](#MoreResponse)</div>
+LoadImage allows you to load an image into local storage from a tarball.
### <a name="MountContainer"></a>func MountContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@@ -770,6 +781,12 @@ $ varlink call -m unix:/run/podman/io.podman/io.podman.PausePod '{"name": "fooba
"pod": "1840835294cf076a822e4e12ba4152411f131bd869e7f6a4e8b16df9b0ea5c7f"
}
~~~
+### <a name="PodStateData"></a>func PodStateData
+<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
+
+method PodStateData(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
+PodStateData returns inspectr level information of a given pod in string form. This call is for
+development of Podman only and generally should not be used.
### <a name="PullImage"></a>func PullImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
diff --git a/cmd/podman/attach.go b/cmd/podman/attach.go
index b70ff649c..074675e45 100644
--- a/cmd/podman/attach.go
+++ b/cmd/podman/attach.go
@@ -35,8 +35,8 @@ func init() {
flags.StringVar(&attachCommand.DetachKeys, "detach-keys", "", "Override the key sequence for detaching a container. Format is a single character [a-Z] or ctrl-<value> where <value> is one of: a-z, @, ^, [, , or _")
flags.BoolVar(&attachCommand.NoStdin, "no-stdin", false, "Do not attach STDIN. The default is false")
flags.BoolVar(&attachCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process (default true)")
-
flags.BoolVarP(&attachCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func attachCmd(c *cliconfig.AttachValues) error {
diff --git a/cmd/podman/build.go b/cmd/podman/build.go
index bb252f171..2054381ec 100644
--- a/cmd/podman/build.go
+++ b/cmd/podman/build.go
@@ -179,7 +179,7 @@ func buildCmd(c *cliconfig.BuildValues) error {
}
runtimeFlags := []string{}
- for _, arg := range c.RuntimeOpts {
+ for _, arg := range c.RuntimeFlags {
runtimeFlags = append(runtimeFlags, "--"+arg)
}
// end from buildah
@@ -258,6 +258,7 @@ func buildCmd(c *cliconfig.BuildValues) error {
RuntimeArgs: runtimeFlags,
SignaturePolicyPath: c.SignaturePolicy,
Squash: c.Squash,
+ Target: c.Target,
}
return runtime.Build(getContext(), c, options, dockerfiles)
}
diff --git a/cmd/podman/checkpoint.go b/cmd/podman/checkpoint.go
index 3484e8957..c9de5638b 100644
--- a/cmd/podman/checkpoint.go
+++ b/cmd/podman/checkpoint.go
@@ -29,6 +29,9 @@ var (
checkpointCommand.GlobalFlags = MainGlobalOpts
return checkpointCmd(&checkpointCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman checkpoint --keep ctrID
podman checkpoint --all
podman checkpoint --leave-running --latest`,
@@ -45,6 +48,7 @@ func init() {
flags.BoolVar(&checkpointCommand.TcpEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections")
flags.BoolVarP(&checkpointCommand.All, "all", "a", false, "Checkpoint all running containers")
flags.BoolVarP(&checkpointCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func checkpointCmd(c *cliconfig.CheckpointValues) error {
@@ -63,11 +67,6 @@ func checkpointCmd(c *cliconfig.CheckpointValues) error {
KeepRunning: c.LeaveRunning,
TCPEstablished: c.TcpEstablished,
}
-
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
-
containers, lastError := getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateRunning, "running")
for _, ctr := range containers {
diff --git a/cmd/podman/cleanup.go b/cmd/podman/cleanup.go
index 89a4ba050..d68255aa2 100644
--- a/cmd/podman/cleanup.go
+++ b/cmd/podman/cleanup.go
@@ -26,6 +26,9 @@ var (
cleanupCommand.GlobalFlags = MainGlobalOpts
return cleanupCmd(&cleanupCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman container cleanup --latest
podman container cleanup ctrID1 ctrID2 ctrID3
podman container cleanup --all`,
@@ -40,6 +43,7 @@ func init() {
flags.BoolVarP(&cleanupCommand.All, "all", "a", false, "Cleans up all containers")
flags.BoolVarP(&cleanupCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&cleanupCommand.Remove, "rm", false, "After cleanup, remove the container entirely")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func cleanupCmd(c *cliconfig.CleanupValues) error {
@@ -49,10 +53,6 @@ func cleanupCmd(c *cliconfig.CleanupValues) error {
}
defer runtime.Shutdown(false)
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
-
cleanupContainers, lastError := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all")
ctx := getContext()
diff --git a/cmd/podman/commands.go b/cmd/podman/commands.go
index 0acb9c398..d8fc44c2f 100644
--- a/cmd/podman/commands.go
+++ b/cmd/podman/commands.go
@@ -6,6 +6,8 @@ import (
"github.com/spf13/cobra"
)
+const remoteclient = false
+
// Commands that the local client implements
func getMainCommands() []*cobra.Command {
rootCommands := []*cobra.Command{
@@ -92,8 +94,6 @@ func getContainerSubCommands() []*cobra.Command {
func getPodSubCommands() []*cobra.Command {
return []*cobra.Command{
_podCreateCommand,
- _podExistsCommand,
- _podInspectCommand,
_podKillCommand,
_podPauseCommand,
_podPsCommand,
diff --git a/cmd/podman/commands_remoteclient.go b/cmd/podman/commands_remoteclient.go
index ba0a4d47e..081043b25 100644
--- a/cmd/podman/commands_remoteclient.go
+++ b/cmd/podman/commands_remoteclient.go
@@ -6,6 +6,8 @@ import (
"github.com/spf13/cobra"
)
+const remoteclient = true
+
// commands that only the remoteclient implements
func getMainCommands() []*cobra.Command {
return []*cobra.Command{}
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index fed07de7c..e297f3921 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
+ "github.com/spf13/cobra"
"os"
"strings"
@@ -36,16 +37,24 @@ func shortID(id string) string {
}
// checkAllAndLatest checks that --all and --latest are used correctly
-func checkAllAndLatest(c *cliconfig.PodmanCommand) error {
- argLen := len(c.InputArgs)
- if (c.Bool("all") || c.Bool("latest")) && argLen > 0 {
- return errors.Errorf("no arguments are needed with --all or --latest")
+func checkAllAndLatest(c *cobra.Command, args []string, ignoreArgLen bool) error {
+ argLen := len(args)
+ if c.Flags().Lookup("all") == nil || c.Flags().Lookup("latest") == nil {
+ return errors.New("unable to lookup values for 'latest' or 'all'")
}
- if c.Bool("all") && c.Bool("latest") {
+ all, _ := c.Flags().GetBool("all")
+ latest, _ := c.Flags().GetBool("latest")
+ if all && latest {
return errors.Errorf("--all and --latest cannot be used together")
}
- if argLen < 1 && !c.Bool("all") && !c.Bool("latest") {
- return errors.Errorf("you must provide at least one pod name or id")
+ if ignoreArgLen {
+ return nil
+ }
+ if (all || latest) && argLen > 0 {
+ return errors.Errorf("no arguments are needed with --all or --latest")
+ }
+ if argLen < 1 && !all && !latest {
+ return errors.Errorf("you must provide at least one name or id")
}
return nil
}
diff --git a/cmd/podman/cp.go b/cmd/podman/cp.go
index 89114fda1..d9f230b67 100644
--- a/cmd/podman/cp.go
+++ b/cmd/podman/cp.go
@@ -1,8 +1,10 @@
package main
import (
+ "io/ioutil"
"os"
"path/filepath"
+ "strconv"
"strings"
"github.com/containers/buildah/util"
@@ -10,6 +12,7 @@ import (
"github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/chrootuser"
+ "github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/archive"
"github.com/containers/storage/pkg/chrootarchive"
@@ -48,6 +51,9 @@ func cpCmd(c *cliconfig.CpValues) error {
if len(args) != 2 {
return errors.Errorf("you must provide a source path and a destination path")
}
+ if os.Geteuid() != 0 {
+ rootless.SetSkipStorageSetup(true)
+ }
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
@@ -76,6 +82,34 @@ func copyBetweenHostAndContainer(runtime *libpod.Runtime, src string, dest strin
ctr = destCtr
}
+ if os.Geteuid() != 0 {
+ s, err := ctr.State()
+ if err != nil {
+ return err
+ }
+ var became bool
+ var ret int
+ if s == libpod.ContainerStateRunning || s == libpod.ContainerStatePaused {
+ data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile)
+ if err != nil {
+ return errors.Wrapf(err, "cannot read conmon PID file %q", ctr.Config().ConmonPidFile)
+ }
+ conmonPid, err := strconv.Atoi(string(data))
+ if err != nil {
+ return errors.Wrapf(err, "cannot parse PID %q", data)
+ }
+ became, ret, err = rootless.JoinDirectUserAndMountNS(uint(conmonPid))
+ } else {
+ became, ret, err = rootless.BecomeRootInUserNS()
+ }
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
+ }
+ }
+
mountPoint, err := ctr.Mount()
if err != nil {
return err
diff --git a/cmd/podman/exec.go b/cmd/podman/exec.go
index 9599be528..7040a7b09 100644
--- a/cmd/podman/exec.go
+++ b/cmd/podman/exec.go
@@ -48,7 +48,7 @@ func init() {
flags.StringVarP(&execCommand.User, "user", "u", "", "Sets the username or UID used and optionally the groupname or GID for the specified command")
flags.StringVarP(&execCommand.Workdir, "workdir", "w", "", "Working directory inside the container")
-
+ markFlagHiddenForRemoteClient("latest", flags)
}
func execCmd(c *cliconfig.ExecValues) error {
diff --git a/cmd/podman/exists.go b/cmd/podman/exists.go
index 7645bb716..aad203818 100644
--- a/cmd/podman/exists.go
+++ b/cmd/podman/exists.go
@@ -5,7 +5,6 @@ import (
"github.com/spf13/cobra"
"os"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/adapter"
"github.com/containers/libpod/libpod/image"
@@ -124,14 +123,14 @@ func podExistsCmd(c *cliconfig.PodExistsValues) error {
if len(args) > 1 || len(args) < 1 {
return errors.New("you may only check for the existence of one pod at a time")
}
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
defer runtime.Shutdown(false)
if _, err := runtime.LookupPod(args[0]); err != nil {
- if errors.Cause(err) == libpod.ErrNoSuchPod {
+ if errors.Cause(err) == libpod.ErrNoSuchPod || err.Error() == "io.podman.PodNotFound" {
os.Exit(1)
}
return err
diff --git a/cmd/podman/inspect.go b/cmd/podman/inspect.go
index a1f3ef81f..48b953207 100644
--- a/cmd/podman/inspect.go
+++ b/cmd/podman/inspect.go
@@ -48,7 +48,7 @@ func init() {
flags.StringVarP(&inspectCommand.Format, "format", "f", "", "Change the output format to a Go template")
flags.BoolVarP(&inspectCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of if the type is a container")
flags.BoolVarP(&inspectCommand.Size, "size", "s", false, "Display total file size if the type is container")
-
+ markFlagHiddenForRemoteClient("latest", flags)
}
func inspectCmd(c *cliconfig.InspectValues) error {
diff --git a/cmd/podman/kill.go b/cmd/podman/kill.go
index 1be4fa959..eb72d53e7 100644
--- a/cmd/podman/kill.go
+++ b/cmd/podman/kill.go
@@ -28,6 +28,9 @@ var (
killCommand.GlobalFlags = MainGlobalOpts
return killCmd(&killCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman kill mywebserver
podman kill 860a4b23
podman kill --signal TERM ctrID`,
@@ -43,6 +46,7 @@ func init() {
flags.StringVarP(&killCommand.Signal, "signal", "s", "KILL", "Signal to send to the container")
flags.BoolVarP(&killCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
// killCmd kills one or more containers with a signal
@@ -52,10 +56,6 @@ func killCmd(c *cliconfig.KillValues) error {
killSignal uint = uint(syscall.SIGTERM)
)
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
-
rootless.SetSkipStorageSetup(true)
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
diff --git a/cmd/podman/logs.go b/cmd/podman/logs.go
index 4cf3b7cb8..97d835d8f 100644
--- a/cmd/podman/logs.go
+++ b/cmd/podman/logs.go
@@ -46,6 +46,7 @@ func init() {
flags.SetInterspersed(false)
+ markFlagHiddenForRemoteClient("latest", flags)
}
func logsCmd(c *cliconfig.LogsValues) error {
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index cf6e44fcd..19bdb40d6 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -59,6 +59,7 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{
_versionCommand: true,
_createCommand: true,
_execCommand: true,
+ _cpCommand: true,
_exportCommand: true,
//// `info` must be executed in an user namespace.
//// If this change, please also update libpod.refreshRootless()
diff --git a/cmd/podman/mount.go b/cmd/podman/mount.go
index ce7c22d60..f4a7bd5ea 100644
--- a/cmd/podman/mount.go
+++ b/cmd/podman/mount.go
@@ -34,6 +34,9 @@ var (
mountCommand.GlobalFlags = MainGlobalOpts
return mountCmd(&mountCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, true)
+ },
}
)
@@ -46,6 +49,7 @@ func init() {
flags.BoolVarP(&mountCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&mountCommand.NoTrunc, "notruncate", false, "Do not truncate output")
+ markFlagHiddenForRemoteClient("latest", flags)
}
// jsonMountPoint stores info about each container
diff --git a/cmd/podman/pod.go b/cmd/podman/pod.go
index cf87730d7..d65e0b384 100644
--- a/cmd/podman/pod.go
+++ b/cmd/podman/pod.go
@@ -20,6 +20,8 @@ var podCommand = cliconfig.PodmanCommand{
//podSubCommands are implemented both in local and remote clients
var podSubCommands = []*cobra.Command{
+ _podExistsCommand,
+ _podInspectCommand,
_podRmCommand,
}
diff --git a/cmd/podman/pod_inspect.go b/cmd/podman/pod_inspect.go
index 58b15328e..1f4d1a3dd 100644
--- a/cmd/podman/pod_inspect.go
+++ b/cmd/podman/pod_inspect.go
@@ -5,8 +5,7 @@ import (
"fmt"
"github.com/containers/libpod/cmd/podman/cliconfig"
- "github.com/containers/libpod/cmd/podman/libpodruntime"
- "github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/adapter"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)
@@ -33,17 +32,15 @@ func init() {
flags := podInspectCommand.Flags()
flags.BoolVarP(&podInspectCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podInspectCmd(c *cliconfig.PodInspectValues) error {
var (
- pod *libpod.Pod
+ pod *adapter.Pod
)
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
args := c.InputArgs
- runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
+ runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
}
diff --git a/cmd/podman/pod_kill.go b/cmd/podman/pod_kill.go
index f6991a1c3..d0318b409 100644
--- a/cmd/podman/pod_kill.go
+++ b/cmd/podman/pod_kill.go
@@ -24,6 +24,9 @@ var (
podKillCommand.GlobalFlags = MainGlobalOpts
return podKillCmd(&podKillCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod kill podID
podman pod kill --signal TERM mywebserver
podman pod kill --latest`,
@@ -37,14 +40,11 @@ func init() {
flags.BoolVarP(&podKillCommand.All, "all", "a", false, "Kill all containers in all pods")
flags.BoolVarP(&podKillCommand.Latest, "latest", "l", false, "Act on the latest pod podman is aware of")
flags.StringVarP(&podKillCommand.Signal, "signal", "s", "KILL", "Signal to send to the containers in the pod")
+ markFlagHiddenForRemoteClient("latest", flags)
}
// podKillCmd kills one or more pods with a signal
func podKillCmd(c *cliconfig.PodKillValues) error {
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_pause.go b/cmd/podman/pod_pause.go
index ea2c80f7b..e01d73c9b 100644
--- a/cmd/podman/pod_pause.go
+++ b/cmd/podman/pod_pause.go
@@ -21,6 +21,9 @@ var (
podPauseCommand.GlobalFlags = MainGlobalOpts
return podPauseCmd(&podPauseCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod pause podID1 podID2
podman pod pause --latest
podman pod pause --all`,
@@ -33,13 +36,10 @@ func init() {
flags := podPauseCommand.Flags()
flags.BoolVarP(&podPauseCommand.All, "all", "a", false, "Pause all running pods")
flags.BoolVarP(&podPauseCommand.Latest, "latest", "l", false, "Act on the latest pod podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podPauseCmd(c *cliconfig.PodPauseValues) error {
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
diff --git a/cmd/podman/pod_ps.go b/cmd/podman/pod_ps.go
index 49af91a1e..85467b6ad 100644
--- a/cmd/podman/pod_ps.go
+++ b/cmd/podman/pod_ps.go
@@ -144,7 +144,7 @@ func init() {
flags.BoolVar(&podPsCommand.NoTrunc, "no-trunc", false, "Do not truncate pod and container IDs")
flags.BoolVarP(&podPsCommand.Quiet, "quiet", "q", false, "Print the numeric IDs of the pods only")
flags.StringVar(&podPsCommand.Sort, "sort", "created", "Sort output by created, id, name, or number")
-
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podPsCmd(c *cliconfig.PodPsValues) error {
diff --git a/cmd/podman/pod_restart.go b/cmd/podman/pod_restart.go
index 2815af0c6..be54630db 100644
--- a/cmd/podman/pod_restart.go
+++ b/cmd/podman/pod_restart.go
@@ -22,6 +22,9 @@ var (
podRestartCommand.GlobalFlags = MainGlobalOpts
return podRestartCmd(&podRestartCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod restart podID1 podID2
podman pod restart --latest
podman pod restart --all`,
@@ -35,13 +38,10 @@ func init() {
flags.BoolVarP(&podRestartCommand.All, "all", "a", false, "Restart all running pods")
flags.BoolVarP(&podRestartCommand.Latest, "latest", "l", false, "Restart the latest pod podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podRestartCmd(c *cliconfig.PodRestartValues) error {
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go
index b615f88c9..b552b9f42 100644
--- a/cmd/podman/pod_rm.go
+++ b/cmd/podman/pod_rm.go
@@ -26,6 +26,9 @@ If --force is specified, all containers will be stopped, then removed.
podRmCommand.GlobalFlags = MainGlobalOpts
return podRmCmd(&podRmCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod rm mywebserverpod
podman pod rm -f 860a4b23
podman pod rm -f -a`,
@@ -39,14 +42,11 @@ func init() {
flags.BoolVarP(&podRmCommand.All, "all", "a", false, "Remove all running pods")
flags.BoolVarP(&podRmCommand.Force, "force", "f", false, "Force removal of a running pod by first stopping all containers, then removing all containers in the pod. The default is false")
flags.BoolVarP(&podRmCommand.Latest, "latest", "l", false, "Remove the latest pod podman is aware of")
-
+ markFlagHiddenForRemoteClient("latest", flags)
}
// podRmCmd deletes pods
func podRmCmd(c *cliconfig.PodRmValues) error {
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
runtime, err := adapter.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_start.go b/cmd/podman/pod_start.go
index d093c51cf..3bba5c2e9 100644
--- a/cmd/podman/pod_start.go
+++ b/cmd/podman/pod_start.go
@@ -26,6 +26,9 @@ var (
podStartCommand.GlobalFlags = MainGlobalOpts
return podStartCmd(&podStartCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod start podID
podman pod start --latest
podman pod start --all`,
@@ -38,13 +41,10 @@ func init() {
flags := podStartCommand.Flags()
flags.BoolVarP(&podStartCommand.All, "all", "a", false, "Start all pods")
flags.BoolVarP(&podStartCommand.Latest, "latest", "l", false, "Start the latest pod podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podStartCmd(c *cliconfig.PodStartValues) error {
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go
index b1779532f..907d6a547 100644
--- a/cmd/podman/pod_stats.go
+++ b/cmd/podman/pod_stats.go
@@ -47,6 +47,7 @@ func init() {
flags.BoolVarP(&podStatsCommand.Latest, "latest", "l", false, "Provide stats on the latest pod podman is aware of")
flags.BoolVar(&podStatsCommand.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false")
flags.BoolVar(&podStatsCommand.NoReset, "no-reset", false, "Disable resetting the screen between intervals")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podStatsCmd(c *cliconfig.PodStatsValues) error {
diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go
index a9237347e..52c92b521 100644
--- a/cmd/podman/pod_stop.go
+++ b/cmd/podman/pod_stop.go
@@ -27,6 +27,9 @@ var (
podStopCommand.GlobalFlags = MainGlobalOpts
return podStopCmd(&podStopCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod stop mywebserverpod
podman pod stop --latest
podman pod stop --timeout 0 490eb 3557fb`,
@@ -40,14 +43,11 @@ func init() {
flags.BoolVarP(&podStopCommand.All, "all", "a", false, "Stop all running pods")
flags.BoolVarP(&podStopCommand.Latest, "latest", "l", false, "Stop the latest pod podman is aware of")
flags.UintVarP(&podStopCommand.Timeout, "timeout", "t", 0, "Seconds to wait for pod stop before killing the container")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podStopCmd(c *cliconfig.PodStopValues) error {
timeout := -1
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "could not get runtime")
diff --git a/cmd/podman/pod_unpause.go b/cmd/podman/pod_unpause.go
index 6c131b92c..35128e87b 100644
--- a/cmd/podman/pod_unpause.go
+++ b/cmd/podman/pod_unpause.go
@@ -22,6 +22,9 @@ var (
podUnpauseCommand.GlobalFlags = MainGlobalOpts
return podUnpauseCmd(&podUnpauseCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman pod unpause podID1 podID2
podman pod unpause --all
podman pod unpause --latest`,
@@ -34,13 +37,10 @@ func init() {
flags := podUnpauseCommand.Flags()
flags.BoolVarP(&podUnpauseCommand.All, "all", "a", false, "Unpause all running pods")
flags.BoolVarP(&podUnpauseCommand.Latest, "latest", "l", false, "Unpause the latest pod podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func podUnpauseCmd(c *cliconfig.PodUnpauseValues) error {
- if err := checkMutuallyExclusiveFlags(&c.PodmanCommand); err != nil {
- return err
- }
-
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
return errors.Wrapf(err, "error creating libpod runtime")
diff --git a/cmd/podman/port.go b/cmd/podman/port.go
index 581371e4f..bcf372a51 100644
--- a/cmd/podman/port.go
+++ b/cmd/podman/port.go
@@ -28,6 +28,9 @@ var (
portCommand.GlobalFlags = MainGlobalOpts
return portCmd(&portCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, true)
+ },
Example: `podman port --all
podman port ctrID 80/tcp
podman port --latest 80`,
@@ -42,6 +45,7 @@ func init() {
flags.BoolVarP(&portCommand.All, "all", "a", false, "Display port information for all containers")
flags.BoolVarP(&portCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func portCmd(c *cliconfig.PortValues) error {
diff --git a/cmd/podman/ps.go b/cmd/podman/ps.go
index d7f0d9da0..9c165b836 100644
--- a/cmd/podman/ps.go
+++ b/cmd/podman/ps.go
@@ -191,6 +191,7 @@ func init() {
flags.StringVar(&psCommand.Sort, "sort", "created", "Sort output by command, created, id, image, names, runningfor, size, or status")
flags.BoolVar(&psCommand.Sync, "sync", false, "Sync container state with OCI runtime")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func psCmd(c *cliconfig.PsValues) error {
diff --git a/cmd/podman/pull.go b/cmd/podman/pull.go
index 0065e975a..476bccb0e 100644
--- a/cmd/podman/pull.go
+++ b/cmd/podman/pull.go
@@ -74,19 +74,16 @@ func pullCmd(c *cliconfig.PullValues) error {
args := c.InputArgs
if len(args) == 0 {
- logrus.Errorf("an image name must be specified")
- return nil
+ return errors.Errorf("an image name must be specified")
}
if len(args) > 1 {
- logrus.Errorf("too many arguments. Requires exactly 1")
- return nil
+ return errors.Errorf("too many arguments. Requires exactly 1")
}
arr := strings.SplitN(args[0], ":", 2)
if len(arr) == 2 {
if c.Bool("all-tags") {
- logrus.Errorf("tag can't be used with --all-tags")
- return nil
+ return errors.Errorf("tag can't be used with --all-tags")
}
}
ctx := getContext()
diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go
index 97b689c02..58fb38874 100644
--- a/cmd/podman/restart.go
+++ b/cmd/podman/restart.go
@@ -26,6 +26,9 @@ var (
restartCommand.GlobalFlags = MainGlobalOpts
return restartCmd(&restartCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman restart ctrID
podman restart --latest
podman restart ctrID1 ctrID2`,
@@ -42,6 +45,7 @@ func init() {
flags.UintVarP(&restartCommand.Timeout, "timeout", "t", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container")
flags.UintVar(&restartCommand.Timeout, "time", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func restartCmd(c *cliconfig.RestartValues) error {
diff --git a/cmd/podman/restore.go b/cmd/podman/restore.go
index 2911bbdd6..5f6e7b892 100644
--- a/cmd/podman/restore.go
+++ b/cmd/podman/restore.go
@@ -29,6 +29,9 @@ var (
restoreCommand.GlobalFlags = MainGlobalOpts
return restoreCmd(&restoreCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman container restore ctrID
podman container restore --latest
podman container restore --all`,
@@ -45,6 +48,7 @@ func init() {
// TODO: add ContainerStateCheckpointed
flags.BoolVar(&restoreCommand.TcpEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func restoreCmd(c *cliconfig.RestoreValues) error {
@@ -63,10 +67,6 @@ func restoreCmd(c *cliconfig.RestoreValues) error {
TCPEstablished: c.TcpEstablished,
}
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
-
containers, lastError := getAllOrLatestContainers(&c.PodmanCommand, runtime, libpod.ContainerStateExited, "checkpointed")
for _, ctr := range containers {
diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go
index 2e5fe1dc0..01ed70f52 100644
--- a/cmd/podman/rm.go
+++ b/cmd/podman/rm.go
@@ -28,6 +28,9 @@ Running containers will not be removed without the -f option.
rmCommand.GlobalFlags = MainGlobalOpts
return rmCmd(&rmCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman rm imageID
podman rm mywebserver myflaskserver 860a4b23
podman rm --force --all`,
@@ -42,6 +45,7 @@ func init() {
flags.BoolVarP(&rmCommand.Force, "force", "f", false, "Force removal of a running container. The default is false")
flags.BoolVarP(&rmCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVarP(&rmCommand.Volumes, "volumes", "v", false, "Remove the volumes associated with the container")
+ markFlagHiddenForRemoteClient("latest", flags)
}
// saveCmd saves the image to either docker-archive or oci
@@ -57,10 +61,6 @@ func rmCmd(c *cliconfig.RmValues) error {
}
defer runtime.Shutdown(false)
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
-
delContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all")
if err != nil {
if c.Force && len(c.InputArgs) > 0 {
diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go
index 54f210e62..d466651f3 100644
--- a/cmd/podman/runlabel.go
+++ b/cmd/podman/runlabel.go
@@ -13,7 +13,6 @@ import (
"github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/utils"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
@@ -87,8 +86,7 @@ func runlabelCmd(c *cliconfig.RunlabelValues) error {
args := c.InputArgs
if len(args) < 2 {
- logrus.Errorf("the runlabel command requires at least 2 arguments: LABEL IMAGE")
- return nil
+ return errors.Errorf("the runlabel command requires at least 2 arguments: LABEL IMAGE")
}
if c.Display && c.Quiet {
return errors.Errorf("the display and quiet flags cannot be used together.")
diff --git a/cmd/podman/save.go b/cmd/podman/save.go
index ba5209f34..ab421add6 100644
--- a/cmd/podman/save.go
+++ b/cmd/podman/save.go
@@ -1,20 +1,25 @@
package main
import (
- "os"
-
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/libpod/adapter"
+ "github.com/containers/libpod/pkg/util"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
+ "os"
+ "strings"
)
const (
ociManifestDir = "oci-dir"
+ ociArchive = "oci-archive"
v2s2ManifestDir = "docker-dir"
+ v2s2Archive = "docker-archive"
)
+var validFormats = []string{ociManifestDir, ociArchive, v2s2ManifestDir, v2s2Archive}
+
var (
saveCommand cliconfig.SaveValues
saveDescription = `
@@ -30,6 +35,16 @@ var (
saveCommand.GlobalFlags = MainGlobalOpts
return saveCmd(&saveCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ format, err := cmd.Flags().GetString("format")
+ if err != nil {
+ return err
+ }
+ if !util.StringInSlice(format, validFormats) {
+ return errors.Errorf("format value must be one of %s", strings.Join(validFormats, " "))
+ }
+ return nil
+ },
Example: `podman save --quiet -o myimage.tar imageID
podman save --format docker-dir -o ubuntu-dir ubuntu
podman save > alpine-all.tar alpine:latest`,
@@ -41,7 +56,7 @@ func init() {
saveCommand.SetUsageTemplate(UsageTemplate())
flags := saveCommand.Flags()
flags.BoolVar(&saveCommand.Compress, "compress", false, "Compress tarball image layers when saving to a directory using the 'dir' transport. (default is same compression type as source)")
- flags.StringVar(&saveCommand.Format, "format", "docker-archive", "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-dir (directory with v2s2 manifest type)")
+ flags.StringVar(&saveCommand.Format, "format", v2s2Archive, "Save image to oci-archive, oci-dir (directory with oci manifest type), docker-archive, docker-dir (directory with v2s2 manifest type)")
flags.StringVarP(&saveCommand.Output, "output", "o", "/dev/stdout", "Write to a file, default is STDOUT")
flags.BoolVarP(&saveCommand.Quiet, "quiet", "q", false, "Suppress the output")
}
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index db8abae83..c645a35c4 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -44,6 +44,7 @@ func init() {
flags.BoolVarP(&startCommand.Interactive, "interactive", "i", false, "Keep STDIN open even if not attached")
flags.BoolVarP(&startCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&startCommand.SigProxy, "sig-proxy", true, "Proxy received signals to the process (default true if attaching, false otherwise)")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func startCmd(c *cliconfig.StartValues) error {
diff --git a/cmd/podman/stats.go b/cmd/podman/stats.go
index 642e54f49..2bbcd0a17 100644
--- a/cmd/podman/stats.go
+++ b/cmd/podman/stats.go
@@ -41,6 +41,9 @@ var (
statsCommand.GlobalFlags = MainGlobalOpts
return statsCmd(&statsCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman stats --all --no-stream
podman stats ctrID
podman stats --no-stream --format "table {{.ID}} {{.Name}} {{.MemUsage}}" ctrID`,
@@ -56,6 +59,7 @@ func init() {
flags.BoolVarP(&statsCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.BoolVar(&statsCommand.NoReset, "no-reset", false, "Disable resetting the screen between intervals")
flags.BoolVar(&statsCommand.NoStream, "no-stream", false, "Disable streaming stats and only pull the first result, default setting is false")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func statsCmd(c *cliconfig.StatsValues) error {
diff --git a/cmd/podman/stop.go b/cmd/podman/stop.go
index 94fdf321e..67c15b2a8 100644
--- a/cmd/podman/stop.go
+++ b/cmd/podman/stop.go
@@ -32,6 +32,9 @@ var (
stopCommand.GlobalFlags = MainGlobalOpts
return stopCmd(&stopCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, false)
+ },
Example: `podman stop ctrID
podman stop --latest
podman stop --timeout 2 mywebserver 6e534f14da9d`,
@@ -46,6 +49,7 @@ func init() {
flags.BoolVarP(&stopCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
flags.UintVar(&stopCommand.Timeout, "time", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container")
flags.UintVarP(&stopCommand.Timeout, "timeout", "t", libpod.CtrRemoveTimeout, "Seconds to wait for stop before killing the container")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func stopCmd(c *cliconfig.StopValues) error {
@@ -54,10 +58,6 @@ func stopCmd(c *cliconfig.StopValues) error {
defer span.Finish()
}
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
-
rootless.SetSkipStorageSetup(true)
runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand)
if err != nil {
diff --git a/cmd/podman/top.go b/cmd/podman/top.go
index d85e1be53..36d6bb6b4 100644
--- a/cmd/podman/top.go
+++ b/cmd/podman/top.go
@@ -55,6 +55,7 @@ func init() {
flags.BoolVar(&topCommand.ListDescriptors, "list-descriptors", false, "")
flags.MarkHidden("list-descriptors")
flags.BoolVarP(&topCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func topCmd(c *cliconfig.TopValues) error {
diff --git a/cmd/podman/umount.go b/cmd/podman/umount.go
index afa0e86db..6d9009388 100644
--- a/cmd/podman/umount.go
+++ b/cmd/podman/umount.go
@@ -31,6 +31,9 @@ An unmount can be forced with the --force flag.
umountCommand.GlobalFlags = MainGlobalOpts
return umountCmd(&umountCommand)
},
+ Args: func(cmd *cobra.Command, args []string) error {
+ return checkAllAndLatest(cmd, args, true)
+ },
Example: `podman umount ctrID
podman umount ctrID1 ctrID2 ctrID3
podman umount --all`,
@@ -44,6 +47,7 @@ func init() {
flags.BoolVarP(&umountCommand.All, "all", "a", false, "Umount all of the currently mounted containers")
flags.BoolVarP(&umountCommand.Force, "force", "f", false, "Force the complete umount all of the currently mounted containers")
flags.BoolVarP(&umountCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func umountCmd(c *cliconfig.UmountValues) error {
@@ -55,9 +59,6 @@ func umountCmd(c *cliconfig.UmountValues) error {
force := c.Force
umountAll := c.All
- if err := checkAllAndLatest(&c.PodmanCommand); err != nil {
- return err
- }
containers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all")
if err != nil {
diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go
index c76e7f2a4..0fbea417b 100644
--- a/cmd/podman/utils.go
+++ b/cmd/podman/utils.go
@@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
+ "github.com/spf13/pflag"
"os"
gosignal "os/signal"
@@ -158,13 +159,6 @@ func (f *RawTtyFormatter) Format(entry *logrus.Entry) ([]byte, error) {
return bytes, err
}
-func checkMutuallyExclusiveFlags(c *cliconfig.PodmanCommand) error {
- if err := checkAllAndLatest(c); err != nil {
- return err
- }
- return nil
-}
-
// For pod commands that have a latest and all flag, getPodsFromContext gets
// pods the user specifies. If there's an error before getting pods, the pods slice
// will be empty and error will be not nil. If an error occured after, the pod slice
@@ -251,3 +245,11 @@ func printParallelOutput(m map[string]error, errCount int) error {
}
return lastError
}
+
+// markFlagHiddenForRemoteClient makes the flag not appear as part of the CLI
+// on the remote-client
+func markFlagHiddenForRemoteClient(flagName string, flags *pflag.FlagSet) {
+ if remoteclient {
+ flags.MarkHidden(flagName)
+ }
+}
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 8ecc2feff..618af3481 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -1082,6 +1082,10 @@ method ContainerInspectData(name: string) -> (config: string)
# development of Podman only and generally should not be used.
method ContainerStateData(name: string) -> (config: string)
+# PodStateData returns inspectr level information of a given pod in string form. This call is for
+# development of Podman only and generally should not be used.
+method PodStateData(name: string) -> (config: string)
+
# Sendfile allows a remote client to send a file to the host
method SendFile(type: string, length: int) -> (file_handle: string)
@@ -1100,11 +1104,15 @@ method GetVolumes(args: []string, all: bool) -> (volumes: []Volume)
# VolumesPrune removes unused volumes on the host
method VolumesPrune() -> (prunedNames: []string, prunedErrors: []string)
+# ImageSave allows you to save an image from the local image storage to a tarball
method ImageSave(options: ImageSaveOptions) -> (reply: MoreResponse)
-
+# GetPodsByContext allows you to get a list pod ids depending on all, latest, or a list of
+# pod names. The definition of latest pod means the latest by creation date. In a multi-
+# user environment, results might differ from what you expect.
method GetPodsByContext(all: bool, latest: bool, args: []string) -> (pods: []string)
+# LoadImage allows you to load an image into local storage from a tarball.
method LoadImage(name: string, inputFile: string, quiet: bool, deleteFile: bool) -> (reply: MoreResponse)
# ImageNotFound means the image could not be found by the provided name or ID in local storage.
diff --git a/cmd/podman/wait.go b/cmd/podman/wait.go
index c6e6240f3..9df7cdbae 100644
--- a/cmd/podman/wait.go
+++ b/cmd/podman/wait.go
@@ -40,6 +40,7 @@ func init() {
flags := waitCommand.Flags()
flags.UintVarP(&waitCommand.Interval, "interval", "i", 250, "Milliseconds to wait before polling for completion")
flags.BoolVarP(&waitCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
+ markFlagHiddenForRemoteClient("latest", flags)
}
func waitCmd(c *cliconfig.WaitValues) error {
diff --git a/docs/podman-attach.1.md b/docs/podman-attach.1.md
index 4322ca2be..ceb945a0e 100644
--- a/docs/podman-attach.1.md
+++ b/docs/podman-attach.1.md
@@ -24,6 +24,8 @@ ctrl-[value] where [value] is one of: a-z, @, ^, [, , or _.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--no-stdin**
Do not attach STDIN. The default is false.
diff --git a/docs/podman-build.1.md b/docs/podman-build.1.md
index 76e16b42c..fdae48b93 100644
--- a/docs/podman-build.1.md
+++ b/docs/podman-build.1.md
@@ -362,6 +362,12 @@ Specifies the name which will be assigned to the resulting image if the build
process completes successfully.
If _imageName_ does not include a registry name, the registry name *localhost* will be prepended to the image name.
+**--target** *stageName*
+
+Set the target build stage to build. When building a Dockerfile with multiple build stages, --target
+can be used to specify an intermediate build stage by name as the final stage for the resulting image.
+Commands after the target stage will be skipped.
+
**--tls-verify** *bool-value*
Require HTTPS and verify certificates when talking to container registries (defaults to true).
diff --git a/docs/podman-container-checkpoint.1.md b/docs/podman-container-checkpoint.1.md
index 94e52dc78..666dbbb80 100644
--- a/docs/podman-container-checkpoint.1.md
+++ b/docs/podman-container-checkpoint.1.md
@@ -25,6 +25,8 @@ Checkpoint all running containers.
Instead of providing the container name or ID, checkpoint the last created container.
+The latest option is not supported on the remote client.
+
**--leave-running, -R**
Leave the container running after checkpointing instead of stopping it.
diff --git a/docs/podman-container-cleanup.1.md b/docs/podman-container-cleanup.1.md
index 2819d1138..e375c12ec 100644
--- a/docs/podman-container-cleanup.1.md
+++ b/docs/podman-container-cleanup.1.md
@@ -19,6 +19,9 @@ Cleanup all containers.
**--latest, -l**
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+
+The latest option is not supported on the remote client.
+
## EXAMPLE
`podman container cleanup mywebserver`
diff --git a/docs/podman-container-restore.1.md b/docs/podman-container-restore.1.md
index 44219f3ef..e47d585cc 100644
--- a/docs/podman-container-restore.1.md
+++ b/docs/podman-container-restore.1.md
@@ -32,6 +32,8 @@ Restore all checkpointed containers.
Instead of providing the container name or ID, restore the last created container.
+The latest option is not supported on the remote client.
+
**--tcp-established**
Restore a container with established TCP connections. If the checkpoint image
diff --git a/docs/podman-diff.1.md b/docs/podman-diff.1.md
index dd5f0edcf..8837b744f 100644
--- a/docs/podman-diff.1.md
+++ b/docs/podman-diff.1.md
@@ -15,6 +15,12 @@ Displays changes on a container or image's filesystem. The container or image w
Alter the output into a different format. The only valid format for diff is `json`.
+**--latest, -l**
+
+Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
+to run containers such as CRI-O, the last started container could be from either of those methods.
+
+The latest option is not supported on the remote client.
## EXAMPLE
diff --git a/docs/podman-exec.1.md b/docs/podman-exec.1.md
index 6f464a8f2..14088b468 100644
--- a/docs/podman-exec.1.md
+++ b/docs/podman-exec.1.md
@@ -24,6 +24,8 @@ Not supported. All exec commands are interactive by default.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--privileged**
Give the process extended Linux capabilities when running the command in container.
diff --git a/docs/podman-inspect.1.md b/docs/podman-inspect.1.md
index b01bc0f4e..5748f29f4 100644
--- a/docs/podman-inspect.1.md
+++ b/docs/podman-inspect.1.md
@@ -27,6 +27,8 @@ The keys of the returned JSON can be used as the values for the --format flag (s
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--size, -s**
Display the total file size if the type is a container
diff --git a/docs/podman-kill.1.md b/docs/podman-kill.1.md
index 85f68a73d..1c14b71d5 100644
--- a/docs/podman-kill.1.md
+++ b/docs/podman-kill.1.md
@@ -19,6 +19,8 @@ Signal all running containers. This does not include paused containers.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--signal, s**
Signal to send to the container. For more information on Linux signals, refer to *man signal(7)*.
diff --git a/docs/podman-load.1.md b/docs/podman-load.1.md
index eca7ecb2e..8b6501a5c 100644
--- a/docs/podman-load.1.md
+++ b/docs/podman-load.1.md
@@ -22,7 +22,9 @@ Note: `:` is a restricted character and cannot be part of the file name.
**--input, -i**
-Read from archive file, default is STDIN
+Read from archive file, default is STDIN.
+
+The remote client requires the use of this option.
**--quiet, -q**
diff --git a/docs/podman-logs.1.md b/docs/podman-logs.1.md
index 6b37aed9e..bc02df954 100644
--- a/docs/podman-logs.1.md
+++ b/docs/podman-logs.1.md
@@ -17,6 +17,13 @@ any logs at the time you execute podman logs
Follow log output. Default is false
+**--latest, -l**
+
+Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
+to run containers such as CRI-O, the last started container could be from either of those methods.
+
+The latest option is not supported on the remote client.
+
**--since=TIMESTAMP**
Show logs since TIMESTAMP. The --since option can be Unix timestamps, date formatted timestamps, or Go duration
diff --git a/docs/podman-mount.1.md b/docs/podman-mount.1.md
index 2cccf5ee0..e244e5daf 100644
--- a/docs/podman-mount.1.md
+++ b/docs/podman-mount.1.md
@@ -33,6 +33,8 @@ Instead of providing the container name or ID, use the last created container.
If you use methods other than Podman to run containers such as CRI-O, the last
started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--notruncate**
Do not truncate IDs in output.
diff --git a/docs/podman-pod-inspect.1.md b/docs/podman-pod-inspect.1.md
index b8fb143ba..a4e6a5559 100644
--- a/docs/podman-pod-inspect.1.md
+++ b/docs/podman-pod-inspect.1.md
@@ -16,6 +16,7 @@ that belong to the pod.
Instead of providing the pod name or ID, use the last created pod. If you use methods other than Podman
to run pods such as CRI-O, the last started pod could be from either of those methods.
+The latest option is not supported on the remote client.
## EXAMPLE
```
diff --git a/docs/podman-pod-kill.1.md b/docs/podman-pod-kill.1.md
index 4376c2d29..2a863d3d9 100644
--- a/docs/podman-pod-kill.1.md
+++ b/docs/podman-pod-kill.1.md
@@ -19,6 +19,8 @@ Sends signal to all containers associated with a pod.
Instead of providing the pod name or ID, use the last created pod. If you use methods other than Podman
to run pods such as CRI-O, the last started pod could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--signal, s**
Signal to send to the containers in the pod. For more information on Linux signals, refer to *man signal(7)*.
diff --git a/docs/podman-pod-pause.1.md b/docs/podman-pod-pause.1.md
index 32c5b927e..418a9ee2a 100644
--- a/docs/podman-pod-pause.1.md
+++ b/docs/podman-pod-pause.1.md
@@ -19,6 +19,8 @@ Pause all pods.
Instead of providing the pod name or ID, pause the last created pod.
+The latest option is not supported on the remote client.
+
## EXAMPLE
podman pod pause mywebserverpod
diff --git a/docs/podman-pod-ps.1.md b/docs/podman-pod-ps.1.md
index 24b343438..ee215154a 100644
--- a/docs/podman-pod-ps.1.md
+++ b/docs/podman-pod-ps.1.md
@@ -42,6 +42,8 @@ Includes the container statuses in the container info field
Show the latest pod created (all states)
+The latest option is not supported on the remote client.
+
**--no-trunc**
Display the extended information
diff --git a/docs/podman-pod-restart.1.md b/docs/podman-pod-restart.1.md
index 1cccd3382..cd6e5c8ce 100644
--- a/docs/podman-pod-restart.1.md
+++ b/docs/podman-pod-restart.1.md
@@ -22,6 +22,8 @@ Restarts all pods
Instead of providing the pod name or ID, restart the last created pod.
+The latest option is not supported on the remote client.
+
## EXAMPLE
```
diff --git a/docs/podman-pod-rm.1.md b/docs/podman-pod-rm.1.md
index 7a300c152..aa26a1bbb 100644
--- a/docs/podman-pod-rm.1.md
+++ b/docs/podman-pod-rm.1.md
@@ -19,6 +19,8 @@ Remove all pods. Can be used in conjunction with \-f as well.
Instead of providing the pod name or ID, remove the last created pod.
+The latest option is not supported on the remote client.
+
**--force, f**
Stop running containers and delete all stopped containers before removal of pod.
diff --git a/docs/podman-pod-start.1.md b/docs/podman-pod-start.1.md
index 253bb5f53..27e40740f 100644
--- a/docs/podman-pod-start.1.md
+++ b/docs/podman-pod-start.1.md
@@ -20,6 +20,8 @@ Starts all pods
Instead of providing the pod name or ID, start the last created pod.
+The latest option is not supported on the remote client.
+
## EXAMPLE
podman pod start mywebserverpod
diff --git a/docs/podman-pod-stop.1.md b/docs/podman-pod-stop.1.md
index 7544f8bf7..338e04d67 100644
--- a/docs/podman-pod-stop.1.md
+++ b/docs/podman-pod-stop.1.md
@@ -19,6 +19,8 @@ Stops all pods
Instead of providing the pod name or ID, stop the last created pod.
+The latest option is not supported on the remote client.
+
**--timeout, --time, t**
Timeout to wait before forcibly stopping the containers in the pod.
diff --git a/docs/podman-pod-top.1.md b/docs/podman-pod-top.1.md
index 0b330eb03..a77ca2b37 100644
--- a/docs/podman-pod-top.1.md
+++ b/docs/podman-pod-top.1.md
@@ -19,6 +19,8 @@ Display the running process of containers in a pod. The *format-descriptors* are
Instead of providing the pod name or ID, use the last created pod.
+The latest option is not supported on the remote client.
+
## FORMAT DESCRIPTORS
The following descriptors are supported in addition to the AIX format descriptors mentioned in ps (1):
diff --git a/docs/podman-pod-unpause.1.md b/docs/podman-pod-unpause.1.md
index 643544ef1..1004e09f9 100644
--- a/docs/podman-pod-unpause.1.md
+++ b/docs/podman-pod-unpause.1.md
@@ -19,6 +19,8 @@ Unpause all pods.
Instead of providing the pod name or ID, unpause the last created pod.
+The latest option is not supported on the remote client.
+
## EXAMPLE
podman pod unpause mywebserverpod
diff --git a/docs/podman-port.1.md b/docs/podman-port.1.md
index 25a8eceb5..020a25d32 100644
--- a/docs/podman-port.1.md
+++ b/docs/podman-port.1.md
@@ -21,6 +21,8 @@ or private ports/protocols as filters.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
## EXAMPLE
List all port mappings
diff --git a/docs/podman-ps.1.md b/docs/podman-ps.1.md
index 8b86703d8..b8b1c3d62 100644
--- a/docs/podman-ps.1.md
+++ b/docs/podman-ps.1.md
@@ -75,6 +75,8 @@ Print the n last created containers (all states)
Show the latest container created (all states)
+The latest option is not supported on the remote client.
+
**--namespace, --ns**
Display namespace information
diff --git a/docs/podman-restart.1.md b/docs/podman-restart.1.md
index 875afa385..dd28e34c7 100644
--- a/docs/podman-restart.1.md
+++ b/docs/podman-restart.1.md
@@ -19,6 +19,8 @@ Restart all containers regardless of their current state.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--running**
Restart all containers that are already in the *running* state.
diff --git a/docs/podman-rm.1.md b/docs/podman-rm.1.md
index f4513c2be..10ebe97f9 100644
--- a/docs/podman-rm.1.md
+++ b/docs/podman-rm.1.md
@@ -26,6 +26,8 @@ Containers could have been created by a different container engine.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--volumes, -v**
Remove the volumes associated with the container. (Not yet implemented)
diff --git a/docs/podman-start.1.md b/docs/podman-start.1.md
index 786936721..b0167003e 100644
--- a/docs/podman-start.1.md
+++ b/docs/podman-start.1.md
@@ -33,6 +33,7 @@ Attach container's STDIN. The default is false.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
**--sig-proxy**=*true*|*false*
diff --git a/docs/podman-stats.1.md b/docs/podman-stats.1.md
index d0b56b2e6..97a9be961 100644
--- a/docs/podman-stats.1.md
+++ b/docs/podman-stats.1.md
@@ -20,6 +20,8 @@ Show all containers. Only running containers are shown by default
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--no-reset**
Do not clear the terminal/screen in between reporting intervals
diff --git a/docs/podman-stop.1.md b/docs/podman-stop.1.md
index e36265d5e..2016a7301 100644
--- a/docs/podman-stop.1.md
+++ b/docs/podman-stop.1.md
@@ -24,6 +24,8 @@ Stop all running containers. This does not include paused containers.
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
**--timeout, --time, t**
Timeout to wait before forcibly stopping the container
diff --git a/docs/podman-top.1.md b/docs/podman-top.1.md
index 7782a3f29..52d1238ef 100644
--- a/docs/podman-top.1.md
+++ b/docs/podman-top.1.md
@@ -20,6 +20,8 @@ Display the running process of the container. The *format-descriptors* are ps (1
Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
## FORMAT DESCRIPTORS
The following descriptors are supported in addition to the AIX format descriptors mentioned in ps (1):
diff --git a/docs/podman-umount.1.md b/docs/podman-umount.1.md
index cceb63019..795f0402d 100644
--- a/docs/podman-umount.1.md
+++ b/docs/podman-umount.1.md
@@ -35,6 +35,8 @@ Instead of providing the container name or ID, use the last created container.
If you use methods other than Podman to run containers such as CRI-O, the last
started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
## EXAMPLE
podman umount containerID
diff --git a/docs/podman-wait.1.md b/docs/podman-wait.1.md
index dd5dc7907..672316eef 100644
--- a/docs/podman-wait.1.md
+++ b/docs/podman-wait.1.md
@@ -22,9 +22,11 @@ After the container stops, the container's return code is printed.
**--latest, -l**
- Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
+Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
to run containers such as CRI-O, the last started container could be from either of those methods.
+The latest option is not supported on the remote client.
+
## EXAMPLES
```
diff --git a/libpod/adapter/pods.go b/libpod/adapter/pods.go
index 59642c42e..9841c20c0 100644
--- a/libpod/adapter/pods.go
+++ b/libpod/adapter/pods.go
@@ -36,3 +36,19 @@ func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValue
}
return podids, errs
}
+
+// GetLatestPod gets the latest pod and wraps it in an adapter pod
+func (r *LocalRuntime) GetLatestPod() (*Pod, error) {
+ pod := Pod{}
+ p, err := r.Runtime.GetLatestPod()
+ pod.Pod = p
+ return &pod, err
+}
+
+// LookupPod gets a pod by name or id and wraps it in an adapter pod
+func (r *LocalRuntime) LookupPod(nameOrID string) (*Pod, error) {
+ pod := Pod{}
+ p, err := r.Runtime.LookupPod(nameOrID)
+ pod.Pod = p
+ return &pod, err
+}
diff --git a/libpod/adapter/pods_remote.go b/libpod/adapter/pods_remote.go
index 3fb147f48..57c78821f 100644
--- a/libpod/adapter/pods_remote.go
+++ b/libpod/adapter/pods_remote.go
@@ -4,10 +4,13 @@ package adapter
import (
"context"
+ "encoding/json"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ "github.com/pkg/errors"
+ "github.com/ulule/deepcopier"
)
// Pod ...
@@ -16,11 +19,13 @@ type Pod struct {
}
type remotepod struct {
- config *libpod.PodConfig
- state *libpod.PodInspectState
- Runtime *LocalRuntime
+ config *libpod.PodConfig
+ state *libpod.PodInspectState
+ containers []libpod.PodContainerInfo
+ Runtime *LocalRuntime
}
+// RemovePods removes one or more based on the cli context.
func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValues) ([]string, []error) {
var (
rmErrs []error
@@ -42,3 +47,52 @@ func (r *LocalRuntime) RemovePods(ctx context.Context, cli *cliconfig.PodRmValue
}
return rmPods, rmErrs
}
+
+// Inspect looks up a pod by name or id and embeds its data into a remote pod
+// object.
+func (r *LocalRuntime) Inspect(nameOrID string) (*Pod, error) {
+ reply, err := iopodman.PodStateData().Call(r.Conn, nameOrID)
+ if err != nil {
+ return nil, err
+ }
+ data := libpod.PodInspect{}
+ if err := json.Unmarshal([]byte(reply), &data); err != nil {
+ return nil, err
+ }
+ pod := Pod{}
+ pod.Runtime = r
+ pod.config = data.Config
+ pod.state = data.State
+ pod.containers = data.Containers
+ return &pod, nil
+}
+
+// GetLatestPod gets the latest pod and wraps it in an adapter pod
+func (r *LocalRuntime) GetLatestPod() (*Pod, error) {
+ reply, err := iopodman.GetPodsByContext().Call(r.Conn, false, true, nil)
+ if err != nil {
+ return nil, err
+ }
+ if len(reply) > 0 {
+ return r.Inspect(reply[0])
+ }
+ return nil, errors.New("no pods exist")
+}
+
+// LookupPod gets a pod by name or ID and wraps it in an adapter pod
+func (r *LocalRuntime) LookupPod(nameOrID string) (*Pod, error) {
+ return r.Inspect(nameOrID)
+}
+
+// Inspect, like libpod pod inspect, returns a libpod.PodInspect object from
+// the data of a remotepod data struct
+func (p *Pod) Inspect() (*libpod.PodInspect, error) {
+ config := new(libpod.PodConfig)
+ deepcopier.Copy(p.remotepod.config).To(config)
+ inspectData := libpod.PodInspect{
+ Config: config,
+ State: p.remotepod.state,
+ Containers: p.containers,
+ }
+ return &inspectData, nil
+}
diff --git a/libpod/container_commit.go b/libpod/container_commit.go
index 026611e51..5c4fd1a31 100644
--- a/libpod/container_commit.go
+++ b/libpod/container_commit.go
@@ -162,7 +162,7 @@ func (c *Container) Commit(ctx context.Context, destImage string, options Contai
importBuilder.SetWorkDir(splitChange[1])
}
}
- candidates, _, err := util.ResolveName(destImage, "", sc, c.runtime.store)
+ candidates, _, _, err := util.ResolveName(destImage, "", sc, c.runtime.store)
if err != nil {
return nil, errors.Wrapf(err, "error resolving name %q", destImage)
}
diff --git a/libpod/options.go b/libpod/options.go
index 7c37fd65b..9aa020b56 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -149,6 +149,7 @@ func WithOCIRuntime(runtime string) RuntimeOption {
}
rt.config.OCIRuntime = runtime
+ rt.config.RuntimePath = nil
return nil
}
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index acc5d6b2a..dfbc7fe33 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -109,6 +109,13 @@ reexec_userns_join (int userns, int mountns)
char uid[16];
char **argv;
int pid;
+ char *cwd = getcwd (NULL, 0);
+
+ if (cwd == NULL)
+ {
+ fprintf (stderr, "error getting current working directory: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
sprintf (uid, "%d", geteuid ());
@@ -154,6 +161,13 @@ reexec_userns_join (int userns, int mountns)
_exit (EXIT_FAILURE);
}
+ if (chdir (cwd) < 0)
+ {
+ fprintf (stderr, "cannot chdir: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+ free (cwd);
+
execvp (argv[0], argv);
_exit (EXIT_FAILURE);
@@ -190,6 +204,13 @@ reexec_in_user_namespace (int ready)
char *listen_fds = NULL;
char *listen_pid = NULL;
bool do_socket_activation = false;
+ char *cwd = getcwd (NULL, 0);
+
+ if (cwd == NULL)
+ {
+ fprintf (stderr, "error getting current working directory: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
listen_pid = getenv("LISTEN_PID");
listen_fds = getenv("LISTEN_FDS");
@@ -265,6 +286,13 @@ reexec_in_user_namespace (int ready)
_exit (EXIT_FAILURE);
}
+ if (chdir (cwd) < 0)
+ {
+ fprintf (stderr, "cannot chdir: %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
+ free (cwd);
+
execvp (argv[0], argv);
_exit (EXIT_FAILURE);
diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go
index 5395a39c0..448f58896 100644
--- a/pkg/varlinkapi/pods.go
+++ b/pkg/varlinkapi/pods.go
@@ -286,3 +286,20 @@ func (i *LibpodAPI) GetPodsByContext(call iopodman.VarlinkCall, all, latest bool
}
return call.ReplyGetPodsByContext(podids)
}
+
+// PodStateData returns a container's state data in string format
+func (i *LibpodAPI) PodStateData(call iopodman.VarlinkCall, name string) error {
+ pod, err := i.Runtime.LookupPod(name)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ data, err := pod.Inspect()
+ if err != nil {
+ return call.ReplyErrorOccurred("unable to obtain pod state")
+ }
+ b, err := json.Marshal(data)
+ if err != nil {
+ return call.ReplyErrorOccurred("unable to serialize pod inspect data")
+ }
+ return call.ReplyPodStateData(string(b))
+}
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index 4b4baa93c..33e05b872 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -28,8 +28,8 @@ func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration
}
// PodmanAsUser is the exec call to podman on the filesystem with the specified uid/gid and environment
-func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, env []string) *PodmanSessionIntegration {
- podmanSession := p.PodmanAsUserBase(args, uid, gid, env)
+func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, cwd string, env []string) *PodmanSessionIntegration {
+ podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env)
return &PodmanSessionIntegration{podmanSession}
}
diff --git a/test/e2e/rootless_test.go b/test/e2e/rootless_test.go
index 2b84d34c9..aa8ed6faa 100644
--- a/test/e2e/rootless_test.go
+++ b/test/e2e/rootless_test.go
@@ -60,7 +60,7 @@ var _ = Describe("Podman rootless", func() {
for _, v := range commands {
env := os.Environ()
env = append(env, "USER=foo")
- cmd := podmanTest.PodmanAsUser([]string{v}, 1000, 1000, env)
+ cmd := podmanTest.PodmanAsUser([]string{v}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
}
@@ -128,13 +128,13 @@ var _ = Describe("Podman rootless", func() {
env = append(env, "PODMAN_ALLOW_SINGLE_ID_MAPPING_IN_USERNS=1")
env = append(env, "USER=foo")
- cmd := rootlessTest.PodmanAsUser([]string{"pod", "create", "--infra=false"}, 1000, 1000, env)
+ cmd := rootlessTest.PodmanAsUser([]string{"pod", "create", "--infra=false"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
podId := cmd.OutputToString()
args := []string{"run", "--pod", podId, "--rootfs", mountPath, "echo", "hello"}
- cmd = rootlessTest.PodmanAsUser(args, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser(args, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
Expect(cmd.LineInOutputContains("hello")).To(BeTrue())
@@ -158,7 +158,7 @@ var _ = Describe("Podman rootless", func() {
env = append(env, fmt.Sprintf("XDG_RUNTIME_DIR=%s", xdgRuntimeDir))
env = append(env, fmt.Sprintf("HOME=%s", home))
env = append(env, "USER=foo")
- cmd := podmanTest.PodmanAsUser([]string{"search", "docker.io/busybox"}, 1000, 1000, env)
+ cmd := podmanTest.PodmanAsUser([]string{"search", "docker.io/busybox"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
})
@@ -175,65 +175,65 @@ var _ = Describe("Podman rootless", func() {
allArgs := append([]string{"run"}, args...)
allArgs = append(allArgs, "--rootfs", mountPath, "echo", "hello")
- cmd := rootlessTest.PodmanAsUser(allArgs, 1000, 1000, env)
+ cmd := rootlessTest.PodmanAsUser(allArgs, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
Expect(cmd.LineInOutputContains("hello")).To(BeTrue())
- cmd = rootlessTest.PodmanAsUser([]string{"rm", "-l", "-f"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"rm", "-l", "-f"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
allArgs = append([]string{"run", "-d"}, args...)
allArgs = append(allArgs, "--security-opt", "seccomp=unconfined", "--rootfs", mountPath, "top")
- cmd = rootlessTest.PodmanAsUser(allArgs, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser(allArgs, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
- cmd = rootlessTest.PodmanAsUser([]string{"restart", "-l", "-t", "0"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"restart", "-l", "-t", "0"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
canUseExec := canExec()
if canUseExec {
- cmd = rootlessTest.PodmanAsUser([]string{"top", "-l"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"top", "-l"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
}
- cmd = rootlessTest.PodmanAsUser([]string{"rm", "-l", "-f"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"rm", "-l", "-f"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
allArgs = append([]string{"run", "-d"}, args...)
allArgs = append(allArgs, "--security-opt", "seccomp=unconfined", "--rootfs", mountPath, "unshare", "-r", "unshare", "-r", "top")
- cmd = rootlessTest.PodmanAsUser(allArgs, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser(allArgs, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
- cmd = rootlessTest.PodmanAsUser([]string{"stop", "-l", "-t", "0"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"stop", "-l", "-t", "0"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
- cmd = rootlessTest.PodmanAsUser([]string{"inspect", "-l", "--type", "container", "--format", "{{ .State.Status }}"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"inspect", "-l", "--type", "container", "--format", "{{ .State.Status }}"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.LineInOutputContains("exited")).To(BeTrue())
- cmd = rootlessTest.PodmanAsUser([]string{"start", "-l"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"start", "-l"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
- cmd = rootlessTest.PodmanAsUser([]string{"stop", "-l", "-t", "0"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"stop", "-l", "-t", "0"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
- cmd = rootlessTest.PodmanAsUser([]string{"start", "-l"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"start", "-l"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
if len(args) == 0 {
- cmd = rootlessTest.PodmanAsUser([]string{"inspect", "-l"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"inspect", "-l"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
data := cmd.InspectContainerToJSON()
@@ -244,24 +244,23 @@ var _ = Describe("Podman rootless", func() {
Skip("ioctl(NS_GET_PARENT) not supported.")
}
- cmd = rootlessTest.PodmanAsUser([]string{"exec", "-l", "echo", "hello"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"exec", "-l", "echo", "hello"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
Expect(cmd.LineInOutputContains("hello")).To(BeTrue())
- cmd = rootlessTest.PodmanAsUser([]string{"ps", "-l", "-q"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"ps", "-l", "-q"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
cid := cmd.OutputToString()
- cmd = rootlessTest.PodmanAsUser([]string{"exec", "-l", "sh", "-c", "echo SeCreTMessage > /file"}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"exec", "-l", "sh", "-c", "echo SeCreTMessage > /file"}, 1000, 1000, "", env)
cmd.WaitWithDefaultTimeout()
Expect(cmd.ExitCode()).To(Equal(0))
- path := filepath.Join(home, "export.tar")
- cmd = rootlessTest.PodmanAsUser([]string{"export", "-o", path, cid}, 1000, 1000, env)
+ cmd = rootlessTest.PodmanAsUser([]string{"export", "-o", "export.tar", cid}, 1000, 1000, home, env)
cmd.WaitWithDefaultTimeout()
- content, err := ioutil.ReadFile(path)
+ content, err := ioutil.ReadFile(filepath.Join(home, "export.tar"))
Expect(err).To(BeNil())
Expect(strings.Contains(string(content), "SeCreTMessage")).To(BeTrue())
}
diff --git a/test/utils/podmantest_test.go b/test/utils/podmantest_test.go
index 60e3e2a97..28f294a94 100644
--- a/test/utils/podmantest_test.go
+++ b/test/utils/podmantest_test.go
@@ -23,7 +23,7 @@ var _ = Describe("PodmanTest test", func() {
FakeOutputs["check"] = []string{"check"}
os.Setenv("HOOK_OPTION", "hook_option")
env := os.Environ()
- session := podmanTest.PodmanAsUserBase([]string{"check"}, 1000, 1000, env)
+ session := podmanTest.PodmanAsUserBase([]string{"check"}, 1000, 1000, "", env)
os.Unsetenv("HOOK_OPTION")
session.WaitWithDefaultTimeout()
Expect(session.Command.Process).ShouldNot(BeNil())
diff --git a/test/utils/utils.go b/test/utils/utils.go
index aace018cd..098779321 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -61,7 +61,7 @@ func (p *PodmanTest) MakeOptions(args []string) []string {
// PodmanAsUserBase exec podman as user. uid and gid is set for credentials useage. env is used
// to record the env for debugging
-func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, env []string) *PodmanSession {
+func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string, env []string) *PodmanSession {
var command *exec.Cmd
podmanOptions := p.MakeOptions(args)
podmanBinary := p.PodmanBinary
@@ -74,14 +74,18 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, env []stri
fmt.Printf("Running: (env: %v) %s %s\n", env, podmanBinary, strings.Join(podmanOptions, " "))
}
if uid != 0 || gid != 0 {
- nsEnterOpts := append([]string{"--userspec", fmt.Sprintf("%d:%d", uid, gid), "/", podmanBinary}, podmanOptions...)
- command = exec.Command("chroot", nsEnterOpts...)
+ pythonCmd := fmt.Sprintf("import os; import sys; uid = %d; gid = %d; cwd = '%s'; os.setgid(gid); os.setuid(uid); os.chdir(cwd) if len(cwd)>0 else True; os.execv(sys.argv[1], sys.argv[1:])", gid, uid, cwd)
+ nsEnterOpts := append([]string{"-c", pythonCmd, podmanBinary}, podmanOptions...)
+ command = exec.Command("python", nsEnterOpts...)
} else {
command = exec.Command(podmanBinary, podmanOptions...)
}
if env != nil {
command.Env = env
}
+ if cwd != "" {
+ command.Dir = cwd
+ }
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
if err != nil {
@@ -92,7 +96,7 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, env []stri
// PodmanBase exec podman with default env.
func (p *PodmanTest) PodmanBase(args []string) *PodmanSession {
- return p.PodmanAsUserBase(args, 0, 0, nil)
+ return p.PodmanAsUserBase(args, 0, 0, "", nil)
}
// WaitForContainer waits on a started container
diff --git a/vendor.conf b/vendor.conf
index ff1a9c4d5..445f0844a 100644
--- a/vendor.conf
+++ b/vendor.conf
@@ -93,13 +93,13 @@ k8s.io/apimachinery kubernetes-1.10.13-beta.0 https://github.com/kubernetes/apim
k8s.io/client-go kubernetes-1.10.13-beta.0 https://github.com/kubernetes/client-go
github.com/mrunalp/fileutils 7d4729fb36185a7c1719923406c9d40e54fb93c7
github.com/varlink/go 3ac79db6fd6aec70924193b090962f92985fe199
-github.com/containers/buildah 973bb88ef1861a5b782c722c471dd79b6732852c
+github.com/containers/buildah v1.7
# TODO: Gotty has not been updated since 2012. Can we find replacement?
github.com/Nvveen/Gotty cd527374f1e5bff4938207604a14f2e38a9cf512
# do not go beyond the below commit as the next one requires a more recent
# docker which is in conflict with openshift/imagebuilder
github.com/fsouza/go-dockerclient 29c1814d12c072344bb91aac5d2ff719db39c523
-github.com/openshift/imagebuilder 474d0f9df2cbabf006bd2b1c263a7b0789e228e0
+github.com/openshift/imagebuilder 36823496a6868f72bc36282cc475eb8a070c0934
github.com/ulikunitz/xz v0.5.5
github.com/coreos/go-iptables v0.4.0
github.com/google/shlex c34317bd91bf98fab745d77b03933cf8769299fe
diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go
index 8b9baea12..755bc348e 100644
--- a/vendor/github.com/containers/buildah/buildah.go
+++ b/vendor/github.com/containers/buildah/buildah.go
@@ -26,7 +26,7 @@ const (
Package = "buildah"
// Version for the Package. Bump version in contrib/rpm/buildah.spec
// too.
- Version = "1.7-dev"
+ Version = "1.7"
// The value we use to identify what type of information, currently a
// serialized Builder structure, we are using as per-container state.
// This should only be changed when we make incompatible changes to
@@ -336,11 +336,6 @@ type BuilderOptions struct {
// needs to be pulled and the image name alone can not be resolved to a
// reference to a source image. No separator is implicitly added.
Registry string
- // Transport is a value which is prepended to the image's name, if it
- // needs to be pulled and the image name alone, or the image name and
- // the registry together, can not be resolved to a reference to a
- // source image. No separator is implicitly added.
- Transport string
// PullBlobDirectory is the name of a directory in which we'll attempt
// to store copies of layer blobs that we pull down, if any. It should
// already exist.
diff --git a/vendor/github.com/containers/buildah/imagebuildah/build.go b/vendor/github.com/containers/buildah/imagebuildah/build.go
index 56ab7aa57..d69eab52f 100644
--- a/vendor/github.com/containers/buildah/imagebuildah/build.go
+++ b/vendor/github.com/containers/buildah/imagebuildah/build.go
@@ -62,11 +62,6 @@ type BuildOptions struct {
// needs to be pulled and the image name alone can not be resolved to a
// reference to a source image. No separator is implicitly added.
Registry string
- // Transport is a value which is prepended to the image's name, if it
- // needs to be pulled and the image name alone, or the image name and
- // the registry together, can not be resolved to a reference to a
- // source image. No separator is implicitly added.
- Transport string
// IgnoreUnrecognizedInstructions tells us to just log instructions we
// don't recognize, and try to keep going.
IgnoreUnrecognizedInstructions bool
@@ -171,6 +166,8 @@ type BuildOptions struct {
ForceRmIntermediateCtrs bool
// BlobDirectory is a directory which we'll use for caching layer blobs.
BlobDirectory string
+ // Target the targeted FROM in the Dockerfile to build
+ Target string
}
// Executor is a buildah-based implementation of the imagebuilder.Executor
@@ -184,7 +181,6 @@ type Executor struct {
builder *buildah.Builder
pullPolicy buildah.PullPolicy
registry string
- transport string
ignoreUnrecognizedInstructions bool
quiet bool
runtime string
@@ -580,7 +576,6 @@ func NewExecutor(store storage.Store, options BuildOptions) (*Executor, error) {
contextDir: options.ContextDirectory,
pullPolicy: options.PullPolicy,
registry: options.Registry,
- transport: options.Transport,
ignoreUnrecognizedInstructions: options.IgnoreUnrecognizedInstructions,
quiet: options.Quiet,
runtime: options.Runtime,
@@ -670,7 +665,6 @@ func (b *Executor) Prepare(ctx context.Context, stage imagebuilder.Stage, from s
FromImage: from,
PullPolicy: b.pullPolicy,
Registry: b.registry,
- Transport: b.transport,
PullBlobDirectory: b.blobDirectory,
SignaturePolicyPath: b.signaturePolicyPath,
ReportWriter: b.reportWriter,
@@ -783,7 +777,7 @@ func (b *Executor) resolveNameToImageRef() (types.ImageReference, error) {
if b.output != "" {
imageRef, err = alltransports.ParseImageName(b.output)
if err != nil {
- candidates, _, err := util.ResolveName(b.output, "", b.systemContext, b.store)
+ candidates, _, _, err := util.ResolveName(b.output, "", b.systemContext, b.store)
if err != nil {
return nil, errors.Wrapf(err, "error parsing target image name %q", b.output)
}
@@ -1441,6 +1435,13 @@ func BuildDockerfiles(ctx context.Context, store storage.Store, options BuildOpt
if err != nil {
return "", nil, errors.Wrap(err, "error reading multiple stages")
}
+ if options.Target != "" {
+ stagesTargeted, ok := stages.ThroughTarget(options.Target)
+ if !ok {
+ return "", nil, errors.Errorf("The target %q was not found in the provided Dockerfile", options.Target)
+ }
+ stages = stagesTargeted
+ }
return exec.Build(ctx, stages)
}
diff --git a/vendor/github.com/containers/buildah/new.go b/vendor/github.com/containers/buildah/new.go
index 7e7f97e49..01c2e733f 100644
--- a/vendor/github.com/containers/buildah/new.go
+++ b/vendor/github.com/containers/buildah/new.go
@@ -28,15 +28,14 @@ const (
minimumTruncatedIDLength = 3
)
-func pullAndFindImage(ctx context.Context, store storage.Store, imageName string, options BuilderOptions, sc *types.SystemContext) (*storage.Image, types.ImageReference, error) {
+func pullAndFindImage(ctx context.Context, store storage.Store, transport string, imageName string, options BuilderOptions, sc *types.SystemContext) (*storage.Image, types.ImageReference, error) {
pullOptions := PullOptions{
ReportWriter: options.ReportWriter,
Store: store,
SystemContext: options.SystemContext,
- Transport: options.Transport,
BlobDirectory: options.PullBlobDirectory,
}
- ref, err := pullImage(ctx, store, imageName, pullOptions, sc)
+ ref, err := pullImage(ctx, store, transport, imageName, pullOptions, sc)
if err != nil {
logrus.Debugf("error pulling image %q: %v", imageName, err)
return nil, nil, err
@@ -101,16 +100,16 @@ func newContainerIDMappingOptions(idmapOptions *IDMappingOptions) storage.IDMapp
return options
}
-func resolveImage(ctx context.Context, systemContext *types.SystemContext, store storage.Store, options BuilderOptions) (types.ImageReference, *storage.Image, error) {
+func resolveImage(ctx context.Context, systemContext *types.SystemContext, store storage.Store, options BuilderOptions) (types.ImageReference, string, *storage.Image, error) {
type failure struct {
resolvedImageName string
err error
}
-
- candidates, searchRegistriesWereUsedButEmpty, err := util.ResolveName(options.FromImage, options.Registry, systemContext, store)
+ candidates, transport, searchRegistriesWereUsedButEmpty, err := util.ResolveName(options.FromImage, options.Registry, systemContext, store)
if err != nil {
- return nil, nil, errors.Wrapf(err, "error parsing reference to image %q", options.FromImage)
+ return nil, "", nil, errors.Wrapf(err, "error parsing reference to image %q", options.FromImage)
}
+
failures := []failure{}
for _, image := range candidates {
var err error
@@ -118,25 +117,25 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
if img, err := store.Image(image); err == nil && img != nil && strings.HasPrefix(img.ID, image) {
ref, err := is.Transport.ParseStoreReference(store, img.ID)
if err != nil {
- return nil, nil, errors.Wrapf(err, "error parsing reference to image %q", img.ID)
+ return nil, "", nil, errors.Wrapf(err, "error parsing reference to image %q", img.ID)
}
- return ref, img, nil
+ return ref, transport, img, nil
}
}
if options.PullPolicy == PullAlways {
- pulledImg, pulledReference, err := pullAndFindImage(ctx, store, image, options, systemContext)
+ pulledImg, pulledReference, err := pullAndFindImage(ctx, store, transport, image, options, systemContext)
if err != nil {
logrus.Debugf("unable to pull and read image %q: %v", image, err)
failures = append(failures, failure{resolvedImageName: image, err: err})
continue
}
- return pulledReference, pulledImg, nil
+ return pulledReference, transport, pulledImg, nil
}
srcRef, err := alltransports.ParseImageName(image)
if err != nil {
- if options.Transport == "" {
+ if transport == "" {
logrus.Debugf("error parsing image name %q: %v", image, err)
failures = append(failures, failure{
resolvedImageName: image,
@@ -144,12 +143,13 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
})
continue
}
- logrus.Debugf("error parsing image name %q as given, trying with transport %q: %v", image, options.Transport, err)
- transport := options.Transport
+ logrus.Debugf("error parsing image name %q as given, trying with transport %q: %v", image, transport, err)
+
+ trans := transport
if transport != util.DefaultTransport {
- transport = transport + ":"
+ trans = trans + ":"
}
- srcRef2, err := alltransports.ParseImageName(transport + image)
+ srcRef2, err := alltransports.ParseImageName(trans + image)
if err != nil {
logrus.Debugf("error parsing image name %q: %v", transport+image, err)
failures = append(failures, failure{
@@ -163,19 +163,19 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
destImage, err := localImageNameForReference(ctx, store, srcRef, options.FromImage)
if err != nil {
- return nil, nil, errors.Wrapf(err, "error computing local image name for %q", transports.ImageName(srcRef))
+ return nil, "", nil, errors.Wrapf(err, "error computing local image name for %q", transports.ImageName(srcRef))
}
if destImage == "" {
- return nil, nil, errors.Errorf("error computing local image name for %q", transports.ImageName(srcRef))
+ return nil, "", nil, errors.Errorf("error computing local image name for %q", transports.ImageName(srcRef))
}
ref, err := is.Transport.ParseStoreReference(store, destImage)
if err != nil {
- return nil, nil, errors.Wrapf(err, "error parsing reference to image %q", destImage)
+ return nil, "", nil, errors.Wrapf(err, "error parsing reference to image %q", destImage)
}
img, err := is.Transport.GetStoreImage(store, ref)
if err == nil {
- return ref, img, nil
+ return ref, transport, img, nil
}
if errors.Cause(err) == storage.ErrImageUnknown && options.PullPolicy != PullIfMissing {
@@ -187,26 +187,26 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
continue
}
- pulledImg, pulledReference, err := pullAndFindImage(ctx, store, image, options, systemContext)
+ pulledImg, pulledReference, err := pullAndFindImage(ctx, store, transport, image, options, systemContext)
if err != nil {
logrus.Debugf("unable to pull and read image %q: %v", image, err)
failures = append(failures, failure{resolvedImageName: image, err: err})
continue
}
- return pulledReference, pulledImg, nil
+ return pulledReference, transport, pulledImg, nil
}
if len(failures) != len(candidates) {
- return nil, nil, fmt.Errorf("internal error: %d candidates (%#v) vs. %d failures (%#v)", len(candidates), candidates, len(failures), failures)
+ return nil, "", nil, fmt.Errorf("internal error: %d candidates (%#v) vs. %d failures (%#v)", len(candidates), candidates, len(failures), failures)
}
registriesConfPath := sysregistries.RegistriesConfPath(systemContext)
switch len(failures) {
case 0:
if searchRegistriesWereUsedButEmpty {
- return nil, nil, errors.Errorf("image name %q is a short name and no search registries are defined in %s.", options.FromImage, registriesConfPath)
+ return nil, "", nil, errors.Errorf("image name %q is a short name and no search registries are defined in %s.", options.FromImage, registriesConfPath)
}
- return nil, nil, fmt.Errorf("internal error: no pull candidates were available for %q for an unknown reason", options.FromImage)
+ return nil, "", nil, fmt.Errorf("internal error: no pull candidates were available for %q for an unknown reason", options.FromImage)
case 1:
err := failures[0].err
@@ -216,7 +216,7 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
if searchRegistriesWereUsedButEmpty {
err = errors.Wrapf(err, "(image name %q is a short name and no search registries are defined in %s)", options.FromImage, registriesConfPath)
}
- return nil, nil, err
+ return nil, "", nil, err
default:
// NOTE: a multi-line error string:
@@ -224,7 +224,7 @@ func resolveImage(ctx context.Context, systemContext *types.SystemContext, store
for _, f := range failures {
e = e + fmt.Sprintf("\n* %q: %s", f.resolvedImageName, f.err.Error())
}
- return nil, nil, errors.New(e)
+ return nil, "", nil, errors.New(e)
}
}
@@ -250,21 +250,19 @@ func findUnusedContainer(name string, containers []storage.Container) string {
}
func newBuilder(ctx context.Context, store storage.Store, options BuilderOptions) (*Builder, error) {
- var ref types.ImageReference
- var img *storage.Image
- var err error
-
+ var (
+ ref types.ImageReference
+ img *storage.Image
+ err error
+ )
if options.FromImage == BaseImageFakeName {
options.FromImage = ""
}
- if options.Transport == "" {
- options.Transport = util.DefaultTransport
- }
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
if options.FromImage != "" && options.FromImage != "scratch" {
- ref, img, err = resolveImage(ctx, systemContext, store, options)
+ ref, _, img, err = resolveImage(ctx, systemContext, store, options)
if err != nil {
return nil, err
}
diff --git a/vendor/github.com/containers/buildah/pkg/cli/common.go b/vendor/github.com/containers/buildah/pkg/cli/common.go
index bbbbf3476..09f951b35 100644
--- a/vendor/github.com/containers/buildah/pkg/cli/common.go
+++ b/vendor/github.com/containers/buildah/pkg/cli/common.go
@@ -55,20 +55,21 @@ type BudResults struct {
File []string
Format string
Iidfile string
- NoCache bool
Label []string
Logfile string
Loglevel int
+ NoCache bool
Platform string
Pull bool
PullAlways bool
Quiet bool
Rm bool
Runtime string
- RuntimeOpts []string
+ RuntimeFlags []string
SignaturePolicy string
Squash bool
Tag []string
+ Target string
TlsVerify bool
}
@@ -138,7 +139,7 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.StringVar(&flags.CertDir, "cert-dir", "", "use certificates at the specified path to access the registry")
fs.BoolVar(&flags.Compress, "compress", false, "This is legacy option, which has no effect on the image")
fs.StringVar(&flags.Creds, "creds", "", "use `[username[:password]]` for accessing the registry")
- fs.BoolVarP(&flags.DisableCompression, "disable-compression", "D", false, "don't compress layers by default")
+ fs.BoolVarP(&flags.DisableCompression, "disable-compression", "D", true, "don't compress layers by default")
fs.BoolVar(&flags.DisableContentTrust, "disable-content-trust", false, "This is a Docker specific option and is a NOOP")
fs.StringSliceVarP(&flags.File, "file", "f", []string{}, "`pathname or URL` of a Dockerfile")
fs.StringVar(&flags.Format, "format", DefaultFormat(), "`format` of the built image's manifest and metadata. Use BUILDAH_FORMAT environment variable to override.")
@@ -153,10 +154,11 @@ func GetBudFlags(flags *BudResults) pflag.FlagSet {
fs.BoolVarP(&flags.Quiet, "quiet", "q", false, "refrain from announcing build instructions and image read/write progress")
fs.BoolVar(&flags.Rm, "rm", true, "Remove intermediate containers after a successful build (default true)")
fs.StringVar(&flags.Runtime, "runtime", util.Runtime(), "`path` to an alternate runtime. Use BUILDAH_RUNTIME environment variable to override.")
- fs.StringSliceVar(&flags.RuntimeOpts, "runtime-flag", []string{}, "add global flags for the container runtime")
+ fs.StringSliceVar(&flags.RuntimeFlags, "runtime-flag", []string{}, "add global flags for the container runtime")
fs.StringVar(&flags.SignaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)")
fs.BoolVar(&flags.Squash, "squash", false, "Squash newly built layers into a single new layer. The build process does not currently support caching so this is a NOOP.")
fs.StringSliceVarP(&flags.Tag, "tag", "t", []string{}, "tagged `name` to apply to the built image")
+ fs.StringVar(&flags.Target, "target", "", "set the target build stage to build")
fs.BoolVar(&flags.TlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry")
return fs
}
diff --git a/vendor/github.com/containers/buildah/pkg/parse/parse.go b/vendor/github.com/containers/buildah/pkg/parse/parse.go
index ffc7c15bb..a26d15631 100644
--- a/vendor/github.com/containers/buildah/pkg/parse/parse.go
+++ b/vendor/github.com/containers/buildah/pkg/parse/parse.go
@@ -251,9 +251,9 @@ func SystemContextFromOptions(c *cobra.Command) (*types.SystemContext, error) {
}
tlsVerify, err := c.Flags().GetBool("tls-verify")
if err == nil && c.Flag("tls-verify").Changed {
- ctx.DockerInsecureSkipTLSVerify = types.NewOptionalBool(tlsVerify)
- ctx.OCIInsecureSkipTLSVerify = tlsVerify
- ctx.DockerDaemonInsecureSkipTLSVerify = tlsVerify
+ ctx.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!tlsVerify)
+ ctx.OCIInsecureSkipTLSVerify = !tlsVerify
+ ctx.DockerDaemonInsecureSkipTLSVerify = !tlsVerify
}
creds, err := c.Flags().GetString("creds")
if err == nil && c.Flag("creds").Changed {
diff --git a/vendor/github.com/containers/buildah/pull.go b/vendor/github.com/containers/buildah/pull.go
index aede1784b..d1f33fb01 100644
--- a/vendor/github.com/containers/buildah/pull.go
+++ b/vendor/github.com/containers/buildah/pull.go
@@ -9,10 +9,13 @@ import (
"github.com/containers/buildah/pkg/blobcache"
"github.com/containers/buildah/util"
cp "github.com/containers/image/copy"
+ "github.com/containers/image/directory"
"github.com/containers/image/docker"
+ dockerarchive "github.com/containers/image/docker/archive"
"github.com/containers/image/docker/reference"
tarfile "github.com/containers/image/docker/tarfile"
ociarchive "github.com/containers/image/oci/archive"
+ oci "github.com/containers/image/oci/layout"
"github.com/containers/image/signature"
is "github.com/containers/image/storage"
"github.com/containers/image/transports"
@@ -40,10 +43,6 @@ type PullOptions struct {
// github.com/containers/image/types SystemContext to hold credentials
// and other authentication/authorization information.
SystemContext *types.SystemContext
- // Transport is a value which is prepended to the image's name, if the
- // image name alone can not be resolved to a reference to a source
- // image. No separator is implicitly added.
- Transport string
// BlobDirectory is the name of a directory in which we'll attempt to
// store copies of layer blobs that we pull down, if any. It should
// already exist.
@@ -51,10 +50,6 @@ type PullOptions struct {
// AllTags is a boolean value that determines if all tagged images
// will be downloaded from the repository. The default is false.
AllTags bool
- // Quiet is a boolean value that determines if minimal output to
- // the user will be displayed, this is best used for logging.
- // The default is false.
- Quiet bool
}
func localImageNameForReference(ctx context.Context, store storage.Store, srcRef types.ImageReference, spec string) (string, error) {
@@ -65,7 +60,7 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef
file := split[len(split)-1]
var name string
switch srcRef.Transport().Name() {
- case util.DockerArchive:
+ case dockerarchive.Transport.Name():
tarSource, err := tarfile.NewSourceFromFile(file)
if err != nil {
return "", errors.Wrapf(err, "error opening tarfile %q as a source image", file)
@@ -92,7 +87,7 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef
}
}
}
- case util.OCIArchive:
+ case ociarchive.Transport.Name():
// retrieve the manifest from index.json to access the image name
manifest, err := ociarchive.LoadManifestDescriptor(srcRef)
if err != nil {
@@ -107,7 +102,14 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef
} else {
name = manifest.Annotations["org.opencontainers.image.ref.name"]
}
- case util.DirTransport:
+ case directory.Transport.Name():
+ // supports pull from a directory
+ name = split[1]
+ // remove leading "/"
+ if name[:1] == "/" {
+ name = name[1:]
+ }
+ case oci.Transport.Name():
// supports pull from a directory
name = split[1]
// remove leading "/"
@@ -152,76 +154,71 @@ func localImageNameForReference(ctx context.Context, store storage.Store, srcRef
// Pull copies the contents of the image from somewhere else to local storage.
func Pull(ctx context.Context, imageName string, options PullOptions) error {
- spec := imageName
systemContext := getSystemContext(options.SystemContext, options.SignaturePolicyPath)
- srcRef, err := alltransports.ParseImageName(spec)
- if err != nil {
- if options.Transport == "" {
- options.Transport = util.DefaultTransport
- }
- logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, options.Transport, err)
- transport := options.Transport
- if transport != util.DefaultTransport {
- transport = transport + ":"
- }
- spec = transport + spec
- srcRef2, err2 := alltransports.ParseImageName(spec)
- if err2 != nil {
- return errors.Wrapf(err2, "error parsing image name %q", imageName)
- }
- srcRef = srcRef2
+
+ boptions := BuilderOptions{
+ FromImage: imageName,
+ SignaturePolicyPath: options.SignaturePolicyPath,
+ SystemContext: systemContext,
+ PullBlobDirectory: options.BlobDirectory,
+ ReportWriter: options.ReportWriter,
}
- if options.Quiet {
- options.ReportWriter = nil // Turns off logging output
+
+ storageRef, transport, img, err := resolveImage(ctx, systemContext, options.Store, boptions)
+ if err != nil {
+ return err
}
- var names []string
+
+ var errs *multierror.Error
if options.AllTags {
- if srcRef.DockerReference() == nil {
- return errors.New("Non-docker transport is currently not supported")
+ if transport != util.DefaultTransport {
+ return errors.New("Non-docker transport is not supported, for --all-tags pulling")
+ }
+
+ spec := transport + storageRef.DockerReference().Name()
+ storageRef, err = alltransports.ParseImageName(spec)
+ if err != nil {
+ return errors.Wrapf(err, "error getting repository tags")
}
- tags, err := docker.GetRepositoryTags(ctx, systemContext, srcRef)
+ tags, err := docker.GetRepositoryTags(ctx, systemContext, storageRef)
if err != nil {
return errors.Wrapf(err, "error getting repository tags")
}
for _, tag := range tags {
name := spec + ":" + tag
- names = append(names, name)
+ if options.ReportWriter != nil {
+ options.ReportWriter.Write([]byte("Pulling " + name + "\n"))
+ }
+ ref, err := pullImage(ctx, options.Store, transport, name, options, systemContext)
+ if err != nil {
+ errs = multierror.Append(errs, err)
+ continue
+ }
+ img, err := is.Transport.GetStoreImage(options.Store, ref)
+ if err != nil {
+ errs = multierror.Append(errs, err)
+ continue
+ }
+ fmt.Printf("%s\n", img.ID)
}
} else {
- names = append(names, spec)
- }
- var errs *multierror.Error
- for _, name := range names {
- if options.ReportWriter != nil {
- options.ReportWriter.Write([]byte("Pulling " + name + "\n"))
- }
- ref, err := pullImage(ctx, options.Store, name, options, systemContext)
- if err != nil {
- errs = multierror.Append(errs, err)
- continue
- }
- img, err := is.Transport.GetStoreImage(options.Store, ref)
- if err != nil {
- errs = multierror.Append(errs, err)
- continue
- }
fmt.Printf("%s\n", img.ID)
}
return errs.ErrorOrNil()
}
-func pullImage(ctx context.Context, store storage.Store, imageName string, options PullOptions, sc *types.SystemContext) (types.ImageReference, error) {
+func pullImage(ctx context.Context, store storage.Store, transport string, imageName string, options PullOptions, sc *types.SystemContext) (types.ImageReference, error) {
spec := imageName
srcRef, err := alltransports.ParseImageName(spec)
if err != nil {
- if options.Transport == "" {
- options.Transport = util.DefaultTransport
- }
- logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, options.Transport, err)
- transport := options.Transport
- if transport != util.DefaultTransport {
- transport = transport + ":"
+ logrus.Debugf("error parsing image name %q, trying with transport %q: %v", spec, transport, err)
+ if transport == "" {
+ transport = util.DefaultTransport
+ } else {
+ if transport != util.DefaultTransport {
+ transport = transport + ":"
+ }
}
spec = transport + spec
srcRef2, err2 := alltransports.ParseImageName(spec)
diff --git a/vendor/github.com/containers/buildah/unshare/unshare.c b/vendor/github.com/containers/buildah/unshare/unshare.c
index 3865e414f..8eefae41b 100644
--- a/vendor/github.com/containers/buildah/unshare/unshare.c
+++ b/vendor/github.com/containers/buildah/unshare/unshare.c
@@ -2,6 +2,8 @@
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <linux/memfd.h>
#include <fcntl.h>
#include <grp.h>
#include <sched.h>
@@ -12,6 +14,28 @@
#include <errno.h>
#include <unistd.h>
+#ifndef F_LINUX_SPECIFIC_BASE
+#define F_LINUX_SPECIFIC_BASE 1024
+#endif
+#ifndef F_ADD_SEALS
+#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
+#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
+#endif
+#ifndef F_SEAL_SEAL
+#define F_SEAL_SEAL 0x0001LU
+#endif
+#ifndef F_SEAL_SHRINK
+#define F_SEAL_SHRINK 0x0002LU
+#endif
+#ifndef F_SEAL_GROW
+#define F_SEAL_GROW 0x0004LU
+#endif
+#ifndef F_SEAL_WRITE
+#define F_SEAL_WRITE 0x0008LU
+#endif
+
+#define BUFSTEP 1024
+
static const char *_max_user_namespaces = "/proc/sys/user/max_user_namespaces";
static const char *_unprivileged_user_namespaces = "/proc/sys/kernel/unprivileged_userns_clone";
@@ -59,6 +83,119 @@ static void _check_proc_sys_file(const char *path)
}
}
+static char **parse_proc_stringlist(const char *list) {
+ int fd, n, i, n_strings;
+ char *buf, *new_buf, **ret;
+ size_t size, new_size, used;
+
+ fd = open(list, O_RDONLY);
+ if (fd == -1) {
+ return NULL;
+ }
+ buf = NULL;
+ size = 0;
+ used = 0;
+ for (;;) {
+ new_size = used + BUFSTEP;
+ new_buf = realloc(buf, new_size);
+ if (new_buf == NULL) {
+ free(buf);
+ fprintf(stderr, "realloc(%ld): out of memory\n", (long)(size + BUFSTEP));
+ return NULL;
+ }
+ buf = new_buf;
+ size = new_size;
+ memset(buf + used, '\0', size - used);
+ n = read(fd, buf + used, size - used - 1);
+ if (n < 0) {
+ fprintf(stderr, "read(): %m\n");
+ return NULL;
+ }
+ if (n == 0) {
+ break;
+ }
+ used += n;
+ }
+ close(fd);
+ n_strings = 0;
+ for (n = 0; n < used; n++) {
+ if ((n == 0) || (buf[n-1] == '\0')) {
+ n_strings++;
+ }
+ }
+ ret = calloc(n_strings + 1, sizeof(char *));
+ if (ret == NULL) {
+ fprintf(stderr, "calloc(): out of memory\n");
+ return NULL;
+ }
+ i = 0;
+ for (n = 0; n < used; n++) {
+ if ((n == 0) || (buf[n-1] == '\0')) {
+ ret[i++] = &buf[n];
+ }
+ }
+ ret[i] = NULL;
+ return ret;
+}
+
+static int buildah_reexec(void) {
+ char **argv, *exename;
+ int fd, mmfd, n_read, n_written;
+ struct stat st;
+ char buf[2048];
+
+ argv = parse_proc_stringlist("/proc/self/cmdline");
+ if (argv == NULL) {
+ return -1;
+ }
+ fd = open("/proc/self/exe", O_RDONLY | O_CLOEXEC);
+ if (fd == -1) {
+ fprintf(stderr, "open(\"/proc/self/exe\"): %m\n");
+ return -1;
+ }
+ if (fstat(fd, &st) == -1) {
+ fprintf(stderr, "fstat(\"/proc/self/exe\"): %m\n");
+ return -1;
+ }
+ exename = basename(argv[0]);
+ mmfd = syscall(SYS_memfd_create, exename, (long) MFD_ALLOW_SEALING | MFD_CLOEXEC);
+ if (mmfd == -1) {
+ fprintf(stderr, "memfd_create(): %m\n");
+ return -1;
+ }
+ for (;;) {
+ n_read = read(fd, buf, sizeof(buf));
+ if (n_read < 0) {
+ fprintf(stderr, "read(\"/proc/self/exe\"): %m\n");
+ return -1;
+ }
+ if (n_read == 0) {
+ break;
+ }
+ n_written = write(mmfd, buf, n_read);
+ if (n_written < 0) {
+ fprintf(stderr, "write(anonfd): %m\n");
+ return -1;
+ }
+ if (n_written != n_read) {
+ fprintf(stderr, "write(anonfd): short write (%d != %d)\n", n_written, n_read);
+ return -1;
+ }
+ }
+ close(fd);
+ if (fcntl(mmfd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL) == -1) {
+ close(mmfd);
+ fprintf(stderr, "Error sealing memfd copy: %m\n");
+ return -1;
+ }
+ if (fexecve(mmfd, argv, environ) == -1) {
+ close(mmfd);
+ fprintf(stderr, "Error during reexec(...): %m\n");
+ return -1;
+ }
+ return 0;
+}
+
void _buildah_unshare(void)
{
int flags, pidfd, continuefd, n, pgrp, sid, ctty;
@@ -132,5 +269,8 @@ void _buildah_unshare(void)
_exit(1);
}
}
+ if (buildah_reexec() != 0) {
+ _exit(1);
+ }
return;
}
diff --git a/vendor/github.com/containers/buildah/unshare/unshare.go b/vendor/github.com/containers/buildah/unshare/unshare.go
index 2a970b8d6..1072c2035 100644
--- a/vendor/github.com/containers/buildah/unshare/unshare.go
+++ b/vendor/github.com/containers/buildah/unshare/unshare.go
@@ -56,8 +56,10 @@ func (c *Cmd) Start() error {
c.Env = append(c.Env, fmt.Sprintf("_Buildah-unshare=%d", c.UnshareFlags))
// Please the libpod "rootless" package to find the expected env variables.
- c.Env = append(c.Env, "_LIBPOD_USERNS_CONFIGURED=done")
- c.Env = append(c.Env, fmt.Sprintf("_LIBPOD_ROOTLESS_UID=%d", os.Geteuid()))
+ if os.Geteuid() != 0 {
+ c.Env = append(c.Env, "_LIBPOD_USERNS_CONFIGURED=done")
+ c.Env = append(c.Env, fmt.Sprintf("_LIBPOD_ROOTLESS_UID=%d", os.Geteuid()))
+ }
// Create the pipe for reading the child's PID.
pidRead, pidWrite, err := os.Pipe()
diff --git a/vendor/github.com/containers/buildah/util/util.go b/vendor/github.com/containers/buildah/util/util.go
index e46f9b7cb..d98493634 100644
--- a/vendor/github.com/containers/buildah/util/util.go
+++ b/vendor/github.com/containers/buildah/util/util.go
@@ -11,14 +11,11 @@ import (
"strings"
"syscall"
- "github.com/containers/image/directory"
- dockerarchive "github.com/containers/image/docker/archive"
"github.com/containers/image/docker/reference"
- ociarchive "github.com/containers/image/oci/archive"
"github.com/containers/image/pkg/sysregistriesv2"
"github.com/containers/image/signature"
is "github.com/containers/image/storage"
- "github.com/containers/image/tarball"
+ "github.com/containers/image/transports"
"github.com/containers/image/types"
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
@@ -43,36 +40,18 @@ var (
"index.docker.io": "library",
"docker.io": "library",
}
- // Transports contains the possible transports used for images
- Transports = map[string]string{
- dockerarchive.Transport.Name(): "",
- ociarchive.Transport.Name(): "",
- directory.Transport.Name(): "",
- tarball.Transport.Name(): "",
- }
- // DockerArchive is the transport we prepend to an image name
- // when saving to docker-archive
- DockerArchive = dockerarchive.Transport.Name()
- // OCIArchive is the transport we prepend to an image name
- // when saving to oci-archive
- OCIArchive = ociarchive.Transport.Name()
- // DirTransport is the transport for pushing and pulling
- // images to and from a directory
- DirTransport = directory.Transport.Name()
- // TarballTransport is the transport for importing a tar archive
- // and creating a filesystem image
- TarballTransport = tarball.Transport.Name()
)
// ResolveName checks if name is a valid image name, and if that name doesn't
// include a domain portion, returns a list of the names which it might
-// correspond to in the set of configured registries,
-// and a boolean which is true iff 1) the list of search registries was used, and 2) it was empty.
+// correspond to in the set of configured registries, the transport used to
+// pull the image, and a boolean which is true iff
+// 1) the list of search registries was used, and 2) it was empty.
// NOTE: The "list of search registries is empty" check does not count blocked registries,
// and neither the implied "localhost" nor a possible firstRegistry are counted
-func ResolveName(name string, firstRegistry string, sc *types.SystemContext, store storage.Store) ([]string, bool, error) {
+func ResolveName(name string, firstRegistry string, sc *types.SystemContext, store storage.Store) ([]string, string, bool, error) {
if name == "" {
- return nil, false, nil
+ return nil, "", false, nil
}
// Maybe it's a truncated image ID. Don't prepend a registry name, then.
@@ -80,27 +59,28 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
if img, err := store.Image(name); err == nil && img != nil && strings.HasPrefix(img.ID, name) {
// It's a truncated version of the ID of an image that's present in local storage;
// we need only expand the ID.
- return []string{img.ID}, false, nil
+ return []string{img.ID}, "", false, nil
}
}
// If the image includes a transport's name as a prefix, use it as-is.
+ if strings.HasPrefix(name, DefaultTransport) {
+ return []string{strings.TrimPrefix(name, DefaultTransport)}, DefaultTransport, false, nil
+ }
split := strings.SplitN(name, ":", 2)
if len(split) == 2 {
- if _, ok := Transports[split[0]]; ok {
- return []string{split[1]}, false, nil
+ if trans := transports.Get(split[0]); trans != nil {
+ return []string{split[1]}, trans.Name(), false, nil
}
}
-
- name = strings.TrimPrefix(name, DefaultTransport)
// If the image name already included a domain component, we're done.
named, err := reference.ParseNormalizedNamed(name)
if err != nil {
- return nil, false, errors.Wrapf(err, "error parsing image name %q", name)
+ return nil, "", false, errors.Wrapf(err, "error parsing image name %q", name)
}
if named.String() == name {
// Parsing produced the same result, so there was a domain name in there to begin with.
- return []string{name}, false, nil
+ return []string{name}, DefaultTransport, false, nil
}
if reference.Domain(named) != "" && RegistryDefaultPathPrefix[reference.Domain(named)] != "" {
// If this domain can cause us to insert something in the middle, check if that happened.
@@ -117,7 +97,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
defaultPrefix := RegistryDefaultPathPrefix[reference.Domain(named)] + "/"
if strings.HasPrefix(repoPath, defaultPrefix) && path.Join(domain, repoPath[len(defaultPrefix):])+tag+digest == name {
// Yup, parsing just inserted a bit in the middle, so there was a domain name there to begin with.
- return []string{name}, false, nil
+ return []string{name}, DefaultTransport, false, nil
}
}
@@ -153,7 +133,7 @@ func ResolveName(name string, firstRegistry string, sc *types.SystemContext, sto
candidate := path.Join(registry, middle, name)
candidates = append(candidates, candidate)
}
- return candidates, searchRegistriesAreEmpty, nil
+ return candidates, DefaultTransport, searchRegistriesAreEmpty, nil
}
// ExpandNames takes unqualified names, parses them as image names, and returns
@@ -164,7 +144,7 @@ func ExpandNames(names []string, firstRegistry string, systemContext *types.Syst
expanded := make([]string, 0, len(names))
for _, n := range names {
var name reference.Named
- nameList, _, err := ResolveName(n, firstRegistry, systemContext, store)
+ nameList, _, _, err := ResolveName(n, firstRegistry, systemContext, store)
if err != nil {
return nil, errors.Wrapf(err, "error parsing name %q", n)
}
@@ -200,7 +180,7 @@ func FindImage(store storage.Store, firstRegistry string, systemContext *types.S
var ref types.ImageReference
var img *storage.Image
var err error
- names, _, err := ResolveName(image, firstRegistry, systemContext, store)
+ names, _, _, err := ResolveName(image, firstRegistry, systemContext, store)
if err != nil {
return nil, nil, errors.Wrapf(err, "error parsing name %q", image)
}
diff --git a/vendor/github.com/containers/buildah/vendor.conf b/vendor/github.com/containers/buildah/vendor.conf
index bda5f3965..7438fc909 100644
--- a/vendor/github.com/containers/buildah/vendor.conf
+++ b/vendor/github.com/containers/buildah/vendor.conf
@@ -3,10 +3,13 @@ github.com/blang/semver v3.5.0
github.com/BurntSushi/toml v0.2.0
github.com/containerd/continuity 004b46473808b3e7a4a3049c20e4376c91eb966d
github.com/containernetworking/cni v0.7.0-alpha1
-github.com/containers/image v1.3
+github.com/containers/image v1.4
+github.com/vbauerster/mpb v3.3.4
+github.com/mattn/go-isatty v0.0.4
+github.com/VividCortex/ewma v1.1.1
github.com/boltdb/bolt v1.3.1
github.com/containers/libpod v1.0
-github.com/containers/storage v1.9
+github.com/containers/storage v1.10
github.com/docker/distribution 5f6282db7d65e6d72ad7c2cc66310724a57be716
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
github.com/docker/docker-credential-helpers v0.6.1
@@ -21,7 +24,6 @@ github.com/gorilla/mux v1.6.2
github.com/hashicorp/errwrap v1.0.0
github.com/hashicorp/go-multierror v1.0.0
github.com/imdario/mergo v0.3.6
-github.com/mattn/go-runewidth v0.0.4
github.com/mattn/go-shellwords v1.0.3
github.com/Microsoft/go-winio v0.4.11
github.com/Microsoft/hcsshim v0.8.3
@@ -36,7 +38,7 @@ github.com/opencontainers/runc v1.0.0-rc6
github.com/opencontainers/runtime-spec v1.0.0
github.com/opencontainers/runtime-tools v0.8.0
github.com/opencontainers/selinux v1.1
-github.com/openshift/imagebuilder a4122153148e3b34161191f868565d8dffe65a69
+github.com/openshift/imagebuilder 36823496a6868f72bc36282cc475eb8a070c0934
github.com/ostreedev/ostree-go 9ab99253d365aac3a330d1f7281cf29f3d22820b
github.com/pkg/errors v0.8.1
github.com/pquerna/ffjson d49c2bc1aa135aad0c6f4fc2056623ec78f5d5ac
@@ -55,7 +57,6 @@ golang.org/x/net 45ffb0cd1ba084b73e26dee67e667e1be5acce83 https://github.com/gol
golang.org/x/sync 37e7f081c4d4c64e13b10787722085407fe5d15f https://github.com/golang/sync
golang.org/x/sys 7fbe1cd0fcc20051e1fcb87fbabec4a1bacaaeba https://github.com/golang/sys
golang.org/x/text e6919f6577db79269a6443b9dc46d18f2238fb5d https://github.com/golang/text
-gopkg.in/cheggaaa/pb.v1 v1.0.27
gopkg.in/yaml.v2 v2.2.2
k8s.io/client-go kubernetes-1.10.13-beta.0 https://github.com/kubernetes/client-go
github.com/klauspost/pgzip v1.2.1
@@ -63,17 +64,4 @@ github.com/klauspost/compress v1.4.1
github.com/klauspost/cpuid v1.2.0
github.com/onsi/gomega v1.4.3
github.com/spf13/cobra v0.0.3
-github.com/cpuguy83/go-md2man v1.0.8
github.com/spf13/pflag v1.0.3
-github.com/inconshreveable/mousetrap v1.0.0
-github.com/russross/blackfriday v2.0.1
-github.com/mitchellh/go-homedir v1.0.0
-github.com/spf13/viper v1.3.1
-github.com/fsnotify/fsnotify v1.4.7
-github.com/hashicorp/hcl v1.0.0
-github.com/magiconair/properties v1.8.0
-github.com/mitchellh/mapstructure v1.1.2
-github.com/pelletier/go-toml v1.2.0
-github.com/spf13/afero v1.2.0
-github.com/spf13/cast v1.3.0
-github.com/spf13/jwalterweatherman v1.0.0
diff --git a/vendor/github.com/openshift/imagebuilder/README.md b/vendor/github.com/openshift/imagebuilder/README.md
index 2f9c110dd..f26b4a7e0 100644
--- a/vendor/github.com/openshift/imagebuilder/README.md
+++ b/vendor/github.com/openshift/imagebuilder/README.md
@@ -70,7 +70,7 @@ is ignored.
## Code Example
-```
+```go
f, err := os.Open("path/to/Dockerfile")
if err != nil {
return err
diff --git a/vendor/github.com/openshift/imagebuilder/builder.go b/vendor/github.com/openshift/imagebuilder/builder.go
index d37965df6..16682af7d 100644
--- a/vendor/github.com/openshift/imagebuilder/builder.go
+++ b/vendor/github.com/openshift/imagebuilder/builder.go
@@ -40,6 +40,7 @@ type Run struct {
type Executor interface {
Preserve(path string) error
+ EnsureContainerPath(path string) error
Copy(excludes []string, copies ...Copy) error
Run(run Run, config docker.Config) error
UnrecognizedInstruction(step *Step) error
@@ -52,6 +53,11 @@ func (logExecutor) Preserve(path string) error {
return nil
}
+func (logExecutor) EnsureContainerPath(path string) error {
+ log.Printf("ENSURE %s", path)
+ return nil
+}
+
func (logExecutor) Copy(excludes []string, copies ...Copy) error {
for _, c := range copies {
log.Printf("COPY %v -> %s (from:%s download:%t), chown: %s", c.Src, c.Dest, c.From, c.Download, c.Chown)
@@ -75,6 +81,10 @@ func (noopExecutor) Preserve(path string) error {
return nil
}
+func (noopExecutor) EnsureContainerPath(path string) error {
+ return nil
+}
+
func (noopExecutor) Copy(excludes []string, copies ...Copy) error {
return nil
}
@@ -153,6 +163,7 @@ func (stages Stages) ByName(name string) (Stage, bool) {
return Stage{}, false
}
+// Get just the target stage.
func (stages Stages) ByTarget(target string) (Stages, bool) {
if len(target) == 0 {
return stages, true
@@ -165,6 +176,19 @@ func (stages Stages) ByTarget(target string) (Stages, bool) {
return nil, false
}
+// Get all the stages up to and including the target.
+func (stages Stages) ThroughTarget(target string) (Stages, bool) {
+ if len(target) == 0 {
+ return stages, true
+ }
+ for i, stage := range stages {
+ if stage.Name == target {
+ return stages[0 : i+1], true
+ }
+ }
+ return nil, false
+}
+
type Stage struct {
Position int
Name string
@@ -319,6 +343,13 @@ func (b *Builder) Run(step *Step, exec Executor, noRunsRemaining bool) error {
if err := exec.Copy(b.Excludes, copies...); err != nil {
return err
}
+
+ if len(b.RunConfig.WorkingDir) > 0 {
+ if err := exec.EnsureContainerPath(b.RunConfig.WorkingDir); err != nil {
+ return err
+ }
+ }
+
for _, run := range runs {
config := b.Config()
config.Env = step.Env
diff --git a/vendor/github.com/openshift/imagebuilder/dispatchers.go b/vendor/github.com/openshift/imagebuilder/dispatchers.go
index f6510c2fd..ff365848a 100644
--- a/vendor/github.com/openshift/imagebuilder/dispatchers.go
+++ b/vendor/github.com/openshift/imagebuilder/dispatchers.go
@@ -128,9 +128,20 @@ func add(b *Builder, args []string, attributes map[string]bool, flagArgs []strin
if len(args) < 2 {
return errAtLeastOneArgument("ADD")
}
+ var chown string
last := len(args) - 1
dest := makeAbsolute(args[last], b.RunConfig.WorkingDir)
- b.PendingCopies = append(b.PendingCopies, Copy{Src: args[0:last], Dest: dest, Download: true})
+ if len(flagArgs) > 0 {
+ for _, arg := range flagArgs {
+ switch {
+ case strings.HasPrefix(arg, "--chown="):
+ chown = strings.TrimPrefix(arg, "--chown=")
+ default:
+ return fmt.Errorf("ADD only supports the --chown=<uid:gid> flag")
+ }
+ }
+ }
+ b.PendingCopies = append(b.PendingCopies, Copy{Src: args[0:last], Dest: dest, Download: true, Chown: chown})
return nil
}