github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/mount.go (about) 1 package main 2 3 import ( 4 js "encoding/json" 5 "fmt" 6 "os" 7 8 of "github.com/containers/buildah/pkg/formats" 9 "github.com/containers/libpod/cmd/podman/cliconfig" 10 "github.com/containers/libpod/cmd/podman/libpodruntime" 11 "github.com/containers/libpod/pkg/rootless" 12 "github.com/pkg/errors" 13 "github.com/sirupsen/logrus" 14 "github.com/spf13/cobra" 15 ) 16 17 var ( 18 mountCommand cliconfig.MountValues 19 20 mountDescription = `podman mount 21 Lists all mounted containers mount points if no container is specified 22 23 podman mount CONTAINER-NAME-OR-ID 24 Mounts the specified container and outputs the mountpoint 25 ` 26 27 _mountCommand = &cobra.Command{ 28 Use: "mount [flags] [CONTAINER]", 29 Short: "Mount a working container's root filesystem", 30 Long: mountDescription, 31 RunE: func(cmd *cobra.Command, args []string) error { 32 mountCommand.InputArgs = args 33 mountCommand.GlobalFlags = MainGlobalOpts 34 mountCommand.Remote = remoteclient 35 return mountCmd(&mountCommand) 36 }, 37 Args: func(cmd *cobra.Command, args []string) error { 38 return checkAllLatestAndCIDFile(cmd, args, true, false) 39 }, 40 } 41 ) 42 43 func init() { 44 mountCommand.Command = _mountCommand 45 mountCommand.SetHelpTemplate(HelpTemplate()) 46 mountCommand.SetUsageTemplate(UsageTemplate()) 47 flags := mountCommand.Flags() 48 flags.BoolVarP(&mountCommand.All, "all", "a", false, "Mount all containers") 49 flags.StringVar(&mountCommand.Format, "format", "", "Change the output format to Go template") 50 flags.BoolVarP(&mountCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of") 51 flags.BoolVar(&mountCommand.NoTrunc, "notruncate", false, "Do not truncate output") 52 53 markFlagHiddenForRemoteClient("latest", flags) 54 } 55 56 // jsonMountPoint stores info about each container 57 type jsonMountPoint struct { 58 ID string `json:"id"` 59 Names []string `json:"names"` 60 MountPoint string `json:"mountpoint"` 61 } 62 63 func mountCmd(c *cliconfig.MountValues) error { 64 runtime, err := libpodruntime.GetRuntime(getContext(), &c.PodmanCommand) 65 if err != nil { 66 return errors.Wrapf(err, "could not get runtime") 67 } 68 defer runtime.DeferredShutdown(false) 69 70 if os.Geteuid() != 0 { 71 if driver := runtime.StorageConfig().GraphDriverName; driver != "vfs" { 72 // Do not allow to mount a graphdriver that is not vfs if we are creating the userns as part 73 // of the mount command. 74 return fmt.Errorf("cannot mount using driver %s in rootless mode", driver) 75 } 76 77 became, ret, err := rootless.BecomeRootInUserNS("") 78 if err != nil { 79 return err 80 } 81 if became { 82 os.Exit(ret) 83 } 84 } 85 86 if c.All && c.Latest { 87 return errors.Errorf("--all and --latest cannot be used together") 88 } 89 90 mountContainers, err := getAllOrLatestContainers(&c.PodmanCommand, runtime, -1, "all") 91 if err != nil { 92 if len(mountContainers) == 0 { 93 return err 94 } 95 fmt.Println(err.Error()) 96 } 97 98 formats := map[string]bool{ 99 "": true, 100 of.JSONString: true, 101 } 102 103 json := c.Format == of.JSONString 104 if !formats[c.Format] { 105 return errors.Errorf("%q is not a supported format", c.Format) 106 } 107 108 var lastError error 109 if len(mountContainers) > 0 { 110 for _, ctr := range mountContainers { 111 if json { 112 if lastError != nil { 113 logrus.Error(lastError) 114 } 115 lastError = errors.Wrapf(err, "json option cannot be used with a container id") 116 continue 117 } 118 mountPoint, err := ctr.Mount() 119 if err != nil { 120 if lastError != nil { 121 logrus.Error(lastError) 122 } 123 lastError = errors.Wrapf(err, "error mounting container %q", ctr.ID()) 124 continue 125 } 126 fmt.Printf("%s\n", mountPoint) 127 } 128 return lastError 129 } else { 130 jsonMountPoints := []jsonMountPoint{} 131 containers, err2 := runtime.GetContainers() 132 if err2 != nil { 133 return errors.Wrapf(err2, "error reading list of all containers") 134 } 135 for _, container := range containers { 136 mounted, mountPoint, err := container.Mounted() 137 if err != nil { 138 return errors.Wrapf(err, "error getting mountpoint for %q", container.ID()) 139 } 140 141 if !mounted { 142 continue 143 } 144 145 if json { 146 jsonMountPoints = append(jsonMountPoints, jsonMountPoint{ID: container.ID(), Names: []string{container.Name()}, MountPoint: mountPoint}) 147 continue 148 } 149 150 if c.NoTrunc { 151 fmt.Printf("%-64s %s\n", container.ID(), mountPoint) 152 } else { 153 fmt.Printf("%-12.12s %s\n", container.ID(), mountPoint) 154 } 155 } 156 if json { 157 data, err := js.MarshalIndent(jsonMountPoints, "", " ") 158 if err != nil { 159 return err 160 } 161 fmt.Printf("%s\n", data) 162 } 163 } 164 return nil 165 }