Adding more varlink endpoints

* runlabel
* checkpoint
* restore
* container|image exists
* mount
* unmount

Signed-off-by: baude <bbaude@redhat.com>
This commit is contained in:
baude
2018-12-03 09:15:29 -06:00
parent 5bb66a47a4
commit 5c02dda869
7 changed files with 389 additions and 71 deletions

103
API.md
View File

@ -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.
### <a name="ContainerCheckpoint"></a>func ContainerCheckpoint
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
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)</div>
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.
### <a name="ContainerExists"></a>func ContainerExists
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerExists(name: [string](https://godoc.org/builtin#string)) [int](https://godoc.org/builtin#int)</div>
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.
### <a name="ContainerRestore"></a>func ContainerRestore
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
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)</div>
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.
### <a name="ContainerRunlabel"></a>func ContainerRunlabel
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ContainerRunlabel(runlabel: [Runlabel](#Runlabel)) </div>
ContainerRunlabel runs executes a command as described by a given container image label.
### <a name="CreateContainer"></a>func CreateContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -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.
### <a name="ImageExists"></a>func ImageExists
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ImageExists(name: [string](https://godoc.org/builtin#string)) [int](https://godoc.org/builtin#int)</div>
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.
### <a name="ImportImage"></a>func ImportImage
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -453,6 +505,17 @@ See also [StopPod](StopPod).
method ListContainerChanges(name: [string](https://godoc.org/builtin#string)) [ContainerChanges](#ContainerChanges)</div>
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.
### <a name="ListContainerMounts"></a>func ListContainerMounts
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ListContainerMounts() [[]string](#[]string)</div>
ListContainerMounts gathers all the mounted container mount points and returns them as an array
of strings
### <a name="ListContainerPorts"></a>func ListContainerPorts
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method ListContainerPorts(name: [string](https://godoc.org/builtin#string)) [NotImplemented](#NotImplemented)</div>
This function is not implemented yet.
### <a name="ListContainerProcesses"></a>func ListContainerProcesses
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -491,6 +554,12 @@ an image currently in storage. See also [InspectImage](InspectImage).
method ListPods() [ListPodData](#ListPodData)</div>
ListPods returns a list of pods in no particular order. They are
returned as an array of ListPodData structs. See also [GetPod](#GetPod).
### <a name="MountContainer"></a>func MountContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method MountContainer(name: [string](https://godoc.org/builtin#string)) [string](https://godoc.org/builtin#string)</div>
MountContainer mounts a container by name or full/partial ID. Upon a successful mount, the destination
mount is returned as a string.
### <a name="PauseContainer"></a>func PauseContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -696,6 +765,11 @@ be found, an [ImageNotFound](#ImageNotFound) error will be returned; otherwise,
method TopPod() [NotImplemented](#NotImplemented)</div>
This method has not been implemented yet.
### <a name="UnmountContainer"></a>func UnmountContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
method UnmountContainer(name: [string](https://godoc.org/builtin#string), force: [bool](https://godoc.org/builtin#bool)) </div>
UnmountContainer umounts a container by its name or full/partial container ID.
### <a name="UnpauseContainer"></a>func UnpauseContainer
<div style="background-color: #E8E8E8; padding: 15px; margin: 10px; border-radius: 10px;">
@ -1293,6 +1367,33 @@ insecure_registries [[]string](#[]string)
store [InfoStore](#InfoStore)
podman [InfoPodmanBinary](#InfoPodmanBinary)
### <a name="Runlabel"></a>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])
### <a name="Sockets"></a>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.
### <a name="NoContainersInPod"></a>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.
### <a name="PodContainerError"></a>type PodContainerError

View File

@ -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")
dockerRegistryOptions := image.DockerRegistryOptions{
DockerCertPath: c.String("cert-dir"),
DockerInsecureSkipTLSVerify: !c.BoolT("tls-verify"),
}
if len(newImage.Names()) < 1 {
imageName = newImage.ID()
} else {
imageName = newImage.Names()[0]
}
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")
return err
}
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 ""
}
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
}

View File

@ -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
}

View File

@ -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)

View File

@ -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())
}

View File

@ -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()
}

49
pkg/varlinkapi/mount.go Normal file
View File

@ -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()
}