mirror of
https://github.com/containers/podman.git
synced 2025-08-06 19:44:14 +08:00
Allow multiple containers and all for umount
Signed-off-by: TomSweeneyRedHat <tsweeney@redhat.com> Closes: #1012 Approved by: rhatdan
This commit is contained in:

committed by
Atomic Bot

parent
3a90b5224d
commit
41bd607c12
@ -1,17 +1,29 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
|
"github.com/projectatomic/libpod/cmd/podman/libpodruntime"
|
||||||
|
"github.com/projectatomic/libpod/libpod"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
umountFlags = []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "all, a",
|
||||||
|
Usage: "umount all of the currently mounted containers",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
umountCommand = cli.Command{
|
umountCommand = cli.Command{
|
||||||
Name: "umount",
|
Name: "umount",
|
||||||
Aliases: []string{"unmount"},
|
Aliases: []string{"unmount"},
|
||||||
Usage: "Unmount a working container's root filesystem",
|
Usage: "Unmounts working container's root filesystem",
|
||||||
Description: "Unmounts a working container's root filesystem",
|
Description: "Unmounts working container's root filesystem",
|
||||||
|
Flags: umountFlags,
|
||||||
Action: umountCmd,
|
Action: umountCmd,
|
||||||
ArgsUsage: "CONTAINER-NAME-OR-ID",
|
ArgsUsage: "CONTAINER-NAME-OR-ID",
|
||||||
}
|
}
|
||||||
@ -24,18 +36,66 @@ func umountCmd(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
defer runtime.Shutdown(false)
|
defer runtime.Shutdown(false)
|
||||||
|
|
||||||
|
umountAll := c.Bool("all")
|
||||||
args := c.Args()
|
args := c.Args()
|
||||||
if len(args) == 0 {
|
if len(args) == 0 && !umountAll {
|
||||||
return errors.Errorf("container ID must be specified")
|
return errors.Errorf("container ID must be specified")
|
||||||
}
|
}
|
||||||
if len(args) > 1 {
|
if len(args) > 0 && umountAll {
|
||||||
return errors.Errorf("too many arguments specified")
|
return errors.Errorf("when using the --all switch, you may not pass any container IDs")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctr, err := runtime.LookupContainer(args[0])
|
umountContainerErrStr := "error unmounting container"
|
||||||
|
var lastError error
|
||||||
|
if len(args) > 0 {
|
||||||
|
for _, name := range args {
|
||||||
|
ctr, err := runtime.LookupContainer(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "error looking up container %q", args[0])
|
if lastError != nil {
|
||||||
|
logrus.Error(lastError)
|
||||||
|
}
|
||||||
|
lastError = errors.Wrapf(err, "%s %s", umountContainerErrStr, name)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctr.Unmount()
|
if err = unmountContainer(ctr); err != nil {
|
||||||
|
if lastError != nil {
|
||||||
|
logrus.Error(lastError)
|
||||||
|
}
|
||||||
|
lastError = errors.Wrapf(err, "%s %s", umountContainerErrStr, name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", ctr.ID())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
containers, err := runtime.GetContainers()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "error reading Containers")
|
||||||
|
}
|
||||||
|
for _, ctr := range containers {
|
||||||
|
ctrState, err := ctr.State()
|
||||||
|
if ctrState == libpod.ContainerStateRunning || err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = unmountContainer(ctr); err != nil {
|
||||||
|
if lastError != nil {
|
||||||
|
logrus.Error(lastError)
|
||||||
|
}
|
||||||
|
lastError = errors.Wrapf(err, "%s %s", umountContainerErrStr, ctr.ID())
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fmt.Printf("%s\n", ctr.ID())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastError
|
||||||
|
}
|
||||||
|
|
||||||
|
func unmountContainer(ctr *libpod.Container) error {
|
||||||
|
if mounted, err := ctr.Mounted(); mounted {
|
||||||
|
return ctr.Unmount()
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return errors.Errorf("container is not mounted")
|
||||||
}
|
}
|
||||||
|
@ -1316,6 +1316,8 @@ _podman_unmount() {
|
|||||||
|
|
||||||
_podman_umount() {
|
_podman_umount() {
|
||||||
local boolean_options="
|
local boolean_options="
|
||||||
|
--all
|
||||||
|
-a
|
||||||
--help
|
--help
|
||||||
-h
|
-h
|
||||||
"
|
"
|
||||||
|
@ -1,17 +1,26 @@
|
|||||||
% podman-umount "1"
|
% podman-umount "1"
|
||||||
|
|
||||||
## NAME
|
## NAME
|
||||||
podman\-umount - Unmount a working container's root file system
|
podman\-umount - Unmount the specified working containers' root file system.
|
||||||
|
|
||||||
## SYNOPSIS
|
## SYNOPSIS
|
||||||
**podman** **umount** **containerID**
|
**podman** **umount** **containerID [...]**
|
||||||
|
|
||||||
## DESCRIPTION
|
## DESCRIPTION
|
||||||
Unmounts the specified container's root file system.
|
Unmounts the specified containers' root file system.
|
||||||
|
|
||||||
|
## OPTIONS
|
||||||
|
**--all, -a**
|
||||||
|
|
||||||
|
All of the currently mounted containers will be unmounted.
|
||||||
|
|
||||||
## EXAMPLE
|
## EXAMPLE
|
||||||
|
|
||||||
podman umount containerID
|
podman umount containerID
|
||||||
|
|
||||||
|
podman umount containerID1 containerID2 containerID3
|
||||||
|
|
||||||
|
podman umount --all
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
podman(1), podman-mount(1)
|
podman(1), podman-mount(1)
|
||||||
|
@ -61,4 +61,52 @@ var _ = Describe("Podman mount", func() {
|
|||||||
umount.WaitWithDefaultTimeout()
|
umount.WaitWithDefaultTimeout()
|
||||||
Expect(umount.ExitCode()).To(Equal(0))
|
Expect(umount.ExitCode()).To(Equal(0))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman umount many", func() {
|
||||||
|
setup1 := podmanTest.Podman([]string{"create", ALPINE, "ls"})
|
||||||
|
setup1.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup1.ExitCode()).To(Equal(0))
|
||||||
|
cid1 := setup1.OutputToString()
|
||||||
|
|
||||||
|
setup2 := podmanTest.Podman([]string{"create", ALPINE, "ls"})
|
||||||
|
setup2.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup2.ExitCode()).To(Equal(0))
|
||||||
|
cid2 := setup2.OutputToString()
|
||||||
|
|
||||||
|
mount1 := podmanTest.Podman([]string{"mount", cid1})
|
||||||
|
mount1.WaitWithDefaultTimeout()
|
||||||
|
Expect(mount1.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
mount2 := podmanTest.Podman([]string{"mount", cid2})
|
||||||
|
mount2.WaitWithDefaultTimeout()
|
||||||
|
Expect(mount2.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
umount := podmanTest.Podman([]string{"umount", cid1, cid2})
|
||||||
|
umount.WaitWithDefaultTimeout()
|
||||||
|
Expect(umount.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("podman umount all", func() {
|
||||||
|
setup1 := podmanTest.Podman([]string{"create", ALPINE, "ls"})
|
||||||
|
setup1.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup1.ExitCode()).To(Equal(0))
|
||||||
|
cid1 := setup1.OutputToString()
|
||||||
|
|
||||||
|
setup2 := podmanTest.Podman([]string{"create", ALPINE, "ls"})
|
||||||
|
setup2.WaitWithDefaultTimeout()
|
||||||
|
Expect(setup2.ExitCode()).To(Equal(0))
|
||||||
|
cid2 := setup2.OutputToString()
|
||||||
|
|
||||||
|
mount1 := podmanTest.Podman([]string{"mount", cid1})
|
||||||
|
mount1.WaitWithDefaultTimeout()
|
||||||
|
Expect(mount1.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
mount2 := podmanTest.Podman([]string{"mount", cid2})
|
||||||
|
mount2.WaitWithDefaultTimeout()
|
||||||
|
Expect(mount2.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
umount := podmanTest.Podman([]string{"umount", "--all"})
|
||||||
|
umount.WaitWithDefaultTimeout()
|
||||||
|
Expect(umount.ExitCode()).To(Equal(0))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user