Update kpod mount and umount to use the new state

The new state for containers has been added
moved kpod mount and umount over to use it

Signed-off-by: Urvashi Mohnani <umohnani@redhat.com>

Closes: #57
Approved by: rhatdan
This commit is contained in:
umohnani8
2017-11-22 10:46:47 -05:00
committed by Atomic Bot
parent 34ba0cb8a9
commit 40dce698d3
4 changed files with 112 additions and 54 deletions

View File

@ -42,7 +42,7 @@ var (
} }
) )
// MountOutputParams stores info about each layer // jsonMountPoint stores info about each container
type jsonMountPoint struct { type jsonMountPoint struct {
ID string `json:"id"` ID string `json:"id"`
Names []string `json:"names"` Names []string `json:"names"`
@ -50,6 +50,16 @@ type jsonMountPoint struct {
} }
func mountCmd(c *cli.Context) error { 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{ formats := map[string]bool{
"": true, "": true,
of.JSONString: true, of.JSONString: true,
@ -64,49 +74,43 @@ func mountCmd(c *cli.Context) error {
if len(args) > 1 { if len(args) > 1 {
return errors.Errorf("too many arguments specified") 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 len(args) == 1 {
if json { if json {
return errors.Wrapf(err, "json option can not be used with a container id") 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 { if err != nil {
return errors.Wrapf(err, "error finding container %q", args[0]) 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 mounting container %q", ctr.ID())
} }
fmt.Printf("%s\n", mountPoint) fmt.Printf("%s\n", mountPoint)
} else { } else {
jsonMountPoints := []jsonMountPoint{} jsonMountPoints := []jsonMountPoint{}
containers, err2 := store.Containers() containers, err2 := runtime.GetContainers()
if err2 != nil { if err2 != nil {
return errors.Wrapf(err2, "error reading list of all containers") return errors.Wrapf(err2, "error reading list of all containers")
} }
for _, container := range containers { for _, container := range containers {
layer, err := store.Layer(container.LayerID) mountPoint, err := container.MountPoint()
if err != nil { 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 continue
} }
if json { 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 continue
} }
if c.Bool("notruncate") { if c.Bool("notruncate") {
fmt.Printf("%-64s %s\n", container.ID, layer.MountPoint) fmt.Printf("%-64s %s\n", container.ID(), mountPoint)
} else { } else {
fmt.Printf("%-12.12s %s\n", container.ID, layer.MountPoint) fmt.Printf("%-12.12s %s\n", container.ID(), mountPoint)
} }
} }
if json { if json {

View File

@ -17,6 +17,12 @@ var (
) )
func umountCmd(c *cli.Context) error { 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() args := c.Args()
if len(args) == 0 { if len(args) == 0 {
return errors.Errorf("container ID must be specified") return errors.Errorf("container ID must be specified")
@ -24,18 +30,11 @@ func umountCmd(c *cli.Context) error {
if len(args) > 1 { if len(args) > 1 {
return errors.Errorf("too many arguments specified") return errors.Errorf("too many arguments specified")
} }
config, err := getConfig(c)
ctr, err := runtime.LookupContainer(args[0])
if err != nil { if err != nil {
return errors.Wrapf(err, "Could not get config") return errors.Wrapf(err, "error looking up container %q", args[0])
}
store, err := getStore(config)
if err != nil {
return err
} }
err = store.Unmount(args[0]) return ctr.Unmount()
if err != nil {
return errors.Wrapf(err, "error unmounting container %q", args[0])
}
return nil
} }

View File

@ -194,6 +194,18 @@ func (c *Container) PID() (int, error) {
return c.state.PID, nil 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 // The path to the container's root filesystem - where the OCI spec will be
// placed, amongst other things // placed, amongst other things
func (c *Container) bundlePath() string { 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 // Mount mounts a container's filesystem on the host
// The path where the container has been mounted is returned // The path where the container has been mounted is returned
func (c *Container) Mount() (string, error) { func (c *Container) Mount(label string) (string, error) {
return "", ErrNotImplemented 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 // Pause pauses a container

View File

@ -13,41 +13,29 @@ function setup() {
} }
@test "mount" { @test "mount" {
skip "Test needs to be converted to kpod run" run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} create $BB ls"
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"
echo "$output" echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
ctr_id="$output" 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 "$output"
echo ${KPOD_BINARY} ${KPOD_OPTIONS} mount $ctr_id
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount --notruncate | grep $ctr_id" run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount --notruncate | grep $ctr_id"
echo "$output" echo "$output"
[ "$status" -eq 0 ] [ "$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" echo "$output"
[ "$status" -eq 0 ] [ "$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" echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
root="$output"
run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount --format=json | python -m json.tool | grep $ctr_id" run bash -c "${KPOD_BINARY} ${KPOD_OPTIONS} mount --format=json | python -m json.tool | grep $ctr_id"
echo "$output" echo "$output"
[ "$status" -eq 0 ] [ "$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" echo "$output"
[ "$status" -eq 0 ] [ "$status" -eq 0 ]
cleanup_ctrs
cleanup_pods
stop_crio
} }