mirror of
https://github.com/containers/podman.git
synced 2025-05-21 17:16:22 +08:00
170 lines
4.4 KiB
Go
170 lines
4.4 KiB
Go
package main
|
|
|
|
import (
|
|
js "encoding/json"
|
|
"fmt"
|
|
"os"
|
|
|
|
of "github.com/containers/buildah/pkg/formats"
|
|
"github.com/containers/libpod/cmd/podman/cliconfig"
|
|
"github.com/containers/libpod/cmd/podman/libpodruntime"
|
|
"github.com/containers/libpod/pkg/rootless"
|
|
"github.com/pkg/errors"
|
|
"github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
mountCommand cliconfig.MountValues
|
|
|
|
mountDescription = `podman mount
|
|
Lists all mounted containers mount points if no container is specified
|
|
|
|
podman mount CONTAINER-NAME-OR-ID
|
|
Mounts the specified container and outputs the mountpoint
|
|
`
|
|
|
|
_mountCommand = &cobra.Command{
|
|
Use: "mount [flags] [CONTAINER]",
|
|
Short: "Mount a working container's root filesystem",
|
|
Long: mountDescription,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
mountCommand.InputArgs = args
|
|
mountCommand.GlobalFlags = MainGlobalOpts
|
|
mountCommand.Remote = remoteclient
|
|
return mountCmd(&mountCommand)
|
|
},
|
|
Args: func(cmd *cobra.Command, args []string) error {
|
|
return checkAllAndLatest(cmd, args, true)
|
|
},
|
|
}
|
|
)
|
|
|
|
func init() {
|
|
mountCommand.Command = _mountCommand
|
|
mountCommand.SetHelpTemplate(HelpTemplate())
|
|
mountCommand.SetUsageTemplate(UsageTemplate())
|
|
flags := mountCommand.Flags()
|
|
flags.BoolVarP(&mountCommand.All, "all", "a", false, "Mount all containers")
|
|
flags.StringVar(&mountCommand.Format, "format", "", "Change the output format to Go template")
|
|
flags.BoolVarP(&mountCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
|
|
flags.BoolVar(&mountCommand.NoTrunc, "notruncate", false, "Do not truncate output")
|
|
|
|
markFlagHiddenForRemoteClient("latest", flags)
|
|
}
|
|
|
|
// jsonMountPoint stores info about each container
|
|
type jsonMountPoint struct {
|
|
ID string `json:"id"`
|
|
Names []string `json:"names"`
|
|
MountPoint string `json:"mountpoint"`
|
|
}
|
|
|
|
func mountCmd(c *cliconfig.MountValues) error {
|
|
runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "could not get runtime")
|
|
}
|
|
defer runtime.DeferredShutdown(false)
|
|
|
|
if os.Geteuid() != 0 {
|
|
rtc, err := runtime.GetConfig()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if driver := rtc.StorageConfig.GraphDriverName; driver != "vfs" {
|
|
// Do not allow to mount a graphdriver that is not vfs if we are creating the userns as part
|
|
// of the mount command.
|
|
return fmt.Errorf("cannot mount using driver %s in rootless mode", driver)
|
|
}
|
|
|
|
became, ret, err := rootless.BecomeRootInUserNS("")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if became {
|
|
os.Exit(ret)
|
|
}
|
|
}
|
|
|
|
if c.All && c.Latest {
|
|
return errors.Errorf("--all and --latest cannot be used together")
|
|
}
|
|
|
|
mountContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all")
|
|
if err != nil {
|
|
if len(mountContainers) == 0 {
|
|
return err
|
|
}
|
|
fmt.Println(err.Error())
|
|
}
|
|
|
|
formats := map[string]bool{
|
|
"": true,
|
|
of.JSONString: true,
|
|
}
|
|
|
|
json := c.Format == of.JSONString
|
|
if !formats[c.Format] {
|
|
return errors.Errorf("%q is not a supported format", c.Format)
|
|
}
|
|
|
|
var lastError error
|
|
if len(mountContainers) > 0 {
|
|
for _, ctr := range mountContainers {
|
|
if json {
|
|
if lastError != nil {
|
|
logrus.Error(lastError)
|
|
}
|
|
lastError = errors.Wrapf(err, "json option cannot be used with a container id")
|
|
continue
|
|
}
|
|
mountPoint, err := ctr.Mount()
|
|
if err != nil {
|
|
if lastError != nil {
|
|
logrus.Error(lastError)
|
|
}
|
|
lastError = errors.Wrapf(err, "error mounting container %q", ctr.ID())
|
|
continue
|
|
}
|
|
fmt.Printf("%s\n", mountPoint)
|
|
}
|
|
return lastError
|
|
} else {
|
|
jsonMountPoints := []jsonMountPoint{}
|
|
containers, err2 := runtime.GetContainers()
|
|
if err2 != nil {
|
|
return errors.Wrapf(err2, "error reading list of all containers")
|
|
}
|
|
for _, container := range containers {
|
|
mounted, mountPoint, err := container.Mounted()
|
|
if err != nil {
|
|
return errors.Wrapf(err, "error getting mountpoint for %q", container.ID())
|
|
}
|
|
|
|
if !mounted {
|
|
continue
|
|
}
|
|
|
|
if json {
|
|
jsonMountPoints = append(jsonMountPoints, jsonMountPoint{ID: container.ID(), Names: []string{container.Name()}, MountPoint: mountPoint})
|
|
continue
|
|
}
|
|
|
|
if c.NoTrunc {
|
|
fmt.Printf("%-64s %s\n", container.ID(), mountPoint)
|
|
} else {
|
|
fmt.Printf("%-12.12s %s\n", container.ID(), mountPoint)
|
|
}
|
|
}
|
|
if json {
|
|
data, err := js.MarshalIndent(jsonMountPoints, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Printf("%s\n", data)
|
|
}
|
|
}
|
|
return nil
|
|
}
|