summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiuseppe Scrivano <gscrivan@redhat.com>2019-03-08 12:06:16 +0100
committerGiuseppe Scrivano <gscrivan@redhat.com>2019-03-11 11:48:28 +0100
commit231129e4dc083d9f63cf1876cc1695f7f8c03f25 (patch)
tree4113cdca5717e8d7a1e0cc97694f03fa1e903410
parent35432ecaae4a8372a6f40a6cac476f0140094c7c (diff)
downloadpodman-231129e4dc083d9f63cf1876cc1695f7f8c03f25.tar.gz
podman-231129e4dc083d9f63cf1876cc1695f7f8c03f25.tar.bz2
podman-231129e4dc083d9f63cf1876cc1695f7f8c03f25.zip
rootless: fix pod stop|rm if uid in the container != 0
join the user namespace where the pod is running, so that we can both manage the storage and correctly send the kill signal to a process which is not running as root in the namespace. Closes: https://github.com/containers/libpod/issues/2577 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
-rw-r--r--cmd/podman/main.go2
-rw-r--r--cmd/podman/pod.go47
-rw-r--r--cmd/podman/pod_rm.go14
-rw-r--r--cmd/podman/pod_stop.go14
-rw-r--r--pkg/adapter/runtime.go40
-rw-r--r--pkg/adapter/runtime_remote.go7
6 files changed, 124 insertions, 0 deletions
diff --git a/cmd/podman/main.go b/cmd/podman/main.go
index c347a922d..1c6217dac 100644
--- a/cmd/podman/main.go
+++ b/cmd/podman/main.go
@@ -70,8 +70,10 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{
_mountCommand: true,
_killCommand: true,
_pauseCommand: true,
+ _podRmCommand: true,
_podKillCommand: true,
_podStatsCommand: true,
+ _podStopCommand: true,
_restartCommand: true,
_rmCommand: true,
_runCommand: true,
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_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/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 732b89530..482b6119a 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -337,3 +337,43 @@ func IsImageNotFound(err error) bool {
func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) {
return r.Runtime.HealthCheck(c.InputArgs[0])
}
+
+// JoinOrCreateRootlessPod joins the specified pod if it is running or it creates a new user namespace
+// if the pod is stopped
+func (r *LocalRuntime) JoinOrCreateRootlessPod(pod *Pod) (bool, int, error) {
+ if os.Geteuid() == 0 {
+ return false, 0, nil
+ }
+ opts := rootless.Opts{
+ Argument: pod.ID(),
+ }
+
+ inspect, err := pod.Inspect()
+ if err != nil {
+ return false, 0, err
+ }
+ for _, ctr := range inspect.Containers {
+ prevCtr, err := r.LookupContainer(ctr.ID)
+ if err != nil {
+ return false, -1, err
+ }
+ s, err := prevCtr.State()
+ if err != nil {
+ return false, -1, err
+ }
+ if s != libpod.ContainerStateRunning && s != libpod.ContainerStatePaused {
+ continue
+ }
+ data, err := ioutil.ReadFile(prevCtr.Config().ConmonPidFile)
+ if err != nil {
+ return false, -1, errors.Wrapf(err, "cannot read conmon PID file %q", prevCtr.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)
+}
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 10c25c3f3..9ca4e245f 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -751,3 +751,10 @@ func IsImageNotFound(err error) bool {
func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) {
return -1, libpod.ErrNotImplemented
}
+
+// JoinOrCreateRootlessPod joins the specified pod if it is running or it creates a new user namespace
+// if the pod is stopped
+func (r *LocalRuntime) JoinOrCreateRootlessPod(pod *Pod) (bool, int, error) {
+ // Nothing to do in the remote case
+ return true, 0, nil
+}