summaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
Diffstat (limited to 'pkg')
-rw-r--r--pkg/adapter/containers.go16
-rw-r--r--pkg/adapter/terminal_linux.go2
-rw-r--r--pkg/hooks/docs/oci-hooks.5.md8
-rw-r--r--pkg/rootless/rootless_linux.go37
-rw-r--r--pkg/rootless/rootless_unsupported.go5
-rw-r--r--pkg/spec/createconfig.go17
-rw-r--r--pkg/spec/spec.go10
-rw-r--r--pkg/varlinkapi/containers.go22
8 files changed, 74 insertions, 43 deletions
diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go
index 51efdccc7..5c33467a7 100644
--- a/pkg/adapter/containers.go
+++ b/pkg/adapter/containers.go
@@ -612,7 +612,9 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
if c.Attach {
inputStream := os.Stdin
if !c.Interactive {
- inputStream = nil
+ if !ctr.Stdin() {
+ inputStream = nil
+ }
}
// attach to the container and also start it not already running
@@ -663,7 +665,7 @@ func (r *LocalRuntime) Start(ctx context.Context, c *cliconfig.StartValues, sigP
lastError = errors.Wrapf(err, "unable to start container %q", container)
continue
}
- fmt.Println(container)
+ fmt.Println(ctr.ID())
}
return exitCode, lastError
}
@@ -899,7 +901,7 @@ func (r *LocalRuntime) execPS(c *libpod.Container, args []string) ([]string, err
}()
cmd := append([]string{"ps"}, args...)
- ec, err := c.Exec(false, false, []string{}, cmd, "", "", streams, 0, nil, "")
+ ec, err := c.Exec(false, false, map[string]string{}, cmd, "", "", streams, 0, nil, "")
if err != nil {
return nil, err
} else if ec != 0 {
@@ -959,12 +961,6 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal
return ec, errors.Wrapf(err, "unable to process environment variables")
}
- // Build env slice of key=value strings for Exec
- 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
@@ -975,7 +971,7 @@ func (r *LocalRuntime) ExecContainer(ctx context.Context, cli *cliconfig.ExecVal
streams.AttachOutput = true
streams.AttachError = true
- ec, err = ExecAttachCtr(ctx, ctr.Container, cli.Tty, cli.Privileged, envs, cmd, cli.User, cli.Workdir, streams, cli.PreserveFDs, cli.DetachKeys)
+ ec, err = ExecAttachCtr(ctx, ctr.Container, cli.Tty, cli.Privileged, env, cmd, cli.User, cli.Workdir, streams, uint(cli.PreserveFDs), cli.DetachKeys)
return define.TranslateExecErrorToExitCode(ec, err), err
}
diff --git a/pkg/adapter/terminal_linux.go b/pkg/adapter/terminal_linux.go
index 26cfd7b5e..16e552802 100644
--- a/pkg/adapter/terminal_linux.go
+++ b/pkg/adapter/terminal_linux.go
@@ -13,7 +13,7 @@ import (
)
// ExecAttachCtr execs and attaches to a container
-func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, tty, privileged bool, env, cmd []string, user, workDir string, streams *libpod.AttachStreams, preserveFDs int, detachKeys string) (int, error) {
+func ExecAttachCtr(ctx context.Context, ctr *libpod.Container, tty, privileged bool, env map[string]string, cmd []string, user, workDir string, streams *libpod.AttachStreams, preserveFDs uint, detachKeys string) (int, error) {
resize := make(chan remotecommand.TerminalSize)
haveTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
diff --git a/pkg/hooks/docs/oci-hooks.5.md b/pkg/hooks/docs/oci-hooks.5.md
index fc0442283..0a01e1bb8 100644
--- a/pkg/hooks/docs/oci-hooks.5.md
+++ b/pkg/hooks/docs/oci-hooks.5.md
@@ -88,9 +88,9 @@ $ cat /etc/containers/oci/hooks.d/oci-systemd-hook.json
"version": "1.0.0",
"hook": {
"path": "/usr/libexec/oci/hooks.d/oci-systemd-hook"
- }
+ },
"when": {
- "commands": [".*/init$" , ".*/systemd$"],
+ "commands": [".*/init$" , ".*/systemd$"]
},
"stages": ["prestart", "poststop"]
}
@@ -105,9 +105,9 @@ $ cat /etc/containers/oci/hooks.d/oci-umount.json
"hook": {
"path": "/usr/libexec/oci/hooks.d/oci-umount",
"args": ["oci-umount", "--debug"],
- }
+ },
"when": {
- "hasBindMounts": true,
+ "hasBindMounts": true
},
"stages": ["prestart"]
}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 05d641383..59f2880c3 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -16,15 +16,14 @@ import (
"strconv"
"strings"
"sync"
- "syscall"
"unsafe"
"github.com/containers/libpod/pkg/errorhandling"
"github.com/containers/storage/pkg/idtools"
- "github.com/docker/docker/pkg/signal"
"github.com/godbus/dbus"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
+ "golang.org/x/sys/unix"
)
/*
@@ -130,7 +129,7 @@ func tryMappingTool(tool string, pid int, hostID int, mappings []idtools.IDMap)
func readUserNs(path string) (string, error) {
b := make([]byte, 256)
- _, err := syscall.Readlink(path, b)
+ _, err := unix.Readlink(path, b)
if err != nil {
return "", err
}
@@ -143,7 +142,7 @@ func readUserNsFd(fd uintptr) (string, error) {
func getParentUserNs(fd uintptr) (uintptr, error) {
const nsGetParent = 0xb702
- ret, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(nsGetParent), 0)
+ ret, _, errno := unix.Syscall(unix.SYS_IOCTL, fd, uintptr(nsGetParent), 0)
if errno != 0 {
return 0, errno
}
@@ -179,7 +178,7 @@ func getUserNSFirstChild(fd uintptr) (*os.File, error) {
for {
nextFd, err := getParentUserNs(fd)
if err != nil {
- if err == syscall.ENOTTY {
+ if err == unix.ENOTTY {
return os.NewFile(fd, "userns child"), nil
}
return nil, errors.Wrapf(err, "cannot get parent user namespace")
@@ -191,14 +190,14 @@ func getUserNSFirstChild(fd uintptr) (*os.File, error) {
}
if ns == currentNS {
- if err := syscall.Close(int(nextFd)); err != nil {
+ if err := unix.Close(int(nextFd)); err != nil {
return nil, err
}
// Drop O_CLOEXEC for the fd.
- _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, fd, syscall.F_SETFD, 0)
+ _, _, errno := unix.Syscall(unix.SYS_FCNTL, fd, unix.F_SETFD, 0)
if errno != 0 {
- if err := syscall.Close(int(fd)); err != nil {
+ if err := unix.Close(int(fd)); err != nil {
logrus.Errorf("failed to close file descriptor %d", fd)
}
return nil, errno
@@ -206,7 +205,7 @@ func getUserNSFirstChild(fd uintptr) (*os.File, error) {
return os.NewFile(fd, "userns child"), nil
}
- if err := syscall.Close(int(fd)); err != nil {
+ if err := unix.Close(int(fd)); err != nil {
return nil, err
}
fd = nextFd
@@ -394,7 +393,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool,
runtime.LockOSThread()
defer runtime.UnlockOSThread()
- fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
+ fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_DGRAM, 0)
if err != nil {
return false, -1, err
}
@@ -431,12 +430,14 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool,
if err != nil {
return false, -1, errors.Wrapf(err, "cannot write setgroups file")
}
+ logrus.Debugf("write setgroups file exited with 0")
uidMap := fmt.Sprintf("/proc/%d/uid_map", pid)
err = ioutil.WriteFile(uidMap, []byte(fmt.Sprintf("%d %d 1\n", 0, os.Geteuid())), 0666)
if err != nil {
return false, -1, errors.Wrapf(err, "cannot write uid_map")
}
+ logrus.Debugf("write uid_map exited with 0")
}
gidsMapped := false
@@ -489,21 +490,21 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (bool,
signals := []os.Signal{}
for sig := 0; sig < numSig; sig++ {
- if sig == int(syscall.SIGTSTP) {
+ if sig == int(unix.SIGTSTP) {
continue
}
- signals = append(signals, syscall.Signal(sig))
+ signals = append(signals, unix.Signal(sig))
}
gosignal.Notify(c, signals...)
defer gosignal.Reset()
go func() {
for s := range c {
- if s == signal.SIGCHLD || s == signal.SIGPIPE {
+ if s == unix.SIGCHLD || s == unix.SIGPIPE {
continue
}
- if err := syscall.Kill(int(pidC), s.(syscall.Signal)); err != nil {
+ if err := unix.Kill(int(pidC), s.(unix.Signal)); err != nil {
logrus.Errorf("failed to kill %d", int(pidC))
}
}
@@ -558,7 +559,7 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
lastErr = nil
break
} else {
- fds, err := syscall.Socketpair(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
+ fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_DGRAM, 0)
if err != nil {
lastErr = err
continue
@@ -602,7 +603,7 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
return joinUserAndMountNS(uint(pausePid), pausePidPath)
}
-func readMappingsProc(path string) ([]idtools.IDMap, error) {
+func ReadMappingsProc(path string) ([]idtools.IDMap, error) {
file, err := os.Open(path)
if err != nil {
return nil, errors.Wrapf(err, "cannot open %s", path)
@@ -668,7 +669,7 @@ func ConfigurationMatches() (bool, error) {
return false, err
}
- currentUIDs, err := readMappingsProc("/proc/self/uid_map")
+ currentUIDs, err := ReadMappingsProc("/proc/self/uid_map")
if err != nil {
return false, err
}
@@ -677,7 +678,7 @@ func ConfigurationMatches() (bool, error) {
return false, err
}
- currentGIDs, err := readMappingsProc("/proc/self/gid_map")
+ currentGIDs, err := ReadMappingsProc("/proc/self/gid_map")
if err != nil {
return false, err
}
diff --git a/pkg/rootless/rootless_unsupported.go b/pkg/rootless/rootless_unsupported.go
index ddd9182b0..ce488f364 100644
--- a/pkg/rootless/rootless_unsupported.go
+++ b/pkg/rootless/rootless_unsupported.go
@@ -65,3 +65,8 @@ func ConfigurationMatches() (bool, error) {
func GetConfiguredMappings() ([]idtools.IDMap, []idtools.IDMap, error) {
return nil, nil, errors.New("this function is not supported on this os")
}
+
+// ReadMappingsProc returns the uid_map and gid_map
+func ReadMappingsProc(path string) ([]idtools.IDMap, error) {
+ return nil, nil
+}
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index a65263b7d..2addfda4b 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -104,7 +104,8 @@ type CreateConfig struct {
NetworkAlias []string //network-alias
PidMode namespaces.PidMode //pid
Pod string //pod
- CgroupMode namespaces.CgroupMode //cgroup
+ PodmanPath string
+ CgroupMode namespaces.CgroupMode //cgroup
PortBindings nat.PortMap
Privileged bool //privileged
Publish []string //publish
@@ -153,7 +154,16 @@ func (c *CreateConfig) createExitCommand(runtime *libpod.Runtime) ([]string, err
return nil, err
}
- cmd, _ := os.Executable()
+ // We need a cleanup process for containers in the current model.
+ // But we can't assume that the caller is Podman - it could be another
+ // user of the API.
+ // As such, provide a way to specify a path to Podman, so we can
+ // still invoke a cleanup process.
+ cmd := c.PodmanPath
+ if cmd == "" {
+ cmd, _ = os.Executable()
+ }
+
command := []string{cmd,
"--root", config.StorageConfig.GraphRoot,
"--runroot", config.StorageConfig.RunRoot,
@@ -195,8 +205,7 @@ func (c *CreateConfig) getContainerCreateOptions(runtime *libpod.Runtime, pod *l
if c.Interactive {
options = append(options, libpod.WithStdin())
}
- if c.Systemd && (strings.HasSuffix(c.Command[0], "init") ||
- strings.HasSuffix(c.Command[0], "systemd")) {
+ if c.Systemd {
options = append(options, libpod.WithSystemd())
}
if c.Name != "" {
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 57c6e8da7..8f00d3270 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -302,8 +302,8 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
// RESOURCES - PIDS
if config.Resources.PidsLimit > 0 {
- // if running on rootless on a cgroupv1 machine, pids limit is
- // not supported. If the value is still the default
+ // if running on rootless on a cgroupv1 machine or using the cgroupfs manager, pids
+ // limit is not supported. If the value is still the default
// then ignore the settings. If the caller asked for a
// non-default, then try to use it.
setPidLimit := true
@@ -312,7 +312,11 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
if err != nil {
return nil, err
}
- if !cgroup2 && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
+ runtimeConfig, err := runtime.GetConfig()
+ if err != nil {
+ return nil, err
+ }
+ if (!cgroup2 || runtimeConfig.CgroupManager != libpod.SystemdCgroupsManager) && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
setPidLimit = false
}
}
diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go
index 79fcef11a..b471ee2cf 100644
--- a/pkg/varlinkapi/containers.go
+++ b/pkg/varlinkapi/containers.go
@@ -9,6 +9,7 @@ import (
"io"
"io/ioutil"
"os"
+ "strings"
"sync"
"syscall"
"time"
@@ -563,9 +564,14 @@ func (i *LibpodAPI) GetAttachSockets(call iopodman.VarlinkCall, name string) err
}
}
+ sockPath, err := ctr.AttachSocketPath()
+ if err != nil {
+ return call.ReplyErrorOccurred(err.Error())
+ }
+
s := iopodman.Sockets{
Container_id: ctr.ID(),
- Io_socket: ctr.AttachSocketPath(),
+ Io_socket: sockPath,
Control_socket: ctr.ControlSocketPath(),
}
return call.ReplyGetAttachSockets(s)
@@ -811,9 +817,19 @@ func (i *LibpodAPI) ExecContainer(call iopodman.VarlinkCall, opts iopodman.ExecO
// ACK the client upgrade request
call.ReplyExecContainer()
- envs := []string{}
+ envs := make(map[string]string)
if opts.Env != nil {
- envs = *opts.Env
+ // HACK: The Varlink API uses the old []string format for env,
+ // storage as "k=v". Split on the = and turn into the new map
+ // format.
+ for _, env := range *opts.Env {
+ splitEnv := strings.SplitN(env, "=", 2)
+ if len(splitEnv) == 1 {
+ logrus.Errorf("Got badly-formatted environment variable %q in exec", env)
+ continue
+ }
+ envs[splitEnv[0]] = splitEnv[1]
+ }
}
var user string