aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2020-07-28 10:25:14 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2020-07-28 10:27:44 -0400
commit6979d140f1c531fd32e885542be27407105ebf90 (patch)
treee2d8c286c22eb5fe4065fa957fe043b546ed8c52 /libpod
parent288ebec6e737c105fa0ef43412de4e0a8997feb9 (diff)
downloadpodman-6979d140f1c531fd32e885542be27407105ebf90.tar.gz
podman-6979d140f1c531fd32e885542be27407105ebf90.tar.bz2
podman-6979d140f1c531fd32e885542be27407105ebf90.zip
Add podman image mount
There are many use cases where you want to just mount an image without creating a container on it. For example you might want to just examine the content in an image after you pull it for security analysys. Or you might want to just use the executables on the image without running it in a container. The image is mounted readonly since we do not want people changing images. Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/image/image.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/libpod/image/image.go b/libpod/image/image.go
index 14ffad4bf..8b2aa318f 100644
--- a/libpod/image/image.go
+++ b/libpod/image/image.go
@@ -1593,6 +1593,63 @@ func (i *Image) newImageEvent(status events.Status) {
}
}
+// Mount mounts a image's filesystem on the host
+// The path where the image has been mounted is returned
+func (i *Image) Mount(options []string, mountLabel string) (string, error) {
+ defer i.newImageEvent(events.Mount)
+ return i.mount(options, mountLabel)
+}
+
+// Unmount unmounts a image's filesystem on the host
+func (i *Image) Unmount(force bool) error {
+ defer i.newImageEvent(events.Unmount)
+ return i.unmount(force)
+}
+
+// Mounted returns whether the image is mounted and the path it is mounted
+// at (if it is mounted).
+// If the image is not mounted, no error is returned, and the mountpoint
+// will be set to "".
+func (i *Image) Mounted() (bool, string, error) {
+ mountedTimes, err := i.imageruntime.store.Mounted(i.TopLayer())
+ if err != nil {
+ return false, "", err
+ }
+
+ if mountedTimes > 0 {
+ layer, err := i.imageruntime.store.Layer(i.TopLayer())
+ if err != nil {
+ return false, "", err
+ }
+ return true, layer.MountPoint, nil
+ }
+
+ return false, "", nil
+}
+
+// mount mounts the container's root filesystem
+func (i *Image) mount(options []string, mountLabel string) (string, error) {
+ mountPoint, err := i.imageruntime.store.MountImage(i.ID(), options, mountLabel)
+ if err != nil {
+ return "", errors.Wrapf(err, "error mounting storage for image %s", i.ID())
+ }
+ mountPoint, err = filepath.EvalSymlinks(mountPoint)
+ if err != nil {
+ return "", errors.Wrapf(err, "error resolving storage path for image %s", i.ID())
+ }
+ return mountPoint, nil
+}
+
+// unmount unmounts the image's root filesystem
+func (i *Image) unmount(force bool) error {
+ // Also unmount storage
+ if _, err := i.imageruntime.store.UnmountImage(i.ID(), force); err != nil {
+ return errors.Wrapf(err, "error unmounting image %s root filesystem", i.ID())
+ }
+
+ return nil
+}
+
// LayerInfo keeps information of single layer
type LayerInfo struct {
// Layer ID