forked from containers/podman
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request containers#6851 from rhatdan/mount
Add podman image mount
- Loading branch information
Showing
16 changed files
with
789 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
package images | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"text/tabwriter" | ||
"text/template" | ||
|
||
"github.com/containers/podman/v2/cmd/podman/registry" | ||
"github.com/containers/podman/v2/cmd/podman/utils" | ||
"github.com/containers/podman/v2/pkg/domain/entities" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
) | ||
|
||
var ( | ||
mountDescription = `podman image mount | ||
Lists all mounted images mount points if no images is specified | ||
podman image mount IMAGE-NAME-OR-ID | ||
Mounts the specified image and prints the mountpoint | ||
` | ||
|
||
mountCommand = &cobra.Command{ | ||
Use: "mount [flags] [IMAGE...]", | ||
Short: "Mount an images's root filesystem", | ||
Long: mountDescription, | ||
RunE: mount, | ||
Example: `podman image mount imgID | ||
podman image mount imgID1 imgID2 imgID3 | ||
podman image mount | ||
podman image mount --all`, | ||
Annotations: map[string]string{ | ||
registry.UnshareNSRequired: "", | ||
registry.ParentNSRequired: "", | ||
}, | ||
} | ||
) | ||
|
||
var ( | ||
mountOpts entities.ImageMountOptions | ||
) | ||
|
||
func mountFlags(flags *pflag.FlagSet) { | ||
flags.BoolVarP(&mountOpts.All, "all", "a", false, "Mount all images") | ||
flags.StringVar(&mountOpts.Format, "format", "", "Print the mounted images in specified format (json)") | ||
} | ||
|
||
func init() { | ||
registry.Commands = append(registry.Commands, registry.CliCommand{ | ||
Mode: []entities.EngineMode{entities.ABIMode}, | ||
Command: mountCommand, | ||
Parent: imageCmd, | ||
}) | ||
mountFlags(mountCommand.Flags()) | ||
} | ||
|
||
func mount(_ *cobra.Command, args []string) error { | ||
var ( | ||
errs utils.OutputErrors | ||
) | ||
if len(args) > 0 && mountOpts.All { | ||
return errors.New("when using the --all switch, you may not pass any image names or IDs") | ||
} | ||
reports, err := registry.ImageEngine().Mount(registry.GetContext(), args, mountOpts) | ||
if err != nil { | ||
return err | ||
} | ||
if len(args) > 0 || mountOpts.All { | ||
for _, r := range reports { | ||
if r.Err == nil { | ||
fmt.Println(r.Path) | ||
continue | ||
} | ||
errs = append(errs, r.Err) | ||
} | ||
return errs.PrintErrors() | ||
} | ||
|
||
switch mountOpts.Format { | ||
case "json": | ||
return printJSON(reports) | ||
case "": | ||
// do nothing | ||
default: | ||
return errors.Errorf("unknown --format argument: %s", mountOpts.Format) | ||
} | ||
|
||
mrs := make([]mountReporter, 0, len(reports)) | ||
for _, r := range reports { | ||
mrs = append(mrs, mountReporter{r}) | ||
} | ||
row := "{{.ID}} {{.Path}}\n" | ||
format := "{{range . }}" + row + "{{end}}" | ||
tmpl, err := template.New("mounts").Parse(format) | ||
if err != nil { | ||
return err | ||
} | ||
w := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', 0) | ||
defer w.Flush() | ||
return tmpl.Execute(w, mrs) | ||
} | ||
|
||
func printJSON(reports []*entities.ImageMountReport) error { | ||
type jreport struct { | ||
ID string `json:"id"` | ||
Names []string | ||
Repositories []string | ||
Mountpoint string `json:"mountpoint"` | ||
} | ||
jreports := make([]jreport, 0, len(reports)) | ||
|
||
for _, r := range reports { | ||
jreports = append(jreports, jreport{ | ||
ID: r.Id, | ||
Names: []string{r.Name}, | ||
Repositories: r.Repositories, | ||
Mountpoint: r.Path, | ||
}) | ||
} | ||
b, err := json.MarshalIndent(jreports, "", " ") | ||
if err != nil { | ||
return err | ||
} | ||
fmt.Println(string(b)) | ||
return nil | ||
} | ||
|
||
type mountReporter struct { | ||
*entities.ImageMountReport | ||
} | ||
|
||
func (m mountReporter) ID() string { | ||
if len(m.Repositories) > 0 { | ||
return m.Repositories[0] | ||
} | ||
return m.Id | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package images | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/containers/podman/v2/cmd/podman/registry" | ||
"github.com/containers/podman/v2/cmd/podman/utils" | ||
"github.com/containers/podman/v2/pkg/domain/entities" | ||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/pflag" | ||
) | ||
|
||
var ( | ||
description = `Image storage increments a mount counter each time an image is mounted. | ||
When an image is unmounted, the mount counter is decremented. The image's root filesystem is physically unmounted only when the mount counter reaches zero indicating no other processes are using the mount. | ||
An unmount can be forced with the --force flag. | ||
` | ||
unmountCommand = &cobra.Command{ | ||
Use: "unmount [flags] IMAGE [IMAGE...]", | ||
Aliases: []string{"umount"}, | ||
Short: "Unmount an image's root filesystem", | ||
Long: description, | ||
RunE: unmount, | ||
Example: `podman unmount imgID | ||
podman unmount imgID1 imgID2 imgID3 | ||
podman unmount --all`, | ||
} | ||
) | ||
|
||
var ( | ||
unmountOpts entities.ImageUnmountOptions | ||
) | ||
|
||
func unmountFlags(flags *pflag.FlagSet) { | ||
flags.BoolVarP(&unmountOpts.All, "all", "a", false, "Unmount all of the currently mounted images") | ||
flags.BoolVarP(&unmountOpts.Force, "force", "f", false, "Force the complete unmount of the specified mounted images") | ||
} | ||
|
||
func init() { | ||
registry.Commands = append(registry.Commands, registry.CliCommand{ | ||
Mode: []entities.EngineMode{entities.ABIMode}, | ||
Parent: imageCmd, | ||
Command: unmountCommand, | ||
}) | ||
unmountFlags(unmountCommand.Flags()) | ||
} | ||
|
||
func unmount(cmd *cobra.Command, args []string) error { | ||
var errs utils.OutputErrors | ||
if len(args) < 1 && !unmountOpts.All { | ||
return errors.New("image name or ID must be specified") | ||
} | ||
if len(args) > 0 && unmountOpts.All { | ||
return errors.New("when using the --all switch, you may not pass any image names or IDs") | ||
} | ||
reports, err := registry.ImageEngine().Unmount(registry.GetContext(), args, unmountOpts) | ||
if err != nil { | ||
return err | ||
} | ||
for _, r := range reports { | ||
if r.Err == nil { | ||
fmt.Println(r.Id) | ||
} else { | ||
errs = append(errs, r.Err) | ||
} | ||
} | ||
return errs.PrintErrors() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.so man1/podman-image-unmount.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
% podman-image-mount(1) | ||
|
||
## NAME | ||
podman\-image\-mount - Mount an image's root filesystem | ||
|
||
## SYNOPSIS | ||
**podman image mount** [*options*] [*image* ...] | ||
|
||
## DESCRIPTION | ||
Mounts the specified images' root file system in a location which can be | ||
accessed from the host, and returns its location. | ||
|
||
If you execute the command without any arguments, Podman will list all of the | ||
currently mounted images. | ||
|
||
Rootless mode only supports mounting VFS driver, unless you enter the user namespace | ||
via the `podman unshare` command. All other storage drivers will fail to mount. | ||
|
||
## RETURN VALUE | ||
The location of the mounted file system. On error an empty string and errno is | ||
returned. | ||
|
||
## OPTIONS | ||
|
||
**--all**, **-a** | ||
|
||
Mount all images. | ||
|
||
**--format**=*format* | ||
|
||
Print the mounted images in specified format (json). | ||
|
||
## EXAMPLE | ||
|
||
``` | ||
podman image mount fedora ubi8-init | ||
/var/lib/containers/storage/overlay/f3ac502d97b5681989dff84dfedc8354239bcecbdc2692f9a639f4e080a02364/merged | ||
/var/lib/containers/storage/overlay/0ff7d7ca68bed1ace424f9df154d2dd7b5a125c19d887f17653cbcd5b6e30ba1/merged | ||
``` | ||
|
||
``` | ||
podman mount | ||
registry.fedoraproject.org/fedora:latest /var/lib/containers/storage/overlay/f3ac502d97b5681989dff84dfedc8354239bcecbdc2692f9a639f4e080a02364/merged | ||
registry.access.redhat.com/ubi8-init:latest /var/lib/containers/storage/overlay/0ff7d7ca68bed1ace424f9df154d2dd7b5a125c19d887f17653cbcd5b6e30ba1/merged | ||
``` | ||
|
||
``` | ||
podman image mount --format json | ||
[ | ||
{ | ||
"id": "00ff39a8bf19f810a7e641f7eb3ddc47635913a19c4996debd91fafb6b379069", | ||
"Names": [ | ||
"sha256:58de585a231aca14a511347bc85b912a6f000159b49bc2b0582032911e5d3a6c" | ||
], | ||
"Repositories": [ | ||
"registry.fedoraproject.org/fedora:latest" | ||
], | ||
"mountpoint": "/var/lib/containers/storage/overlay/0ccfac04663bbe8813b5f24502ee0b7371ce5bf3c5adeb12e4258d191c2cf7bc/merged" | ||
}, | ||
{ | ||
"id": "bcc2dc9a261774ad25a15e07bb515f9b77424266abf2a1252ec7bcfed1dd0ac2", | ||
"Names": [ | ||
"sha256:d5f260b2e51b3ee9d05de1c31d261efc9af28e7d2d47cedf054c496d71424d63" | ||
], | ||
"Repositories": [ | ||
"registry.access.redhat.com/ubi8-init:latest" | ||
], | ||
"mountpoint": "/var/lib/containers/storage/overlay/d66b58e3391ea8ce4c81316c72e22b332618f2a28b461a32ed673e8998cdaeb8/merged" | ||
} | ||
] | ||
``` | ||
|
||
## SEE ALSO | ||
podman(1), podman-image-umount(1), mount(8), podman-unshare(1) |
Oops, something went wrong.