mirror of
https://github.com/containers/podman.git
synced 2025-06-21 01:19:15 +08:00
rootless: fix rm when uid in the container != 0
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
@ -73,6 +73,7 @@ var cmdsNotRequiringRootless = map[*cobra.Command]bool{
|
||||
_podKillCommand: true,
|
||||
_podStatsCommand: true,
|
||||
_restartCommand: true,
|
||||
_rmCommand: true,
|
||||
_runCommand: true,
|
||||
_unpauseCommand: true,
|
||||
_searchCommand: true,
|
||||
|
@ -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 {
|
||||
|
Reference in New Issue
Block a user