Files
Valentin Rothberg 8489dc4345 move go module to v2
With the advent of Podman 2.0.0 we crossed the magical barrier of go
modules.  While we were able to continue importing all packages inside
of the project, the project could not be vendored anymore from the
outside.

Move the go module to new major version and change all imports to
`github.com/containers/libpod/v2`.  The renaming of the imports
was done via `gomove` [1].

[1] https://github.com/KSubedi/gomove

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
2020-07-06 15:50:12 +02:00

238 lines
6.3 KiB
Go

// +build varlink
package varlinkapi
import (
"context"
"strconv"
"strings"
"time"
"github.com/containers/buildah"
"github.com/containers/libpod/v2/libpod"
"github.com/containers/libpod/v2/libpod/define"
"github.com/containers/libpod/v2/pkg/channelwriter"
iopodman "github.com/containers/libpod/v2/pkg/varlink"
"github.com/containers/storage/pkg/archive"
)
// getContext returns a non-nil, empty context
func getContext() context.Context {
return context.TODO()
}
func makeListContainer(containerID string, batchInfo BatchContainerStruct) iopodman.Container {
var (
mounts []iopodman.ContainerMount
ports []iopodman.ContainerPortMappings
)
ns := GetNamespaces(batchInfo.Pid)
for _, mount := range batchInfo.ConConfig.Spec.Mounts {
m := iopodman.ContainerMount{
Destination: mount.Destination,
Type: mount.Type,
Source: mount.Source,
Options: mount.Options,
}
mounts = append(mounts, m)
}
for _, pm := range batchInfo.ConConfig.PortMappings {
p := iopodman.ContainerPortMappings{
Host_port: strconv.Itoa(int(pm.HostPort)),
Host_ip: pm.HostIP,
Protocol: pm.Protocol,
Container_port: strconv.Itoa(int(pm.ContainerPort)),
}
ports = append(ports, p)
}
// If we find this needs to be done for other container endpoints, we should
// convert this to a separate function or a generic map from struct function.
namespace := iopodman.ContainerNameSpace{
User: ns.User,
Uts: ns.UTS,
Pidns: ns.PIDNS,
Pid: ns.PID,
Cgroup: ns.Cgroup,
Net: ns.NET,
Mnt: ns.MNT,
Ipc: ns.IPC,
}
lc := iopodman.Container{
Id: containerID,
Image: batchInfo.ConConfig.RootfsImageName,
Imageid: batchInfo.ConConfig.RootfsImageID,
Command: batchInfo.ConConfig.Spec.Process.Args,
Createdat: batchInfo.ConConfig.CreatedTime.Format(time.RFC3339),
Runningfor: time.Since(batchInfo.ConConfig.CreatedTime).String(),
Status: batchInfo.ConState.String(),
Ports: ports,
Names: batchInfo.ConConfig.Name,
Labels: batchInfo.ConConfig.Labels,
Mounts: mounts,
Containerrunning: batchInfo.ConState == define.ContainerStateRunning,
Namespaces: namespace,
}
if batchInfo.Size != nil {
lc.Rootfssize = batchInfo.Size.RootFsSize
lc.Rwsize = batchInfo.Size.RwSize
}
return lc
}
func makeListPodContainers(containerID string, batchInfo BatchContainerStruct) iopodman.ListPodContainerInfo {
lc := iopodman.ListPodContainerInfo{
Id: containerID,
Status: batchInfo.ConState.String(),
Name: batchInfo.ConConfig.Name,
}
return lc
}
func makeListPod(pod *libpod.Pod, batchInfo PsOptions) (iopodman.ListPodData, error) {
var listPodsContainers []iopodman.ListPodContainerInfo
var errPodData = iopodman.ListPodData{}
status, err := pod.GetPodStatus()
if err != nil {
return errPodData, err
}
containers, err := pod.AllContainers()
if err != nil {
return errPodData, err
}
for _, ctr := range containers {
batchInfo, err := BatchContainerOp(ctr, batchInfo)
if err != nil {
return errPodData, err
}
listPodsContainers = append(listPodsContainers, makeListPodContainers(ctr.ID(), batchInfo))
}
listPod := iopodman.ListPodData{
Createdat: pod.CreatedTime().Format(time.RFC3339),
Id: pod.ID(),
Name: pod.Name(),
Status: status,
Cgroup: pod.CgroupParent(),
Numberofcontainers: strconv.Itoa(len(listPodsContainers)),
Containersinfo: listPodsContainers,
}
return listPod, nil
}
func handlePodCall(call iopodman.VarlinkCall, pod *libpod.Pod, ctrErrs map[string]error, err error) error {
if err != nil && ctrErrs == nil {
return call.ReplyErrorOccurred(err.Error())
}
if ctrErrs != nil {
containerErrs := make([]iopodman.PodContainerErrorData, len(ctrErrs))
for ctr, reason := range ctrErrs {
ctrErr := iopodman.PodContainerErrorData{Containerid: ctr, Reason: reason.Error()}
containerErrs = append(containerErrs, ctrErr)
}
return call.ReplyPodContainerError(pod.ID(), containerErrs)
}
return nil
}
func stringCompressionToArchiveType(s string) archive.Compression {
switch strings.ToUpper(s) {
case "BZIP2":
return archive.Bzip2
case "GZIP":
return archive.Gzip
case "XZ":
return archive.Xz
}
return archive.Uncompressed
}
func stringPullPolicyToType(s string) buildah.PullPolicy {
switch strings.ToUpper(s) {
case "PULLIFMISSING":
return buildah.PullIfMissing
case "PULLALWAYS":
return buildah.PullAlways
case "PULLNEVER":
return buildah.PullNever
}
return buildah.PullIfMissing
}
func derefBool(inBool *bool) bool {
if inBool == nil {
return false
}
return *inBool
}
func derefString(in *string) string {
if in == nil {
return ""
}
return *in
}
func makePsOpts(inOpts iopodman.PsOpts) PsOptions {
last := 0
if inOpts.Last != nil {
lastT := *inOpts.Last
last = int(lastT)
}
return PsOptions{
All: inOpts.All,
Last: last,
Latest: derefBool(inOpts.Latest),
NoTrunc: derefBool(inOpts.NoTrunc),
Pod: derefBool(inOpts.Pod),
Size: derefBool(inOpts.Size),
Sort: derefString(inOpts.Sort),
Namespace: true,
Sync: derefBool(inOpts.Sync),
}
}
// forwardOutput is a helper method for varlink endpoints that employ both more and without
// more. it is capable of sending updates as the output writer gets them or append them
// all to a log. the chan error is the error from the libpod call so we can honor
// and error event in that case.
func forwardOutput(log []string, c chan error, wantsMore bool, output *channelwriter.Writer, reply func(br iopodman.MoreResponse) error) ([]string, error) {
done := false
for {
select {
// We need to check if the libpod func being called has returned an
// error yet
case err := <-c:
if err != nil {
return nil, err
}
done = true
// if no error is found, we pull what we can from the log writer and
// append it to log string slice
case line := <-output.ByteChannel:
log = append(log, string(line))
// If the end point is being used in more mode, send what we have
if wantsMore {
br := iopodman.MoreResponse{
Logs: log,
}
if err := reply(br); err != nil {
return nil, err
}
// "reset" the log to empty because we are sending what we
// get as we get it
log = []string{}
}
}
if done {
break
}
}
return log, nil
}