summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml48
-rw-r--r--Makefile2
-rw-r--r--cmd/podman/containers/checkpoint.go1
-rw-r--r--cmd/podman/containers/restore.go1
-rw-r--r--contrib/cirrus/add_second_partition.sh63
-rwxr-xr-xcontrib/cirrus/runner.sh3
-rwxr-xr-xcontrib/cirrus/setup_environment.sh31
-rw-r--r--docs/source/markdown/podman-container-checkpoint.1.md8
-rw-r--r--docs/source/markdown/podman-container-inspect.1.md22
-rw-r--r--docs/source/markdown/podman-container-restore.1.md8
-rw-r--r--docs/source/markdown/podman-create.1.md10
-rw-r--r--docs/source/markdown/podman-run.1.md10
-rw-r--r--go.mod6
-rw-r--r--go.sum13
-rw-r--r--libpod/container_api.go3
-rw-r--r--libpod/container_config.go7
-rw-r--r--libpod/container_inspect.go1
-rw-r--r--libpod/define/container_inspect.go1
-rw-r--r--libpod/networking_linux.go20
-rw-r--r--libpod/oci_conmon_linux.go21
-rw-r--r--libpod/options.go14
-rw-r--r--libpod/runtime_ctr.go2
-rw-r--r--pkg/api/handlers/compat/containers_create.go2
-rw-r--r--pkg/api/handlers/compat/exec.go4
-rw-r--r--pkg/bindings/containers/types.go2
-rw-r--r--pkg/bindings/containers/types_checkpoint_options.go15
-rw-r--r--pkg/bindings/containers/types_restore_options.go15
-rw-r--r--pkg/bindings/test/common_test.go2
-rw-r--r--pkg/checkpoint/checkpoint_restore.go5
-rw-r--r--pkg/domain/entities/containers.go2
-rw-r--r--pkg/domain/infra/abi/containers.go4
-rw-r--r--pkg/domain/infra/tunnel/containers.go2
-rw-r--r--pkg/machine/ignition.go2
-rw-r--r--pkg/specgen/generate/container_create.go63
-rw-r--r--pkg/specgenutil/util.go54
-rw-r--r--pkg/specgenutil/volumes.go2
-rw-r--r--pkg/util/filters.go25
-rw-r--r--pkg/util/mountOpts.go1
-rw-r--r--test/e2e/checkpoint_test.go37
-rw-r--r--test/e2e/volume_ls_test.go11
-rw-r--r--test/system/520-checkpoint.bats175
-rw-r--r--vendor/modules.txt6
42 files changed, 466 insertions, 258 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index 091b37627..961104e96 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -24,12 +24,12 @@ env:
####
#### Cache-image names to test with (double-quotes around names are critical)
####
- FEDORA_NAME: "fedora-34"
- PRIOR_FEDORA_NAME: "fedora-33"
+ FEDORA_NAME: "fedora-35"
+ PRIOR_FEDORA_NAME: "fedora-34"
UBUNTU_NAME: "ubuntu-2110"
# Google-cloud VM Images
- IMAGE_SUFFIX: "c4955591916388352"
+ IMAGE_SUFFIX: "c6226133906620416"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
@@ -148,11 +148,11 @@ build_task:
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
# ID for re-use of build output
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- # - env: &priorfedora_envvars
- # DISTRO_NV: ${PRIOR_FEDORA_NAME}
- # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
- # _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ - env: &priorfedora_envvars
+ DISTRO_NV: ${PRIOR_FEDORA_NAME}
+ VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
+ _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- env: &ubuntu_envvars
DISTRO_NV: ${UBUNTU_NAME}
VM_IMAGE_NAME: ${UBUNTU_CACHE_IMAGE_NAME}
@@ -230,12 +230,18 @@ bindings_task:
clone_script: *noop # Comes from cache
setup_script: *setup
main_script: *main
- always: &html_artifacts
+ always: &logs_artifacts
<<: *runner_stats
# Required for `contrib/cirrus/logformatter` to work properly
html_artifacts:
path: ./*.html
type: text/html
+ package_versions_script: '$SCRIPT_BASE/logcollector.sh packages'
+ df_script: '$SCRIPT_BASE/logcollector.sh df'
+ audit_log_script: '$SCRIPT_BASE/logcollector.sh audit'
+ journal_script: '$SCRIPT_BASE/logcollector.sh journal'
+ podman_system_info_script: '$SCRIPT_BASE/logcollector.sh podman'
+ time_script: '$SCRIPT_BASE/logcollector.sh time'
# Build the "libpod" API documentation `swagger.yaml` and
@@ -402,7 +408,7 @@ unit_test_task:
- validate
matrix:
- env: *stdenvars
- #- env: *priorfedora_envvars
+ - env: *priorfedora_envvars
- env: *ubuntu_envvars
# Special-case: Rootless on latest Fedora (standard) VM
- name: "Rootless unit on $DISTRO_NV"
@@ -416,7 +422,7 @@ unit_test_task:
gopath_cache: *ro_gopath_cache
setup_script: *setup
main_script: *main
- always: *runner_stats
+ always: *logs_artifacts
apiv2_test_task:
@@ -437,14 +443,8 @@ apiv2_test_task:
gopath_cache: *ro_gopath_cache
setup_script: *setup
main_script: *main
- always: &logs_artifacts
- <<: *html_artifacts
- package_versions_script: '$SCRIPT_BASE/logcollector.sh packages'
- df_script: '$SCRIPT_BASE/logcollector.sh df'
- audit_log_script: '$SCRIPT_BASE/logcollector.sh audit'
- journal_script: '$SCRIPT_BASE/logcollector.sh journal'
- podman_system_info_script: '$SCRIPT_BASE/logcollector.sh podman'
- time_script: '$SCRIPT_BASE/logcollector.sh time'
+ always: *logs_artifacts
+
compose_test_task:
name: "compose test on $DISTRO_NV ($PRIV_NAME)"
@@ -522,11 +522,11 @@ container_integration_test_task:
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
- # - env:
- # DISTRO_NV: ${PRIOR_FEDORA_NAME}
- # _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
- # VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
- # CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
+ - env:
+ DISTRO_NV: ${PRIOR_FEDORA_NAME}
+ _BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ VM_IMAGE_NAME: ${PRIOR_FEDORA_CACHE_IMAGE_NAME}
+ CTR_FQIN: ${PRIOR_FEDORA_CONTAINER_FQIN}
gce_instance: *standardvm
timeout_in: 90m
env:
diff --git a/Makefile b/Makefile
index 2b8154752..ceecda274 100644
--- a/Makefile
+++ b/Makefile
@@ -893,7 +893,7 @@ uninstall:
.PHONY: clean-binaries
clean-binaries: ## Remove platform/architecture specific binary files
rm -rf \
- bin \
+ bin
.PHONY: clean
clean: clean-binaries ## Clean all make artifacts
diff --git a/cmd/podman/containers/checkpoint.go b/cmd/podman/containers/checkpoint.go
index d92bc3e5e..e8dd25978 100644
--- a/cmd/podman/containers/checkpoint.go
+++ b/cmd/podman/containers/checkpoint.go
@@ -55,6 +55,7 @@ func init() {
flags.BoolVarP(&checkpointOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files")
flags.BoolVarP(&checkpointOptions.LeaveRunning, "leave-running", "R", false, "Leave the container running after writing checkpoint to disk")
flags.BoolVar(&checkpointOptions.TCPEstablished, "tcp-established", false, "Checkpoint a container with established TCP connections")
+ flags.BoolVar(&checkpointOptions.FileLocks, "file-locks", false, "Checkpoint a container with file locks")
flags.BoolVarP(&checkpointOptions.All, "all", "a", false, "Checkpoint all running containers")
exportFlagName := "export"
diff --git a/cmd/podman/containers/restore.go b/cmd/podman/containers/restore.go
index 4ac14001a..cf0ad5f80 100644
--- a/cmd/podman/containers/restore.go
+++ b/cmd/podman/containers/restore.go
@@ -53,6 +53,7 @@ func init() {
flags.BoolVarP(&restoreOptions.All, "all", "a", false, "Restore all checkpointed containers")
flags.BoolVarP(&restoreOptions.Keep, "keep", "k", false, "Keep all temporary checkpoint files")
flags.BoolVar(&restoreOptions.TCPEstablished, "tcp-established", false, "Restore a container with established TCP connections")
+ flags.BoolVar(&restoreOptions.FileLocks, "file-locks", false, "Restore a container with file locks")
importFlagName := "import"
flags.StringVarP(&restoreOptions.Import, importFlagName, "i", "", "Restore from exported checkpoint archive (tar.gz)")
diff --git a/contrib/cirrus/add_second_partition.sh b/contrib/cirrus/add_second_partition.sh
deleted file mode 100644
index 322dd2512..000000000
--- a/contrib/cirrus/add_second_partition.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env bash
-
-# N/B: This script could mega f*!@up your disks if run by mistake.
-# it is left without the execute-bit on purpose!
-
-set -eo pipefail
-
-# shellcheck source=./lib.sh
-source $(dirname $0)/lib.sh
-
-# $SLASH_DEVICE is the disk device to be f*xtuP
-SLASH_DEVICE="/dev/sda" # Always the case on GCP
-
-# The unallocated space results from the difference in disk-size between VM Image
-# and runtime request.
-NEW_PART_START="50%"
-NEW_PART_END="100%"
-
-
-if [[ ! -r "/root" ]] || [[ -r "/root/second_partition_ready" ]]
-then
- warn "Ignoring attempted execution of $(basename $0)"
- exit 0
-fi
-
-[[ -x "$(type -P parted)" ]] || \
- die "The parted command is required."
-
-[[ ! -b ${SLASH_DEVICE}2 ]] || \
- die "Found unexpected block device ${SLASH_DEVICE}2"
-
-PPRINTCMD="parted --script ${SLASH_DEVICE} print"
-FINDMNTCMD="findmnt --source=${SLASH_DEVICE}1 --mountpoint=/ --canonicalize --evaluate --first-only --noheadings"
-TMPF=$(mktemp -p '' $(basename $0)_XXXX)
-trap "rm -f $TMPF" EXIT
-
-if $FINDMNTCMD | tee $TMPF | egrep -q "^/\s+${SLASH_DEVICE}1"
-then
- msg "Repartitioning original partition table:"
- $PPRINTCMD
-else
- die "Unexpected output from '$FINDMNTCMD': $(<$TMPF)"
-fi
-
-echo "Adding partition offset within unpartitioned space."
-parted --script --align optimal /dev/sda unit % mkpart primary "" "" "$NEW_PART_START" "$NEW_PART_END"
-
-msg "New partition table:"
-$PPRINTCMD
-
-msg "Growing ${SLASH_DEVICE}1 meet start of ${SLASH_DEVICE}2"
-growpart ${SLASH_DEVICE} 1
-
-FSTYPE=$(findmnt --first-only --noheadings --output FSTYPE ${SLASH_DEVICE}1)
-echo "Expanding $FSTYPE filesystem on ${SLASH_DEVICE}1"
-case $FSTYPE in
- ext*) resize2fs ${SLASH_DEVICE}1 ;;
- *) die "Script $(basename $0) doesn't know how to resize a $FSTYPE filesystem." ;;
-esac
-
-# Must happen last - signals completion to other tooling
-msg "Recording newly available disk partition device into /root/second_partition_ready"
-echo "${SLASH_DEVICE}2" > /root/second_partition_ready
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index 8ef2a6e64..4c27dfa4b 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -84,7 +84,8 @@ function _run_bindings() {
# Subshell needed so logformatter will write output in cwd; if it runs in
# the subdir, .cirrus.yml will not find the html'ized log
- (cd pkg/bindings/test && ginkgo -trace -noColor -debug -r) |& logformatter
+ (cd pkg/bindings/test && \
+ ginkgo -progress -trace -noColor -debug -timeout 30m -r -v) |& logformatter
}
function _run_docker-py() {
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 90d28b7ac..8f535c7e7 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -20,13 +20,6 @@ die_unknown() {
}
msg "************************************************************"
-msg "FIXME: force-install catatonit 0.17.0 until CI images are updated"
-msg "************************************************************"
-# FIXME: this is just a temporary workaround to force-install
-# catatonit 0.17.0. Please remove once the images are updated.
-./hack/install_catatonit.sh --force
-
-msg "************************************************************"
msg "Setting up runtime environment"
msg "************************************************************"
show_env_vars
@@ -126,12 +119,6 @@ case "$OS_RELEASE_ID" in
ubuntu) ;;
fedora)
if ((CONTAINER==0)); then
- msg "Configuring / Expanding host storage."
- # VM is setup to allow flexibility in testing alternate storage.
- # For general use, simply make use of all available space.
- bash "$SCRIPT_BASE/add_second_partition.sh"
- $SCRIPT_BASE/logcollector.sh df
-
# All SELinux distros need this for systemd-in-a-container
msg "Enabling container_manage_cgroup"
setsebool container_manage_cgroup true
@@ -171,6 +158,18 @@ case "$TEST_ENVIRON" in
# affected/related tests are sensitive to this variable.
warn "Disabling usernamespace integration testing"
echo "SKIP_USERNS=1" >> /etc/ci_environment
+
+ # In F35 the hard-coded default
+ # (from containers-common-1-32.fc35.noarch) is 'journald' despite
+ # the upstream repository having this line commented-out.
+ # Containerized integration tests cannot run with 'journald'
+ # as there is no daemon/process there to receive them.
+ cconf="/usr/share/containers/containers.conf"
+ note="- commented-out by setup_environment.sh"
+ if grep -Eq '^log_driver.+journald' "$cconf"; then
+ warn "Patching out $cconf journald log_driver"
+ sed -r -i -e "s/^log_driver(.*)/# log_driver\1 $note/" "$cconf"
+ fi
fi
;;
*) die_unknown TEST_ENVIRON
@@ -219,10 +218,8 @@ case "$TEST_FLAVOR" in
remove_packaged_podman_files
make install PREFIX=/usr ETCDIR=/etc
- # TODO: Don't install stuff at test runtime! Do this from
- # cache_images/fedora_packaging.sh in containers/automation_images
- # and STRONGLY prefer installing RPMs vs pip packages in venv
- dnf install -y python3-virtualenv python3-pytest4
+ msg "Installing previously downloaded/cached packages"
+ dnf install -y $PACKAGE_DOWNLOAD_DIR/python3*.rpm
virtualenv venv
source venv/bin/activate
pip install --upgrade pip
diff --git a/docs/source/markdown/podman-container-checkpoint.1.md b/docs/source/markdown/podman-container-checkpoint.1.md
index 1faa40a94..200920ca9 100644
--- a/docs/source/markdown/podman-container-checkpoint.1.md
+++ b/docs/source/markdown/podman-container-checkpoint.1.md
@@ -110,6 +110,14 @@ restore. Defaults to not checkpointing *containers* with established TCP
connections.\
The default is **false**.
+#### **--file-locks**
+
+Checkpoint a *container* with file locks. If an application running in the container
+is using file locks, this OPTION is required during checkpoint and restore. Otherwise
+checkpointing *containers* with file locks is expected to fail. If file locks are not
+used, this option is ignored.\
+The default is **false**.
+
#### **--with-previous**
Check out the *container* with previous criu image files in pre-dump. It only works on `runc 1.0-rc3` or `higher`.\
diff --git a/docs/source/markdown/podman-container-inspect.1.md b/docs/source/markdown/podman-container-inspect.1.md
index 54b3cb2ae..dfed294fc 100644
--- a/docs/source/markdown/podman-container-inspect.1.md
+++ b/docs/source/markdown/podman-container-inspect.1.md
@@ -133,28 +133,6 @@ $ podman container inspect foobar
"Ports": {},
"SandboxKey": ""
},
- "ExitCommand": [
- "/usr/bin/podman",
- "--root",
- "/home/dwalsh/.local/share/containers/storage",
- "--runroot",
- "/run/user/3267/containers",
- "--log-level",
- "warning",
- "--cgroup-manager",
- "systemd",
- "--tmpdir",
- "/run/user/3267/libpod/tmp",
- "--runtime",
- "crun",
- "--storage-driver",
- "overlay",
- "--events-backend",
- "journald",
- "container",
- "cleanup",
- "99f66530fe9c7249f7cf29f78e8661669d5831cbe4ee80ea757d5e922dd6a8a6"
- ],
"Namespace": "",
"IsInfra": false,
"Config": {
diff --git a/docs/source/markdown/podman-container-restore.1.md b/docs/source/markdown/podman-container-restore.1.md
index be67792fc..10477fc77 100644
--- a/docs/source/markdown/podman-container-restore.1.md
+++ b/docs/source/markdown/podman-container-restore.1.md
@@ -143,6 +143,14 @@ option is ignored. Defaults to not restoring *containers* with established TCP
connections.\
The default is **false**.
+#### **--file-locks**
+
+Restore a *container* with file locks. This option is required to
+restore file locks from a checkpoint image. If the checkpoint image
+does not contain file locks, this option is ignored. Defaults to not
+restoring file locks.\
+The default is **false**.
+
## EXAMPLE
Restores the container "mywebserver".
```
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 811d16880..b58fd1e18 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -606,7 +606,9 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· ro, readonly: true or false (default).
- . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+
+ · idmap: true or false (default). If specified, create an idmapped mount to the target user namespace in the container.
Options specific to image:
@@ -622,7 +624,9 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
. relabel: shared, private.
- . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ · idmap: true or false (default). If specified, create an idmapped mount to the target user namespace in the container.
+
+ . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
Options specific to tmpfs:
@@ -636,7 +640,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· notmpcopyup: Disable copying files from the image to the tmpfs.
- . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
Options specific to devpts:
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 3d908444b..90c456544 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -633,7 +633,9 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· ro, readonly: true or false (default).
- . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+
+ · idmap: true or false (default). If specified, create an idmapped mount to the target user namespace in the container.
Options specific to image:
@@ -649,7 +651,9 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
. relabel: shared, private.
- . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ · idmap: true or false (default). If specified, create an idmapped mount to the target user namespace in the container.
+
+ . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
Options specific to tmpfs:
@@ -663,7 +667,7 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
· notmpcopyup: Disable copying files from the image to the tmpfs.
- . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ . U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
Options specific to devpts:
diff --git a/go.mod b/go.mod
index 32d1d4b85..93c9dfba3 100644
--- a/go.mod
+++ b/go.mod
@@ -24,7 +24,7 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/digitalocean/go-qemu v0.0.0-20210209191958-152a1535e49f
github.com/docker/distribution v2.7.1+incompatible
- github.com/docker/docker v20.10.10+incompatible
+ github.com/docker/docker v20.10.11+incompatible
github.com/docker/go-connections v0.4.0
github.com/docker/go-plugins-helpers v0.0.0-20200102110956-c9a8a2d92ccc
github.com/docker/go-units v0.4.0
@@ -69,8 +69,8 @@ require (
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0
gopkg.in/fsnotify.v1 v1.4.7 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
- k8s.io/api v0.22.3
- k8s.io/apimachinery v0.22.3
+ k8s.io/api v0.22.4
+ k8s.io/apimachinery v0.22.4
)
replace github.com/onsi/gomega => github.com/onsi/gomega v1.16.0
diff --git a/go.sum b/go.sum
index c9438f28b..b303c2221 100644
--- a/go.sum
+++ b/go.sum
@@ -336,8 +336,9 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v20.10.10+incompatible h1:GKkP0T7U4ks6X3lmmHKC2QDprnpRJor2Z5a8m62R9ZM=
github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v20.10.11+incompatible h1:OqzI/g/W54LczvhnccGqniFoQghHx3pklbLuhfXpqGo=
+github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/docker-credential-helpers v0.6.4 h1:axCks+yV+2MR3/kZhAmy07yC56WZ2Pwu/fKWtKuZB0o=
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
@@ -1494,13 +1495,13 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.22.3 h1:wOoES2GoSkUsdped2RB4zYypPqWtvprGoKCENTOOjP4=
-k8s.io/api v0.22.3/go.mod h1:azgiXFiXqiWyLCfI62/eYBOu19rj2LKmIhFPP4+33fs=
+k8s.io/api v0.22.4 h1:UvyHW0ezB2oIgHAxlYoo6UJQObYXU7awuNarwoHEOjw=
+k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.22.3 h1:mrvBG5CZnEfwgpVqWcrRKvdsYECTrhAR6cApAgdsflk=
-k8s.io/apimachinery v0.22.3/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
+k8s.io/apimachinery v0.22.4 h1:9uwcvPpukBw/Ri0EUmWz+49cnFtaoiyEhQTK+xOe7Ck=
+k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
@@ -1527,7 +1528,7 @@ k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
-k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
+k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
diff --git a/libpod/container_api.go b/libpod/container_api.go
index a41bb03df..7ae9f497c 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -798,6 +798,9 @@ type ContainerCheckpointOptions struct {
// how much time each component in the stack requires to
// checkpoint a container.
PrintStats bool
+ // FileLocks tells the API to checkpoint/restore a container
+ // with file-locks
+ FileLocks bool
}
// Checkpoint checkpoints a container
diff --git a/libpod/container_config.go b/libpod/container_config.go
index 412be835f..57f5b92ac 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -364,13 +364,6 @@ type ContainerMiscConfig struct {
PostConfigureNetNS bool `json:"postConfigureNetNS"`
// OCIRuntime used to create the container
OCIRuntime string `json:"runtime,omitempty"`
- // ExitCommand is the container's exit command.
- // This Command will be executed when the container exits by Conmon.
- // It is usually used to invoke post-run cleanup - for example, in
- // Podman, it invokes `podman container cleanup`, which in turn calls
- // Libpod's Cleanup() API to unmount the container and clean up its
- // network.
- ExitCommand []string `json:"exitCommand,omitempty"`
// IsInfra is a bool indicating whether this container is an infra container used for
// sharing kernel namespaces in a pod
IsInfra bool `json:"pause"`
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 0dae810de..76a08ce30 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -119,7 +119,6 @@ func (c *Container) getContainerInspectData(size bool, driverData *define.Driver
},
Image: config.RootfsImageID,
ImageName: config.RootfsImageName,
- ExitCommand: config.ExitCommand,
Namespace: config.Namespace,
Rootfs: config.Rootfs,
Pod: config.Pod,
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index 7decb18a8..9f939335c 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -654,7 +654,6 @@ type InspectContainerData struct {
Mounts []InspectMount `json:"Mounts"`
Dependencies []string `json:"Dependencies"`
NetworkSettings *InspectNetworkSettings `json:"NetworkSettings"` //TODO
- ExitCommand []string `json:"ExitCommand"`
Namespace string `json:"Namespace"`
IsInfra bool `json:"IsInfra"`
Config *InspectContainerConfig `json:"Config"`
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 9be600bb4..314a74427 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -4,6 +4,7 @@ package libpod
import (
"crypto/rand"
+ "crypto/sha1"
"fmt"
"io/ioutil"
"net"
@@ -400,10 +401,7 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
return nil, nil
}
var rootlessNetNS *RootlessNetNS
- runDir, err := util.GetRuntimeDir()
- if err != nil {
- return nil, err
- }
+ runDir := r.config.Engine.TmpDir
lfile := filepath.Join(runDir, "rootless-netns.lock")
lock, err := lockfile.GetLockfile(lfile)
@@ -429,7 +427,15 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
if err != nil {
return nil, err
}
- path := filepath.Join(nsDir, rootlessNetNsName)
+
+ // create a hash from the static dir
+ // the cleanup will check if there are running containers
+ // if you run a several libpod instances with different root/runroot directories this check will fail
+ // we want one netns for each libpod static dir so we use the hash to prevent name collisions
+ hash := sha1.Sum([]byte(r.config.Engine.StaticDir))
+ netnsName := fmt.Sprintf("%s-%x", rootlessNetNsName, hash[:10])
+
+ path := filepath.Join(nsDir, netnsName)
ns, err := ns.GetNS(path)
if err != nil {
if !new {
@@ -437,8 +443,8 @@ func (r *Runtime) GetRootlessNetNs(new bool) (*RootlessNetNS, error) {
return nil, errors.Wrap(err, "error getting rootless network namespace")
}
// create a new namespace
- logrus.Debug("creating rootless network namespace")
- ns, err = netns.NewNSWithName(rootlessNetNsName)
+ logrus.Debugf("creating rootless network namespace with name %q", netnsName)
+ ns, err = netns.NewNSWithName(netnsName)
if err != nil {
return nil, errors.Wrap(err, "error creating rootless network namespace")
}
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 533a0d78b..bcf45ec8d 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -30,6 +30,7 @@ import (
"github.com/containers/podman/v3/pkg/checkpoint/crutils"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/podman/v3/utils"
"github.com/containers/storage/pkg/homedir"
@@ -794,6 +795,9 @@ func (r *ConmonOCIRuntime) CheckpointContainer(ctr *Container, options Container
if options.TCPEstablished {
args = append(args, "--tcp-established")
}
+ if options.FileLocks {
+ args = append(args, "--file-locks")
+ }
if !options.PreCheckPoint && options.KeepRunning {
args = append(args, "--leave-running")
}
@@ -1071,11 +1075,15 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
args = append(args, "--no-pivot")
}
- if len(ctr.config.ExitCommand) > 0 {
- args = append(args, "--exit-command", ctr.config.ExitCommand[0])
- for _, arg := range ctr.config.ExitCommand[1:] {
- args = append(args, []string{"--exit-command-arg", arg}...)
- }
+ exitCommand, err := specgenutil.CreateExitCommandArgs(ctr.runtime.storageConfig, ctr.runtime.config, logrus.IsLevelEnabled(logrus.DebugLevel), ctr.AutoRemove(), false)
+ if err != nil {
+ return 0, err
+ }
+ exitCommand = append(exitCommand, ctr.config.ID)
+
+ args = append(args, "--exit-command", exitCommand[0])
+ for _, arg := range exitCommand[1:] {
+ args = append(args, []string{"--exit-command-arg", arg}...)
}
// Pass down the LISTEN_* environment (see #10443).
@@ -1101,6 +1109,9 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
if restoreOptions.TCPEstablished {
args = append(args, "--runtime-opt", "--tcp-established")
}
+ if restoreOptions.FileLocks {
+ args = append(args, "--runtime-opt", "--file-locks")
+ }
if restoreOptions.Pod != "" {
mountLabel := ctr.config.MountLabel
processLabel := ctr.config.ProcessLabel
diff --git a/libpod/options.go b/libpod/options.go
index 0cc4c784c..3f0f9fbe0 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -835,20 +835,6 @@ func WithIDMappings(idmappings storage.IDMappingOptions) CtrCreateOption {
}
}
-// WithExitCommand sets the ExitCommand for the container, appending on the ctr.ID() to the end
-func WithExitCommand(exitCommand []string) CtrCreateOption {
- return func(ctr *Container) error {
- if ctr.valid {
- return define.ErrCtrFinalized
- }
-
- ctr.config.ExitCommand = exitCommand
- ctr.config.ExitCommand = append(ctr.config.ExitCommand, ctr.ID())
-
- return nil
- }
-}
-
// WithUTSNSFromPod indicates the the container should join the UTS namespace of
// its pod
func WithUTSNSFromPod(p *Pod) CtrCreateOption {
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 114bf9315..05f22c1fe 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -186,8 +186,6 @@ func (r *Runtime) initContainerVariables(rSpec *spec.Spec, config *ContainerConf
// If the ID is empty a new name for the restored container was requested
if ctr.config.ID == "" {
ctr.config.ID = stringid.GenerateNonCryptoID()
- // Fixup ExitCommand with new ID
- ctr.config.ExitCommand[len(ctr.config.ExitCommand)-1] = ctr.config.ID
}
// Reset the log path to point to the default
ctr.config.LogPath = ""
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 1e175d664..d5abb6e44 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -55,7 +55,7 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
newImage, resolvedName, err := runtime.LibimageRuntime().LookupImage(body.Config.Image, nil)
if err != nil {
if errors.Cause(err) == storage.ErrImageUnknown {
- utils.Error(w, "No such image", http.StatusNotFound, err)
+ utils.Error(w, "No such image", http.StatusNotFound, errors.Wrap(err, "No such image"))
return
}
diff --git a/pkg/api/handlers/compat/exec.go b/pkg/api/handlers/compat/exec.go
index ea61a1013..76f720bf2 100644
--- a/pkg/api/handlers/compat/exec.go
+++ b/pkg/api/handlers/compat/exec.go
@@ -12,7 +12,7 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/api/server/idle"
api "github.com/containers/podman/v3/pkg/api/types"
- "github.com/containers/podman/v3/pkg/specgen/generate"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -65,7 +65,7 @@ func ExecCreateHandler(w http.ResponseWriter, r *http.Request) {
return
}
// Automatically log to syslog if the server has log-level=debug set
- exitCommandArgs, err := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), true, true)
+ exitCommandArgs, err := specgenutil.CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), true, true)
if err != nil {
utils.InternalServerError(w, err)
return
diff --git a/pkg/bindings/containers/types.go b/pkg/bindings/containers/types.go
index 9f7986cbd..81a53a549 100644
--- a/pkg/bindings/containers/types.go
+++ b/pkg/bindings/containers/types.go
@@ -53,6 +53,7 @@ type CheckpointOptions struct {
PrintStats *bool
PreCheckpoint *bool
WithPrevious *bool
+ FileLocks *bool
}
//go:generate go run ../generator/generator.go RestoreOptions
@@ -69,6 +70,7 @@ type RestoreOptions struct {
Pod *string
PrintStats *bool
PublishPorts []string
+ FileLocks *bool
}
//go:generate go run ../generator/generator.go CreateOptions
diff --git a/pkg/bindings/containers/types_checkpoint_options.go b/pkg/bindings/containers/types_checkpoint_options.go
index 6301564e2..391748d76 100644
--- a/pkg/bindings/containers/types_checkpoint_options.go
+++ b/pkg/bindings/containers/types_checkpoint_options.go
@@ -136,3 +136,18 @@ func (o *CheckpointOptions) GetWithPrevious() bool {
}
return *o.WithPrevious
}
+
+// WithFileLocks set field FileLocks to given value
+func (o *CheckpointOptions) WithFileLocks(value bool) *CheckpointOptions {
+ o.FileLocks = &value
+ return o
+}
+
+// GetFileLocks returns value of field FileLocks
+func (o *CheckpointOptions) GetFileLocks() bool {
+ if o.FileLocks == nil {
+ var z bool
+ return z
+ }
+ return *o.FileLocks
+}
diff --git a/pkg/bindings/containers/types_restore_options.go b/pkg/bindings/containers/types_restore_options.go
index 8817b834b..7af2bba32 100644
--- a/pkg/bindings/containers/types_restore_options.go
+++ b/pkg/bindings/containers/types_restore_options.go
@@ -181,3 +181,18 @@ func (o *RestoreOptions) GetPublishPorts() []string {
}
return o.PublishPorts
}
+
+// WithFileLocks set field FileLocks to given value
+func (o *RestoreOptions) WithFileLocks(value bool) *RestoreOptions {
+ o.FileLocks = &value
+ return o
+}
+
+// GetFileLocks returns value of field FileLocks
+func (o *RestoreOptions) GetFileLocks() bool {
+ if o.FileLocks == nil {
+ var z bool
+ return z
+ }
+ return *o.FileLocks
+}
diff --git a/pkg/bindings/test/common_test.go b/pkg/bindings/test/common_test.go
index d996595bf..233666a48 100644
--- a/pkg/bindings/test/common_test.go
+++ b/pkg/bindings/test/common_test.go
@@ -151,7 +151,7 @@ func createTempDirInTempDir() (string, error) {
}
func (b *bindingTest) startAPIService() *gexec.Session {
- cmd := []string{"--log-level=debug", "--events-backend=file", "system", "service", "--timeout=0", b.sock}
+ cmd := []string{"--log-level=debug", "system", "service", "--timeout=0", b.sock}
session := b.runPodman(cmd)
sock := strings.TrimPrefix(b.sock, "unix://")
diff --git a/pkg/checkpoint/checkpoint_restore.go b/pkg/checkpoint/checkpoint_restore.go
index 3a300daaf..85fe6a77e 100644
--- a/pkg/checkpoint/checkpoint_restore.go
+++ b/pkg/checkpoint/checkpoint_restore.go
@@ -239,11 +239,6 @@ func CRImportCheckpoint(ctx context.Context, runtime *libpod.Runtime, restoreOpt
}
}
- // Check if the ExitCommand points to the correct container ID
- if containerConfig.ExitCommand[len(containerConfig.ExitCommand)-1] != containerConfig.ID {
- return nil, errors.Errorf("'ExitCommandID' uses ID %s instead of container ID %s", containerConfig.ExitCommand[len(containerConfig.ExitCommand)-1], containerConfig.ID)
- }
-
containers = append(containers, container)
return containers, nil
}
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 1a4019bb1..1677c067f 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -191,6 +191,7 @@ type CheckpointOptions struct {
WithPrevious bool
Compression archive.Compression
PrintStats bool
+ FileLocks bool
}
type CheckpointReport struct {
@@ -215,6 +216,7 @@ type RestoreOptions struct {
PublishPorts []string
Pod string
PrintStats bool
+ FileLocks bool
}
type RestoreReport struct {
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 69c628669..631eb3a43 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -29,6 +29,7 @@ import (
"github.com/containers/podman/v3/pkg/signal"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/specgen/generate"
+ "github.com/containers/podman/v3/pkg/specgenutil"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
"github.com/pkg/errors"
@@ -516,6 +517,7 @@ func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds [
WithPrevious: options.WithPrevious,
Compression: options.Compression,
PrintStats: options.PrintStats,
+ FileLocks: options.FileLocks,
}
if options.All {
@@ -656,7 +658,7 @@ func makeExecConfig(options entities.ExecOptions, rt *libpod.Runtime) (*libpod.E
return nil, errors.Wrapf(err, "error retrieving Libpod configuration to build exec exit command")
}
// TODO: Add some ability to toggle syslog
- exitCommandArgs, err := generate.CreateExitCommandArgs(storageConfig, runtimeConfig, false, false, true)
+ exitCommandArgs, err := specgenutil.CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), false, true)
if err != nil {
return nil, errors.Wrapf(err, "error constructing exit command for exec session")
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index a7dcc923b..2127f8749 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -303,6 +303,7 @@ func (ic *ContainerEngine) ContainerExport(ctx context.Context, nameOrID string,
func (ic *ContainerEngine) ContainerCheckpoint(ctx context.Context, namesOrIds []string, opts entities.CheckpointOptions) ([]*entities.CheckpointReport, error) {
options := new(containers.CheckpointOptions)
+ options.WithFileLocks(opts.FileLocks)
options.WithIgnoreRootfs(opts.IgnoreRootFS)
options.WithKeep(opts.Keep)
options.WithExport(opts.Export)
@@ -352,6 +353,7 @@ func (ic *ContainerEngine) ContainerRestore(ctx context.Context, namesOrIds []st
}
options := new(containers.RestoreOptions)
+ options.WithFileLocks(opts.FileLocks)
options.WithIgnoreRootfs(opts.IgnoreRootFS)
options.WithIgnoreVolumes(opts.IgnoreVolumes)
options.WithIgnoreStaticIP(opts.IgnoreStaticIP)
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index 42d729458..e19940b22 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -81,7 +81,7 @@ func NewIgnitionFile(ign DynamicIgnition) error {
// so a listening host knows it can being interacting with it
ready := `[Unit]
Requires=dev-virtio\\x2dports-%s.device
-After=remove-moby.service
+After=remove-moby.service sshd.socket sshd.service
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index f90fef9e8..df5d2e8ff 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -3,17 +3,14 @@ package generate
import (
"context"
"fmt"
- "os"
"path/filepath"
"strings"
cdi "github.com/container-orchestrated-devices/container-device-interface/pkg"
"github.com/containers/common/libimage"
- "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
- "github.com/containers/storage/types"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
@@ -163,15 +160,6 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
}
options = append(options, opts...)
- var exitCommandArgs []string
-
- exitCommandArgs, err = CreateExitCommandArgs(rt.StorageConfig(), rtc, logrus.IsLevelEnabled(logrus.DebugLevel), s.Remove, false)
- if err != nil {
- return nil, nil, nil, err
- }
-
- options = append(options, libpod.WithExitCommand(exitCommandArgs))
-
if len(s.Aliases) > 0 {
options = append(options, libpod.WithNetworkAliases(s.Aliases))
}
@@ -500,54 +488,3 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
}
return options, nil
}
-
-func CreateExitCommandArgs(storageConfig types.StoreOptions, config *config.Config, syslog, rm, exec bool) ([]string, error) {
- // 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.
-
- podmanPath, err := os.Executable()
- if err != nil {
- return nil, err
- }
-
- command := []string{podmanPath,
- "--root", storageConfig.GraphRoot,
- "--runroot", storageConfig.RunRoot,
- "--log-level", logrus.GetLevel().String(),
- "--cgroup-manager", config.Engine.CgroupManager,
- "--tmpdir", config.Engine.TmpDir,
- "--cni-config-dir", config.Network.NetworkConfigDir,
- }
- if config.Engine.OCIRuntime != "" {
- command = append(command, []string{"--runtime", config.Engine.OCIRuntime}...)
- }
- if storageConfig.GraphDriverName != "" {
- command = append(command, []string{"--storage-driver", storageConfig.GraphDriverName}...)
- }
- for _, opt := range storageConfig.GraphDriverOptions {
- command = append(command, []string{"--storage-opt", opt}...)
- }
- if config.Engine.EventsLogger != "" {
- command = append(command, []string{"--events-backend", config.Engine.EventsLogger}...)
- }
-
- if syslog {
- command = append(command, "--syslog")
- }
- command = append(command, []string{"container", "cleanup"}...)
-
- if rm {
- command = append(command, "--rm")
- }
-
- // This has to be absolutely last, to ensure that the exec session ID
- // will be added after it by Libpod.
- if exec {
- command = append(command, "--exec")
- }
-
- return command, nil
-}
diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go
index 15676d086..b47082b7f 100644
--- a/pkg/specgenutil/util.go
+++ b/pkg/specgenutil/util.go
@@ -3,10 +3,13 @@ package specgenutil
import (
"io/ioutil"
"net"
+ "os"
"strconv"
"strings"
+ "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/network/types"
+ storageTypes "github.com/containers/storage/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -272,3 +275,54 @@ func parseAndValidatePort(port string) (uint16, error) {
}
return uint16(num), nil
}
+
+func CreateExitCommandArgs(storageConfig storageTypes.StoreOptions, config *config.Config, syslog, rm, exec bool) ([]string, error) {
+ // 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.
+
+ podmanPath, err := os.Executable()
+ if err != nil {
+ return nil, err
+ }
+
+ command := []string{podmanPath,
+ "--root", storageConfig.GraphRoot,
+ "--runroot", storageConfig.RunRoot,
+ "--log-level", logrus.GetLevel().String(),
+ "--cgroup-manager", config.Engine.CgroupManager,
+ "--tmpdir", config.Engine.TmpDir,
+ "--cni-config-dir", config.Network.NetworkConfigDir,
+ }
+ if config.Engine.OCIRuntime != "" {
+ command = append(command, []string{"--runtime", config.Engine.OCIRuntime}...)
+ }
+ if storageConfig.GraphDriverName != "" {
+ command = append(command, []string{"--storage-driver", storageConfig.GraphDriverName}...)
+ }
+ for _, opt := range storageConfig.GraphDriverOptions {
+ command = append(command, []string{"--storage-opt", opt}...)
+ }
+ if config.Engine.EventsLogger != "" {
+ command = append(command, []string{"--events-backend", config.Engine.EventsLogger}...)
+ }
+
+ if syslog {
+ command = append(command, "--syslog")
+ }
+ command = append(command, []string{"container", "cleanup"}...)
+
+ if rm {
+ command = append(command, "--rm")
+ }
+
+ // This has to be absolutely last, to ensure that the exec session ID
+ // will be added after it by Libpod.
+ if exec {
+ command = append(command, "--exec")
+ }
+
+ return command, nil
+}
diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index 184bfadf8..8ff770f9c 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -355,6 +355,8 @@ func getBindMount(args []string) (spec.Mount, error) {
newMount.Options = append(newMount.Options, "U")
}
setOwnership = true
+ case "idmap":
+ newMount.Options = append(newMount.Options, "idmap")
case "consistency":
// Often used on MACs and mistakenly on Linux platforms.
// Since Docker ignores this option so shall we.
diff --git a/pkg/util/filters.go b/pkg/util/filters.go
index e252c1ddf..5af868873 100644
--- a/pkg/util/filters.go
+++ b/pkg/util/filters.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
+ "regexp"
"strings"
"time"
@@ -94,6 +95,28 @@ func PrepareFilters(r *http.Request) (*map[string][]string, error) {
return &filterMap, nil
}
+func wildCardToRegexp(pattern string) string {
+ var result strings.Builder
+ for i, literal := range strings.Split(pattern, "*") {
+ // Replace * with .*
+ if i > 0 {
+ result.WriteString(".*")
+ }
+ // Quote any regular expression meta characters in the
+ // literal text.
+ result.WriteString(regexp.QuoteMeta(literal))
+ }
+ return result.String()
+}
+
+func matchPattern(pattern string, value string) bool {
+ if strings.Contains(pattern, "*") {
+ result, _ := regexp.MatchString(wildCardToRegexp(pattern), value)
+ return result
+ }
+ return false
+}
+
// MatchLabelFilters matches labels and returns true if they are valid
func MatchLabelFilters(filterValues []string, labels map[string]string) bool {
outer:
@@ -106,7 +129,7 @@ outer:
filterValue = ""
}
for labelKey, labelValue := range labels {
- if labelKey == filterKey && (filterValue == "" || labelValue == filterValue) {
+ if ((labelKey == filterKey) || matchPattern(filterKey, labelKey)) && (filterValue == "" || labelValue == filterValue) {
continue outer
}
}
diff --git a/pkg/util/mountOpts.go b/pkg/util/mountOpts.go
index f13dc94ec..959763dba 100644
--- a/pkg/util/mountOpts.go
+++ b/pkg/util/mountOpts.go
@@ -33,6 +33,7 @@ func ProcessOptions(options []string, isTmpfs bool, sourcePath string) ([]string
// Some options have parameters - size, mode
splitOpt := strings.SplitN(opt, "=", 2)
switch splitOpt[0] {
+ case "idmap":
case "O":
if len(options) > 1 {
return nil, errors.Wrapf(ErrDupeMntOption, "'O' option can not be used with other options")
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index 14545c4f9..4963b04fc 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -1340,4 +1340,41 @@ var _ = Describe("Podman checkpoint", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
+ It("podman checkpoint and restore container with --file-locks", func() {
+ if !strings.Contains(podmanTest.OCIRuntime, "runc") {
+ // TODO: Enable test for crun when this feature has been released
+ // https://github.com/containers/crun/pull/783
+ Skip("FIXME: requires crun >= 1.4")
+ }
+ localRunString := getRunString([]string{"--name", "test_name", ALPINE, "flock", "test.lock", "sleep", "100"})
+ session := podmanTest.Podman(localRunString)
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ // Checkpoint is expected to fail without --file-locks
+ result := podmanTest.Podman([]string{"container", "checkpoint", "test_name"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("criu failed"))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+
+ // Checkpoint is expected to succeed with --file-locks
+ result = podmanTest.Podman([]string{"container", "checkpoint", "--file-locks", "test_name"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Exited"))
+
+ result = podmanTest.Podman([]string{"container", "restore", "--file-locks", "test_name"})
+ result.WaitWithDefaultTimeout()
+
+ Expect(result).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
+ Expect(podmanTest.GetContainerStatus()).To(ContainSubstring("Up"))
+
+ result = podmanTest.Podman([]string{"rm", "-t", "0", "-f", "test_name"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ })
})
diff --git a/test/e2e/volume_ls_test.go b/test/e2e/volume_ls_test.go
index 0dd1a2b7c..6c4b22fa5 100644
--- a/test/e2e/volume_ls_test.go
+++ b/test/e2e/volume_ls_test.go
@@ -45,6 +45,17 @@ var _ = Describe("Podman volume ls", func() {
Expect(len(session.OutputToStringArray())).To(Equal(2))
})
+ It("podman ls volume filter with a key pattern", func() {
+ session := podmanTest.Podman([]string{"volume", "create", "--label", "helloworld=world", "myvol2"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"volume", "ls", "--filter", "label=hello*"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(len(session.OutputToStringArray())).To(Equal(2))
+ })
+
It("podman ls volume with JSON format", func() {
session := podmanTest.Podman([]string{"volume", "create", "myvol"})
session.WaitWithDefaultTimeout()
diff --git a/test/system/520-checkpoint.bats b/test/system/520-checkpoint.bats
new file mode 100644
index 000000000..723a20cc4
--- /dev/null
+++ b/test/system/520-checkpoint.bats
@@ -0,0 +1,175 @@
+#!/usr/bin/env bats -*- bats -*-
+#
+# test podman checkpoint. Similar in many ways to our pause tests.
+#
+
+load helpers
+
+CHECKED_ROOTLESS=
+function setup() {
+ # FIXME: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1857257
+ # TL;DR they keep fixing it then breaking it again. There's a test we
+ # could run to see if it's fixed, but it's way too complicated. Since
+ # integration tests also skip checkpoint tests on Ubuntu, do the same here.
+ if grep -qiw ubuntu /etc/os-release; then
+ skip "FIXME: checkpointing broken in Ubuntu 2004, 2104, 2110, ..."
+ fi
+
+ # None of these tests work rootless....
+ if is_rootless; then
+ # ...however, is that a genuine cast-in-stone limitation, or one
+ # that can some day be fixed? If one day some PR removes that
+ # restriction, fail loudly here, so the developer can enable tests.
+ if [[ -n "$CHECKED_ROOTLESS" ]]; then
+ run_podman '?' container checkpoint -l
+ is "$output" "Error: checkpointing a container requires root" \
+ "Confirming that rootless checkpoint doesn't work. If that changed, please reexamine this test file!"
+ CHECKED_ROOTLESS=y
+ fi
+ skip "checkpoint does not work rootless"
+ fi
+
+ basic_setup
+}
+
+function teardown() {
+ run_podman '?' volume rm myvol
+
+ basic_teardown
+}
+
+@test "podman checkpoint - basic test" {
+ run_podman run -d $IMAGE sh -c 'while :;do cat /proc/uptime; sleep 0.1;done'
+ local cid="$output"
+
+ # Wait for container to start emitting output
+ wait_for_output '[1-9]\+' $cid
+
+ # Checkpoint, and confirm via inspect
+ run_podman container checkpoint $cid
+ is "$output" "$cid" "podman container checkpoint"
+
+ run_podman container inspect \
+ --format '{{.State.Status}}:{{.State.Running}}:{{.State.Paused}}:{{.State.Checkpointed}}' $cid
+ is "$output" "exited:false:false:true" "State. Status:Running:Pause:Checkpointed"
+
+ # Plan A was to do something similar to 080-pause.bats: sleep for long
+ # enough to cause a gap in the timestamps in the log. But checkpoint
+ # doesn't seem to work like that: upon restore, even if we sleep a long
+ # time, the newly-started container seems to pick back up close to
+ # where it left off. (Maybe it's something about /proc/uptime?)
+ # Anyway, scratch Plan A. Plan B is simply to make sure that the
+ # restarted container spits something out.
+ run_podman logs $cid
+ local nlines_before="${#lines[*]}"
+
+ # Restart immediately and confirm state
+ run_podman container restore $cid
+ is "$output" "$cid" "podman container restore"
+
+ # Note that upon restore, .Checkpointed reverts to false (#12117)
+ run_podman container inspect \
+ --format '{{.State.Status}}:{{.State.Running}}:{{.State.Paused}}:{{.State.Checkpointed}}' $cid
+ is "$output" "running:true:false:false" \
+ "State. Status:Running:Pause:Checkpointed"
+
+ # Pause briefly to let restarted container emit some output
+ sleep 0.3
+
+ # Get full logs, and make sure something changed
+ run_podman logs $cid
+ local nlines_after="${#lines[*]}"
+ if [[ $nlines_after -eq $nlines_before ]]; then
+ die "Container failed to output new lines after first restore"
+ fi
+
+ # Same thing again: test for https://github.com/containers/crun/issues/756
+ # in which, after second checkpoint/restore, we lose logs
+ run_podman container checkpoint $cid
+ run_podman container logs $cid
+ nlines_before="${#lines[*]}"
+ run_podman container restore $cid
+
+ # Give container time to write new output; then confirm that something
+ # was emitted
+ sleep 0.3
+ run_podman container logs $cid
+ nlines_after="${#lines[*]}"
+ if [[ $nlines_after -eq $nlines_before ]]; then
+ die "stdout went away after second restore (crun issue 756)"
+ fi
+
+ run_podman rm -t 0 -f $cid
+}
+
+
+@test "podman checkpoint --export, with volumes" {
+ skip_if_remote "Test uses --root/--runroot, which are N/A over remote"
+
+ # Create a root in tempdir. We will run a container here.
+ local p_root=${PODMAN_TMPDIR}/testroot/root
+ local p_runroot=${PODMAN_TMPDIR}/testroot/runroot
+ mkdir -p $p_root $p_runroot
+
+ # To avoid network pull, copy $IMAGE straight to temp root
+ local p_opts="--root $p_root --runroot $p_runroot --events-backend file"
+ run_podman save -o $PODMAN_TMPDIR/image.tar $IMAGE
+ run_podman $p_opts load -i $PODMAN_TMPDIR/image.tar
+
+ # Create a volume, find unused network port, and create a webserv container
+ run_podman $p_opts volume create myvol
+ local cname=c_$(random_string 10)
+ local host_port=$(random_free_port)
+ local server=http://127.0.0.1:$host_port
+
+ run_podman $p_opts run -d --name $cname --volume myvol:/myvol \
+ -p $host_port:80 \
+ -w /myvol \
+ $IMAGE sh -c "/bin/busybox-extras httpd -p 80;echo $cname >cname;echo READY;while :;do cat /proc/uptime >mydate.tmp;mv -f mydate.tmp mydate;sleep 0.1;done"
+ local cid="$output"
+ _PODMAN_TEST_OPTS="$p_opts" wait_for_ready $cid
+
+ # Confirm that container responds
+ run curl --max-time 3 -s $server/cname
+ is "$output" "$cname" "curl $server/cname"
+ run curl --max-time 3 -s $server/mydate
+ local date_oldroot="$output"
+
+ # Checkpoint...
+ run_podman $p_opts container checkpoint \
+ --ignore-rootfs \
+ --export=$PODMAN_TMPDIR/$cname.tar.gz \
+ $cname
+
+ # ...confirm that port is now closed
+ run curl --max-time 1 -s $server/mydate
+ is "$status" "7" "cannot connect to port $host_port while container is down"
+
+ # ...now restore it to our regular root
+ run_podman container restore --import=$PODMAN_TMPDIR/$cname.tar.gz
+ is "$output" "$cid"
+
+ # Inspect (on regular root). Note that, unlike the basic test above,
+ # .State.Checkpointed here is *false*.
+ run_podman container inspect \
+ --format '{{.State.Status}}:{{.State.Running}}:{{.State.Paused}}:{{.State.Checkpointed}}' $cname
+ is "$output" "running:true:false:false" "State. Status:Running:Pause:Checkpointed"
+
+ # Pause a moment to let the restarted container update the timestamp file
+ sleep .3
+ run curl --max-time 3 -s $server/mydate
+ local date_newroot="$output"
+ if [[ $date_newroot = $date_oldroot ]]; then
+ die "Restored container did not update the timestamp file"
+ fi
+
+ run_podman exec $cid cat /myvol/cname
+ is "$output" "$cname" "volume transferred fine"
+
+ run_podman rm -t 0 -f $cid
+ run_podman volume rm -f myvol
+}
+
+# FIXME: test --leave-running
+
+# vim: filetype=sh
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 916cf41ae..047c228e2 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -288,7 +288,7 @@ github.com/docker/distribution/registry/client/auth/challenge
github.com/docker/distribution/registry/client/transport
github.com/docker/distribution/registry/storage/cache
github.com/docker/distribution/registry/storage/cache/memory
-# github.com/docker/docker v20.10.10+incompatible
+# github.com/docker/docker v20.10.11+incompatible
github.com/docker/docker/api
github.com/docker/docker/api/types
github.com/docker/docker/api/types/blkiodev
@@ -802,10 +802,10 @@ gopkg.in/tomb.v1
gopkg.in/yaml.v2
# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gopkg.in/yaml.v3
-# k8s.io/api v0.22.3
+# k8s.io/api v0.22.4
k8s.io/api/apps/v1
k8s.io/api/core/v1
-# k8s.io/apimachinery v0.22.3
+# k8s.io/apimachinery v0.22.4
k8s.io/apimachinery/pkg/api/resource
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/conversion