summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml36
-rwxr-xr-xAPI.md2
-rw-r--r--Makefile5
-rw-r--r--cmd/podman/cliconfig/defaults.go5
-rw-r--r--cmd/podman/common.go11
-rw-r--r--cmd/podman/main_local.go19
-rw-r--r--cmd/podman/shared/create.go21
-rw-r--r--cmd/podman/shared/intermediate.go2
-rw-r--r--cmd/podman/shared/intermediate_varlink.go5
-rw-r--r--cmd/podman/start.go3
-rw-r--r--cmd/podman/varlink/io.podman.varlink2
-rwxr-xr-xcontrib/cirrus/integration_test.sh4
-rw-r--r--contrib/cirrus/lib.sh7
-rwxr-xr-xcontrib/cirrus/logcollector.sh11
-rw-r--r--contrib/cirrus/packer/fedora_setup.sh1
-rw-r--r--contrib/varlink/io.podman.socket1
-rw-r--r--docs/podman-create.1.md14
-rw-r--r--docs/podman-derivative-api64
-rw-r--r--docs/podman-run.1.md14
-rw-r--r--go.mod3
-rw-r--r--go.sum14
-rw-r--r--libpod/boltdb_state.go11
-rw-r--r--libpod/container_internal.go3
-rw-r--r--libpod/info.go13
-rw-r--r--libpod/runtime_ctr.go22
-rw-r--r--pkg/rootless/rootless.go45
-rw-r--r--pkg/rootless/rootless_linux.go11
-rw-r--r--pkg/rootless/rootless_unsupported.go5
-rw-r--r--pkg/spec/createconfig.go3
-rw-r--r--pkg/spec/spec.go23
-rw-r--r--pkg/sysinfo/sysinfo.go9
-rw-r--r--pkg/sysinfo/sysinfo_linux.go15
-rw-r--r--test/e2e/start_test.go4
-rw-r--r--test/e2e/systemd_test.go2
-rw-r--r--vendor/github.com/containers/psgo/.travis.yml6
-rw-r--r--vendor/github.com/containers/psgo/Makefile9
-rw-r--r--vendor/github.com/containers/psgo/go.mod2
-rw-r--r--vendor/github.com/containers/psgo/go.sum8
-rw-r--r--vendor/github.com/containers/psgo/internal/cgroups/cgroups.go44
-rw-r--r--vendor/github.com/containers/psgo/internal/proc/pids.go78
-rw-r--r--vendor/modules.txt3
41 files changed, 439 insertions, 121 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 7f295e22e..71fa68d45 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -30,7 +30,7 @@ env:
####
#### Cache-image names to test with (double-quotes around names are critical)
###
- _BUILT_IMAGE_SUFFIX: "libpod-5816955207942144"
+ _BUILT_IMAGE_SUFFIX: "libpod-6296905679634432"
FEDORA_CACHE_IMAGE_NAME: "fedora-30-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-${_BUILT_IMAGE_SUFFIX}"
SPECIAL_FEDORA_CACHE_IMAGE_NAME: "xfedora-30-${_BUILT_IMAGE_SUFFIX}"
@@ -368,38 +368,7 @@ testing_task:
df_script: '$SCRIPT_BASE/logcollector.sh df'
audit_log_script: '$SCRIPT_BASE/logcollector.sh audit'
journal_script: '$SCRIPT_BASE/logcollector.sh journal'
-
-# Test crun only on latest Fedora
-testing_crun_task:
-
- depends_on:
- - "gating"
- - "vendor"
- - "varlink_api"
- - "build_each_commit"
- - "build_without_cgo"
-
- # Only test build cache-images, if that's what's requested
- only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*'
-
- timeout_in: 120m
-
- env:
- ADD_SECOND_PARTITION: true
- OCI_RUNTIME: "/usr/bin/crun"
-
- networking_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/networking.sh'
- setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}'
- install_crun_script: 'dnf install -y crun'
- unit_test_script: '$SCRIPT_BASE/unit_test.sh |& ${TIMESTAMP}'
- integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}'
- system_test_script: '$SCRIPT_BASE/system_test.sh |& ${TIMESTAMP}'
-
- on_failure:
- failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh'
-
- always:
- <<: *standardlogs
+ varlink_script: '$SCRIPT_BASE/logcollector.sh varlink'
# This task executes tests under unique environments/conditions
@@ -686,7 +655,6 @@ success_task:
- "meta"
- "image_prune"
- "testing"
- - "testing_crun"
- "special_testing_rootless"
- "special_testing_in_podman"
- "special_testing_cgroupv2"
diff --git a/API.md b/API.md
index a9905c940..a2a093bec 100755
--- a/API.md
+++ b/API.md
@@ -1591,7 +1591,7 @@ subgidname [?string](#?string)
sysctl [?[]string](#?[]string)
-systemd [?bool](#?bool)
+systemd [?string](#?string)
tmpfs [?[]string](#?[]string)
diff --git a/Makefile b/Makefile
index 97f5d407c..735981d34 100644
--- a/Makefile
+++ b/Makefile
@@ -89,6 +89,9 @@ RELEASE_DIST_VER ?= $(shell hack/get_release_info.sh DIST_VER)
RELEASE_ARCH ?= $(shell hack/get_release_info.sh ARCH)
RELEASE_BASENAME := $(shell hack/get_release_info.sh BASENAME)
+# If non-empty, logs all output from varlink during remote system testing
+VARLINK_LOG ?=
+
# If GOPATH not specified, use one in the local directory
ifeq ($(GOPATH),)
export GOPATH := $(CURDIR)/_output
@@ -274,7 +277,7 @@ remotesystem:
if timeout -v 1 true; then \
SOCK_FILE=$(shell mktemp --dry-run --tmpdir io.podman.XXXXXX);\
export PODMAN_VARLINK_ADDRESS=unix:$$SOCK_FILE; \
- ./bin/podman varlink --timeout=0 $$PODMAN_VARLINK_ADDRESS &>/dev/null & \
+ ./bin/podman varlink --timeout=0 $$PODMAN_VARLINK_ADDRESS &> $(if $(VARLINK_LOG),$(VARLINK_LOG),/dev/null) & \
retry=5;\
while [[ $$retry -ge 0 ]]; do\
echo Waiting for varlink server...;\
diff --git a/cmd/podman/cliconfig/defaults.go b/cmd/podman/cliconfig/defaults.go
index d5dae0874..ce695d153 100644
--- a/cmd/podman/cliconfig/defaults.go
+++ b/cmd/podman/cliconfig/defaults.go
@@ -1,10 +1,5 @@
package cliconfig
-const (
- // DefaultSystemD value
- DefaultSystemD bool = true
-)
-
var (
// DefaultHealthCheckInterval default value
DefaultHealthCheckInterval = "30s"
diff --git a/cmd/podman/common.go b/cmd/podman/common.go
index 0115e6ef1..e93586b62 100644
--- a/cmd/podman/common.go
+++ b/cmd/podman/common.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/libpod/cmd/podman/shared"
"github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/sysinfo"
"github.com/fatih/camelcase"
jsoniter "github.com/json-iterator/go"
"github.com/pkg/errors"
@@ -374,8 +375,8 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"PID namespace to use",
)
createFlags.Int64(
- "pids-limit", 0,
- "Tune container pids limit (set -1 for unlimited)",
+ "pids-limit", sysinfo.GetDefaultPidsLimit(),
+ "Tune container pids limit (set 0 for unlimited)",
)
createFlags.String(
"pod", "",
@@ -454,9 +455,9 @@ func getCreateFlags(c *cliconfig.PodmanCommand) {
"sysctl", []string{},
"Sysctl options (default [])",
)
- createFlags.Bool(
- "systemd", cliconfig.DefaultSystemD,
- "Run container in systemd mode if the command executable is systemd or init",
+ createFlags.String(
+ "systemd", "true",
+ `Run container in systemd mode ("true"|"false"|"always" (default "true")`,
)
createFlags.StringArray(
"tmpfs", []string{},
diff --git a/cmd/podman/main_local.go b/cmd/podman/main_local.go
index 917096e17..bdffb6b1e 100644
--- a/cmd/podman/main_local.go
+++ b/cmd/podman/main_local.go
@@ -200,17 +200,12 @@ func setupRootless(cmd *cobra.Command, args []string) error {
return errors.Wrapf(err, "could not get pause process pid file path")
}
- if _, err := os.Stat(pausePidPath); err == nil {
- became, ret, err := rootless.TryJoinFromFilePaths("", false, []string{pausePidPath})
- if err != nil {
- logrus.Errorf("cannot join pause process. You may need to remove %s and stop all containers", pausePidPath)
- logrus.Errorf("you can use `%s system migrate` to recreate the pause process and restart the containers", os.Args[0])
- logrus.Errorf(err.Error())
- os.Exit(1)
- }
- if became {
- os.Exit(ret)
- }
+ became, ret, err := rootless.TryJoinPauseProcess(pausePidPath)
+ if err != nil {
+ return err
+ }
+ if became {
+ os.Exit(ret)
}
// if there is no pid file, try to join existing containers, and create a pause process.
@@ -225,7 +220,7 @@ func setupRootless(cmd *cobra.Command, args []string) error {
paths = append(paths, ctr.Config().ConmonPidFile)
}
- became, ret, err := rootless.TryJoinFromFilePaths(pausePidPath, true, paths)
+ became, ret, err = rootless.TryJoinFromFilePaths(pausePidPath, true, paths)
if err := movePauseProcessToScope(); err != nil {
conf, err := runtime.GetConfig()
if err != nil {
diff --git a/cmd/podman/shared/create.go b/cmd/podman/shared/create.go
index c9b05d2c4..7c56db8db 100644
--- a/cmd/podman/shared/create.go
+++ b/cmd/podman/shared/create.go
@@ -662,9 +662,17 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
return nil, errors.Errorf("invalid image-volume type %q. Pick one of bind, tmpfs, or ignore", c.String("image-volume"))
}
- var systemd bool
- if command != nil && c.Bool("systemd") && ((filepath.Base(command[0]) == "init") || (filepath.Base(command[0]) == "systemd")) {
- systemd = true
+ systemd := c.String("systemd") == "always"
+ if !systemd && command != nil {
+ x, err := strconv.ParseBool(c.String("systemd"))
+ if err != nil {
+ return nil, errors.Wrapf(err, "cannot parse bool %s", c.String("systemd"))
+ }
+ if x && (command[0] == "/usr/sbin/init" || (filepath.Base(command[0]) == "systemd")) {
+ systemd = true
+ }
+ }
+ if systemd {
if signalString == "" {
stopSignal, err = signal.ParseSignal("RTMIN+3")
if err != nil {
@@ -686,6 +694,11 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
logDriver = c.String("log-driver")
}
+ pidsLimit := c.Int64("pids-limit")
+ if c.String("cgroups") == "disabled" && !c.Changed("pids-limit") {
+ pidsLimit = 0
+ }
+
config := &cc.CreateConfig{
Annotations: annotations,
BuiltinImgVolumes: ImageVolumes,
@@ -764,7 +777,7 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
MemorySwappiness: int(memorySwappiness),
KernelMemory: memoryKernel,
OomScoreAdj: c.Int("oom-score-adj"),
- PidsLimit: c.Int64("pids-limit"),
+ PidsLimit: pidsLimit,
Ulimit: c.StringSlice("ulimit"),
},
RestartPolicy: c.String("restart"),
diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go
index cccdd1bea..0f71dc087 100644
--- a/cmd/podman/shared/intermediate.go
+++ b/cmd/podman/shared/intermediate.go
@@ -449,7 +449,7 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes
m["subgidname"] = newCRString(c, "subgidname")
m["subuidname"] = newCRString(c, "subuidname")
m["sysctl"] = newCRStringSlice(c, "sysctl")
- m["systemd"] = newCRBool(c, "systemd")
+ m["systemd"] = newCRString(c, "systemd")
m["tmpfs"] = newCRStringArray(c, "tmpfs")
m["tty"] = newCRBool(c, "tty")
m["uidmap"] = newCRStringSlice(c, "uidmap")
diff --git a/cmd/podman/shared/intermediate_varlink.go b/cmd/podman/shared/intermediate_varlink.go
index 9dbf83950..c95470a72 100644
--- a/cmd/podman/shared/intermediate_varlink.go
+++ b/cmd/podman/shared/intermediate_varlink.go
@@ -152,7 +152,7 @@ func (g GenericCLIResults) MakeVarlink() iopodman.Create {
Subuidname: StringToPtr(g.Find("subuidname")),
Subgidname: StringToPtr(g.Find("subgidname")),
Sysctl: StringSliceToPtr(g.Find("sysctl")),
- Systemd: BoolToPtr(g.Find("systemd")),
+ Systemd: StringToPtr(g.Find("systemd")),
Tmpfs: StringSliceToPtr(g.Find("tmpfs")),
Tty: BoolToPtr(g.Find("tty")),
Uidmap: StringSliceToPtr(g.Find("uidmap")),
@@ -321,6 +321,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
var memSwapDefault int64 = -1
netModeDefault := "bridge"
+ systemdDefault := "true"
if rootless.IsRootless() {
netModeDefault = "slirp4netns"
}
@@ -409,7 +410,7 @@ func VarlinkCreateToGeneric(opts iopodman.Create) GenericCLIResults {
m["subgidname"] = stringFromVarlink(opts.Subgidname, "subgidname", nil)
m["subuidname"] = stringFromVarlink(opts.Subuidname, "subuidname", nil)
m["sysctl"] = stringSliceFromVarlink(opts.Sysctl, "sysctl", nil)
- m["systemd"] = boolFromVarlink(opts.Systemd, "systemd", cliconfig.DefaultSystemD)
+ m["systemd"] = stringFromVarlink(opts.Systemd, "systemd", &systemdDefault)
m["tmpfs"] = stringSliceFromVarlink(opts.Tmpfs, "tmpfs", nil)
m["tty"] = boolFromVarlink(opts.Tty, "tty", false)
m["uidmap"] = stringSliceFromVarlink(opts.Uidmap, "uidmap", nil)
diff --git a/cmd/podman/start.go b/cmd/podman/start.go
index 737a6d9f1..2d2cf74d2 100644
--- a/cmd/podman/start.go
+++ b/cmd/podman/start.go
@@ -60,6 +60,9 @@ func startCmd(c *cliconfig.StartValues) error {
}
sigProxy := c.SigProxy || attach
+ if c.Flag("sig-proxy").Changed {
+ sigProxy = c.SigProxy
+ }
if sigProxy && !attach {
return errors.Wrapf(define.ErrInvalidArg, "you cannot use sig-proxy without --attach")
diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink
index 2408dc80c..13e8394fb 100644
--- a/cmd/podman/varlink/io.podman.varlink
+++ b/cmd/podman/varlink/io.podman.varlink
@@ -363,7 +363,7 @@ type Create (
subuidname: ?string,
subgidname: ?string,
sysctl: ?[]string,
- systemd: ?bool,
+ systemd: ?string,
tmpfs: ?[]string,
tty: ?bool,
uidmap: ?[]string,
diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh
index 110066ea7..e8f6c50d9 100755
--- a/contrib/cirrus/integration_test.sh
+++ b/contrib/cirrus/integration_test.sh
@@ -4,7 +4,7 @@ set -e
source $(dirname $0)/lib.sh
-req_env_var GOSRC SCRIPT_BASE OS_RELEASE_ID OS_RELEASE_VER CONTAINER_RUNTIME
+req_env_var GOSRC SCRIPT_BASE OS_RELEASE_ID OS_RELEASE_VER CONTAINER_RUNTIME VARLINK_LOG
# Our name must be of the form xxxx_test or xxxx_test.sh, where xxxx is
# the test suite to run; currently (2019-05) the only option is 'integration'
@@ -59,7 +59,7 @@ case "$SPECIALMODE" in
make test-binaries
if [[ "$TEST_REMOTE_CLIENT" == "true" ]]
then
- make remote${TESTSUITE}
+ make remote${TESTSUITE} VARLINK_LOG=$VARLINK_LOG
else
make local${TESTSUITE}
fi
diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh
index fe4c25e73..8a7d3c1a3 100644
--- a/contrib/cirrus/lib.sh
+++ b/contrib/cirrus/lib.sh
@@ -35,6 +35,9 @@ PACKER_BASE=${PACKER_BASE:-./contrib/cirrus/packer}
SETUP_MARKER_FILEPATH="${SETUP_MARKER_FILEPATH:-/var/tmp/.setup_environment_sh_complete}"
AUTHOR_NICKS_FILEPATH="${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/git_authors_to_irc_nicks.csv"
+# Log remote-client system test varlink output here
+export VARLINK_LOG=/var/tmp/varlink.log
+
cd $GOSRC
if type -P git &> /dev/null && [[ -d "$GOSRC/.git" ]]
then
@@ -370,8 +373,8 @@ remove_packaged_podman_files() {
# yum/dnf/dpkg may list system directories, only remove files
$LISTING_CMD | while read fullpath
do
- # TODO: This can go away when conmon gets it's own package
- if [[ -d "$fullpath" ]] || [[ $(basename "$fullpath") == "conmon" ]] ; then continue; fi
+ # Sub-directories may contain unrelated/valuable stuff
+ if [[ -d "$fullpath" ]]; then continue; fi
ooe.sh sudo rm -vf "$fullpath"
done
diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh
index b0a644f8c..17f5eb099 100755
--- a/contrib/cirrus/logcollector.sh
+++ b/contrib/cirrus/logcollector.sh
@@ -4,7 +4,7 @@ set -e
source $(dirname $0)/lib.sh
-req_env_var CIRRUS_WORKING_DIR OS_RELEASE_ID
+req_env_var CIRRUS_WORKING_DIR OS_RELEASE_ID TEST_REMOTE_CLIENT
# Assume there are other log collection commands to follow - Don't
# let one break another that may be useful, but also keep any
@@ -32,6 +32,15 @@ case $1 in
df) showrun df -lhTx tmpfs ;;
ginkgo) showrun cat $CIRRUS_WORKING_DIR/test/e2e/ginkgo-node-*.log ;;
journal) showrun journalctl -b ;;
+ varlink)
+ if [[ "$TEST_REMOTE_CLIENT" == "true" ]]
+ then
+ echo "(Trailing 100 lines of $VARLINK_LOG)"
+ showrun tail -100 $VARLINK_LOG
+ else
+ die 0 "\$TEST_REMOTE_CLIENT is not 'true': $TEST_REMOTE_CLIENT"
+ fi
+ ;;
packages)
# These names are common to Fedora and Ubuntu
PKG_NAMES=(\
diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh
index 679ad3b8d..38b9e6860 100644
--- a/contrib/cirrus/packer/fedora_setup.sh
+++ b/contrib/cirrus/packer/fedora_setup.sh
@@ -31,6 +31,7 @@ ooe.sh sudo dnf install -y \
bridge-utils \
btrfs-progs-devel \
bzip2 \
+ conmon \
container-selinux \
containernetworking-plugins \
containers-common \
diff --git a/contrib/varlink/io.podman.socket b/contrib/varlink/io.podman.socket
index 629a5dd20..f6a3ddc49 100644
--- a/contrib/varlink/io.podman.socket
+++ b/contrib/varlink/io.podman.socket
@@ -8,4 +8,3 @@ SocketMode=0600
[Install]
WantedBy=sockets.target
-Also=multi-user.target
diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md
index c088f3e94..35602f97b 100644
--- a/docs/podman-create.1.md
+++ b/docs/podman-create.1.md
@@ -552,7 +552,7 @@ Default is to create a private PID namespace for the container
**--pids-limit**=*limit*
-Tune the container's pids limit. Set `-1` to have unlimited pids for the container.
+Tune the container's pids limit. Set `0` to have unlimited pids for the container. (default "4096" on systems that support PIDS cgroups).
**--pod**=*name*
@@ -710,12 +710,18 @@ Network Namespace - current sysctls allowed:
Note: if you use the --network=host option these sysctls will not be allowed.
-**--systemd**=*true|false*
+**--systemd**=*true|false|always*
Run container in systemd mode. The default is *true*.
-If the command you running inside of the container is systemd or init, podman
-will setup tmpfs mount points in the following directories:
+The value *always* enforces the systemd mode is enforced without
+looking at the executable name. Otherwise, if set to true and the
+command you are running inside the container is systemd or
+/usr/sbin/init.
+
+If the command you are running inside of the container is systemd or
+/usr/sbin/init, Podman will setup tmpfs mount points in the following
+directories:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
diff --git a/docs/podman-derivative-api b/docs/podman-derivative-api
new file mode 100644
index 000000000..1b6153df5
--- /dev/null
+++ b/docs/podman-derivative-api
@@ -0,0 +1,64 @@
+.TH How to use libpod for custom/derivative projects
+.PP
+libpod today is a Golang library and a CLI. The choice of interface you make has advantages and disadvantages.
+
+.SH Running as a subprocess
+.PP
+Advantages:
+
+.RS
+.IP \(bu 2
+Many commands output JSON
+.IP \(bu 2
+Works with languages other than Golang
+.IP \(bu 2
+Easy to get started
+
+.RE
+
+.PP
+Disadvantages:
+
+.RS
+.IP \(bu 2
+Error handling is harder
+.IP \(bu 2
+May be slower
+.IP \(bu 2
+Can't hook into or control low\-level things like how images are pulled
+
+.RE
+
+.SH Vendoring into a Go project
+.PP
+Advantages:
+
+.RS
+.IP \(bu 2
+Significant power and control
+
+.RE
+
+.PP
+Disadvantages:
+
+.RS
+.IP \(bu 2
+You are now on the hook for container runtime security updates (partially, \fB\fCrunc\fR/\fB\fCcrun\fR are separate)
+.IP \(bu 2
+Binary size
+.IP \(bu 2
+Potential skew between multiple libpod versions operating on the same storage can cause problems
+
+.RE
+
+.SH Varlink
+.PP
+Some code exists for this; splits the difference. Future uncertain.
+
+.SH Making the choice
+.PP
+A good question to ask first is: Do you want users to be able to use \fB\fCpodman\fR to manipulate the containers created by your project?
+If so, that makes it more likely that you want to run \fB\fCpodman\fR as a subprocess. If you want a separate image store and a fundamentally
+different experience; if what you're doing with containers is quite different from those created by the \fB\fCpodman\fR CLI,
+that may drive you towards vendoring.
diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md
index d677f8262..e255119d7 100644
--- a/docs/podman-run.1.md
+++ b/docs/podman-run.1.md
@@ -565,7 +565,7 @@ Default is to create a private PID namespace for the container
**--pids-limit**=*limit*
-Tune the container's pids limit. Set `-1` to have unlimited pids for the container.
+Tune the container's pids limit. Set `0` to have unlimited pids for the container. (default "4096" on systems that support PIDS cgroups).
**--pod**=*name*
@@ -747,12 +747,18 @@ Network Namespace - current sysctls allowed:
Note: if you use the `--network=host` option these sysctls will not be allowed.
-**--systemd**=*true|false*
+**--systemd**=*true|false|always*
Run container in systemd mode. The default is *true*.
-If the command you are running inside of the container is systemd or init, Podman
-will setup tmpfs mount points in the following directories:
+The value *always* enforces the systemd mode is enforced without
+looking at the executable name. Otherwise, if set to true and the
+command you are running inside the container is systemd or
+/usr/sbin/init.
+
+If the command you are running inside of the container is systemd or
+/usr/sbin/init, Podman will setup tmpfs mount points in the following
+directories:
/run, /run/lock, /tmp, /sys/fs/cgroup/systemd, /var/lib/journal
diff --git a/go.mod b/go.mod
index 40a05553c..356ceaa7a 100644
--- a/go.mod
+++ b/go.mod
@@ -14,9 +14,8 @@ require (
github.com/containernetworking/cni v0.7.1
github.com/containernetworking/plugins v0.8.2
github.com/containers/buildah v1.11.3
- github.com/containers/image v3.0.2+incompatible // indirect
github.com/containers/image/v4 v4.0.1
- github.com/containers/psgo v1.3.1
+ github.com/containers/psgo v1.3.2
github.com/containers/storage v1.13.4
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
diff --git a/go.sum b/go.sum
index 24bcc6ed8..e724b93d0 100644
--- a/go.sum
+++ b/go.sum
@@ -69,6 +69,20 @@ github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDpl
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/psgo v1.3.1 h1:1kE+jJ9Ou5f9zQT/M2IdeSclsKWsXrSFlOcnqc+F2TA=
github.com/containers/psgo v1.3.1/go.mod h1:LLiRMmxZ6FWP4bB/fOUu6kDT+4okk/ZCeeykqh0O5Ns=
+github.com/containers/psgo v1.3.2 h1:jYfppPih3S/j2Yi5O14AXjd8GfCx1ph9L3YsoK3adko=
+github.com/containers/psgo v1.3.2/go.mod h1:ENXXLQ5E1At4K0EUsGogXBJi/C28gwqkONWeLPI9fJ8=
+github.com/containers/storage v1.12.10-0.20190627120555-8eed0c36d1e3 h1:kO/YA36sGuPDFvVIzZxJp7xmwa+/wCVADxDSuFzsZwM=
+github.com/containers/storage v1.12.10-0.20190627120555-8eed0c36d1e3/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.11 h1:r35VsROen9Kw3+LN/v4O4g7cT5zQPX06vkcjqScJ2z8=
+github.com/containers/storage v1.12.11/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.12 h1:gao0GNzjmSX4Ai/StOHtUVIrBguC0OKyvx/ZMwBdyuY=
+github.com/containers/storage v1.12.12/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.13 h1:GtaLCY8p1Drlk1Oew581jGvB137UaO+kpz0HII67T0A=
+github.com/containers/storage v1.12.13/go.mod h1:+RirK6VQAqskQlaTBrOG6ulDvn4si2QjFE1NZCn06MM=
+github.com/containers/storage v1.12.16 h1:zePYS1GiG8CuRqLCeA0ufx4X27K06HcJLV50DdojL+Y=
+github.com/containers/storage v1.12.16/go.mod h1:QsZp4XMJjyPNNbQHZeyNW3OmhwsWviI+7S6iOcu6a4c=
+github.com/containers/storage v1.13.1 h1:rjVirLS9fCGkUFlLDZEoGDDUugtIf46DufWvJu08wxQ=
+github.com/containers/storage v1.13.1/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.2 h1:UXZ0Ckmk6+6+4vj2M2ywruVtH97pnRoAhTG8ctd+yQI=
github.com/containers/storage v1.13.2/go.mod h1:6D8nK2sU9V7nEmAraINRs88ZEscM5C5DK+8Npp27GeA=
github.com/containers/storage v1.13.4 h1:j0bBaJDKbUHtAW1MXPFnwXJtqcH+foWeuXK1YaBV5GA=
diff --git a/libpod/boltdb_state.go b/libpod/boltdb_state.go
index e43d54eee..0bb1df7b8 100644
--- a/libpod/boltdb_state.go
+++ b/libpod/boltdb_state.go
@@ -2,6 +2,7 @@ package libpod
import (
"bytes"
+ "os"
"strings"
"sync"
@@ -658,9 +659,13 @@ func (s *BoltState) UpdateContainer(ctr *Container) error {
return err
}
- // Handle network namespace
- if err := replaceNetNS(netNSPath, ctr, newState); err != nil {
- return err
+ // Handle network namespace.
+ if os.Geteuid() == 0 {
+ // Do it only when root, either on the host or as root in the
+ // user namespace.
+ if err := replaceNetNS(netNSPath, ctr, newState); err != nil {
+ return err
+ }
}
// New state compiled successfully, swap it into the current state
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index a4dcd23be..ac921d737 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -939,6 +939,9 @@ func (c *Container) init(ctx context.Context, retainRetries bool) error {
// With the spec complete, do an OCI create
if err := c.ociRuntime.createContainer(c, nil); err != nil {
+ if strings.Contains(err.Error(), "this version of runc doesn't work on cgroups v2") {
+ logrus.Errorf("oci runtime %q does not support CGroups V2: use system migrate to mitigate", c.ociRuntime.name)
+ }
return err
}
diff --git a/libpod/info.go b/libpod/info.go
index 297086ebb..6caa87038 100644
--- a/libpod/info.go
+++ b/libpod/info.go
@@ -69,6 +69,18 @@ func (r *Runtime) hostInfo() (map[string]interface{}, error) {
program["Package"] = packageVersion(path)
info["slirp4netns"] = program
}
+ uidmappings, err := rootless.ReadMappingsProc("/proc/self/uid_map")
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading uid mappings")
+ }
+ gidmappings, err := rootless.ReadMappingsProc("/proc/self/gid_map")
+ if err != nil {
+ return nil, errors.Wrapf(err, "error reading gid mappings")
+ }
+ idmappings := make(map[string]interface{})
+ idmappings["uidmap"] = uidmappings
+ idmappings["gidmap"] = gidmappings
+ info["IDMappings"] = idmappings
}
info["OCIRuntime"] = map[string]interface{}{
"path": r.defaultOCIRuntime.path,
@@ -128,6 +140,7 @@ func (r *Runtime) hostInfo() (map[string]interface{}, error) {
}
info["hostname"] = host
info["eventlogger"] = r.eventer.String()
+
return info, nil
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 1a2987244..78176a400 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -576,11 +576,33 @@ func (r *Runtime) evictContainer(ctx context.Context, idOrName string, removeVol
if !r.valid {
return "", define.ErrRuntimeStopped
}
+
id, err := r.state.LookupContainerID(idOrName)
if err != nil {
return "", errors.Wrapf(err, "Failed to find container %q in state", idOrName)
}
+ // Begin by trying a normal removal. Valid containers will be removed normally.
+ tmpCtr, err := r.state.Container(id)
+ if err == nil {
+ logrus.Infof("Container %s successfully retrieved from state, attempting normal removal", id)
+ // Assume force = true for the evict case
+ err = r.removeContainer(ctx, tmpCtr, true, removeVolume, false)
+ if !tmpCtr.valid {
+ // If the container is marked invalid, remove succeeded
+ // in kicking it out of the state - no need to continue.
+ return id, err
+ }
+
+ if err == nil {
+ // Something has gone seriously wrong - no error but
+ // container was not removed.
+ logrus.Errorf("Container %s not removed with no error", id)
+ } else {
+ logrus.Warnf("Failed to removal container %s normally, proceeding with evict: %v", id, err)
+ }
+ }
+
// Error out if the container does not exist in libpod
exists, err := r.state.HasContainer(id)
if err != nil {
diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go
new file mode 100644
index 000000000..7e9fe9db6
--- /dev/null
+++ b/pkg/rootless/rootless.go
@@ -0,0 +1,45 @@
+package rootless
+
+import (
+ "os"
+
+ "github.com/containers/storage"
+ "github.com/pkg/errors"
+)
+
+func TryJoinPauseProcess(pausePidPath string) (bool, int, error) {
+ if _, err := os.Stat(pausePidPath); err != nil {
+ return false, -1, nil
+ }
+
+ became, ret, err := TryJoinFromFilePaths("", false, []string{pausePidPath})
+ if err == nil {
+ return became, ret, err
+ }
+
+ // It could not join the pause process, let's lock the file before trying to delete it.
+ pidFileLock, err := storage.GetLockfile(pausePidPath)
+ if err != nil {
+ // The file was deleted by another process.
+ if os.IsNotExist(err) {
+ return false, -1, nil
+ }
+ return false, -1, errors.Wrapf(err, "error acquiring lock on %s", pausePidPath)
+ }
+
+ pidFileLock.Lock()
+ defer func() {
+ if pidFileLock.Locked() {
+ pidFileLock.Unlock()
+ }
+ }()
+
+ // Now the pause PID file is locked. Try to join once again in case it changed while it was not locked.
+ became, ret, err = TryJoinFromFilePaths("", false, []string{pausePidPath})
+ if err != nil {
+ // It is still failing. We can safely remove it.
+ os.Remove(pausePidPath)
+ return false, -1, nil
+ }
+ return became, ret, err
+}
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 6f6239e5f..99307e8c4 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -431,12 +431,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
@@ -566,10 +568,10 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
r, w := os.NewFile(uintptr(fds[0]), "read file"), os.NewFile(uintptr(fds[1]), "write file")
- defer errorhandling.CloseQuiet(w)
defer errorhandling.CloseQuiet(r)
if _, _, err := becomeRootInUserNS("", path, w); err != nil {
+ w.Close()
lastErr = err
continue
}
@@ -578,7 +580,6 @@ func TryJoinFromFilePaths(pausePidPath string, needNewNamespace bool, paths []st
return false, 0, err
}
defer func() {
- errorhandling.CloseQuiet(r)
C.reexec_in_user_namespace_wait(-1, 0)
}()
@@ -603,7 +604,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)
@@ -669,7 +670,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
}
@@ -678,7 +679,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..3685450f0 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -195,8 +195,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 c7aa003e8..57c6e8da7 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -7,6 +7,7 @@ import (
"github.com/containers/libpod/libpod"
"github.com/containers/libpod/pkg/cgroups"
"github.com/containers/libpod/pkg/rootless"
+ "github.com/containers/libpod/pkg/sysinfo"
"github.com/docker/docker/oci/caps"
"github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/user"
@@ -300,9 +301,25 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
blockAccessToKernelFilesystems(config, &g)
// RESOURCES - PIDS
- if config.Resources.PidsLimit != 0 {
- g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit)
- addedResources = true
+ 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
+ // then ignore the settings. If the caller asked for a
+ // non-default, then try to use it.
+ setPidLimit := true
+ if rootless.IsRootless() {
+ cgroup2, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, err
+ }
+ if !cgroup2 && config.Resources.PidsLimit == sysinfo.GetDefaultPidsLimit() {
+ setPidLimit = false
+ }
+ }
+ if setPidLimit {
+ g.SetLinuxResourcesPidsLimit(config.Resources.PidsLimit)
+ addedResources = true
+ }
}
for name, val := range config.Env {
diff --git a/pkg/sysinfo/sysinfo.go b/pkg/sysinfo/sysinfo.go
index f046de4b1..686f66ce5 100644
--- a/pkg/sysinfo/sysinfo.go
+++ b/pkg/sysinfo/sysinfo.go
@@ -142,3 +142,12 @@ func popcnt(x uint64) (n byte) {
x *= 0x0101010101010101
return byte(x >> 56)
}
+
+// GetDefaultPidsLimit returns the default pids limit to run containers with
+func GetDefaultPidsLimit() int64 {
+ sysInfo := New(true)
+ if !sysInfo.PidsLimit {
+ return 0
+ }
+ return 4096
+}
diff --git a/pkg/sysinfo/sysinfo_linux.go b/pkg/sysinfo/sysinfo_linux.go
index 9e675c655..76bda23c6 100644
--- a/pkg/sysinfo/sysinfo_linux.go
+++ b/pkg/sysinfo/sysinfo_linux.go
@@ -7,6 +7,7 @@ import (
"path"
"strings"
+ cg "github.com/containers/libpod/pkg/cgroups"
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
@@ -227,12 +228,18 @@ func checkCgroupCpusetInfo(cgMounts map[string]string, quiet bool) cgroupCpusetI
// checkCgroupPids reads the pids information from the pids cgroup mount point.
func checkCgroupPids(quiet bool) cgroupPids {
- _, err := cgroups.FindCgroupMountpoint("", "pids")
+ cgroup2, err := cg.IsCgroup2UnifiedMode()
if err != nil {
- if !quiet {
- logrus.Warn(err)
+ logrus.Errorf("Failed to check cgroups version: %v", err)
+ }
+ if !cgroup2 {
+ _, err := cgroups.FindCgroupMountpoint("", "pids")
+ if err != nil {
+ if !quiet {
+ logrus.Warn(err)
+ }
+ return cgroupPids{}
}
- return cgroupPids{}
}
return cgroupPids{
diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go
index 06ab6aacd..13f14183b 100644
--- a/test/e2e/start_test.go
+++ b/test/e2e/start_test.go
@@ -110,7 +110,7 @@ var _ = Describe("Podman start", func() {
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).Should(BeNumerically(">", 0))
- Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout).Should(BeZero())
+ Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout, 3.0).Should(BeZero())
})
It("podman failed to start without --rm should NOT delete the container", func() {
@@ -122,7 +122,7 @@ var _ = Describe("Podman start", func() {
start.WaitWithDefaultTimeout()
Expect(start.ExitCode()).Should(BeNumerically(">", 0))
- Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout).Should(Equal(1))
+ Eventually(podmanTest.NumberOfContainers(), defaultWaitTimeout, 3.0).Should(Equal(1))
})
It("podman start --sig-proxy should not work without --attach", func() {
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index 02778d493..9ec48ba00 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -94,7 +94,7 @@ WantedBy=multi-user.target
Expect(pull.ExitCode()).To(Equal(0))
ctrName := "testSystemd"
- run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", systemdImage, "init"})
+ run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", systemdImage, "/usr/sbin/init"})
run.WaitWithDefaultTimeout()
Expect(run.ExitCode()).To(Equal(0))
ctrID := run.OutputToString()
diff --git a/vendor/github.com/containers/psgo/.travis.yml b/vendor/github.com/containers/psgo/.travis.yml
index 1399d24d3..c07bb140b 100644
--- a/vendor/github.com/containers/psgo/.travis.yml
+++ b/vendor/github.com/containers/psgo/.travis.yml
@@ -14,6 +14,6 @@ before_install:
- sudo apt-get install -qq bats
script:
- - make validate || travis_terminate 1
- - make build || travis_terminate 1
- - make test || travis_terminate 1
+ - make validate
+ - make build
+ - make test
diff --git a/vendor/github.com/containers/psgo/Makefile b/vendor/github.com/containers/psgo/Makefile
index 6050b9d5b..361820784 100644
--- a/vendor/github.com/containers/psgo/Makefile
+++ b/vendor/github.com/containers/psgo/Makefile
@@ -1,4 +1,5 @@
export GO111MODULE=off
+export GOPROXY=https://proxy.golang.org
SHELL= /bin/bash
GO ?= go
@@ -9,11 +10,17 @@ PROJECT := github.com/containers/psgo
BATS_TESTS := *.bats
GO_SRC=$(shell find . -name \*.go)
+GO_BUILD=$(GO) build
+# Go module support: set `-mod=vendor` to use the vendored sources
+ifeq ($(shell go help mod >/dev/null 2>&1 && echo true), true)
+ GO_BUILD=GO111MODULE=on $(GO) build -mod=vendor
+endif
+
all: validate build
.PHONY: build
build: $(GO_SRC)
- $(GO) build -buildmode=pie -o $(BUILD_DIR)/$(NAME) $(PROJECT)/sample
+ $(GO_BUILD) -buildmode=pie -o $(BUILD_DIR)/$(NAME) $(PROJECT)/sample
.PHONY: clean
clean:
diff --git a/vendor/github.com/containers/psgo/go.mod b/vendor/github.com/containers/psgo/go.mod
index a194ec196..d9d54c5f7 100644
--- a/vendor/github.com/containers/psgo/go.mod
+++ b/vendor/github.com/containers/psgo/go.mod
@@ -6,6 +6,6 @@ require (
github.com/opencontainers/runc v0.0.0-20190425234816-dae70e8efea4
github.com/pkg/errors v0.0.0-20190227000051-27936f6d90f9
github.com/sirupsen/logrus v0.0.0-20190403091019-9b3cdde74fbe
- github.com/stretchr/testify v1.3.0
+ github.com/stretchr/testify v1.4.0
golang.org/x/sys v0.0.0-20190425145619-16072639606e
)
diff --git a/vendor/github.com/containers/psgo/go.sum b/vendor/github.com/containers/psgo/go.sum
index da6c750db..bbdd99730 100644
--- a/vendor/github.com/containers/psgo/go.sum
+++ b/vendor/github.com/containers/psgo/go.sum
@@ -16,8 +16,12 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
-github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190425145619-16072639606e h1:4ktJgTV34+N3qOZUc5fAaG3Pb11qzMm3PkAoTAgUZ2I=
golang.org/x/sys v0.0.0-20190425145619-16072639606e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/vendor/github.com/containers/psgo/internal/cgroups/cgroups.go b/vendor/github.com/containers/psgo/internal/cgroups/cgroups.go
new file mode 100644
index 000000000..eecaf87cb
--- /dev/null
+++ b/vendor/github.com/containers/psgo/internal/cgroups/cgroups.go
@@ -0,0 +1,44 @@
+// Copyright 2019 psgo authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cgroups
+
+import (
+ "sync"
+ "syscall"
+)
+
+const (
+ CgroupRoot = "/sys/fs/cgroup"
+ cgroup2SuperMagic = 0x63677270
+)
+
+var (
+ isUnifiedOnce sync.Once
+ isUnified bool
+ isUnifiedErr error
+)
+
+// IsCgroup2UnifiedMode returns whether we are running in cgroup or cgroupv2 mode.
+func IsCgroup2UnifiedMode() (bool, error) {
+ isUnifiedOnce.Do(func() {
+ var st syscall.Statfs_t
+ if err := syscall.Statfs(CgroupRoot, &st); err != nil {
+ isUnified, isUnifiedErr = false, err
+ } else {
+ isUnified, isUnifiedErr = st.Type == cgroup2SuperMagic, nil
+ }
+ })
+ return isUnified, isUnifiedErr
+}
diff --git a/vendor/github.com/containers/psgo/internal/proc/pids.go b/vendor/github.com/containers/psgo/internal/proc/pids.go
index ff4887364..69e8befc1 100644
--- a/vendor/github.com/containers/psgo/internal/proc/pids.go
+++ b/vendor/github.com/containers/psgo/internal/proc/pids.go
@@ -1,4 +1,4 @@
-// Copyright 2018 psgo authors
+// Copyright 2018-2019 psgo authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -18,8 +18,11 @@ import (
"bufio"
"fmt"
"os"
+ "path/filepath"
"strconv"
"strings"
+
+ "github.com/containers/psgo/internal/cgroups"
)
// GetPIDs extracts and returns all PIDs from /proc.
@@ -49,45 +52,98 @@ func GetPIDs() ([]string, error) {
return pids, nil
}
-// pidCgroupPath returns the path to the pid's pids cgroup.
-func pidCgroupPath(pid string) (string, error) {
+// GetPIDsFromCgroup returns a strings slice of all pids listesd in pid's pids
+// cgroup. It automatically detects if we're running in unified mode or not.
+func GetPIDsFromCgroup(pid string) ([]string, error) {
+ unified, err := cgroups.IsCgroup2UnifiedMode()
+ if err != nil {
+ return nil, err
+ }
+ if unified {
+ return getPIDsFromCgroupV2(pid)
+ }
+ return getPIDsFromCgroupV1(pid)
+}
+
+// getPIDsFromCgroupV1 returns a strings slice of all pids listesd in pid's pids
+// cgroup.
+func getPIDsFromCgroupV1(pid string) ([]string, error) {
+ // First, find the corresponding path to the PID cgroup.
f, err := os.Open(fmt.Sprintf("/proc/%s/cgroup", pid))
if err != nil {
- return "", err
+ return nil, err
}
defer f.Close()
scanner := bufio.NewScanner(f)
+ cgroupPath := ""
for scanner.Scan() {
fields := strings.Split(scanner.Text(), ":")
if len(fields) != 3 {
continue
}
if fields[1] == "pids" {
- return fmt.Sprintf("/sys/fs/cgroup/pids/%s/cgroup.procs", fields[2]), nil
+ cgroupPath = fmt.Sprintf("/sys/fs/cgroup/pids/%s/cgroup.procs", fields[2])
}
}
- return "", fmt.Errorf("couldn't find pids group for PID %s", pid)
+
+ if cgroupPath == "" {
+ return nil, fmt.Errorf("couldn't find v1 pids group for PID %s", pid)
+ }
+
+ // Second, extract the PIDs inside the cgroup.
+ f, err = os.Open(cgroupPath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ pids := []string{}
+ scanner = bufio.NewScanner(f)
+ for scanner.Scan() {
+ pids = append(pids, scanner.Text())
+ }
+
+ return pids, nil
}
-// GetPIDsFromCgroup returns a strings slice of all pids listesd in pid's pids
+// getPIDsFromCgroupV2 returns a strings slice of all pids listesd in pid's pids
// cgroup.
-func GetPIDsFromCgroup(pid string) ([]string, error) {
- cgroupPath, err := pidCgroupPath(pid)
+func getPIDsFromCgroupV2(pid string) ([]string, error) {
+ // First, find the corresponding path to the PID cgroup.
+ f, err := os.Open(fmt.Sprintf("/proc/%s/cgroup", pid))
if err != nil {
return nil, err
}
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ cgroupSlice := ""
+ for scanner.Scan() {
+ fields := strings.Split(scanner.Text(), ":")
+ if len(fields) != 3 {
+ continue
+ }
+ cgroupSlice = fields[2]
+ break
+ }
+
+ if cgroupSlice == "" {
+ return nil, fmt.Errorf("couldn't find v2 pids group for PID %s", pid)
+ }
- f, err := os.Open(cgroupPath)
+ // Second, extract the PIDs inside the cgroup.
+ f, err = os.Open(filepath.Join(cgroups.CgroupRoot, cgroupSlice, "cgroup.procs"))
if err != nil {
return nil, err
}
defer f.Close()
pids := []string{}
- scanner := bufio.NewScanner(f)
+ scanner = bufio.NewScanner(f)
for scanner.Scan() {
pids = append(pids, scanner.Text())
}
+
return pids, nil
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index c01409444..c422598fb 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -108,12 +108,13 @@ github.com/containers/image/v4/pkg/blobinfocache/memory
github.com/containers/image/v4/pkg/blobinfocache/internal/prioritize
# github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b
github.com/containers/libtrust
-# github.com/containers/psgo v1.3.1
+# github.com/containers/psgo v1.3.2
github.com/containers/psgo
github.com/containers/psgo/internal/capabilities
github.com/containers/psgo/internal/dev
github.com/containers/psgo/internal/proc
github.com/containers/psgo/internal/process
+github.com/containers/psgo/internal/cgroups
github.com/containers/psgo/internal/host
# github.com/containers/storage v1.13.4
github.com/containers/storage