aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/containers.go82
-rw-r--r--pkg/adapter/containers_remote.go73
-rw-r--r--pkg/adapter/runtime_remote.go17
-rw-r--r--pkg/adapter/runtime_remote_supported.go1
-rw-r--r--pkg/adapter/sigproxy_linux.go (renamed from pkg/adapter/sigproxy.go)0
-rw-r--r--pkg/adapter/terminal.go81
-rw-r--r--pkg/adapter/terminal_linux.go91
-rw-r--r--pkg/spec/config_linux.go6
-rw-r--r--pkg/spec/createconfig.go7
-rw-r--r--pkg/systemdgen/systemdgen.go43
-rw-r--r--pkg/util/utils.go72
-rw-r--r--pkg/util/utils_supported.go60
-rw-r--r--pkg/util/utils_windows.go12
-rw-r--r--pkg/varlinkapi/containers.go15
-rw-r--r--pkg/varlinkapi/generate.go22
15 files changed, 422 insertions, 160 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 9ec897a60..d575bc9b0 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -18,6 +18,7 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/adapter/shortcuts"
+ "github.com/containers/libpod/pkg/systemdgen"
"github.com/containers/storage"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -133,6 +134,43 @@ func (r *LocalRuntime) KillContainers(ctx context.Context, cli *cliconfig.KillVa
return pool.Run()
}
+// InitContainers initializes container(s) based on CLI inputs.
+// Returns list of successful id(s), map of failed id(s) to errors, or a general
+// error not from the container.
+func (r *LocalRuntime) InitContainers(ctx context.Context, cli *cliconfig.InitValues) ([]string, map[string]error, error) {
+ maxWorkers := shared.DefaultPoolSize("init")
+ if cli.GlobalIsSet("max-workers") {
+ maxWorkers = cli.GlobalFlags.MaxWorks
+ }
+ logrus.Debugf("Setting maximum init workers to %d", maxWorkers)
+
+ ctrs, err := shortcuts.GetContainersByContext(cli.All, cli.Latest, cli.InputArgs, r.Runtime)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ pool := shared.NewPool("init", maxWorkers, len(ctrs))
+ for _, c := range ctrs {
+ ctr := c
+
+ pool.Add(shared.Job{
+ ctr.ID(),
+ func() error {
+ err := ctr.Init(ctx)
+ if err != nil {
+ // If we're initializing all containers, ignore invalid state errors
+ if cli.All && errors.Cause(err) == libpod.ErrCtrStateInvalid {
+ return nil
+ }
+ return err
+ }
+ return nil
+ },
+ })
+ }
+ return pool.Run()
+}
+
// RemoveContainers removes container(s) based on CLI inputs.
func (r *LocalRuntime) RemoveContainers(ctx context.Context, cli *cliconfig.RmValues) ([]string, map[string]error, error) {
var (
@@ -876,3 +914,47 @@ func cleanupContainer(ctx context.Context, ctr *libpod.Container, runtime *Local
}
return nil
}
+
+// Port displays port information about existing containers
+func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
+ var (
+ portContainers []*Container
+ containers []*libpod.Container
+ err error
+ )
+
+ if !c.All {
+ containers, err = shortcuts.GetContainersByContext(false, c.Latest, c.InputArgs, r.Runtime)
+ } else {
+ containers, err = r.Runtime.GetRunningContainers()
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ //Convert libpod containers to adapter Containers
+ for _, con := range containers {
+ if state, _ := con.State(); state != libpod.ContainerStateRunning {
+ continue
+ }
+ portContainers = append(portContainers, &Container{con})
+ }
+ return portContainers, nil
+}
+
+// GenerateSystemd creates a unit file for a container
+func (r *LocalRuntime) GenerateSystemd(c *cliconfig.GenerateSystemdValues) (string, error) {
+ ctr, err := r.Runtime.LookupContainer(c.InputArgs[0])
+ if err != nil {
+ return "", err
+ }
+ timeout := int(ctr.StopTimeout())
+ if c.StopTimeout >= 0 {
+ timeout = int(c.StopTimeout)
+ }
+ name := ctr.ID()
+ if c.Name {
+ name = ctr.Name()
+ }
+ return systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), c.RestartPolicy, ctr.Config().StaticDir, timeout)
+}
diff --git a/pkg/adapter/containers_remote.go b/pkg/adapter/containers_remote.go
index a3a48a564..201249fc3 100644
--- a/pkg/adapter/containers_remote.go
+++ b/pkg/adapter/containers_remote.go
@@ -18,6 +18,7 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/inspect"
"github.com/containers/libpod/pkg/varlinkapi/virtwriter"
+ "github.com/cri-o/ocicni/pkg/ocicni"
"github.com/docker/docker/pkg/term"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
@@ -63,6 +64,19 @@ func (c *Container) Unpause() error {
return err
}
+func (c *Container) PortMappings() ([]ocicni.PortMapping, error) {
+ // First check if the container belongs to a network namespace (like a pod)
+ // Taken from libpod portmappings()
+ if len(c.config.NetNsCtr) > 0 {
+ netNsCtr, err := c.Runtime.LookupContainer(c.config.NetNsCtr)
+ if err != nil {
+ return nil, errors.Wrapf(err, "unable to lookup network namespace for container %s", c.ID())
+ }
+ return netNsCtr.PortMappings()
+ }
+ return c.config.PortMappings, nil
+}
+
// Config returns a container config
func (r *LocalRuntime) Config(name string) *libpod.ContainerConfig {
// TODO the Spec being returned is not populated. Matt and I could not figure out why. Will defer
@@ -234,6 +248,40 @@ func (r *LocalRuntime) StopContainers(ctx context.Context, cli *cliconfig.StopVa
return ok, failures, nil
}
+// InitContainers initializes container(s) based on Varlink.
+// It returns a list of successful ID(s), a map of failed container ID to error,
+// or an error if a more general error occurred.
+func (r *LocalRuntime) InitContainers(ctx context.Context, cli *cliconfig.InitValues) ([]string, map[string]error, error) {
+ var (
+ ok = []string{}
+ failures = map[string]error{}
+ )
+
+ ids, err := iopodman.GetContainersByContext().Call(r.Conn, cli.All, cli.Latest, cli.InputArgs)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ for _, id := range ids {
+ initialized, err := iopodman.InitContainer().Call(r.Conn, id)
+ if err != nil {
+ if cli.All {
+ switch err.(type) {
+ case *iopodman.InvalidState:
+ ok = append(ok, initialized)
+ default:
+ failures[id] = err
+ }
+ } else {
+ failures[id] = err
+ }
+ } else {
+ ok = append(ok, initialized)
+ }
+ }
+ return ok, failures, nil
+}
+
// KillContainers sends signal to container(s) based on varlink.
// Returns list of successful id(s), map of failed id(s) + error, or error not from container
func (r *LocalRuntime) KillContainers(ctx context.Context, cli *cliconfig.KillValues, signal syscall.Signal) ([]string, map[string]error, error) {
@@ -888,3 +936,28 @@ func (r *LocalRuntime) Prune(ctx context.Context, maxWorkers int, force bool) ([
func (r *LocalRuntime) CleanupContainers(ctx context.Context, cli *cliconfig.CleanupValues) ([]string, map[string]error, error) {
return nil, nil, errors.New("container cleanup not supported for remote clients")
}
+
+// Port displays port information about existing containers
+func (r *LocalRuntime) Port(c *cliconfig.PortValues) ([]*Container, error) {
+ var (
+ containers []*Container
+ err error
+ )
+ // This one is a bit odd because when all is used, we only use running containers.
+ if !c.All {
+ containers, err = r.GetContainersByContext(false, c.Latest, c.InputArgs)
+ } else {
+ // we need to only use running containers if all
+ filters := []string{libpod.ContainerStateRunning.String()}
+ containers, err = r.LookupContainersWithStatus(filters)
+ }
+ if err != nil {
+ return nil, err
+ }
+ return containers, nil
+}
+
+// GenerateSystemd creates a systemd until for a container
+func (r *LocalRuntime) GenerateSystemd(c *cliconfig.GenerateSystemdValues) (string, error) {
+ return iopodman.GenerateSystemd().Call(r.Conn, c.InputArgs[0], c.RestartPolicy, int64(c.StopTimeout), c.Name)
+}
diff --git a/pkg/adapter/runtime_remote.go b/pkg/adapter/runtime_remote.go
index 6102daccf..4986d16f7 100644
--- a/pkg/adapter/runtime_remote.go
+++ b/pkg/adapter/runtime_remote.go
@@ -889,3 +889,20 @@ func (r *LocalRuntime) GenerateKube(c *cliconfig.GenerateKubeValues) (*v1.Pod, *
err = json.Unmarshal([]byte(reply.Service), &service)
return &pod, &service, err
}
+
+// GetContainersByContext looks up containers based on the cli input of all, latest, or a list
+func (r *LocalRuntime) GetContainersByContext(all bool, latest bool, namesOrIDs []string) ([]*Container, error) {
+ var containers []*Container
+ cids, err := iopodman.GetContainersByContext().Call(r.Conn, all, latest, namesOrIDs)
+ if err != nil {
+ return nil, err
+ }
+ for _, cid := range cids {
+ ctr, err := r.LookupContainer(cid)
+ if err != nil {
+ return nil, err
+ }
+ containers = append(containers, ctr)
+ }
+ return containers, nil
+}
diff --git a/pkg/adapter/runtime_remote_supported.go b/pkg/adapter/runtime_remote_supported.go
new file mode 100644
index 000000000..b8e8da308
--- /dev/null
+++ b/pkg/adapter/runtime_remote_supported.go
@@ -0,0 +1 @@
+package adapter
diff --git a/pkg/adapter/sigproxy.go b/pkg/adapter/sigproxy_linux.go
index af968cb89..af968cb89 100644
--- a/pkg/adapter/sigproxy.go
+++ b/pkg/adapter/sigproxy_linux.go
diff --git a/pkg/adapter/terminal.go b/pkg/adapter/terminal.go
index 0b608decf..373c78322 100644
--- a/pkg/adapter/terminal.go
+++ b/pkg/adapter/terminal.go
@@ -2,16 +2,12 @@ package adapter
import (
"context"
- "fmt"
"os"
gosignal "os/signal"
- "github.com/containers/libpod/libpod"
"github.com/docker/docker/pkg/signal"
"github.com/docker/docker/pkg/term"
- "github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/crypto/ssh/terminal"
"k8s.io/client-go/tools/remotecommand"
)
@@ -19,83 +15,6 @@ import (
type RawTtyFormatter struct {
}
-// StartAttachCtr starts and (if required) attaches to a container
-func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool, recursive bool) error {
- resize := make(chan remotecommand.TerminalSize)
-
- haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
-
- // Check if we are attached to a terminal. If we are, generate resize
- // events, and set the terminal to raw mode
- if haveTerminal && ctr.Spec().Process.Terminal {
- logrus.Debugf("Handling terminal attach")
-
- subCtx, cancel := context.WithCancel(ctx)
- defer cancel()
-
- resizeTty(subCtx, resize)
-
- oldTermState, err := term.SaveState(os.Stdin.Fd())
- if err != nil {
- return errors.Wrapf(err, "unable to save terminal state")
- }
-
- logrus.SetFormatter(&RawTtyFormatter{})
- term.SetRawTerminal(os.Stdin.Fd())
-
- defer restoreTerminal(oldTermState)
- }
-
- streams := new(libpod.AttachStreams)
- streams.OutputStream = stdout
- streams.ErrorStream = stderr
- streams.InputStream = stdin
- streams.AttachOutput = true
- streams.AttachError = true
- streams.AttachInput = true
-
- if stdout == nil {
- logrus.Debugf("Not attaching to stdout")
- streams.AttachOutput = false
- }
- if stderr == nil {
- logrus.Debugf("Not attaching to stderr")
- streams.AttachError = false
- }
- if stdin == nil {
- logrus.Debugf("Not attaching to stdin")
- streams.AttachInput = false
- }
-
- if !startContainer {
- if sigProxy {
- ProxySignals(ctr)
- }
-
- return ctr.Attach(streams, detachKeys, resize)
- }
-
- attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, recursive)
- if err != nil {
- return err
- }
-
- if sigProxy {
- ProxySignals(ctr)
- }
-
- if stdout == nil && stderr == nil {
- fmt.Printf("%s\n", ctr.ID())
- }
-
- err = <-attachChan
- if err != nil {
- return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
- }
-
- return nil
-}
-
// getResize returns a TerminalSize command matching stdin's current
// size on success, and nil on errors.
func getResize() *remotecommand.TerminalSize {
diff --git a/pkg/adapter/terminal_linux.go b/pkg/adapter/terminal_linux.go
new file mode 100644
index 000000000..3c4c3bd38
--- /dev/null
+++ b/pkg/adapter/terminal_linux.go
@@ -0,0 +1,91 @@
+package adapter
+
+import (
+ "context"
+ "fmt"
+ "os"
+
+ "github.com/containers/libpod/libpod"
+ "github.com/docker/docker/pkg/term"
+ "github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
+ "golang.org/x/crypto/ssh/terminal"
+ "k8s.io/client-go/tools/remotecommand"
+)
+
+// StartAttachCtr starts and (if required) attaches to a container
+func StartAttachCtr(ctx context.Context, ctr *libpod.Container, stdout, stderr, stdin *os.File, detachKeys string, sigProxy bool, startContainer bool, recursive bool) error {
+ resize := make(chan remotecommand.TerminalSize)
+
+ haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
+
+ // Check if we are attached to a terminal. If we are, generate resize
+ // events, and set the terminal to raw mode
+ if haveTerminal && ctr.Spec().Process.Terminal {
+ logrus.Debugf("Handling terminal attach")
+
+ subCtx, cancel := context.WithCancel(ctx)
+ defer cancel()
+
+ resizeTty(subCtx, resize)
+
+ oldTermState, err := term.SaveState(os.Stdin.Fd())
+ if err != nil {
+ return errors.Wrapf(err, "unable to save terminal state")
+ }
+
+ logrus.SetFormatter(&RawTtyFormatter{})
+ term.SetRawTerminal(os.Stdin.Fd())
+
+ defer restoreTerminal(oldTermState)
+ }
+
+ streams := new(libpod.AttachStreams)
+ streams.OutputStream = stdout
+ streams.ErrorStream = stderr
+ streams.InputStream = stdin
+ streams.AttachOutput = true
+ streams.AttachError = true
+ streams.AttachInput = true
+
+ if stdout == nil {
+ logrus.Debugf("Not attaching to stdout")
+ streams.AttachOutput = false
+ }
+ if stderr == nil {
+ logrus.Debugf("Not attaching to stderr")
+ streams.AttachError = false
+ }
+ if stdin == nil {
+ logrus.Debugf("Not attaching to stdin")
+ streams.AttachInput = false
+ }
+
+ if !startContainer {
+ if sigProxy {
+ ProxySignals(ctr)
+ }
+
+ return ctr.Attach(streams, detachKeys, resize)
+ }
+
+ attachChan, err := ctr.StartAndAttach(ctx, streams, detachKeys, resize, recursive)
+ if err != nil {
+ return err
+ }
+
+ if sigProxy {
+ ProxySignals(ctr)
+ }
+
+ if stdout == nil && stderr == nil {
+ fmt.Printf("%s\n", ctr.ID())
+ }
+
+ err = <-attachChan
+ if err != nil {
+ return errors.Wrapf(err, "error attaching to container %s", ctr.ID())
+ }
+
+ return nil
+}
diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go
index a1873086e..eb2acf984 100644
--- a/pkg/spec/config_linux.go
+++ b/pkg/spec/config_linux.go
@@ -244,3 +244,9 @@ func makeThrottleArray(throttleInput []string, rateType int) ([]spec.LinuxThrott
}
return ltds, nil
}
+
+func getStatFromPath(path string) (unix.Stat_t, error) {
+ s := unix.Stat_t{}
+ err := unix.Stat(path, &s)
+ return s, err
+}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 4d2d8304c..90e7accf3 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -17,7 +17,6 @@ import (
"github.com/opencontainers/runtime-tools/generate"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
- "golang.org/x/sys/unix"
)
// Type constants
@@ -411,9 +410,3 @@ func NatToOCIPortBindings(ports nat.PortMap) ([]ocicni.PortMapping, error) {
func (c *CreateConfig) AddPrivilegedDevices(g *generate.Generator) error {
return c.addPrivilegedDevices(g)
}
-
-func getStatFromPath(path string) (unix.Stat_t, error) {
- s := unix.Stat_t{}
- err := unix.Stat(path, &s)
- return s, err
-}
diff --git a/pkg/systemdgen/systemdgen.go b/pkg/systemdgen/systemdgen.go
new file mode 100644
index 000000000..3d1c31b5d
--- /dev/null
+++ b/pkg/systemdgen/systemdgen.go
@@ -0,0 +1,43 @@
+package systemdgen
+
+import (
+ "fmt"
+ "path/filepath"
+
+ "github.com/pkg/errors"
+)
+
+var template = `[Unit]
+Description=%s Podman Container
+[Service]
+Restart=%s
+ExecStart=/usr/bin/podman start %s
+ExecStop=/usr/bin/podman stop -t %d %s
+KillMode=none
+Type=forking
+PIDFile=%s
+[Install]
+WantedBy=multi-user.target`
+
+var restartPolicies = []string{"no", "on-success", "on-failure", "on-abnormal", "on-watchdog", "on-abort", "always"}
+
+// ValidateRestartPolicy checks that the user-provided policy is valid
+func ValidateRestartPolicy(restart string) error {
+ for _, i := range restartPolicies {
+ if i == restart {
+ return nil
+ }
+ }
+ return errors.Errorf("%s is not a valid restart policy", restart)
+}
+
+// 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) {
+ 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)
+ return unit, nil
+}
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 136f8fadd..14b0c2b55 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -6,12 +6,10 @@ import (
"path/filepath"
"strings"
"sync"
- "syscall"
"time"
"github.com/BurntSushi/toml"
"github.com/containers/image/types"
- "github.com/containers/libpod/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/idtools"
"github.com/opencontainers/image-spec/specs-go/v1"
@@ -187,76 +185,6 @@ var (
rootlessRuntimeDir string
)
-// GetRootlessRuntimeDir returns the runtime directory when running as non root
-func GetRootlessRuntimeDir() (string, error) {
- var rootlessRuntimeDirError error
-
- rootlessRuntimeDirOnce.Do(func() {
- runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
- uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
- if runtimeDir == "" {
- tmpDir := filepath.Join("/run", "user", uid)
- os.MkdirAll(tmpDir, 0700)
- st, err := os.Stat(tmpDir)
- if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
- runtimeDir = tmpDir
- }
- }
- if runtimeDir == "" {
- tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid))
- os.MkdirAll(tmpDir, 0700)
- st, err := os.Stat(tmpDir)
- if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
- runtimeDir = tmpDir
- }
- }
- if runtimeDir == "" {
- home := os.Getenv("HOME")
- if home == "" {
- rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
- return
- }
- resolvedHome, err := filepath.EvalSymlinks(home)
- if err != nil {
- rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home)
- return
- }
- runtimeDir = filepath.Join(resolvedHome, "rundir")
- }
- rootlessRuntimeDir = runtimeDir
- })
-
- if rootlessRuntimeDirError != nil {
- return "", rootlessRuntimeDirError
- }
- return rootlessRuntimeDir, nil
-}
-
-// GetRootlessDirInfo returns the parent path of where the storage for containers and
-// volumes will be in rootless mode
-func GetRootlessDirInfo() (string, string, error) {
- rootlessRuntime, err := GetRootlessRuntimeDir()
- if err != nil {
- return "", "", err
- }
-
- dataDir := os.Getenv("XDG_DATA_HOME")
- if dataDir == "" {
- home := os.Getenv("HOME")
- if home == "" {
- return "", "", fmt.Errorf("neither XDG_DATA_HOME nor HOME was set non-empty")
- }
- // runc doesn't like symlinks in the rootfs path, and at least
- // on CoreOS /home is a symlink to /var/home, so resolve any symlink.
- resolvedHome, err := filepath.EvalSymlinks(home)
- if err != nil {
- return "", "", errors.Wrapf(err, "cannot resolve %s", home)
- }
- dataDir = filepath.Join(resolvedHome, ".local", "share")
- }
- return dataDir, rootlessRuntime, nil
-}
-
type tomlOptionsConfig struct {
MountProgram string `toml:"mount_program"`
}
diff --git a/pkg/util/utils_supported.go b/pkg/util/utils_supported.go
new file mode 100644
index 000000000..af5e67fc1
--- /dev/null
+++ b/pkg/util/utils_supported.go
@@ -0,0 +1,60 @@
+// +build linux darwin
+
+package util
+
+// TODO once rootless function is consolidated under libpod, we
+// should work to take darwin from this
+
+import (
+ "fmt"
+ "github.com/containers/libpod/pkg/rootless"
+ "github.com/pkg/errors"
+ "os"
+ "path/filepath"
+ "syscall"
+)
+
+// GetRootlessRuntimeDir returns the runtime directory when running as non root
+func GetRootlessRuntimeDir() (string, error) {
+ var rootlessRuntimeDirError error
+
+ rootlessRuntimeDirOnce.Do(func() {
+ runtimeDir := os.Getenv("XDG_RUNTIME_DIR")
+ uid := fmt.Sprintf("%d", rootless.GetRootlessUID())
+ if runtimeDir == "" {
+ tmpDir := filepath.Join("/run", "user", uid)
+ os.MkdirAll(tmpDir, 0700)
+ st, err := os.Stat(tmpDir)
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
+ runtimeDir = tmpDir
+ }
+ }
+ if runtimeDir == "" {
+ tmpDir := filepath.Join(os.TempDir(), fmt.Sprintf("run-%s", uid))
+ os.MkdirAll(tmpDir, 0700)
+ st, err := os.Stat(tmpDir)
+ if err == nil && int(st.Sys().(*syscall.Stat_t).Uid) == os.Geteuid() && st.Mode().Perm() == 0700 {
+ runtimeDir = tmpDir
+ }
+ }
+ if runtimeDir == "" {
+ home := os.Getenv("HOME")
+ if home == "" {
+ rootlessRuntimeDirError = fmt.Errorf("neither XDG_RUNTIME_DIR nor HOME was set non-empty")
+ return
+ }
+ resolvedHome, err := filepath.EvalSymlinks(home)
+ if err != nil {
+ rootlessRuntimeDirError = errors.Wrapf(err, "cannot resolve %s", home)
+ return
+ }
+ runtimeDir = filepath.Join(resolvedHome, "rundir")
+ }
+ rootlessRuntimeDir = runtimeDir
+ })
+
+ if rootlessRuntimeDirError != nil {
+ return "", rootlessRuntimeDirError
+ }
+ return rootlessRuntimeDir, nil
+}
diff --git a/pkg/util/utils_windows.go b/pkg/util/utils_windows.go
new file mode 100644
index 000000000..1e9ccea90
--- /dev/null
+++ b/pkg/util/utils_windows.go
@@ -0,0 +1,12 @@
+// +build windows
+
+package util
+
+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")
+}
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 872c7bc26..c8be41636 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -365,6 +365,21 @@ func (i *LibpodAPI) StartContainer(call iopodman.VarlinkCall, name string) error
return call.ReplyStartContainer(ctr.ID())
}
+// InitContainer initializes the container given by Varlink.
+func (i *LibpodAPI) InitContainer(call iopodman.VarlinkCall, name string) error {
+ ctr, err := i.Runtime.LookupContainer(name)
+ if err != nil {
+ return call.ReplyContainerNotFound(name, err.Error())
+ }
+ if err := ctr.Init(getContext()); err != nil {
+ if errors.Cause(err) == libpod.ErrCtrStateInvalid {
+ return call.ReplyInvalidState(ctr.ID(), err.Error())
+ }
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ return call.ReplyInitContainer(ctr.ID())
+}
+
// StopContainer ...
func (i *LibpodAPI) StopContainer(call iopodman.VarlinkCall, name string, timeout int64) error {
ctr, err := i.Runtime.LookupContainer(name)
diff --git a/pkg/varlinkapi/generate.go b/pkg/varlinkapi/generate.go
index bc600c397..9dc20d582 100644
--- a/pkg/varlinkapi/generate.go
+++ b/pkg/varlinkapi/generate.go
@@ -6,6 +6,7 @@ import (
"encoding/json"
"github.com/containers/libpod/cmd/podman/shared"
iopodman "github.com/containers/libpod/cmd/podman/varlink"
+ "github.com/containers/libpod/pkg/systemdgen"
)
// GenerateKube ...
@@ -28,3 +29,24 @@ func (i *LibpodAPI) GenerateKube(call iopodman.VarlinkCall, name string, service
Service: string(servB),
})
}
+
+// GenerateSystemd ...
+func (i *LibpodAPI) GenerateSystemd(call iopodman.VarlinkCall, nameOrID, restart string, stopTimeout int64, useName bool) error {
+ ctr, err := i.Runtime.LookupContainer(nameOrID)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ timeout := int(ctr.StopTimeout())
+ if stopTimeout >= 0 {
+ timeout = int(stopTimeout)
+ }
+ name := ctr.ID()
+ if useName {
+ name = ctr.Name()
+ }
+ unit, err := systemdgen.CreateSystemdUnitAsString(name, ctr.ID(), restart, ctr.Config().StaticDir, timeout)
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+ return call.ReplyGenerateSystemd(unit)
+}