Skip to content

Commit

Permalink
rootless: fix rm when uid in the container != 0
Browse files Browse the repository at this point in the history
Signed-off-by: Giuseppe Scrivano <[email protected]>
  • Loading branch information
giuseppe committed Mar 11, 2019
1 parent d6ebccf commit 35432ec
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
1 change: 1 addition & 0 deletions cmd/podman/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{
_podKillCommand: true,
_podStatsCommand: true,
_restartCommand: true,
_rmCommand: true,
_runCommand: true,
_unpauseCommand: true,
_searchCommand: true,
Expand Down
79 changes: 79 additions & 0 deletions cmd/podman/rm.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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 {
Expand Down

0 comments on commit 35432ec

Please sign in to comment.