Files
podman/cmd/podman/mount.go
baude e053e0e05e first pass of corrections for golangci-lint
Signed-off-by: baude <bbaude@redhat.com>
2019-07-10 15:52:17 -05:00

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
}