From 5c02dda869390725a799339b094f548d327c9122 Mon Sep 17 00:00:00 2001 From: baude Date: Mon, 3 Dec 2018 09:15:29 -0600 Subject: Adding more varlink endpoints * runlabel * checkpoint * restore * container|image exists * mount * unmount Signed-off-by: baude --- API.md | 103 ++++++++++++++++++++++++++++++++++- cmd/podman/runlabel.go | 81 ++++----------------------- cmd/podman/shared/container.go | 81 +++++++++++++++++++++++++++ cmd/podman/varlink/io.podman.varlink | 52 ++++++++++++++++++ pkg/varlinkapi/containers.go | 49 +++++++++++++++++ pkg/varlinkapi/images.go | 45 +++++++++++++++ pkg/varlinkapi/mount.go | 49 +++++++++++++++++ 7 files changed, 389 insertions(+), 71 deletions(-) create mode 100644 pkg/varlinkapi/mount.go diff --git a/API.md b/API.md index 34d401aca..4d48e8245 100755 --- a/API.md +++ b/API.md @@ -9,6 +9,14 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func Commit(name: string, image_name: string, changes: []string, author: string, message: string, pause: bool, manifestType: string) string](#Commit) +[func ContainerCheckpoint(name: string, keep: bool, leaveRunning: bool, tcpEstablished: bool) string](#ContainerCheckpoint) + +[func ContainerExists(name: string) int](#ContainerExists) + +[func ContainerRestore(name: string, keep: bool, tcpEstablished: bool) string](#ContainerRestore) + +[func ContainerRunlabel(runlabel: Runlabel) ](#ContainerRunlabel) + [func CreateContainer(create: Create) string](#CreateContainer) [func CreateImage() NotImplemented](#CreateImage) @@ -43,6 +51,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func HistoryImage(name: string) ImageHistory](#HistoryImage) +[func ImageExists(name: string) int](#ImageExists) + [func ImportImage(source: string, reference: string, message: string, changes: []string) string](#ImportImage) [func InspectContainer(name: string) string](#InspectContainer) @@ -57,6 +67,10 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ListContainerChanges(name: string) ContainerChanges](#ListContainerChanges) +[func ListContainerMounts() []string](#ListContainerMounts) + +[func ListContainerPorts(name: string) NotImplemented](#ListContainerPorts) + [func ListContainerProcesses(name: string, opts: []string) []string](#ListContainerProcesses) [func ListContainers() ListContainerData](#ListContainers) @@ -65,6 +79,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func ListPods() ListPodData](#ListPods) +[func MountContainer(name: string) string](#MountContainer) + [func PauseContainer(name: string) string](#PauseContainer) [func PausePod(name: string) string](#PausePod) @@ -103,6 +119,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [func TopPod() NotImplemented](#TopPod) +[func UnmountContainer(name: string, force: bool) ](#UnmountContainer) + [func UnpauseContainer(name: string) string](#UnpauseContainer) [func UnpausePod(name: string) string](#UnpausePod) @@ -165,6 +183,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [type PodmanInfo](#PodmanInfo) +[type Runlabel](#Runlabel) + [type Sockets](#Sockets) [type StringResponse](#StringResponse) @@ -211,6 +231,31 @@ attributes: _CMD, ENTRYPOINT, ENV, EXPOSE, LABEL, ONBUILD, STOPSIGNAL, USER, VOL container while it is being committed, pass a _true_ bool for the pause argument. If the container cannot be found by the ID or name provided, a (ContainerNotFound)[#ContainerNotFound] error will be returned; otherwise, the resulting image's ID will be returned as a string. +### func ContainerCheckpoint +
+ +method ContainerCheckpoint(name: [string](https://godoc.org/builtin#string), keep: [bool](https://godoc.org/builtin#bool), leaveRunning: [bool](https://godoc.org/builtin#bool), tcpEstablished: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)
+ContainerCheckPoint performs a checkpopint on a container by its name or full/partial container +ID. On successful checkpoint, the id of the checkpointed container is returned. +### func ContainerExists +
+ +method ContainerExists(name: [string](https://godoc.org/builtin#string)) [int](https://godoc.org/builtin#int)
+ContainerExists takes a full or partial container ID or name and returns an int as to +whether the container exists in local storage. A result of 0 means the container does +exists; whereas a result of 1 means it could not be found. +### func ContainerRestore +
+ +method ContainerRestore(name: [string](https://godoc.org/builtin#string), keep: [bool](https://godoc.org/builtin#bool), tcpEstablished: [bool](https://godoc.org/builtin#bool)) [string](https://godoc.org/builtin#string)
+ContainerRestore restores a container that has been checkpointed. The container to be restored can +be identified by its name or full/partial container ID. A successful restore will result in the return +of the container's ID. +### func ContainerRunlabel +
+ +method ContainerRunlabel(runlabel: [Runlabel](#Runlabel))
+ContainerRunlabel runs executes a command as described by a given container image label. ### func CreateContainer
@@ -403,6 +448,13 @@ method HistoryImage(name: [string](https://godoc.org/builtin#string)) [ImageHist HistoryImage takes the name or ID of an image and returns information about its history and layers. The returned history is in the form of an array of ImageHistory structures. If the image cannot be found, an [ImageNotFound](#ImageNotFound) error is returned. +### func ImageExists +
+ +method ImageExists(name: [string](https://godoc.org/builtin#string)) [int](https://godoc.org/builtin#int)
+ImageExists talks a full or partial image ID or name and returns an int as to whether +the image exists in local storage. An int result of 0 means the image does exist in +local storage; whereas 1 indicates the image does not exists in local storage. ### func ImportImage
@@ -453,6 +505,17 @@ See also [StopPod](StopPod). method ListContainerChanges(name: [string](https://godoc.org/builtin#string)) [ContainerChanges](#ContainerChanges)
ListContainerChanges takes a name or ID of a container and returns changes between the container and its base image. It returns a struct of changed, deleted, and added path names. +### func ListContainerMounts +
+ +method ListContainerMounts() [[]string](#[]string)
+ListContainerMounts gathers all the mounted container mount points and returns them as an array +of strings +### func ListContainerPorts +
+ +method ListContainerPorts(name: [string](https://godoc.org/builtin#string)) [NotImplemented](#NotImplemented)
+This function is not implemented yet. ### func ListContainerProcesses
@@ -491,6 +554,12 @@ an image currently in storage. See also [InspectImage](InspectImage). method ListPods() [ListPodData](#ListPodData)
ListPods returns a list of pods in no particular order. They are returned as an array of ListPodData structs. See also [GetPod](#GetPod). +### func MountContainer +
+ +method MountContainer(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)
+MountContainer mounts a container by name or full/partial ID. Upon a successful mount, the destination +mount is returned as a string. ### func PauseContainer
@@ -696,6 +765,11 @@ be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise, method TopPod() [NotImplemented](#NotImplemented)
This method has not been implemented yet. +### func UnmountContainer +
+ +method UnmountContainer(name: [string](https://godoc.org/builtin#string), force: [bool](https://godoc.org/builtin#bool))
+UnmountContainer umounts a container by its name or full/partial container ID. ### func UnpauseContainer
@@ -1293,6 +1367,33 @@ insecure_registries [[]string](#[]string) store [InfoStore](#InfoStore) podman [InfoPodmanBinary](#InfoPodmanBinary) +### type Runlabel + +Runlabel describes the required input for container runlabel + +image [string](https://godoc.org/builtin#string) + +authfile [string](https://godoc.org/builtin#string) + +certDir [string](https://godoc.org/builtin#string) + +creds [string](https://godoc.org/builtin#string) + +display [bool](https://godoc.org/builtin#bool) + +name [string](https://godoc.org/builtin#string) + +pull [bool](https://godoc.org/builtin#bool) + +signaturePolicyPath [string](https://godoc.org/builtin#string) + +tlsVerify [bool](https://godoc.org/builtin#bool) + +label [string](https://godoc.org/builtin#string) + +extraArgs [[]string](#[]string) + +opts [map[string]](#map[string]) ### type Sockets Sockets describes sockets location for a container @@ -1336,7 +1437,7 @@ ImageNotFound means the image could not be found by the provided name or ID in l NoContainerRunning means none of the containers requested are running in a command that requires a running container. ### type NoContainersInPod -NoContainersInPod means a pod has no containers on which to perform operation. It contains +NoContainersInPod means a pod has no containers on which to perform the operation. It contains the pod ID. ### type PodContainerError diff --git a/cmd/podman/runlabel.go b/cmd/podman/runlabel.go index e1dee1fb2..b0d87d0d9 100644 --- a/cmd/podman/runlabel.go +++ b/cmd/podman/runlabel.go @@ -6,11 +6,9 @@ import ( "os" "strings" - "github.com/containers/image/types" "github.com/containers/libpod/cmd/podman/libpodruntime" "github.com/containers/libpod/cmd/podman/shared" "github.com/containers/libpod/libpod/image" - "github.com/containers/libpod/pkg/util" "github.com/containers/libpod/utils" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -94,7 +92,7 @@ func runlabelCmd(c *cli.Context) error { imageName string stdErr, stdOut io.Writer stdIn io.Reader - newImage *image.Image + extraArgs []string ) // Evil images could trick into recursively executing the runlabel @@ -124,6 +122,9 @@ func runlabelCmd(c *cli.Context) error { return errors.Errorf("the display and quiet flags cannot be used together.") } + if len(args) > 2 { + extraArgs = args[2:] + } pull := c.Bool("pull") label := args[0] @@ -151,75 +152,24 @@ func runlabelCmd(c *cli.Context) error { stdIn = nil } - if pull { - var registryCreds *types.DockerAuthConfig - if c.IsSet("creds") { - creds, err := util.ParseRegistryCreds(c.String("creds")) - if err != nil { - return err - } - registryCreds = creds - } - dockerRegistryOptions := image.DockerRegistryOptions{ - DockerRegistryCreds: registryCreds, - DockerCertPath: c.String("cert-dir"), - DockerInsecureSkipTLSVerify: !c.BoolT("tls-verify"), - } - authfile := getAuthFile(c.String("authfile")) - - newImage, err = runtime.ImageRuntime().New(ctx, runlabelImage, c.String("signature-policy"), authfile, stdOut, &dockerRegistryOptions, image.SigningOptions{}, false, false) - } else { - newImage, err = runtime.ImageRuntime().NewFromLocal(runlabelImage) - } - if err != nil { - return errors.Wrapf(err, "unable to find image") - } - - if len(newImage.Names()) < 1 { - imageName = newImage.ID() - } else { - imageName = newImage.Names()[0] + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerCertPath: c.String("cert-dir"), + DockerInsecureSkipTLSVerify: !c.BoolT("tls-verify"), } - runLabel, err := newImage.GetLabel(ctx, label) + authfile := getAuthFile(c.String("authfile")) + runLabel, imageName, err := shared.GetRunlabel(label, runlabelImage, ctx, runtime, pull, c.String("creds"), dockerRegistryOptions, authfile, c.String("signature-policy"), stdOut) if err != nil { return err } - - // If no label to execute, we return if runLabel == "" { return nil } - // The user provided extra arguments that need to be tacked onto the label's command - if len(args) > 2 { - runLabel = fmt.Sprintf("%s %s", runLabel, strings.Join(args[2:], " ")) - } - - cmd, err := shared.GenerateCommand(runLabel, imageName, c.String("name")) + cmd, env, err := shared.GenerateRunlabelCommand(runLabel, imageName, c.String("name"), opts, extraArgs) if err != nil { - return errors.Wrapf(err, "unable to generate command") - } - env := shared.GenerateRunEnvironment(c.String("name"), imageName, opts) - env = append(env, "PODMAN_RUNLABEL_NESTED=1") - - envmap := envSliceToMap(env) - - envmapper := func(k string) string { - switch k { - case "OPT1": - return envmap["OPT1"] - case "OPT2": - return envmap["OPT2"] - case "OPT3": - return envmap["OPT3"] - } - return "" + return err } - - newS := os.Expand(strings.Join(cmd, " "), envmapper) - cmd = strings.Split(newS, " ") - if !c.Bool("quiet") { fmt.Printf("Command: %s\n", strings.Join(cmd, " ")) if c.Bool("display") { @@ -228,12 +178,3 @@ func runlabelCmd(c *cli.Context) error { } return utils.ExecCmdWithStdStreams(stdIn, stdOut, stdErr, env, cmd[0], cmd[1:]...) } - -func envSliceToMap(env []string) map[string]string { - m := make(map[string]string) - for _, i := range env { - split := strings.Split(i, "=") - m[split[0]] = strings.Join(split[1:], " ") - } - return m -} diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index 4404268d4..d0e892961 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -1,10 +1,15 @@ package shared import ( + "context" "encoding/json" "fmt" + "github.com/containers/image/types" + "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/util" "github.com/cri-o/ocicni/pkg/ocicni" "github.com/docker/go-units" + "io" "os" "path/filepath" "regexp" @@ -589,3 +594,79 @@ func portsToString(ports []ocicni.PortMapping) string { } return strings.Join(portDisplay, ", ") } + +// GetRunlabel is a helper function for runlabel; it gets the image if needed and begins the +// contruction of the runlabel output and environment variables +func GetRunlabel(label string, runlabelImage string, ctx context.Context, runtime *libpod.Runtime, pull bool, inputCreds string, dockerRegistryOptions image.DockerRegistryOptions, authfile string, signaturePolicyPath string, output io.Writer) (string, string, error) { + var ( + newImage *image.Image + err error + imageName string + ) + if pull { + var registryCreds *types.DockerAuthConfig + if inputCreds != "" { + creds, err := util.ParseRegistryCreds(inputCreds) + if err != nil { + return "", "", err + } + registryCreds = creds + } + dockerRegistryOptions.DockerRegistryCreds = registryCreds + newImage, err = runtime.ImageRuntime().New(ctx, runlabelImage, signaturePolicyPath, authfile, output, &dockerRegistryOptions, image.SigningOptions{}, false, false) + } else { + newImage, err = runtime.ImageRuntime().NewFromLocal(runlabelImage) + } + if err != nil { + return "", "", errors.Wrapf(err, "unable to find image") + } + + if len(newImage.Names()) < 1 { + imageName = newImage.ID() + } else { + imageName = newImage.Names()[0] + } + + runLabel, err := newImage.GetLabel(ctx, label) + return runLabel, imageName, err +} + +// GenerateRunlabelCommand generates the command that will eventually be execucted by podman +func GenerateRunlabelCommand(runLabel, imageName, name string, opts map[string]string, extraArgs []string) ([]string, []string, error) { + // The user provided extra arguments that need to be tacked onto the label's command + if len(extraArgs) > 0 { + runLabel = fmt.Sprintf("%s %s", runLabel, strings.Join(extraArgs, " ")) + } + cmd, err := GenerateCommand(runLabel, imageName, name) + if err != nil { + return nil, nil, errors.Wrapf(err, "unable to generate command") + } + env := GenerateRunEnvironment(name, imageName, opts) + env = append(env, "PODMAN_RUNLABEL_NESTED=1") + + envmap := envSliceToMap(env) + + envmapper := func(k string) string { + switch k { + case "OPT1": + return envmap["OPT1"] + case "OPT2": + return envmap["OPT2"] + case "OPT3": + return envmap["OPT3"] + } + return "" + } + newS := os.Expand(strings.Join(cmd, " "), envmapper) + cmd = strings.Split(newS, " ") + return cmd, env, nil +} + +func envSliceToMap(env []string) map[string]string { + m := make(map[string]string) + for _, i := range env { + split := strings.Split(i, "=") + m[split[0]] = strings.Join(split[1:], " ") + } + return m +} diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 4a4a1854c..b081b60a3 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -371,6 +371,22 @@ type PodContainerErrorData ( reason: string ) +# Runlabel describes the required input for container runlabel +type Runlabel( + image: string, + authfile: string, + certDir: string, + creds: string, + display: bool, + name: string, + pull: bool, + signaturePolicyPath: string, + tlsVerify: bool, + label: string, + extraArgs: []string, + opts: [string]string +) + # Ping provides a response for developers to ensure their varlink setup is working. # #### Example # ~~~ @@ -804,6 +820,42 @@ method TopPod() -> (notimplemented: NotImplemented) # ~~~ method GetPodStats(name: string) -> (pod: string, containers: []ContainerStats) +# ImageExists talks a full or partial image ID or name and returns an int as to whether +# the image exists in local storage. An int result of 0 means the image does exist in +# local storage; whereas 1 indicates the image does not exists in local storage. +method ImageExists(name: string) -> (exists: int) + +# ContainerExists takes a full or partial container ID or name and returns an int as to +# whether the container exists in local storage. A result of 0 means the container does +# exists; whereas a result of 1 means it could not be found. +method ContainerExists(name: string) -> (exists: int) + +# ContainerCheckPoint performs a checkpopint on a container by its name or full/partial container +# ID. On successful checkpoint, the id of the checkpointed container is returned. +method ContainerCheckpoint(name: string, keep: bool, leaveRunning: bool, tcpEstablished: bool) -> (id: string) + +# ContainerRestore restores a container that has been checkpointed. The container to be restored can +# be identified by its name or full/partial container ID. A successful restore will result in the return +# of the container's ID. +method ContainerRestore(name: string, keep: bool, tcpEstablished: bool) -> (id: string) + +# ContainerRunlabel runs executes a command as described by a given container image label. +method ContainerRunlabel(runlabel: Runlabel) -> () + +# ListContainerMounts gathers all the mounted container mount points and returns them as an array +# of strings +method ListContainerMounts() -> (mounts: []string) + +# MountContainer mounts a container by name or full/partial ID. Upon a successful mount, the destination +# mount is returned as a string. +method MountContainer(name: string) -> (path: string) + +# UnmountContainer umounts a container by its name or full/partial container ID. +method UnmountContainer(name: string, force: bool) -> () + +# This function is not implemented yet. +method ListContainerPorts(name: string) -> (notimplemented: NotImplemented) + # ImageNotFound means the image could not be found by the provided name or ID in local storage. error ImageNotFound (name: string) diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index f517e9b6e..07d981786 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -278,6 +278,18 @@ func (i *LibpodAPI) RestartContainer(call iopodman.VarlinkCall, name string, tim return call.ReplyRestartContainer(ctr.ID()) } +// ContainerExists looks in local storage for the existence of a container +func (i *LibpodAPI) ContainerExists(call iopodman.VarlinkCall, name string) error { + _, err := i.Runtime.LookupContainer(name) + if errors.Cause(err) == libpod.ErrNoSuchCtr { + return call.ReplyContainerExists(1) + } + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyContainerExists(0) +} + // KillContainer kills a running container. If you want to use the default SIGTERM signal, just send a -1 // for the signal arg. func (i *LibpodAPI) KillContainer(call iopodman.VarlinkCall, name string, signal int64) error { @@ -413,3 +425,40 @@ func (i *LibpodAPI) GetAttachSockets(call iopodman.VarlinkCall, name string) err } return call.ReplyGetAttachSockets(s) } + +// ContainerCheckpoint ... +func (i *LibpodAPI) ContainerCheckpoint(call iopodman.VarlinkCall, name string, keep, leaveRunning, tcpEstablished bool) error { + ctx := getContext() + ctr, err := i.Runtime.LookupContainer(name) + if err != nil { + return call.ReplyContainerNotFound(name) + } + + options := libpod.ContainerCheckpointOptions{ + Keep: keep, + TCPEstablished: tcpEstablished, + KeepRunning: leaveRunning, + } + if err := ctr.Checkpoint(ctx, options); err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyContainerCheckpoint(ctr.ID()) +} + +// ContainerRestore ... +func (i *LibpodAPI) ContainerRestore(call iopodman.VarlinkCall, name string, keep, tcpEstablished bool) error { + ctx := getContext() + ctr, err := i.Runtime.LookupContainer(name) + if err != nil { + return call.ReplyContainerNotFound(name) + } + + options := libpod.ContainerCheckpointOptions{ + Keep: keep, + TCPEstablished: tcpEstablished, + } + if err := ctr.Restore(ctx, options); err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyContainerRestore(ctr.ID()) +} diff --git a/pkg/varlinkapi/images.go b/pkg/varlinkapi/images.go index 42e285b53..6d3f19422 100644 --- a/pkg/varlinkapi/images.go +++ b/pkg/varlinkapi/images.go @@ -4,7 +4,9 @@ import ( "bytes" "encoding/json" "fmt" + "github.com/containers/libpod/cmd/podman/shared" "io" + "os" "path/filepath" "strings" "time" @@ -19,6 +21,7 @@ import ( "github.com/containers/libpod/libpod/image" sysreg "github.com/containers/libpod/pkg/registries" "github.com/containers/libpod/pkg/util" + "github.com/containers/libpod/utils" "github.com/docker/go-units" "github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/runtime-spec/specs-go" @@ -500,3 +503,45 @@ func (i *LibpodAPI) PullImage(call iopodman.VarlinkCall, name string) error { } return call.ReplyPullImage(newImage.ID()) } + +// ImageExists returns bool as to whether the input image exists in local storage +func (i *LibpodAPI) ImageExists(call iopodman.VarlinkCall, name string) error { + _, err := i.Runtime.ImageRuntime().NewFromLocal(name) + if errors.Cause(err) == libpod.ErrNoSuchImage { + return call.ReplyImageExists(1) + } + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyImageExists(0) +} + +// ContainerRunlabel ... +func (i *LibpodAPI) ContainerRunlabel(call iopodman.VarlinkCall, input iopodman.Runlabel) error { + ctx := getContext() + dockerRegistryOptions := image.DockerRegistryOptions{ + DockerCertPath: input.CertDir, + DockerInsecureSkipTLSVerify: !input.TlsVerify, + } + + stdErr := os.Stderr + stdOut := os.Stdout + stdIn := os.Stdin + + runLabel, imageName, err := shared.GetRunlabel(input.Label, input.Image, ctx, i.Runtime, input.Pull, input.Creds, dockerRegistryOptions, input.Authfile, input.SignaturePolicyPath, nil) + if err != nil { + return err + } + if runLabel == "" { + return nil + } + + cmd, env, err := shared.GenerateRunlabelCommand(runLabel, imageName, input.Name, input.Opts, input.ExtraArgs) + if err != nil { + return err + } + if err := utils.ExecCmdWithStdStreams(stdIn, stdOut, stdErr, env, cmd[0], cmd[1:]...); err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyContainerRunlabel() +} diff --git a/pkg/varlinkapi/mount.go b/pkg/varlinkapi/mount.go new file mode 100644 index 000000000..84e6b2709 --- /dev/null +++ b/pkg/varlinkapi/mount.go @@ -0,0 +1,49 @@ +package varlinkapi + +import ( + "github.com/containers/libpod/cmd/podman/varlink" +) + +// ListContainerMounts ... +func (i *LibpodAPI) ListContainerMounts(call iopodman.VarlinkCall) error { + var mounts []string + allContainers, err := i.Runtime.GetAllContainers() + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + for _, container := range allContainers { + mounted, mountPoint, err := container.Mounted() + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + if mounted { + mounts = append(mounts, mountPoint) + } + } + return call.ReplyListContainerMounts(mounts) +} + +// MountContainer ... +func (i *LibpodAPI) MountContainer(call iopodman.VarlinkCall, name string) error { + container, err := i.Runtime.LookupContainer(name) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + path, err := container.Mount() + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyMountContainer(path) +} + +// UnmountContainer ... +func (i *LibpodAPI) UnmountContainer(call iopodman.VarlinkCall, name string, force bool) error { + container, err := i.Runtime.LookupContainer(name) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + if err := container.Unmount(force); err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyUnmountContainer() +} -- cgit v1.2.3-54-g00ecf