diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/adapter/containers.go | 16 | ||||
-rw-r--r-- | pkg/adapter/terminal_linux.go | 2 | ||||
-rw-r--r-- | pkg/hooks/docs/oci-hooks.5.md | 8 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 37 | ||||
-rw-r--r-- | pkg/rootless/rootless_unsupported.go | 5 | ||||
-rw-r--r-- | pkg/spec/createconfig.go | 17 | ||||
-rw-r--r-- | pkg/spec/spec.go | 10 | ||||
-rw-r--r-- | pkg/varlinkapi/containers.go | 22 |
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 |