diff options
author | haircommander <pehunt@redhat.com> | 2018-08-14 13:24:21 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2018-08-16 20:31:50 +0000 |
commit | 0059989783851ec536faf8a290eea863148dcb6c (patch) | |
tree | cece1412a11936cd49f70fcb6fb7876f44e001b1 | |
parent | edffded1fbecff2f22ec0a388789e8c2edab0153 (diff) | |
download | podman-0059989783851ec536faf8a290eea863148dcb6c.tar.gz podman-0059989783851ec536faf8a290eea863148dcb6c.tar.bz2 podman-0059989783851ec536faf8a290eea863148dcb6c.zip |
Add Pod API to varlink.
Including: GetPod, StartPod, StopPod, RestartPod, KillPod, PausePod, UnpausePod, CreatePod, RemovePod, and InspectPod
Signed-off-by: haircommander <pehunt@redhat.com>
Closes: #1275
Approved by: mheon
-rw-r--r-- | cmd/podman/varlink/io.podman.varlink | 20 | ||||
-rw-r--r-- | pkg/varlinkapi/pods.go | 231 | ||||
-rw-r--r-- | pkg/varlinkapi/util.go | 40 |
3 files changed, 281 insertions, 10 deletions
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index 18b37207c..0e6f0f054 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -638,21 +638,21 @@ method PullImage(name: string) -> (id: string) # "pod": "8759dafbc0a4dc3bcfb57eeb72e4331eb73c5cc09ab968e65ce45b9ad5c4b6bb" # } # ~~~ -method CreatePod() -> (notimplemented: NotImplemented) +method CreatePod(name: string, cgroup_parent: string, labels: [string]string) -> (pod: string) # ListPods returns a list of pods in no particular order. They are # returned as an array of ListPodData structs. See also [GetPod](#GetPod). -method ListPods() -> (notimplemented: NotImplemented) +method ListPods() -> (pods: []ListPodData) # GetPod takes a name or ID of a pod and returns single [ListPodData](#ListPodData) # structure. A [PodNotFound](#PodNotFound) error will be returned if the pod cannot be found. # See also [ListPods](ListPods). -method GetPod() -> (notimplemented: NotImplemented) +method GetPod(name: string) -> (pod: ListPodData) # InspectPod takes the name or ID of an image and returns a string respresentation of data associated with the # pod. You must serialize the string into JSON to use it further. A [PodNotFound](#PodNotFound) error will # be returned if the pod cannot be found. -method InspectPod() -> (notimplemented: NotImplemented) +method InspectPod(name: string) -> (pod: string) # StartPod starts containers in a pod. It takes the name or ID of pod. If the pod cannot be found, a [PodNotFound](#PodNotFound) # error will be returned. Containers in a pod are started independently. If there is an error starting one container, the ID of those containers @@ -696,7 +696,7 @@ method StopPod(name: string) -> (pod: string) # "pod": "135d71b9495f7c3967f536edad57750bfdb569336cd107d8aabab45565ffcfb6" # } # ~~~ -method RestartPod() -> (notimplemented: NotImplemented) +method RestartPod(name: string) -> (pod: string) # KillPod takes the name or ID of a pod as well as a signal to be applied to the pod. If the pod cannot be found, a # [PodNotFound](#PodNotFound) error is returned. @@ -704,7 +704,7 @@ method RestartPod() -> (notimplemented: NotImplemented) # will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). # If the pod was killed with no errors, the pod ID is returned. # See also [StopPod](StopPod). -method KillPod() -> (notimplemented: NotImplemented) +method KillPod(name: string, signal: int) -> (pod: string) # PausePod takes the name or ID of a pod and pauses the running containers associated with it. If the pod cannot be found, # a [PodNotFound](#PodNotFound) error will be returned. @@ -712,7 +712,7 @@ method KillPod() -> (notimplemented: NotImplemented) # will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). # If the pod was paused with no errors, the pod ID is returned. # See also [UnpausePod](#UnpausePod). -method PausePod() -> (notimplemented: NotImplemented) +method PausePod(name: string) -> (pod: string) # UnpausePod takes the name or ID of a pod and unpauses the paused containers associated with it. If the pod cannot be # found, a [PodNotFound](#PodNotFound) error will be returned. @@ -720,7 +720,7 @@ method PausePod() -> (notimplemented: NotImplemented) # will be returned in a list, along with the ID of the pod in a [PodContainerError](#PodContainerError). # If the pod was unpaused with no errors, the pod ID is returned. # See also [PausePod](#PausePod). -method UnpausePod() -> (notimplemented: NotImplemented) +method UnpausePod(name: string) -> (pod: string) # RemovePod takes the name or ID of a pod as well a boolean representing whether a running # container in the pod can be stopped and removed. If a pod has containers associated with it, and force is not true, @@ -731,12 +731,12 @@ method UnpausePod() -> (notimplemented: NotImplemented) # If the pod was removed with no errors, the pod ID is returned. # #### Example # ~~~ -# $ varlink call -m unix:/run/podman/io.podman/io.podman.RemovePod '{"name": "62f4fd98cb57"}' +# $ varlink call -m unix:/run/podman/io.podman/io.podman.RemovePod '{"name": "62f4fd98cb57", "force": "true"}' # { # "pod": "62f4fd98cb57f529831e8f90610e54bba74bd6f02920ffb485e15376ed365c20" # } # ~~~ -method RemovePod() -> (notimplemented: NotImplemented) +method RemovePod(name: string, force: bool) -> (pod: string) # This method has not be implemented yet. method WaitPod() -> (notimplemented: NotImplemented) diff --git a/pkg/varlinkapi/pods.go b/pkg/varlinkapi/pods.go new file mode 100644 index 000000000..272c348fc --- /dev/null +++ b/pkg/varlinkapi/pods.go @@ -0,0 +1,231 @@ +package varlinkapi + +import ( + "encoding/json" + "syscall" + + "github.com/projectatomic/libpod/cmd/podman/batchcontainer" + "github.com/projectatomic/libpod/cmd/podman/varlink" + "github.com/projectatomic/libpod/libpod" +) + +// CreatePod ... +func (i *LibpodAPI) CreatePod(call iopodman.VarlinkCall, name, cgroupParent string, labels map[string]string) error { + var options []libpod.PodCreateOption + if cgroupParent != "" { + options = append(options, libpod.WithPodCgroupParent(cgroupParent)) + } + if len(labels) > 0 { + options = append(options, libpod.WithPodLabels(labels)) + } + if name != "" { + options = append(options, libpod.WithPodName(name)) + } + options = append(options, libpod.WithPodCgroups()) + + pod, err := i.Runtime.NewPod(options...) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + return call.ReplyCreatePod(pod.ID()) +} + +// ListPods ... +func (i *LibpodAPI) ListPods(call iopodman.VarlinkCall) error { + var ( + listPods []iopodman.ListPodData + ) + + pods, err := i.Runtime.GetAllPods() + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + opts := batchcontainer.PsOptions{} + for _, pod := range pods { + listPod, err := makeListPod(pod, opts) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + listPods = append(listPods, listPod) + } + return call.ReplyListPods(listPods) +} + +// GetPod ... +func (i *LibpodAPI) GetPod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + opts := batchcontainer.PsOptions{} + + listPod, err := makeListPod(pod, opts) + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + + return call.ReplyGetPod(listPod) +} + +// InspectPod ... +func (i *LibpodAPI) InspectPod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + inspectData, err := pod.Inspect() + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + b, err := json.Marshal(&inspectData) + if err != nil { + return call.ReplyErrorOccurred("unable to serialize") + } + return call.ReplyInspectPod(string(b)) +} + +// StartPod ... +func (i *LibpodAPI) StartPod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + ctrErrs, err := pod.Start(getContext()) + if err != nil && ctrErrs == nil { + return call.ReplyErrorOccurred(err.Error()) + } + if ctrErrs != nil { + containerErrs := make([]string, len(ctrErrs)) + for ctr := range ctrErrs { + containerErrs = append(containerErrs, ctr) + } + return call.ReplyPodContainerError(pod.ID(), containerErrs) + } + + return call.ReplyStartPod(pod.ID()) +} + +// StopPod ... +func (i *LibpodAPI) StopPod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + ctrErrs, err := pod.Stop(true) + if err != nil && ctrErrs == nil { + return call.ReplyErrorOccurred(err.Error()) + } + if ctrErrs != nil { + containerErrs := make([]string, len(ctrErrs)) + for ctr := range ctrErrs { + containerErrs = append(containerErrs, ctr) + } + return call.ReplyPodContainerError(pod.ID(), containerErrs) + } + + return call.ReplyStopPod(pod.ID()) +} + +// RestartPod ... +func (i *LibpodAPI) RestartPod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + ctrErrs, err := pod.Restart(getContext()) + if err != nil && ctrErrs == nil { + return call.ReplyErrorOccurred(err.Error()) + } + if ctrErrs != nil { + containerErrs := make([]string, len(ctrErrs)) + for ctr := range ctrErrs { + containerErrs = append(containerErrs, ctr) + } + return call.ReplyPodContainerError(pod.ID(), containerErrs) + } + + return call.ReplyRestartPod(pod.ID()) +} + +// KillPod kills the running containers in a pod. If you want to use the default SIGTERM signal, +// just send a -1 for the signal arg. +func (i *LibpodAPI) KillPod(call iopodman.VarlinkCall, name string, signal int64) error { + killSignal := uint(syscall.SIGTERM) + if signal != -1 { + killSignal = uint(signal) + } + + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + ctrErrs, err := pod.Kill(killSignal) + if err != nil && ctrErrs == nil { + return call.ReplyErrorOccurred(err.Error()) + } + if ctrErrs != nil { + containerErrs := make([]string, len(ctrErrs)) + for ctr := range ctrErrs { + containerErrs = append(containerErrs, ctr) + } + return call.ReplyPodContainerError(pod.ID(), containerErrs) + } + + return call.ReplyKillPod(pod.ID()) +} + +// PausePod ... +func (i *LibpodAPI) PausePod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + ctrErrs, err := pod.Pause() + if err != nil && ctrErrs == nil { + return call.ReplyErrorOccurred(err.Error()) + } + if ctrErrs != nil { + containerErrs := make([]string, len(ctrErrs)) + for ctr := range ctrErrs { + containerErrs = append(containerErrs, ctr) + } + return call.ReplyPodContainerError(pod.ID(), containerErrs) + } + + return call.ReplyPausePod(pod.ID()) +} + +// UnpausePod ... +func (i *LibpodAPI) UnpausePod(call iopodman.VarlinkCall, name string) error { + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + ctrErrs, err := pod.Unpause() + if err != nil && ctrErrs == nil { + return call.ReplyErrorOccurred(err.Error()) + } + if ctrErrs != nil { + containerErrs := make([]string, len(ctrErrs)) + for ctr := range ctrErrs { + containerErrs = append(containerErrs, ctr) + } + return call.ReplyPodContainerError(pod.ID(), containerErrs) + } + + return call.ReplyUnpausePod(pod.ID()) +} + +// RemovePod ... +func (i *LibpodAPI) RemovePod(call iopodman.VarlinkCall, name string, force bool) error { + ctx := getContext() + pod, err := i.Runtime.LookupPod(name) + if err != nil { + return call.ReplyPodNotFound(name) + } + if err = i.Runtime.RemovePod(ctx, pod, force, force); err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + + return call.ReplyRemovePod(pod.ID()) +} diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go index b33e43f96..74afabd0f 100644 --- a/pkg/varlinkapi/util.go +++ b/pkg/varlinkapi/util.go @@ -77,3 +77,43 @@ func makeListContainer(containerID string, batchInfo batchcontainer.BatchContain } return lc } + +func makeListPodContainers(containerID string, batchInfo batchcontainer.BatchContainerStruct) iopodman.ListPodContainerInfo { + lc := iopodman.ListPodContainerInfo{ + Id: containerID, + Status: batchInfo.ConState.String(), + Name: batchInfo.ConConfig.Name, + } + return lc +} + +func makeListPod(pod *libpod.Pod, batchInfo batchcontainer.PsOptions) (iopodman.ListPodData, error) { + var listPodsContainers []iopodman.ListPodContainerInfo + var errPodData = iopodman.ListPodData{} + status, err := pod.Status() + if err != nil { + return errPodData, err + } + containers, err := pod.AllContainers() + if err != nil { + return errPodData, err + } + for _, ctr := range containers { + batchInfo, err := batchcontainer.BatchContainerOp(ctr, batchInfo) + if err != nil { + return errPodData, err + } + + listPodsContainers = append(listPodsContainers, makeListPodContainers(ctr.ID(), batchInfo)) + } + listPod := iopodman.ListPodData{ + Createdat: pod.CreatedTime().String(), + Id: pod.ID(), + Name: pod.Name(), + Status: status, + Cgroup: pod.CgroupParent(), + Numberofcontainers: strconv.Itoa(len(listPodsContainers)), + Containersinfo: listPodsContainers, + } + return listPod, nil +} |