diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2019-03-11 10:01:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-11 10:01:25 -0700 |
commit | 6421208e0f6ff1fba58eafdab12e897b5ed12e3b (patch) | |
tree | d2a44ec8b92d343d675027f524738875191027d8 /cmd | |
parent | f5afe88098d8825ea63ccb63875d48edab0eb111 (diff) | |
parent | 231129e4dc083d9f63cf1876cc1695f7f8c03f25 (diff) | |
download | podman-6421208e0f6ff1fba58eafdab12e897b5ed12e3b.tar.gz podman-6421208e0f6ff1fba58eafdab12e897b5ed12e3b.tar.bz2 podman-6421208e0f6ff1fba58eafdab12e897b5ed12e3b.zip |
Merge pull request #2583 from giuseppe/rootless-fix-pod-rm
rootless: fix stop and rm when the container is running with uid != 0
Diffstat (limited to 'cmd')
-rw-r--r-- | cmd/podman/main.go | 29 | ||||
-rw-r--r-- | cmd/podman/pod.go | 47 | ||||
-rw-r--r-- | cmd/podman/pod_rm.go | 14 | ||||
-rw-r--r-- | cmd/podman/pod_stats.go | 5 | ||||
-rw-r--r-- | cmd/podman/pod_stop.go | 14 | ||||
-rw-r--r-- | cmd/podman/rm.go | 79 |
6 files changed, 176 insertions, 12 deletions
diff --git a/cmd/podman/main.go b/cmd/podman/main.go index 3571f526e..bbeb72397 100644 --- a/cmd/podman/main.go +++ b/cmd/podman/main.go @@ -65,18 +65,23 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{ _exportCommand: true, //// `info` must be executed in an user namespace. //// If this change, please also update libpod.refreshRootless() - _loginCommand: true, - _logoutCommand: true, - _mountCommand: true, - _killCommand: true, - _pauseCommand: true, - _restartCommand: true, - _runCommand: true, - _unpauseCommand: true, - _searchCommand: true, - _statsCommand: true, - _stopCommand: true, - _topCommand: true, + _loginCommand: true, + _logoutCommand: true, + _mountCommand: true, + _killCommand: true, + _pauseCommand: true, + _podRmCommand: true, + _podKillCommand: true, + _podStatsCommand: true, + _podStopCommand: true, + _restartCommand: true, + _rmCommand: true, + _runCommand: true, + _unpauseCommand: true, + _searchCommand: true, + _statsCommand: true, + _stopCommand: true, + _topCommand: true, } var rootCmd = &cobra.Command{ diff --git a/cmd/podman/pod.go b/cmd/podman/pod.go index 2d9bca21d..9a9c7a702 100644 --- a/cmd/podman/pod.go +++ b/cmd/podman/pod.go @@ -1,7 +1,12 @@ package main import ( + "os" + "github.com/containers/libpod/cmd/podman/cliconfig" + "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/rootless" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -34,6 +39,48 @@ var podSubCommands = []*cobra.Command{ _podUnpauseCommand, } +func joinPodNS(runtime *adapter.LocalRuntime, all, latest bool, inputArgs []string) ([]string, bool, bool, error) { + if rootless.IsRootless() { + if os.Geteuid() == 0 { + return []string{rootless.Argument()}, false, false, nil + } else { + var err error + var pods []*adapter.Pod + if all { + pods, err = runtime.GetAllPods() + if err != nil { + return nil, false, false, errors.Wrapf(err, "unable to get pods") + } + } else if latest { + pod, err := runtime.GetLatestPod() + if err != nil { + return nil, false, false, errors.Wrapf(err, "unable to get latest pod") + } + pods = append(pods, pod) + } else { + for _, i := range inputArgs { + pod, err := runtime.LookupPod(i) + if err != nil { + return nil, false, false, errors.Wrapf(err, "unable to lookup pod %s", i) + } + pods = append(pods, pod) + } + } + for _, p := range pods { + _, ret, err := runtime.JoinOrCreateRootlessPod(p) + if err != nil { + return nil, false, false, err + } + if ret != 0 { + os.Exit(ret) + } + } + os.Exit(0) + } + } + return inputArgs, all, latest, nil +} + func init() { podCommand.AddCommand(podSubCommands...) podCommand.SetHelpTemplate(HelpTemplate()) diff --git a/cmd/podman/pod_rm.go b/cmd/podman/pod_rm.go index a40992818..735676f8a 100644 --- a/cmd/podman/pod_rm.go +++ b/cmd/podman/pod_rm.go @@ -2,9 +2,11 @@ package main import ( "fmt" + "os" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -46,11 +48,23 @@ func init() { // podRmCmd deletes pods func podRmCmd(c *cliconfig.PodRmValues) error { + if os.Geteuid() != 0 { + rootless.SetSkipStorageSetup(true) + } runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) + + if rootless.IsRootless() { + var err error + c.InputArgs, c.All, c.Latest, err = joinPodNS(runtime, c.All, c.Latest, c.InputArgs) + if err != nil { + return err + } + } + podRmIds, podRmErrors := runtime.RemovePods(getContext(), c) for _, p := range podRmIds { fmt.Println(p) diff --git a/cmd/podman/pod_stats.go b/cmd/podman/pod_stats.go index 7dbd84525..5c30e0595 100644 --- a/cmd/podman/pod_stats.go +++ b/cmd/podman/pod_stats.go @@ -53,6 +53,11 @@ func init() { } func podStatsCmd(c *cliconfig.PodStatsValues) error { + + if os.Geteuid() != 0 { + return errors.New("stats is not supported in rootless mode") + } + format := c.Format all := c.All latest := c.Latest diff --git a/cmd/podman/pod_stop.go b/cmd/podman/pod_stop.go index f1b0ac51f..754a3a7db 100644 --- a/cmd/podman/pod_stop.go +++ b/cmd/podman/pod_stop.go @@ -2,9 +2,11 @@ package main import ( "fmt" + "os" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/pkg/adapter" + "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -46,12 +48,24 @@ func init() { } func podStopCmd(c *cliconfig.PodStopValues) error { + if os.Geteuid() != 0 { + rootless.SetSkipStorageSetup(true) + } + runtime, err := adapter.GetRuntime(&c.PodmanCommand) if err != nil { return errors.Wrapf(err, "could not get runtime") } defer runtime.Shutdown(false) + if rootless.IsRootless() { + var err error + c.InputArgs, c.All, c.Latest, err = joinPodNS(runtime, c.All, c.Latest, c.InputArgs) + if err != nil { + return err + } + } + podStopIds, podStopErrors := runtime.StopPods(getContext(), c) for _, p := range podStopIds { fmt.Println(p) diff --git a/cmd/podman/rm.go b/cmd/podman/rm.go index 4230bb396..56aaae9eb 100644 --- a/cmd/podman/rm.go +++ b/cmd/podman/rm.go @@ -2,12 +2,16 @@ package main import ( "fmt" + "io/ioutil" + "os" + "strconv" "github.com/containers/libpod/cmd/podman/cliconfig" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -48,11 +52,39 @@ func init() { markFlagHiddenForRemoteClient("latest", flags) } +func joinContainerOrCreateRootlessUserNS(runtime *libpod.Runtime, ctr *libpod.Container) (bool, int, error) { + if os.Geteuid() == 0 { + return false, 0, nil + } + s, err := ctr.State() + if err != nil { + return false, -1, err + } + opts := rootless.Opts{ + Argument: ctr.ID(), + } + if s == libpod.ContainerStateRunning || s == libpod.ContainerStatePaused { + data, err := ioutil.ReadFile(ctr.Config().ConmonPidFile) + if err != nil { + return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", ctr.Config().ConmonPidFile) + } + conmonPid, err := strconv.Atoi(string(data)) + if err != nil { + return false, -1, errors.Wrapf(err, "cannot parse PID %q", data) + } + return rootless.JoinDirectUserAndMountNSWithOpts(uint(conmonPid), &opts) + } + return rootless.BecomeRootInUserNSWithOpts(&opts) +} + // saveCmd saves the image to either docker-archive or oci func rmCmd(c *cliconfig.RmValues) error { var ( deleteFuncs []shared.ParallelWorkerInput ) + if os.Geteuid() != 0 { + rootless.SetSkipStorageSetup(true) + } ctx := getContext() runtime, err := libpodruntime.GetRuntime(&c.PodmanCommand) @@ -61,6 +93,53 @@ func rmCmd(c *cliconfig.RmValues) error { } defer runtime.Shutdown(false) + if rootless.IsRootless() { + // When running in rootless mode we cannot manage different containers and + // user namespaces from the same context, so be sure to re-exec once for each + // container we are dealing with. + // What we do is to first collect all the containers we want to delete, then + // we re-exec in each of the container namespaces and from there remove the single + // container. + var container *libpod.Container + if os.Geteuid() == 0 { + // We are in the namespace, override InputArgs with the single + // argument that was passed down to us. + c.All = false + c.Latest = false + c.InputArgs = []string{rootless.Argument()} + } else { + var containers []*libpod.Container + if c.All { + containers, err = runtime.GetContainers() + } else if c.Latest { + container, err = runtime.GetLatestContainer() + if err != nil { + return errors.Wrapf(err, "unable to get latest pod") + } + containers = append(containers, container) + } else { + for _, c := range c.InputArgs { + container, err = runtime.LookupContainer(c) + if err != nil { + return err + } + containers = append(containers, container) + } + } + // Now we really delete the containers. + for _, c := range containers { + _, ret, err := joinContainerOrCreateRootlessUserNS(runtime, c) + if err != nil { + return err + } + if ret != 0 { + os.Exit(ret) + } + } + os.Exit(0) + } + } + failureCnt := 0 delContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all") if err != nil { |