mirror of
https://github.com/containers/podman.git
synced 2025-07-02 16:57:24 +08:00
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:
@ -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 {
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user