summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/containers.go113
-rw-r--r--pkg/adapter/containers_remote.go34
-rw-r--r--pkg/adapter/info_remote.go14
-rw-r--r--pkg/adapter/pods.go302
-rw-r--r--pkg/adapter/pods_remote.go27
-rw-r--r--pkg/adapter/runtime.go28
-rw-r--r--pkg/adapter/runtime_remote.go18
-rw-r--r--pkg/cgroups/cgroups.go2
-rw-r--r--pkg/cgroups/cpu.go2
-rw-r--r--pkg/hooks/0.1.0/hook.go2
-rw-r--r--pkg/hooks/1.0.0/when_test.go2
-rw-r--r--pkg/logs/logs.go5
-rw-r--r--pkg/rootless/rootless_linux.c14
-rw-r--r--pkg/rootless/rootless_linux.go90
-rw-r--r--pkg/rootless/rootless_unsupported.go19
-rw-r--r--pkg/spec/config_linux.go25
-rw-r--r--pkg/spec/config_linux_cgo.go34
-rw-r--r--pkg/spec/config_linux_nocgo.go11
-rw-r--r--pkg/sysinfo/sysinfo_test.go2
-rw-r--r--pkg/systemdgen/systemdgen.go28
-rw-r--r--pkg/systemdgen/systemdgen_test.go18
-rw-r--r--pkg/tracing/tracing.go6
-rw-r--r--pkg/trust/trust.go2
-rw-r--r--pkg/util/utils.go11
-rw-r--r--pkg/util/utils_darwin.go11
-rw-r--r--pkg/util/utils_linux.go11
-rw-r--r--pkg/util/utils_supported.go5
-rw-r--r--pkg/util/utils_windows.go16
-rw-r--r--pkg/varlinkapi/attach.go4
-rw-r--r--pkg/varlinkapi/containers.go21
-rw-r--r--pkg/varlinkapi/system.go6
-rw-r--r--pkg/varlinkapi/util.go3
32 files changed, 741 insertions, 145 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 5751a9c3a..0ea89a72c 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -20,9 +20,11 @@ import (
"github.com/containers/image/manifest"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
+ "github.com/containers/libpod/cmd/podman/shared/parse"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/libpod/image"
+ "github.com/containers/libpod/libpod/logs"
"github.com/containers/libpod/pkg/adapter/shortcuts"
"github.com/containers/libpod/pkg/systemdgen"
"github.com/containers/psgo"
@@ -242,7 +244,7 @@ func (r *LocalRuntime) UmountRootFilesystems(ctx context.Context, cli *cliconfig
logrus.Debugf("Error umounting container %s state: %s", ctr.ID(), err.Error())
continue
}
- if state == libpod.ContainerStateRunning {
+ if state == define.ContainerStateRunning {
logrus.Debugf("Error umounting container %s, is running", ctr.ID())
continue
}
@@ -283,13 +285,14 @@ func (r *LocalRuntime) WaitOnContainers(ctx context.Context, cli *cliconfig.Wait
}
// Log logs one or more containers
-func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *libpod.LogOptions) error {
+func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *logs.LogOptions) error {
+
var wg sync.WaitGroup
options.WaitGroup = &wg
if len(c.InputArgs) > 1 {
options.Multi = true
}
- logChannel := make(chan *libpod.LogLine, int(c.Tail)*len(c.InputArgs)+1)
+ logChannel := make(chan *logs.LogLine, int(c.Tail)*len(c.InputArgs)+1)
containers, err := shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime)
if err != nil {
return err
@@ -381,8 +384,18 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
}
}
}
+
+ config, err := r.Runtime.GetConfig()
+ if err != nil {
+ return exitCode, err
+ }
+ detachKeys := c.String("detach-keys")
+ if detachKeys == "" {
+ detachKeys = config.DetachKeys
+ }
+
// if the container was created as part of a pod, also start its dependencies, if any.
- if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, c.String("detach-keys"), c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
+ if err := StartAttachCtr(ctx, ctr, outputStream, errorStream, inputStream, detachKeys, c.Bool("sig-proxy"), true, c.IsSet("pod")); err != nil {
// We've manually detached from the container
// Do not perform cleanup, or wait for container exit code
// Just exit immediately
@@ -407,10 +420,6 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode
if errors.Cause(err) == define.ErrNoSuchCtr {
// The container may have been removed
// Go looking for an exit file
- config, err := r.Runtime.GetConfig()
- if err != nil {
- return exitCode, err
- }
ctrExitCode, err := ReadExitFile(config.TmpDir, ctr.ID())
if err != nil {
logrus.Errorf("Cannot get exit code: %v", err)
@@ -488,7 +497,7 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er
if err != nil {
return errors.Wrapf(err, "unable to determine state of %s", ctr.ID())
}
- if conState != libpod.ContainerStateRunning {
+ if conState != define.ContainerStateRunning {
return errors.Errorf("you can only attach to running containers")
}
@@ -539,16 +548,23 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error {
}
// Restore one or more containers
-func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues, options libpod.ContainerCheckpointOptions) error {
+func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues) error {
var (
containers []*libpod.Container
err, lastError error
filterFuncs []libpod.ContainerFilter
)
+ options := libpod.ContainerCheckpointOptions{
+ Keep: c.Keep,
+ TCPEstablished: c.TcpEstablished,
+ TargetFile: c.Import,
+ Name: c.Name,
+ }
+
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
state, _ := c.State()
- return state == libpod.ContainerStateExited
+ return state == define.ContainerStateExited
})
if c.Import != "" {
@@ -606,7 +622,7 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
return exitCode, errors.Wrapf(err, "unable to get container state")
}
- ctrRunning := ctrState == libpod.ContainerStateRunning
+ ctrRunning := ctrState == define.ContainerStateRunning
if c.Attach {
inputStream := os.Stdin
@@ -732,7 +748,7 @@ func (r *LocalRuntime) UnpauseContainers(ctx context.Context, cli *cliconfig.Unp
var filterFuncs []libpod.ContainerFilter
filterFuncs = append(filterFuncs, func(c *libpod.Container) bool {
state, _ := c.State()
- return state == libpod.ContainerStatePaused
+ return state == define.ContainerStatePaused
})
ctrs, err = r.GetContainers(filterFuncs...)
} else {
@@ -929,7 +945,7 @@ func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([
if c.PodID() != "" {
return false
}
- if state == libpod.ContainerStateStopped || state == libpod.ContainerStateExited {
+ if state == define.ContainerStateStopped || state == define.ContainerStateExited {
return true
}
return false
@@ -1020,7 +1036,7 @@ func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
//Convert libpod containers to adapter Containers
for _, con := range containers {
- if state, _ := con.State(); state != libpod.ContainerStateRunning {
+ if state, _ := con.State(); state != define.ContainerStateRunning {
continue
}
portContainers = append(portContainers, &Container{con})
@@ -1042,7 +1058,14 @@ func (r *LocalRuntime) GenerateSystemd(c *cliconfig.GenerateSystemdValues) (stri
if c.Name {
name = ctr.Name()
}
- return systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), c.RestartPolicy, ctr.Config().StaticDir, timeout)
+
+ config := ctr.Config()
+ conmonPidFile := config.ConmonPidFile
+ if conmonPidFile == "" {
+ return "", errors.Errorf("conmon PID file path is empty, try to recreate the container with --conmon-pidfile flag")
+ }
+
+ return systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), c.RestartPolicy, conmonPidFile, timeout)
}
// GetNamespaces returns namespace information about a container for PS
@@ -1101,3 +1124,61 @@ func (r *LocalRuntime) Commit(ctx context.Context, c *cliconfig.CommitValues, co
}
return newImage.ID(), nil
}
+
+// Exec a command in a container
+func (r *LocalRuntime) Exec(c *cliconfig.ExecValues, cmd []string) error {
+ var ctr *Container
+ var err error
+
+ if c.Latest {
+ ctr, err = r.GetLatestContainer()
+ } else {
+ ctr, err = r.LookupContainer(c.InputArgs[0])
+ }
+ if err != nil {
+ return errors.Wrapf(err, "unable to exec into %s", c.InputArgs[0])
+ }
+
+ if c.PreserveFDs > 0 {
+ entries, err := ioutil.ReadDir("/proc/self/fd")
+ if err != nil {
+ return errors.Wrapf(err, "unable to read /proc/self/fd")
+ }
+ m := make(map[int]bool)
+ for _, e := range entries {
+ i, err := strconv.Atoi(e.Name())
+ if err != nil {
+ if err != nil {
+ return errors.Wrapf(err, "cannot parse %s in /proc/self/fd", e.Name())
+ }
+ }
+ m[i] = true
+ }
+ for i := 3; i < 3+c.PreserveFDs; i++ {
+ if _, found := m[i]; !found {
+ return errors.New("invalid --preserve-fds=N specified. Not enough FDs available")
+ }
+ }
+ }
+
+ // ENVIRONMENT VARIABLES
+ env := map[string]string{}
+
+ if err := parse.ReadKVStrings(env, []string{}, c.Env); err != nil {
+ return errors.Wrapf(err, "unable to process environment variables")
+ }
+ envs := []string{}
+ for k, v := range env {
+ envs = append(envs, fmt.Sprintf("%s=%s", k, v))
+ }
+
+ streams := new(libpod.AttachStreams)
+ streams.OutputStream = os.Stdout
+ streams.ErrorStream = os.Stderr
+ streams.InputStream = os.Stdin
+ streams.AttachOutput = true
+ streams.AttachError = true
+ streams.AttachInput = true
+
+ return ctr.Exec(c.Tty, c.Privileged, envs, cmd, c.User, c.Workdir, streams, c.PreserveFDs)
+}
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index c52dc1d7a..5836d0788 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -17,6 +17,7 @@ import (
iopodman "github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/libpod/logs"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
"github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/docker/pkg/term"
@@ -411,8 +412,8 @@ func BatchContainerOp(ctr *Container, opts shared.PsOptions) (shared.BatchContai
return bcs, nil
}
-// Logs one or more containers over a varlink connection
-func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *libpod.LogOptions) error {
+// Log one or more containers over a varlink connection
+func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *logs.LogOptions) error {
// GetContainersLogs
reply, err := iopodman.GetContainersLogs().Send(r.Conn, uint64(varlink.More), c.InputArgs, c.Follow, c.Latest, options.Since.Format(time.RFC3339Nano), int64(c.Tail), c.Timestamps)
if err != nil {
@@ -434,7 +435,7 @@ func (r *LocalRuntime) Log(c *cliconfig.LogsValues, options *libpod.LogOptions)
if err != nil {
return errors.Wrapf(err, "unable to parse time of log %s", log.Time)
}
- logLine := libpod.LogLine{
+ logLine := logs.LogLine{
Device: log.Device,
ParseLogType: log.ParseLogType,
Time: lTime,
@@ -516,7 +517,7 @@ func (r *LocalRuntime) Ps(c *cliconfig.PsValues, opts shared.PsOptions) ([]share
RootFsSize: ctr.RootFsSize,
RwSize: ctr.RwSize,
}
- state, err := libpod.StringToContainerStatus(ctr.State)
+ state, err := define.StringToContainerStatus(ctr.State)
if err != nil {
return nil, err
}
@@ -645,7 +646,7 @@ func (r *LocalRuntime) Attach(ctx context.Context, c *cliconfig.AttachValues) er
if err != nil {
return nil
}
- if ctr.state.State != libpod.ContainerStateRunning {
+ if ctr.state.State != define.ContainerStateRunning {
return errors.New("you can only attach to running containers")
}
inputStream := os.Stdin
@@ -682,7 +683,7 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error {
if err != nil {
return err
}
- if ctr.state.State == libpod.ContainerStateRunning {
+ if ctr.state.State == define.ContainerStateRunning {
runningIds = append(runningIds, id)
}
}
@@ -703,7 +704,7 @@ func (r *LocalRuntime) Checkpoint(c *cliconfig.CheckpointValues) error {
}
// Restore one or more containers
-func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues, options libpod.ContainerCheckpointOptions) error {
+func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues) error {
if c.Import != "" {
return errors.New("the remote client does not support importing checkpoints")
}
@@ -722,7 +723,7 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues,
if err != nil {
return err
}
- if ctr.state.State != libpod.ContainerStateRunning {
+ if ctr.state.State != define.ContainerStateRunning {
exitedIDs = append(exitedIDs, id)
}
}
@@ -730,7 +731,7 @@ func (r *LocalRuntime) Restore(ctx context.Context, c *cliconfig.RestoreValues,
}
for _, id := range ids {
- if _, err := iopodman.ContainerRestore().Call(r.Conn, id, options.Keep, options.TCPEstablished); err != nil {
+ if _, err := iopodman.ContainerRestore().Call(r.Conn, id, c.Keep, c.TcpEstablished); err != nil {
if lastError != nil {
fmt.Fprintln(os.Stderr, lastError)
}
@@ -797,7 +798,7 @@ func (r *LocalRuntime) PauseContainers(ctx context.Context, cli *cliconfig.Pause
)
if cli.All {
- filters := []string{libpod.ContainerStateRunning.String()}
+ filters := []string{define.ContainerStateRunning.String()}
ctrs, err = r.LookupContainersWithStatus(filters)
} else {
ctrs, err = r.LookupContainers(cli.InputArgs)
@@ -834,7 +835,7 @@ func (r *LocalRuntime) UnpauseContainers(ctx context.Context, cli *cliconfig.Unp
logrus.Debugf("Setting maximum rm workers to %d", maxWorkers)
if cli.All {
- filters := []string{libpod.ContainerStatePaused.String()}
+ filters := []string{define.ContainerStatePaused.String()}
ctrs, err = r.LookupContainersWithStatus(filters)
} else {
ctrs, err = r.LookupContainers(cli.InputArgs)
@@ -873,7 +874,7 @@ func (r *LocalRuntime) Restart(ctx context.Context, c *cliconfig.RestartValues)
}
restartContainers = append(restartContainers, lastCtr)
} else if c.Running {
- containers, err = r.LookupContainersWithStatus([]string{libpod.ContainerStateRunning.String()})
+ containers, err = r.LookupContainersWithStatus([]string{define.ContainerStateRunning.String()})
if err != nil {
return nil, nil, err
}
@@ -941,7 +942,7 @@ func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([
)
logrus.Debugf("Setting maximum rm workers to %d", maxWorkers)
- filters := []string{libpod.ContainerStateExited.String()}
+ filters := []string{define.ContainerStateExited.String()}
ctrs, err = r.LookupContainersWithStatus(filters)
if err != nil {
return ok, failures, err
@@ -974,7 +975,7 @@ func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
containers, err = r.GetContainersByContext(false, c.Latest, c.InputArgs)
} else {
// we need to only use running containers if all
- filters := []string{libpod.ContainerStateRunning.String()}
+ filters := []string{define.ContainerStateRunning.String()}
containers, err = r.LookupContainersWithStatus(filters)
}
if err != nil {
@@ -1025,3 +1026,8 @@ func (r *LocalRuntime) Commit(ctx context.Context, c *cliconfig.CommitValues, co
}
return iid, nil
}
+
+// Exec executes a container in a running container
+func (r *LocalRuntime) Exec(c *cliconfig.ExecValues, cmd []string) error {
+ return define.ErrNotImplemented
+}
diff --git a/pkg/adapter/info_remote.go b/pkg/adapter/info_remote.go
index 3b2d02a5a..3170e5b3d 100644
--- a/pkg/adapter/info_remote.go
+++ b/pkg/adapter/info_remote.go
@@ -4,16 +4,16 @@ package adapter
import (
"encoding/json"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/cmd/podman/varlink"
- "github.com/containers/libpod/libpod"
)
// Info returns information for the host system and its components
-func (r RemoteRuntime) Info() ([]libpod.InfoData, error) {
+func (r RemoteRuntime) Info() ([]define.InfoData, error) {
// TODO the varlink implementation for info should be updated to match the output for regular info
var (
- reply []libpod.InfoData
+ reply []define.InfoData
hostInfo map[string]interface{}
store map[string]interface{}
)
@@ -43,9 +43,9 @@ func (r RemoteRuntime) Info() ([]libpod.InfoData, error) {
insecureRegistries["registries"] = info.Insecure_registries
// Add everything to the reply
- reply = append(reply, libpod.InfoData{Type: "host", Data: hostInfo})
- reply = append(reply, libpod.InfoData{Type: "registries", Data: registries})
- reply = append(reply, libpod.InfoData{Type: "insecure registries", Data: insecureRegistries})
- reply = append(reply, libpod.InfoData{Type: "store", Data: store})
+ reply = append(reply, define.InfoData{Type: "host", Data: hostInfo})
+ reply = append(reply, define.InfoData{Type: "registries", Data: registries})
+ reply = append(reply, define.InfoData{Type: "insecure registries", Data: insecureRegistries})
+ reply = append(reply, define.InfoData{Type: "store", Data: store})
return reply, nil
}
diff --git a/pkg/adapter/pods.go b/pkg/adapter/pods.go
index bb7d9cce6..a28e1ab4b 100644
--- a/pkg/adapter/pods.go
+++ b/pkg/adapter/pods.go
@@ -4,14 +4,33 @@ package adapter
import (
"context"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
"strings"
+ "github.com/containers/image/types"
"github.com/containers/libpod/cmd/podman/cliconfig"
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/image"
"github.com/containers/libpod/pkg/adapter/shortcuts"
+ ns "github.com/containers/libpod/pkg/namespaces"
+ createconfig "github.com/containers/libpod/pkg/spec"
+ "github.com/containers/storage"
+ "github.com/cri-o/ocicni/pkg/ocicni"
+ "github.com/ghodss/yaml"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ v1 "k8s.io/api/core/v1"
+)
+
+const (
+ // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
+ createDirectoryPermission = 0755
+ // https://kubernetes.io/docs/concepts/storage/volumes/#hostpath
+ createFilePermission = 0644
)
// PodContainerStats is struct containing an adapter Pod and a libpod
@@ -420,3 +439,286 @@ func (r *LocalRuntime) GetStatPods(c *cliconfig.PodStatsValues) ([]*Pod, error)
}
return adapterPods, nil
}
+
+// PlayKubeYAML creates pods and containers from a kube YAML file
+func (r *LocalRuntime) PlayKubeYAML(ctx context.Context, c *cliconfig.KubePlayValues, yamlFile string) (*Pod, error) {
+ var (
+ containers []*libpod.Container
+ pod *libpod.Pod
+ podOptions []libpod.PodCreateOption
+ podYAML v1.Pod
+ registryCreds *types.DockerAuthConfig
+ writer io.Writer
+ )
+
+ content, err := ioutil.ReadFile(yamlFile)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := yaml.Unmarshal(content, &podYAML); err != nil {
+ return nil, errors.Wrapf(err, "unable to read %s as YAML", yamlFile)
+ }
+
+ // check for name collision between pod and container
+ podName := podYAML.ObjectMeta.Name
+ for _, n := range podYAML.Spec.Containers {
+ if n.Name == podName {
+ fmt.Printf("a container exists with the same name (%s) as the pod in your YAML file; changing pod name to %s_pod\n", podName, podName)
+ podName = fmt.Sprintf("%s_pod", podName)
+ }
+ }
+
+ podOptions = append(podOptions, libpod.WithInfraContainer())
+ podOptions = append(podOptions, libpod.WithPodName(podName))
+ // TODO for now we just used the default kernel namespaces; we need to add/subtract this from yaml
+
+ nsOptions, err := shared.GetNamespaceOptions(strings.Split(shared.DefaultKernelNamespaces, ","))
+ if err != nil {
+ return nil, err
+ }
+ podOptions = append(podOptions, nsOptions...)
+ podPorts := getPodPorts(podYAML.Spec.Containers)
+ podOptions = append(podOptions, libpod.WithInfraContainerPorts(podPorts))
+
+ // Create the Pod
+ pod, err = r.NewPod(ctx, podOptions...)
+ if err != nil {
+ return nil, err
+ }
+
+ podInfraID, err := pod.InfraContainerID()
+ if err != nil {
+ return nil, err
+ }
+
+ namespaces := map[string]string{
+ // Disabled during code review per mheon
+ //"pid": fmt.Sprintf("container:%s", podInfraID),
+ "net": fmt.Sprintf("container:%s", podInfraID),
+ "user": fmt.Sprintf("container:%s", podInfraID),
+ "ipc": fmt.Sprintf("container:%s", podInfraID),
+ "uts": fmt.Sprintf("container:%s", podInfraID),
+ }
+ if !c.Quiet {
+ writer = os.Stderr
+ }
+
+ dockerRegistryOptions := image.DockerRegistryOptions{
+ DockerRegistryCreds: registryCreds,
+ DockerCertPath: c.CertDir,
+ }
+ if c.Flag("tls-verify").Changed {
+ dockerRegistryOptions.DockerInsecureSkipTLSVerify = types.NewOptionalBool(!c.TlsVerify)
+ }
+
+ // map from name to mount point
+ volumes := make(map[string]string)
+ for _, volume := range podYAML.Spec.Volumes {
+ hostPath := volume.VolumeSource.HostPath
+ if hostPath == nil {
+ return nil, errors.Errorf("HostPath is currently the only supported VolumeSource")
+ }
+ if hostPath.Type != nil {
+ switch *hostPath.Type {
+ case v1.HostPathDirectoryOrCreate:
+ if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
+ if err := os.Mkdir(hostPath.Path, createDirectoryPermission); err != nil {
+ return nil, errors.Errorf("Error creating HostPath %s at %s", volume.Name, hostPath.Path)
+ }
+ }
+ // unconditionally label a newly created volume as private
+ if err := libpod.LabelVolumePath(hostPath.Path, false); err != nil {
+ return nil, errors.Wrapf(err, "Error giving %s a label", hostPath.Path)
+ }
+ break
+ case v1.HostPathFileOrCreate:
+ if _, err := os.Stat(hostPath.Path); os.IsNotExist(err) {
+ f, err := os.OpenFile(hostPath.Path, os.O_RDONLY|os.O_CREATE, createFilePermission)
+ if err != nil {
+ return nil, errors.Errorf("Error creating HostPath %s at %s", volume.Name, hostPath.Path)
+ }
+ if err := f.Close(); err != nil {
+ logrus.Warnf("Error in closing newly created HostPath file: %v", err)
+ }
+ }
+ // unconditionally label a newly created volume as private
+ if err := libpod.LabelVolumePath(hostPath.Path, false); err != nil {
+ return nil, errors.Wrapf(err, "Error giving %s a label", hostPath.Path)
+ }
+ break
+ case v1.HostPathDirectory:
+ case v1.HostPathFile:
+ case v1.HostPathUnset:
+ // do nothing here because we will verify the path exists in validateVolumeHostDir
+ break
+ default:
+ return nil, errors.Errorf("Directories are the only supported HostPath type")
+ }
+ }
+
+ if err := createconfig.ValidateVolumeHostDir(hostPath.Path); err != nil {
+ return nil, errors.Wrapf(err, "Error in parsing HostPath in YAML")
+ }
+ volumes[volume.Name] = hostPath.Path
+ }
+
+ for _, container := range podYAML.Spec.Containers {
+ newImage, err := r.ImageRuntime().New(ctx, container.Image, c.SignaturePolicy, c.Authfile, writer, &dockerRegistryOptions, image.SigningOptions{}, false, nil)
+ if err != nil {
+ return nil, err
+ }
+ createConfig, err := kubeContainerToCreateConfig(ctx, container, r.Runtime, newImage, namespaces, volumes, pod.ID())
+ if err != nil {
+ return nil, err
+ }
+ ctr, err := shared.CreateContainerFromCreateConfig(r.Runtime, createConfig, ctx, pod)
+ if err != nil {
+ return nil, err
+ }
+ containers = append(containers, ctr)
+ }
+
+ // start the containers
+ for _, ctr := range containers {
+ if err := ctr.Start(ctx, true); err != nil {
+ // Making this a hard failure here to avoid a mess
+ // the other containers are in created status
+ return nil, err
+ }
+ }
+
+ // We've now successfully converted this YAML into a pod
+ // print our pod and containers, signifying we succeeded
+ fmt.Printf("Pod:\n%s\n", pod.ID())
+ if len(containers) == 1 {
+ fmt.Printf("Container:\n")
+ }
+ if len(containers) > 1 {
+ fmt.Printf("Containers:\n")
+ }
+ for _, ctr := range containers {
+ fmt.Println(ctr.ID())
+ }
+
+ if err := playcleanup(ctx, r, pod, nil); err != nil {
+ logrus.Errorf("unable to remove pod %s after failing to play kube", pod.ID())
+ }
+ return nil, nil
+}
+
+func playcleanup(ctx context.Context, runtime *LocalRuntime, pod *libpod.Pod, err error) error {
+ if err != nil && pod != nil {
+ return runtime.RemovePod(ctx, pod, true, true)
+ }
+ return nil
+}
+
+// getPodPorts converts a slice of kube container descriptions to an
+// array of ocicni portmapping descriptions usable in libpod
+func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
+ var infraPorts []ocicni.PortMapping
+ for _, container := range containers {
+ for _, p := range container.Ports {
+ portBinding := ocicni.PortMapping{
+ HostPort: p.HostPort,
+ ContainerPort: p.ContainerPort,
+ Protocol: strings.ToLower(string(p.Protocol)),
+ }
+ if p.HostIP != "" {
+ logrus.Debug("HostIP on port bindings is not supported")
+ }
+ infraPorts = append(infraPorts, portBinding)
+ }
+ }
+ return infraPorts
+}
+
+// kubeContainerToCreateConfig takes a v1.Container and returns a createconfig describing a container
+func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container, runtime *libpod.Runtime, newImage *image.Image, namespaces map[string]string, volumes map[string]string, podID string) (*createconfig.CreateConfig, error) {
+ var (
+ containerConfig createconfig.CreateConfig
+ )
+
+ // The default for MemorySwappiness is -1, not 0
+ containerConfig.Resources.MemorySwappiness = -1
+
+ containerConfig.Image = containerYAML.Image
+ containerConfig.ImageID = newImage.ID()
+ containerConfig.Name = containerYAML.Name
+ containerConfig.Tty = containerYAML.TTY
+ containerConfig.WorkDir = containerYAML.WorkingDir
+
+ containerConfig.Pod = podID
+
+ imageData, _ := newImage.Inspect(ctx)
+
+ containerConfig.User = "0"
+ if imageData != nil {
+ containerConfig.User = imageData.Config.User
+ }
+
+ if containerConfig.SecurityOpts != nil {
+ if containerYAML.SecurityContext.ReadOnlyRootFilesystem != nil {
+ containerConfig.ReadOnlyRootfs = *containerYAML.SecurityContext.ReadOnlyRootFilesystem
+ }
+ if containerYAML.SecurityContext.Privileged != nil {
+ containerConfig.Privileged = *containerYAML.SecurityContext.Privileged
+ }
+
+ if containerYAML.SecurityContext.AllowPrivilegeEscalation != nil {
+ containerConfig.NoNewPrivs = !*containerYAML.SecurityContext.AllowPrivilegeEscalation
+ }
+ }
+
+ containerConfig.Command = []string{}
+ if imageData != nil && imageData.Config != nil {
+ containerConfig.Command = append(containerConfig.Command, imageData.Config.Entrypoint...)
+ }
+ if len(containerConfig.Command) != 0 {
+ containerConfig.Command = append(containerConfig.Command, containerYAML.Command...)
+ } else if imageData != nil && imageData.Config != nil {
+ containerConfig.Command = append(containerConfig.Command, imageData.Config.Cmd...)
+ }
+ if imageData != nil && len(containerConfig.Command) == 0 {
+ return nil, errors.Errorf("No command specified in container YAML or as CMD or ENTRYPOINT in this image for %s", containerConfig.Name)
+ }
+
+ containerConfig.StopSignal = 15
+
+ // If the user does not pass in ID mappings, just set to basics
+ if containerConfig.IDMappings == nil {
+ containerConfig.IDMappings = &storage.IDMappingOptions{}
+ }
+
+ containerConfig.NetMode = ns.NetworkMode(namespaces["net"])
+ containerConfig.IpcMode = ns.IpcMode(namespaces["ipc"])
+ containerConfig.UtsMode = ns.UTSMode(namespaces["uts"])
+ // disabled in code review per mheon
+ //containerConfig.PidMode = ns.PidMode(namespaces["pid"])
+ containerConfig.UsernsMode = ns.UsernsMode(namespaces["user"])
+ if len(containerConfig.WorkDir) == 0 {
+ containerConfig.WorkDir = "/"
+ }
+
+ // Set default environment variables and incorporate data from image, if necessary
+ envs := shared.EnvVariablesFromData(imageData)
+
+ // Environment Variables
+ for _, e := range containerYAML.Env {
+ envs[e.Name] = e.Value
+ }
+ containerConfig.Env = envs
+
+ for _, volume := range containerYAML.VolumeMounts {
+ hostPath, exists := volumes[volume.Name]
+ if !exists {
+ return nil, errors.Errorf("Volume mount %s specified for container but not configured in volumes", volume.Name)
+ }
+ if err := createconfig.ValidateVolumeCtrDir(volume.MountPath); err != nil {
+ return nil, errors.Wrapf(err, "error in parsing MountPath")
+ }
+ containerConfig.Volumes = append(containerConfig.Volumes, fmt.Sprintf("%s:%s", hostPath, volume.MountPath))
+ }
+ return &containerConfig, nil
+}
diff --git a/pkg/adapter/pods_remote.go b/pkg/adapter/pods_remote.go
index 125d057b0..0c62ac923 100644
--- a/pkg/adapter/pods_remote.go
+++ b/pkg/adapter/pods_remote.go
@@ -258,25 +258,25 @@ func (p *Pod) AllContainers() ([]*Container, error) {
}
// Status ...
-func (p *Pod) Status() (map[string]libpod.ContainerStatus, error) {
- ctrs := make(map[string]libpod.ContainerStatus)
+func (p *Pod) Status() (map[string]define.ContainerStatus, error) {
+ ctrs := make(map[string]define.ContainerStatus)
for _, i := range p.containers {
- var status libpod.ContainerStatus
+ var status define.ContainerStatus
switch i.State {
case "exited":
- status = libpod.ContainerStateExited
+ status = define.ContainerStateExited
case "stopped":
- status = libpod.ContainerStateStopped
+ status = define.ContainerStateStopped
case "running":
- status = libpod.ContainerStateRunning
+ status = define.ContainerStateRunning
case "paused":
- status = libpod.ContainerStatePaused
+ status = define.ContainerStatePaused
case "created":
- status = libpod.ContainerStateCreated
- case "configured":
- status = libpod.ContainerStateConfigured
+ status = define.ContainerStateCreated
+ case "define.red":
+ status = define.ContainerStateConfigured
default:
- status = libpod.ContainerStateUnknown
+ status = define.ContainerStateUnknown
}
ctrs[i.ID] = status
}
@@ -564,3 +564,8 @@ func (r *LocalRuntime) PrunePods(ctx context.Context, cli *cliconfig.PodPruneVal
}
return ok, failures, nil
}
+
+// PlayKubeYAML creates pods and containers from a kube YAML file
+func (r *LocalRuntime) PlayKubeYAML(ctx context.Context, c *cliconfig.KubePlayValues, yamlFile string) (*Pod, error) {
+ return nil, define.ErrNotImplemented
+}
diff --git a/pkg/adapter/runtime.go b/pkg/adapter/runtime.go
index 37ee1b737..8ef88f36b 100644
--- a/pkg/adapter/runtime.go
+++ b/pkg/adapter/runtime.go
@@ -5,6 +5,7 @@ package adapter
import (
"bufio"
"context"
+ "github.com/containers/libpod/libpod/define"
"io"
"io/ioutil"
"os"
@@ -57,12 +58,26 @@ type Volume struct {
// VolumeFilter is for filtering volumes on the client
type VolumeFilter func(*Volume) bool
+// GetRuntimeNoStore returns a localruntime struct wit an embedded runtime but
+// without a configured storage.
+func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
+ runtime, err := libpodruntime.GetRuntimeNoStore(ctx, c)
+ if err != nil {
+ return nil, err
+ }
+ return getRuntime(runtime)
+}
+
// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
runtime, err := libpodruntime.GetRuntime(ctx, c)
if err != nil {
return nil, err
}
+ return getRuntime(runtime)
+}
+
+func getRuntime(runtime *libpod.Runtime) (*LocalRuntime, error) {
return &LocalRuntime{
Runtime: runtime,
}, nil
@@ -313,8 +328,13 @@ func IsImageNotFound(err error) bool {
}
// HealthCheck is a wrapper to same named function in libpod
-func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) {
- return r.Runtime.HealthCheck(c.InputArgs[0])
+func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (string, error) {
+ output := "unhealthy"
+ status, err := r.Runtime.HealthCheck(c.InputArgs[0])
+ if status == libpod.HealthCheckSuccess {
+ output = "healthy"
+ }
+ return output, err
}
// Events is a wrapper to libpod to obtain libpod/podman events
@@ -395,8 +415,8 @@ func (r *LocalRuntime) GetPodsByStatus(statuses []string) ([]*libpod.Pod, error)
}
// GetVersion is an alias to satisfy interface{}
-func (r *LocalRuntime) GetVersion() (libpod.Version, error) {
- return libpod.GetVersion()
+func (r *LocalRuntime) GetVersion() (define.Version, error) {
+ return define.GetVersion()
}
// RemoteEndpoint resolve interface requirement
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 97e28e901..800ed7569 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -50,6 +50,12 @@ type LocalRuntime struct {
*RemoteRuntime
}
+// GetRuntimeNoStore returns a LocalRuntime struct with the actual runtime embedded in it
+// The nostore is ignored
+func GetRuntimeNoStore(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
+ return GetRuntime(ctx, c)
+}
+
// GetRuntime returns a LocalRuntime struct with the actual runtime embedded in it
func GetRuntime(ctx context.Context, c *cliconfig.PodmanCommand) (*LocalRuntime, error) {
var (
@@ -771,8 +777,8 @@ func IsImageNotFound(err error) bool {
}
// HealthCheck executes a container's healthcheck over a varlink connection
-func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (libpod.HealthCheckStatus, error) {
- return -1, define.ErrNotImplemented
+func (r *LocalRuntime) HealthCheck(c *cliconfig.HealthCheckValues) (string, error) {
+ return "", define.ErrNotImplemented
}
// Events monitors libpod/podman events over a varlink connection
@@ -907,22 +913,22 @@ func (r *LocalRuntime) GetContainersByContext(all bool, latest bool, namesOrIDs
}
// GetVersion returns version information from service
-func (r *LocalRuntime) GetVersion() (libpod.Version, error) {
+func (r *LocalRuntime) GetVersion() (define.Version, error) {
version, goVersion, gitCommit, built, osArch, apiVersion, err := iopodman.GetVersion().Call(r.Conn)
if err != nil {
- return libpod.Version{}, errors.Wrapf(err, "Unable to obtain server version information")
+ return define.Version{}, errors.Wrapf(err, "Unable to obtain server version information")
}
var buildTime int64
if built != "" {
t, err := time.Parse(time.RFC3339, built)
if err != nil {
- return libpod.Version{}, nil
+ return define.Version{}, nil
}
buildTime = t.Unix()
}
- return libpod.Version{
+ return define.Version{
RemoteAPIVersion: apiVersion,
Version: version,
GoVersion: goVersion,
diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index 426bda559..d6c19212b 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -30,7 +30,7 @@ type CgroupControl struct {
additionalControllers []controller
}
-// CPUUsage keeps stats for the CPU usage
+// CPUUsage keeps stats for the CPU usage (unit: nanoseconds)
type CPUUsage struct {
Kernel uint64
Total uint64
diff --git a/pkg/cgroups/cpu.go b/pkg/cgroups/cpu.go
index 3f969fd3c..8640d490e 100644
--- a/pkg/cgroups/cpu.go
+++ b/pkg/cgroups/cpu.go
@@ -85,12 +85,14 @@ func (c *cpuHandler) Stat(ctr *CgroupControl, m *Metrics) error {
if err != nil {
return err
}
+ usage.Kernel *= 1000
}
if val, found := values["system_usec"]; found {
usage.Total, err = strconv.ParseUint(cleanString(val[0]), 10, 0)
if err != nil {
return err
}
+ usage.Total *= 1000
}
// FIXME: How to read usage.PerCPU?
} else {
diff --git a/pkg/hooks/0.1.0/hook.go b/pkg/hooks/0.1.0/hook.go
index ba68b0f10..88a387647 100644
--- a/pkg/hooks/0.1.0/hook.go
+++ b/pkg/hooks/0.1.0/hook.go
@@ -6,7 +6,7 @@ import (
"errors"
"strings"
- hooks "github.com/containers/libpod/pkg/hooks"
+ "github.com/containers/libpod/pkg/hooks"
current "github.com/containers/libpod/pkg/hooks/1.0.0"
rspec "github.com/opencontainers/runtime-spec/specs-go"
)
diff --git a/pkg/hooks/1.0.0/when_test.go b/pkg/hooks/1.0.0/when_test.go
index 7187b297b..a749063ff 100644
--- a/pkg/hooks/1.0.0/when_test.go
+++ b/pkg/hooks/1.0.0/when_test.go
@@ -30,7 +30,7 @@ func TestAlways(t *testing.T) {
for _, always := range []bool{true, false} {
for _, or := range []bool{true, false} {
for _, process := range []*rspec.Process{processStruct, nil} {
- t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, (process != nil)), func(t *testing.T) {
+ t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, process != nil), func(t *testing.T) {
config.Process = process
when := When{Always: &always, Or: or}
match, err := when.Match(config, map[string]string{}, false)
diff --git a/pkg/logs/logs.go b/pkg/logs/logs.go
index 7fb5c7ea8..0f684750e 100644
--- a/pkg/logs/logs.go
+++ b/pkg/logs/logs.go
@@ -29,6 +29,7 @@ import (
"time"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -134,7 +135,7 @@ func parseCRILog(log []byte, msg *logMessage) error {
}
// Keep this forward compatible.
tags := bytes.Split(log[:idx], tagDelimiter)
- partial := (LogTag(tags[0]) == LogTagPartial)
+ partial := LogTag(tags[0]) == LogTagPartial
// Trim the tailing new line if this is a partial line.
if partial && len(log) > 0 && log[len(log)-1] == '\n' {
log = log[:len(log)-1]
@@ -209,7 +210,7 @@ func followLog(reader *bufio.Reader, writer *logWriter, opts *LogOptions, ctr *l
if err != nil {
return err
}
- if state != libpod.ContainerStateRunning && state != libpod.ContainerStatePaused {
+ if state != define.ContainerStateRunning && state != define.ContainerStatePaused {
break
}
continue
diff --git a/pkg/rootless/rootless_linux.c b/pkg/rootless/rootless_linux.c
index c409e3343..19b76f387 100644
--- a/pkg/rootless/rootless_linux.c
+++ b/pkg/rootless/rootless_linux.c
@@ -82,7 +82,7 @@ do_pause ()
struct sigaction act;
int const sig[] =
{
- SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM, SIGPOLL,
+ SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGPOLL,
SIGPROF, SIGVTALRM, SIGXCPU, SIGXFSZ, 0
};
@@ -244,7 +244,7 @@ static void __attribute__((constructor)) init()
/* Shortcut. If we are able to join the pause pid file, do it now so we don't
need to re-exec. */
xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR");
- if (xdg_runtime_dir && xdg_runtime_dir[0] && can_use_shortcut ())
+ if (geteuid () != 0 && xdg_runtime_dir && xdg_runtime_dir[0] && can_use_shortcut ())
{
int r;
int fd;
@@ -542,6 +542,11 @@ reexec_userns_join (int userns, int mountns, char *pause_pid_file_path)
fprintf (stderr, "cannot sigdelset(SIGCHLD): %s\n", strerror (errno));
_exit (EXIT_FAILURE);
}
+ if (sigdelset (&sigset, SIGTERM) < 0)
+ {
+ fprintf (stderr, "cannot sigdelset(SIGTERM): %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
if (sigprocmask (SIG_BLOCK, &sigset, &oldsigset) < 0)
{
fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
@@ -736,6 +741,11 @@ reexec_in_user_namespace (int ready, char *pause_pid_file_path, char *file_to_re
fprintf (stderr, "cannot sigdelset(SIGCHLD): %s\n", strerror (errno));
_exit (EXIT_FAILURE);
}
+ if (sigdelset (&sigset, SIGTERM) < 0)
+ {
+ fprintf (stderr, "cannot sigdelset(SIGTERM): %s\n", strerror (errno));
+ _exit (EXIT_FAILURE);
+ }
if (sigprocmask (SIG_BLOCK, &sigset, &oldsigset) < 0)
{
fprintf (stderr, "cannot block signals: %s\n", strerror (errno));
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index ca8faecbd..8028a359c 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -1,4 +1,4 @@
-// +build linux
+// +build linux,cgo
package rootless
@@ -9,14 +9,17 @@ import (
"os/exec"
gosignal "os/signal"
"os/user"
+ "path/filepath"
"runtime"
"strconv"
+ "strings"
"sync"
"syscall"
"unsafe"
"github.com/containers/storage/pkg/idtools"
"github.com/docker/docker/pkg/signal"
+ "github.com/godbus/dbus"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -198,24 +201,90 @@ func getUserNSFirstChild(fd uintptr) (*os.File, error) {
}
}
-func enableLinger(pausePid string) {
- if pausePid == "" {
- return
+// EnableLinger configures the system to not kill the user processes once the session
+// terminates
+func EnableLinger() (string, error) {
+ uid := fmt.Sprintf("%d", GetRootlessUID())
+
+ conn, err := dbus.SystemBus()
+ if err == nil {
+ defer conn.Close()
+ }
+
+ lingerEnabled := false
+
+ // If we have a D-BUS connection, attempt to read the LINGER property from it.
+ if conn != nil {
+ path := dbus.ObjectPath(fmt.Sprintf("/org/freedesktop/login1/user/_%s", uid))
+ ret, err := conn.Object("org.freedesktop.login1", path).GetProperty("org.freedesktop.login1.User.Linger")
+ if err == nil && ret.Value().(bool) {
+ lingerEnabled = true
+ }
+ }
+
+ xdgRuntimeDir := os.Getenv("XDG_RUNTIME_DIR")
+ lingerFile := ""
+ if xdgRuntimeDir != "" && !lingerEnabled {
+ lingerFile = filepath.Join(xdgRuntimeDir, "libpod/linger")
+ _, err := os.Stat(lingerFile)
+ if err == nil {
+ lingerEnabled = true
+ }
}
- // If we are trying to write a pause pid file, make sure we can leave processes
- // running longer than the user session.
- err := exec.Command("loginctl", "enable-linger", fmt.Sprintf("%d", GetRootlessUID())).Run()
+
+ if !lingerEnabled {
+ // First attempt with D-BUS, if it fails, then attempt with "loginctl enable-linger"
+ if conn != nil {
+ o := conn.Object("org.freedesktop.login1", "/org/freedesktop/login1")
+ ret := o.Call("org.freedesktop.login1.Manager.SetUserLinger", 0, uint32(GetRootlessUID()), true, true)
+ if ret.Err == nil {
+ lingerEnabled = true
+ }
+ }
+ if !lingerEnabled {
+ err := exec.Command("loginctl", "enable-linger", uid).Run()
+ if err == nil {
+ lingerEnabled = true
+ } else {
+ logrus.Debugf("cannot run `loginctl enable-linger` for the current user: %v", err)
+ }
+ }
+ if lingerEnabled && lingerFile != "" {
+ f, err := os.Create(lingerFile)
+ if err == nil {
+ f.Close()
+ } else {
+ logrus.Debugf("could not create linger file: %v", err)
+ }
+ }
+ }
+
+ if !lingerEnabled {
+ return "", nil
+ }
+
+ // If we have a D-BUS connection, attempt to read the RUNTIME PATH from it.
+ if conn != nil {
+ path := dbus.ObjectPath(fmt.Sprintf("/org/freedesktop/login1/user/_%s", uid))
+ ret, err := conn.Object("org.freedesktop.login1", path).GetProperty("org.freedesktop.login1.User.RuntimePath")
+ if err == nil {
+ return strings.Trim(ret.String(), "\"\n"), nil
+ }
+ }
+
+ // If XDG_RUNTIME_DIR is not set and the D-BUS call didn't work, try to get the runtime path with "loginctl"
+ output, err := exec.Command("loginctl", "-pRuntimePath", "show-user", uid).Output()
if err != nil {
- logrus.Warnf("cannot run `loginctl enable-linger` for the current user: %v", err)
+ logrus.Debugf("could not get RuntimePath using loginctl: %v", err)
+ return "", nil
}
+ return strings.Trim(strings.Replace(string(output), "RuntimePath=", "", -1), "\"\n"), nil
}
// joinUserAndMountNS re-exec podman in a new userNS and join the user and mount
// namespace of the specified PID without looking up its parent. Useful to join directly
// the conmon process.
func joinUserAndMountNS(pid uint, pausePid string) (bool, int, error) {
- enableLinger(pausePid)
-
if os.Geteuid() == 0 || os.Getenv("_CONTAINERS_USERNS_CONFIGURED") != "" {
return false, -1, nil
}
@@ -406,7 +475,6 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool,
// If podman was re-executed the caller needs to propagate the error code returned by the child
// process.
func BecomeRootInUserNS(pausePid string) (bool, int, error) {
- enableLinger(pausePid)
return becomeRootInUserNS(pausePid, "", nil)
}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
index c063adee5..a8485c083 100644
--- a/pkg/rootless/rootless_unsupported.go
+++ b/pkg/rootless/rootless_unsupported.go
@@ -1,14 +1,21 @@
-// +build !linux
+// +build !linux !cgo
package rootless
import (
+ "os"
+
"github.com/pkg/errors"
)
-// IsRootless returns false on all non-linux platforms
+// IsRootless returns whether the user is rootless
func IsRootless() bool {
- return false
+ uid := os.Geteuid()
+ // os.Geteuid() on Windows returns -1
+ if uid == -1 {
+ return false
+ }
+ return uid != 0
}
// BecomeRootInUserNS re-exec podman in a new userNS. It returns whether podman was re-executed
@@ -29,6 +36,12 @@ func GetRootlessGID() int {
return -1
}
+// EnableLinger configures the system to not kill the user processes once the session
+// terminates
+func EnableLinger() (string, error) {
+ return "", nil
+}
+
// TryJoinFromFilePaths attempts to join the namespaces of the pid files in paths.
// This is useful when there are already running containers and we
// don't have a pause process yet. We can use the paths to the conmon
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
index eb2acf984..9f6a4a058 100644
--- a/pkg/spec/config_linux.go
+++ b/pkg/spec/config_linux.go
@@ -4,12 +4,10 @@ package createconfig
import (
"fmt"
- "io/ioutil"
"os"
"path/filepath"
"strings"
- "github.com/docker/docker/profiles/seccomp"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/devices"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -130,29 +128,6 @@ func (c *CreateConfig) addPrivilegedDevices(g *generate.Generator) error {
return nil
}
-func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
- var seccompConfig *spec.LinuxSeccomp
- var err error
-
- if config.SeccompProfilePath != "" {
- seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
- if err != nil {
- return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- seccompConfig, err = seccomp.LoadProfile(string(seccompProfile), configSpec)
- if err != nil {
- return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- } else {
- seccompConfig, err = seccomp.GetDefaultProfile(configSpec)
- if err != nil {
- return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
- }
- }
-
- return seccompConfig, nil
-}
-
func (c *CreateConfig) createBlockIO() (*spec.LinuxBlockIO, error) {
var ret *spec.LinuxBlockIO
bio := &spec.LinuxBlockIO{}
diff --git a/pkg/spec/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go
new file mode 100644
index 000000000..e6e92a7cc
--- /dev/null
+++ b/pkg/spec/config_linux_cgo.go
@@ -0,0 +1,34 @@
+// +build linux,cgo
+
+package createconfig
+
+import (
+ "io/ioutil"
+
+ "github.com/docker/docker/profiles/seccomp"
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+ "github.com/pkg/errors"
+)
+
+func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
+ var seccompConfig *spec.LinuxSeccomp
+ var err error
+
+ if config.SeccompProfilePath != "" {
+ seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
+ if err != nil {
+ return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
+ }
+ seccompConfig, err = seccomp.LoadProfile(string(seccompProfile), configSpec)
+ if err != nil {
+ return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
+ }
+ } else {
+ seccompConfig, err = seccomp.GetDefaultProfile(configSpec)
+ if err != nil {
+ return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
+ }
+ }
+
+ return seccompConfig, nil
+}
diff --git a/pkg/spec/config_linux_nocgo.go b/pkg/spec/config_linux_nocgo.go
new file mode 100644
index 000000000..10329ff3b
--- /dev/null
+++ b/pkg/spec/config_linux_nocgo.go
@@ -0,0 +1,11 @@
+// +build linux,!cgo
+
+package createconfig
+
+import (
+ spec "github.com/opencontainers/runtime-spec/specs-go"
+)
+
+func getSeccompConfig(config *CreateConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
+ return nil, nil
+}
diff --git a/pkg/sysinfo/sysinfo_test.go b/pkg/sysinfo/sysinfo_test.go
index b61fbcf54..895828f26 100644
--- a/pkg/sysinfo/sysinfo_test.go
+++ b/pkg/sysinfo/sysinfo_test.go
@@ -20,7 +20,7 @@ func TestIsCpusetListAvailable(t *testing.T) {
for _, c := range cases {
r, err := isCpusetListAvailable(c.provided, c.available)
if (c.err && err == nil) && r != c.res {
- t.Fatalf("Expected pair: %v, %v for %s, %s. Got %v, %v instead", c.res, c.err, c.provided, c.available, (c.err && err == nil), r)
+ t.Fatalf("Expected pair: %v, %v for %s, %s. Got %v, %v instead", c.res, c.err, c.provided, c.available, c.err && err == nil, r)
}
}
}
diff --git a/pkg/systemdgen/systemdgen.go b/pkg/systemdgen/systemdgen.go
index 3d1c31b5d..06c5ebde5 100644
--- a/pkg/systemdgen/systemdgen.go
+++ b/pkg/systemdgen/systemdgen.go
@@ -2,17 +2,18 @@ package systemdgen
import (
"fmt"
- "path/filepath"
+ "os"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
var template = `[Unit]
Description=%s Podman Container
[Service]
Restart=%s
-ExecStart=/usr/bin/podman start %s
-ExecStop=/usr/bin/podman stop -t %d %s
+ExecStart=%s start %s
+ExecStop=%s stop -t %d %s
KillMode=none
Type=forking
PIDFile=%s
@@ -33,11 +34,26 @@ func ValidateRestartPolicy(restart string) error {
// CreateSystemdUnitAsString takes variables to create a systemd unit file used to control
// a libpod container
-func CreateSystemdUnitAsString(name, cid, restart, pidPath string, stopTimeout int) (string, error) {
+func CreateSystemdUnitAsString(name, cid, restart, pidFile string, stopTimeout int) (string, error) {
+ podmanExe := getPodmanExecutable()
+ return createSystemdUnitAsString(podmanExe, name, cid, restart, pidFile, stopTimeout)
+}
+
+func createSystemdUnitAsString(exe, name, cid, restart, pidFile string, stopTimeout int) (string, error) {
if err := ValidateRestartPolicy(restart); err != nil {
return "", err
}
- pidFile := filepath.Join(pidPath, fmt.Sprintf("%s.pid", cid))
- unit := fmt.Sprintf(template, name, restart, name, stopTimeout, name, pidFile)
+
+ unit := fmt.Sprintf(template, name, restart, exe, name, exe, stopTimeout, name, pidFile)
return unit, nil
}
+
+func getPodmanExecutable() string {
+ podmanExe, err := os.Executable()
+ if err != nil {
+ podmanExe = "/usr/bin/podman"
+ logrus.Warnf("Could not obtain podman executable location, using default %s", podmanExe)
+ }
+
+ return podmanExe
+}
diff --git a/pkg/systemdgen/systemdgen_test.go b/pkg/systemdgen/systemdgen_test.go
index f2f49e750..e413b24ce 100644
--- a/pkg/systemdgen/systemdgen_test.go
+++ b/pkg/systemdgen/systemdgen_test.go
@@ -41,7 +41,7 @@ ExecStart=/usr/bin/podman start 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4
ExecStop=/usr/bin/podman stop -t 10 639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401
KillMode=none
Type=forking
-PIDFile=/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid
+PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
[Install]
WantedBy=multi-user.target`
@@ -53,15 +53,16 @@ ExecStart=/usr/bin/podman start foobar
ExecStop=/usr/bin/podman stop -t 10 foobar
KillMode=none
Type=forking
-PIDFile=/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401.pid
+PIDFile=/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid
[Install]
WantedBy=multi-user.target`
type args struct {
+ exe string
name string
cid string
restart string
- pidPath string
+ pidFile string
stopTimeout int
}
tests := []struct {
@@ -73,10 +74,11 @@ WantedBy=multi-user.target`
{"good with id",
args{
+ "/usr/bin/podman",
"639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
"639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
"always",
- "/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/",
+ "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
10,
},
goodID,
@@ -84,10 +86,11 @@ WantedBy=multi-user.target`
},
{"good with name",
args{
+ "/usr/bin/podman",
"foobar",
"639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
"always",
- "/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/",
+ "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
10,
},
goodName,
@@ -95,10 +98,11 @@ WantedBy=multi-user.target`
},
{"bad restart policy",
args{
+ "/usr/bin/podman",
"639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
"639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401",
"never",
- "/var/lib/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/",
+ "/var/run/containers/storage/overlay-containers/639c53578af4d84b8800b4635fa4e680ee80fd67e0e6a2d4eea48d1e3230f401/userdata/conmon.pid",
10,
},
"",
@@ -107,7 +111,7 @@ WantedBy=multi-user.target`
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- got, err := CreateSystemdUnitAsString(tt.args.name, tt.args.cid, tt.args.restart, tt.args.pidPath, tt.args.stopTimeout)
+ got, err := createSystemdUnitAsString(tt.args.exe, tt.args.name, tt.args.cid, tt.args.restart, tt.args.pidFile, tt.args.stopTimeout)
if (err != nil) != tt.wantErr {
t.Errorf("CreateSystemdUnitAsString() error = %v, wantErr %v", err, tt.wantErr)
return
diff --git a/pkg/tracing/tracing.go b/pkg/tracing/tracing.go
index cae76dee8..d028ddf8f 100644
--- a/pkg/tracing/tracing.go
+++ b/pkg/tracing/tracing.go
@@ -4,9 +4,9 @@ import (
"fmt"
"io"
- opentracing "github.com/opentracing/opentracing-go"
- jaeger "github.com/uber/jaeger-client-go"
- config "github.com/uber/jaeger-client-go/config"
+ "github.com/opentracing/opentracing-go"
+ "github.com/uber/jaeger-client-go"
+ "github.com/uber/jaeger-client-go/config"
)
// Init returns an instance of Jaeger Tracer that samples 100% of traces and logs all spans to stdout.
diff --git a/pkg/trust/trust.go b/pkg/trust/trust.go
index 9a75474ae..3bfe4bda1 100644
--- a/pkg/trust/trust.go
+++ b/pkg/trust/trust.go
@@ -14,7 +14,7 @@ import (
"github.com/containers/image/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- yaml "gopkg.in/yaml.v2"
+ "gopkg.in/yaml.v2"
)
// PolicyContent struct for policy.json file
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 61cdbbf38..9e49f08a0 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -337,3 +337,14 @@ func GetGlobalOpts(c *cliconfig.RunlabelValues) string {
})
return strings.Join(optsCommand, " ")
}
+
+// OpenExclusiveFile opens a file for writing and ensure it doesn't already exist
+func OpenExclusiveFile(path string) (*os.File, error) {
+ baseDir := filepath.Dir(path)
+ if baseDir != "" {
+ if _, err := os.Stat(baseDir); err != nil {
+ return nil, err
+ }
+ }
+ return os.OpenFile(path, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
+}
diff --git a/pkg/util/utils_darwin.go b/pkg/util/utils_darwin.go
new file mode 100644
index 000000000..33a46a5d4
--- /dev/null
+++ b/pkg/util/utils_darwin.go
@@ -0,0 +1,11 @@
+//+build darwin
+
+package util
+
+import (
+ "github.com/pkg/errors"
+)
+
+func GetContainerPidInformationDescriptors() ([]string, error) {
+ return []string{}, errors.New("this function is not supported on darwin")
+}
diff --git a/pkg/util/utils_linux.go b/pkg/util/utils_linux.go
new file mode 100644
index 000000000..47fa1031f
--- /dev/null
+++ b/pkg/util/utils_linux.go
@@ -0,0 +1,11 @@
+package util
+
+import (
+ "github.com/containers/psgo"
+)
+
+// GetContainerPidInformationDescriptors returns a string slice of all supported
+// format descriptors of GetContainerPidInformation.
+func GetContainerPidInformationDescriptors() ([]string, error) {
+ return psgo.ListDescriptors(), nil
+}
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
index f8045f855..99c9e4f1e 100644
--- a/pkg/util/utils_supported.go
+++ b/pkg/util/utils_supported.go
@@ -7,11 +7,12 @@ package util
import (
"fmt"
- "github.com/containers/libpod/pkg/rootless"
- "github.com/pkg/errors"
"os"
"path/filepath"
"syscall"
+
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
)
// GetRootlessRuntimeDir returns the runtime directory when running as non root
diff --git a/pkg/util/utils_windows.go b/pkg/util/utils_windows.go
index 3faa6f10c..635558bf7 100644
--- a/pkg/util/utils_windows.go
+++ b/pkg/util/utils_windows.go
@@ -6,18 +6,24 @@ import (
"github.com/pkg/errors"
)
-// GetRootlessRuntimeDir returns the runtime directory when running as non root
-func GetRootlessRuntimeDir() (string, error) {
- return "", errors.New("this function is not implemented for windows")
-}
-
// IsCgroup2UnifiedMode returns whether we are running in cgroup 2 unified mode.
func IsCgroup2UnifiedMode() (bool, error) {
return false, errors.New("this function is not implemented for windows")
}
+// GetContainerPidInformationDescriptors returns a string slice of all supported
+// format descriptors of GetContainerPidInformation.
+func GetContainerPidInformationDescriptors() ([]string, error) {
+ return nil, errors.New("this function is not implemented for windows")
+}
+
// GetRootlessPauseProcessPidPath returns the path to the file that holds the pid for
// the pause process
func GetRootlessPauseProcessPidPath() (string, error) {
return "", errors.New("this function is not implemented for windows")
}
+
+// GetRootlessRuntimeDir returns the runtime directory when running as non root
+func GetRootlessRuntimeDir() (string, error) {
+ return "", errors.New("this function is not implemented for windows")
+}
diff --git a/pkg/varlinkapi/attach.go b/pkg/varlinkapi/attach.go
index 3f0a119f4..afa88e6a3 100644
--- a/pkg/varlinkapi/attach.go
+++ b/pkg/varlinkapi/attach.go
@@ -58,7 +58,7 @@ func (i *LibpodAPI) Attach(call iopodman.VarlinkCall, name string, detachKeys st
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- if !start && state != libpod.ContainerStateRunning {
+ if !start && state != define.ContainerStateRunning {
return call.ReplyErrorOccurred("container must be running to attach")
}
@@ -73,7 +73,7 @@ func (i *LibpodAPI) Attach(call iopodman.VarlinkCall, name string, detachKeys st
}
}()
- if state == libpod.ContainerStateRunning {
+ if state == define.ContainerStateRunning {
finalErr = attach(ctr, streams, detachKeys, resize, errChan)
} else {
finalErr = startAndAttach(ctr, streams, detachKeys, resize, errChan)
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index ed3243f21..6855a7231 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -17,6 +17,7 @@ import (
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define"
+ "github.com/containers/libpod/libpod/logs"
"github.com/containers/libpod/pkg/adapter/shortcuts"
cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/storage/pkg/archive"
@@ -139,7 +140,7 @@ func (i *LibpodAPI) GetContainersByStatus(call iopodman.VarlinkCall, statuses []
containers []iopodman.Container
)
for _, status := range statuses {
- lpstatus, err := libpod.StringToContainerStatus(status)
+ lpstatus, err := define.StringToContainerStatus(status)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
@@ -199,7 +200,7 @@ func (i *LibpodAPI) ListContainerProcesses(call iopodman.VarlinkCall, name strin
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- if containerState != libpod.ContainerStateRunning {
+ if containerState != define.ContainerStateRunning {
return call.ReplyErrorOccurred(fmt.Sprintf("container %s is not running", name))
}
var psArgs []string
@@ -230,7 +231,7 @@ func (i *LibpodAPI) GetContainerLogs(call iopodman.VarlinkCall, name string) err
return call.ReplyErrorOccurred(err.Error())
}
if _, err := os.Stat(logPath); err != nil {
- if containerState == libpod.ContainerStateConfigured {
+ if containerState == define.ContainerStateConfigured {
return call.ReplyGetContainerLogs(logs)
}
}
@@ -260,7 +261,7 @@ func (i *LibpodAPI) GetContainerLogs(call iopodman.VarlinkCall, name string) err
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- if state != libpod.ContainerStateRunning && state != libpod.ContainerStatePaused {
+ if state != define.ContainerStateRunning && state != define.ContainerStatePaused {
return call.ReplyErrorOccurred(fmt.Sprintf("%s is no longer running", ctr.ID()))
}
@@ -360,7 +361,7 @@ func (i *LibpodAPI) StartContainer(call iopodman.VarlinkCall, name string) error
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- if state == libpod.ContainerStateRunning || state == libpod.ContainerStatePaused {
+ if state == define.ContainerStateRunning || state == define.ContainerStatePaused {
return call.ReplyErrorOccurred("container is already running or paused")
}
recursive := false
@@ -511,7 +512,7 @@ func (i *LibpodAPI) DeleteStoppedContainers(call iopodman.VarlinkCall) error {
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- if state != libpod.ContainerStateRunning {
+ if state != define.ContainerStateRunning {
if err := i.Runtime.RemoveContainer(ctx, ctr, false, false); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
@@ -535,7 +536,7 @@ func (i *LibpodAPI) GetAttachSockets(call iopodman.VarlinkCall, name string) err
// If the container hasn't been run, we need to run init
// so the conmon sockets get created.
- if status == libpod.ContainerStateConfigured || status == libpod.ContainerStateStopped {
+ if status == define.ContainerStateConfigured || status == define.ContainerStateStopped {
if err := ctr.Init(getContext()); err != nil {
return call.ReplyErrorOccurred(err.Error())
}
@@ -720,7 +721,7 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string,
if err != nil {
return call.ReplyErrorOccurred(err.Error())
}
- options := libpod.LogOptions{
+ options := logs.LogOptions{
Follow: follow,
Since: sinceTime,
Tail: uint64(tail),
@@ -731,7 +732,7 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string,
if len(names) > 1 {
options.Multi = true
}
- logChannel := make(chan *libpod.LogLine, int(tail)*len(names)+1)
+ logChannel := make(chan *logs.LogLine, int(tail)*len(names)+1)
containers, err := shortcuts.GetContainersByContext(false, latest, names, i.Runtime)
if err != nil {
return call.ReplyErrorOccurred(err.Error())
@@ -753,7 +754,7 @@ func (i *LibpodAPI) GetContainersLogs(call iopodman.VarlinkCall, names []string,
return call.ReplyGetContainersLogs(iopodman.LogLine{})
}
-func newPodmanLogLine(line *libpod.LogLine) iopodman.LogLine {
+func newPodmanLogLine(line *logs.LogLine) iopodman.LogLine {
return iopodman.LogLine{
Device: line.Device,
ParseLogType: line.ParseLogType,
diff --git a/pkg/varlinkapi/system.go b/pkg/varlinkapi/system.go
index 59bfec75b..9b5b3a5b1 100644
--- a/pkg/varlinkapi/system.go
+++ b/pkg/varlinkapi/system.go
@@ -3,17 +3,17 @@
package varlinkapi
import (
+ "github.com/containers/libpod/libpod/define"
goruntime "runtime"
"strings"
"time"
"github.com/containers/libpod/cmd/podman/varlink"
- "github.com/containers/libpod/libpod"
)
// GetVersion ...
func (i *LibpodAPI) GetVersion(call iopodman.VarlinkCall) error {
- versionInfo, err := libpod.GetVersion()
+ versionInfo, err := define.GetVersion()
if err != nil {
return err
}
@@ -30,7 +30,7 @@ func (i *LibpodAPI) GetVersion(call iopodman.VarlinkCall) error {
// GetInfo returns details about the podman host and its stores
func (i *LibpodAPI) GetInfo(call iopodman.VarlinkCall) error {
- versionInfo, err := libpod.GetVersion()
+ versionInfo, err := define.GetVersion()
if err != nil {
return err
}
diff --git a/pkg/varlinkapi/util.go b/pkg/varlinkapi/util.go
index 8716c963a..a74105795 100644
--- a/pkg/varlinkapi/util.go
+++ b/pkg/varlinkapi/util.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/cmd/podman/varlink"
"github.com/containers/libpod/libpod"
+ "github.com/containers/libpod/libpod/define"
"github.com/containers/storage/pkg/archive"
)
@@ -73,7 +74,7 @@ func makeListContainer(containerID string, batchInfo shared.BatchContainerStruct
Names: batchInfo.ConConfig.Name,
Labels: batchInfo.ConConfig.Labels,
Mounts: mounts,
- Containerrunning: batchInfo.ConState == libpod.ContainerStateRunning,
+ Containerrunning: batchInfo.ConState == define.ContainerStateRunning,
Namespaces: namespace,
}
if batchInfo.Size != nil {