diff options
-rw-r--r-- | cmd/kpod/mount.go | 46 | ||||
-rw-r--r-- | cmd/kpod/umount.go | 21 | ||||
-rw-r--r-- | libpod/container.go | 71 | ||||
-rw-r--r-- | test/kpod_mount.bats | 28 |
4 files changed, 112 insertions, 54 deletions
diff --git a/cmd/kpod/mount.go b/cmd/kpod/mount.go index d9df7ffa5..e90f54537 100644 --- a/cmd/kpod/mount.go +++ b/cmd/kpod/mount.go @@ -42,7 +42,7 @@ var ( } ) -// MountOutputParams stores info about each layer +// jsonMountPoint stores info about each container type jsonMountPoint struct { ID string `json:"id"` Names []string `json:"names"` @@ -50,6 +50,16 @@ type jsonMountPoint struct { } func mountCmd(c *cli.Context) error { + if err := validateFlags(c, mountFlags); err != nil { + return err + } + + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + defer runtime.Shutdown(false) + formats := map[string]bool{ "": true, of.JSONString: true, @@ -64,49 +74,43 @@ func mountCmd(c *cli.Context) error { if len(args) > 1 { return errors.Errorf("too many arguments specified") } - if err := validateFlags(c, mountFlags); err != nil { - return err - } - config, err := getConfig(c) - if err != nil { - return errors.Wrapf(err, "Could not get config") - } - store, err := getStore(config) - if err != nil { - return errors.Wrapf(err, "error getting store") - } + if len(args) == 1 { if json { return errors.Wrapf(err, "json option can not be used with a container id") } - mountPoint, err := store.Mount(args[0], c.String("label")) + ctr, err := runtime.LookupContainer(args[0]) + if err != nil { + return errors.Wrapf(err, "error looking up container %q", args[0]) + } + mountPoint, err := ctr.Mount(c.String("label")) if err != nil { - return errors.Wrapf(err, "error finding container %q", args[0]) + return errors.Wrapf(err, "error mounting container %q", ctr.ID()) } fmt.Printf("%s\n", mountPoint) } else { jsonMountPoints := []jsonMountPoint{} - containers, err2 := store.Containers() + containers, err2 := runtime.GetContainers() if err2 != nil { return errors.Wrapf(err2, "error reading list of all containers") } for _, container := range containers { - layer, err := store.Layer(container.LayerID) + mountPoint, err := container.MountPoint() if err != nil { - return errors.Wrapf(err, "error finding layer %q for container %q", container.LayerID, container.ID) + return errors.Wrapf(err, "error getting mountpoint for %q", container.ID()) } - if layer.MountPoint == "" { + if mountPoint == "" { continue } if json { - jsonMountPoints = append(jsonMountPoints, jsonMountPoint{ID: container.ID, Names: container.Names, MountPoint: layer.MountPoint}) + jsonMountPoints = append(jsonMountPoints, jsonMountPoint{ID: container.ID(), Names: []string{container.Name()}, MountPoint: mountPoint}) continue } if c.Bool("notruncate") { - fmt.Printf("%-64s %s\n", container.ID, layer.MountPoint) + fmt.Printf("%-64s %s\n", container.ID(), mountPoint) } else { - fmt.Printf("%-12.12s %s\n", container.ID, layer.MountPoint) + fmt.Printf("%-12.12s %s\n", container.ID(), mountPoint) } } if json { diff --git a/cmd/kpod/umount.go b/cmd/kpod/umount.go index bad6752ab..4b6aba99e 100644 --- a/cmd/kpod/umount.go +++ b/cmd/kpod/umount.go @@ -17,6 +17,12 @@ var ( ) func umountCmd(c *cli.Context) error { + runtime, err := getRuntime(c) + if err != nil { + return errors.Wrapf(err, "could not get runtime") + } + defer runtime.Shutdown(false) + args := c.Args() if len(args) == 0 { return errors.Errorf("container ID must be specified") @@ -24,18 +30,11 @@ func umountCmd(c *cli.Context) error { if len(args) > 1 { return errors.Errorf("too many arguments specified") } - config, err := getConfig(c) - if err != nil { - return errors.Wrapf(err, "Could not get config") - } - store, err := getStore(config) - if err != nil { - return err - } - err = store.Unmount(args[0]) + ctr, err := runtime.LookupContainer(args[0]) if err != nil { - return errors.Wrapf(err, "error unmounting container %q", args[0]) + return errors.Wrapf(err, "error looking up container %q", args[0]) } - return nil + + return ctr.Unmount() } diff --git a/libpod/container.go b/libpod/container.go index 8ad0bb10d..f0a6d58eb 100644 --- a/libpod/container.go +++ b/libpod/container.go @@ -194,6 +194,18 @@ func (c *Container) PID() (int, error) { return c.state.PID, nil } +// MountPoint returns the mount point of the continer +func (c *Container) MountPoint() (string, error) { + c.lock.Lock() + defer c.lock.Unlock() + + if err := c.runtime.state.UpdateContainer(c); err != nil { + return "", errors.Wrapf(err, "error updating container %s state", c.ID()) + } + + return c.state.Mountpoint, nil +} + // The path to the container's root filesystem - where the OCI spec will be // placed, amongst other things func (c *Container) bundlePath() string { @@ -463,8 +475,63 @@ func (c *Container) Attach(noStdin bool, keys string, attached chan<- bool) erro // Mount mounts a container's filesystem on the host // The path where the container has been mounted is returned -func (c *Container) Mount() (string, error) { - return "", ErrNotImplemented +func (c *Container) Mount(label string) (string, error) { + c.lock.Lock() + defer c.lock.Unlock() + + if err := c.syncContainer(); err != nil { + return "", err + } + + // return mountpoint if container already mounted + if c.state.Mounted { + return c.state.Mountpoint, nil + } + + mountLabel := label + if label == "" { + mountLabel = c.config.MountLabel + } + mountPoint, err := c.runtime.store.Mount(c.ID(), mountLabel) + if err != nil { + return "", err + } + c.state.Mountpoint = mountPoint + c.state.Mounted = true + c.config.MountLabel = mountLabel + + if err := c.runtime.state.SaveContainer(c); err != nil { + return "", errors.Wrapf(err, "error saving container %s state", c.ID()) + } + + return mountPoint, nil +} + +// Unmount unmounts a container's filesystem on the host +func (c *Container) Unmount() error { + c.lock.Lock() + defer c.lock.Unlock() + + if err := c.syncContainer(); err != nil { + return err + } + + if c.state.State == ContainerStateRunning || c.state.State == ContainerStatePaused { + return errors.Wrapf(ErrCtrStateInvalid, "cannot remove storage for container %s as it is running or paused", c.ID()) + } + + if !c.state.Mounted { + return nil + } + + err := c.runtime.store.Unmount(c.ID()) + if err != nil { + return errors.Wrapf(err, "error unmounting container %q", c.ID()) + } + c.state.Mountpoint = "" + c.state.Mounted = false + + return c.runtime.state.SaveContainer(c) } // Pause pauses a container diff --git a/test/kpod_mount.bats b/test/kpod_mount.bats index 48f581505..35f707451 100644 --- a/test/kpod_mount.bats +++ b/test/kpod_mount.bats @@ -13,41 +13,29 @@ function setup() { } @test "mount" { - skip "Test needs to be converted to kpod run" - start_crio - run crioctl pod run --config "$TESTDATA"/sandbox_config.json - echo "$output" - [ "$status" -eq 0 ] - pod_id="$output" - run crioctl image pull "$IMAGE" - echo "$output" - [ "$status" -eq 0 ] - run crioctl ctr create --config "$TESTDATA"/container_config.json --pod "$pod_id" + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} create $BB ls" echo "$output" [ "$status" -eq 0 ] ctr_id="$output" - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} mount $ctr_id + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount $ctr_id" echo "$output" - echo ${KPOD_BINARY} ${KPOD_OPTIONS} mount $ctr_id [ "$status" -eq 0 ] run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount --notruncate | grep $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unmount $ctr_id + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} unmount $ctr_id" echo "$output" [ "$status" -eq 0 ] - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} mount $ctr_id + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount $ctr_id" echo "$output" [ "$status" -eq 0 ] - root="$output" run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount --format=json | python -m json.tool | grep $ctr_id" echo "$output" [ "$status" -eq 0 ] - touch $root/foobar - run bash -c ${KPOD_BINARY} ${KPOD_OPTIONS} unmount $ctr_id + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} unmount $ctr_id" + echo "$output" + [ "$status" -eq 0 ] + run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} rm $ctr_id" echo "$output" [ "$status" -eq 0 ] - cleanup_ctrs - cleanup_pods - stop_crio } |