diff options
author | Giuseppe Scrivano <gscrivan@redhat.com> | 2018-12-11 10:22:34 +0100 |
---|---|---|
committer | Giuseppe Scrivano <gscrivan@redhat.com> | 2018-12-11 10:24:06 +0100 |
commit | 9a7416c3426d6fbad1205f333b8b2c6da4908be2 (patch) | |
tree | 865443909bc352fa480a319b0a156a7e79e9c0b1 /cmd/podman/restart.go | |
parent | 235a6300744636f650728f2a7545243aed045c91 (diff) | |
download | podman-9a7416c3426d6fbad1205f333b8b2c6da4908be2.tar.gz podman-9a7416c3426d6fbad1205f333b8b2c6da4908be2.tar.bz2 podman-9a7416c3426d6fbad1205f333b8b2c6da4908be2.zip |
rootless: fix restart when using fuse-overlayfs
With rootless containers we cannot really restart an existing container
as we would need to join the mount namespace as well to be able to reuse
the storage, so ensure the container is stopped first.
Closes: https://github.com/containers/libpod/issues/1965
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'cmd/podman/restart.go')
-rw-r--r-- | cmd/podman/restart.go | 81 |
1 files changed, 74 insertions, 7 deletions
diff --git a/cmd/podman/restart.go b/cmd/podman/restart.go index 630493ef4..c6fe1025a 100644 --- a/cmd/podman/restart.go +++ b/cmd/podman/restart.go @@ -1,9 +1,13 @@ package main import ( + "fmt" + "os" + "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod" + "github.com/containers/libpod/pkg/rootless" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" @@ -47,6 +51,10 @@ func restartCmd(c *cli.Context) error { restartContainers []*libpod.Container ) + if os.Geteuid() != 0 { + rootless.SetSkipStorageSetup(true) + } + args := c.Args() runOnly := c.Bool("running") all := c.Bool("all") @@ -95,6 +103,29 @@ func restartCmd(c *cli.Context) error { } } + maxWorkers := shared.Parallelize("restart") + if c.GlobalIsSet("max-workers") { + maxWorkers = c.GlobalInt("max-workers") + } + + logrus.Debugf("Setting maximum workers to %d", maxWorkers) + + if rootless.IsRootless() { + // With rootless containers we cannot really restart an existing container + // as we would need to join the mount namespace as well to be able to reuse + // the storage. + if err := stopRootlessContainers(restartContainers, timeout, useTimeout, maxWorkers); err != nil { + return err + } + became, ret, err := rootless.BecomeRootInUserNS() + if err != nil { + return err + } + if became { + os.Exit(ret) + } + } + // We now have a slice of all the containers to be restarted. Iterate them to // create restart Funcs with a timeout as needed for _, ctr := range restartContainers { @@ -114,13 +145,49 @@ func restartCmd(c *cli.Context) error { }) } - maxWorkers := shared.Parallelize("restart") - if c.GlobalIsSet("max-workers") { - maxWorkers = c.GlobalInt("max-workers") - } - - logrus.Debugf("Setting maximum workers to %d", maxWorkers) - restartErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, restartFuncs) return printParallelOutput(restartErrors, errCount) } + +func stopRootlessContainers(stopContainers []*libpod.Container, timeout uint, useTimeout bool, maxWorkers int) error { + var stopFuncs []shared.ParallelWorkerInput + for _, ctr := range stopContainers { + state, err := ctr.State() + if err != nil { + return err + } + if state != libpod.ContainerStateRunning { + continue + } + + ctrTimeout := ctr.StopTimeout() + if useTimeout { + ctrTimeout = timeout + } + + c := ctr + f := func() error { + return c.StopWithTimeout(ctrTimeout) + } + + stopFuncs = append(stopFuncs, shared.ParallelWorkerInput{ + ContainerID: c.ID(), + ParallelFunc: f, + }) + + restartErrors, errCount := shared.ParallelExecuteWorkerPool(maxWorkers, stopFuncs) + var lastError error + for _, result := range restartErrors { + if result != nil { + if errCount > 1 { + fmt.Println(result.Error()) + } + lastError = result + } + } + if lastError != nil { + return lastError + } + } + return nil +} |