diff options
-rw-r--r-- | .cirrus.yml | 1 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | cmd/podman/main_local.go | 19 | ||||
-rw-r--r-- | cmd/podman/start.go | 3 | ||||
-rwxr-xr-x | contrib/cirrus/integration_test.sh | 4 | ||||
-rw-r--r-- | contrib/cirrus/lib.sh | 3 | ||||
-rwxr-xr-x | contrib/cirrus/logcollector.sh | 11 | ||||
-rw-r--r-- | libpod/boltdb_state.go | 11 | ||||
-rw-r--r-- | pkg/rootless/rootless.go | 45 | ||||
-rw-r--r-- | pkg/rootless/rootless_linux.go | 3 |
10 files changed, 84 insertions, 21 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 08d5b7ac4..71fa68d45 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -368,6 +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' + varlink_script: '$SCRIPT_BASE/logcollector.sh varlink' # This task executes tests under unique environments/conditions @@ -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/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/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/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 94a94f70d..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 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/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/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..05d641383 100644 --- a/pkg/rootless/rootless_linux.go +++ b/pkg/rootless/rootless_linux.go @@ -566,10 +566,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 +578,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) }() |