diff options
30 files changed, 262 insertions, 33 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 204feb2fd..66bb7d4ce 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -28,11 +28,13 @@ env: TIMESTAMP: "awk --file ${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/timestamp.awk" #### - #### Cache-image names to test with + #### Cache-image names to test with (double-quotes around names are critical) ### - FEDORA_CACHE_IMAGE_NAME: "fedora-30-libpod-5789386598252544" - PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-5789386598252544" - UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-5789386598252544" + _BUILT_IMAGE_SUFFIX: "libpod-5751722641719296" + 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}" + UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-${_BUILT_IMAGE_SUFFIX}" #### #### Variables for composing new cache-images (used in PR testing) from @@ -262,6 +264,7 @@ meta_task: IMGNAMES: >- ${FEDORA_CACHE_IMAGE_NAME} ${PRIOR_FEDORA_CACHE_IMAGE_NAME} + ${SPECIAL_FEDORA_CACHE_IMAGE_NAME} ${UBUNTU_CACHE_IMAGE_NAME} ${IMAGE_BUILDER_CACHE_IMAGE_NAME} BUILDID: "${CIRRUS_BUILD_ID}" @@ -286,7 +289,7 @@ image_prune_task: - "meta" container: - image: "quay.io/cevich/imgprune:latest" # see contrib/imgprune + image: "quay.io/libpod/imgprune:latest" # see contrib/imgprune cpu: 1 memory: 1 @@ -345,6 +348,49 @@ testing_task: audit_log_script: '$SCRIPT_BASE/logcollector.sh audit' journal_script: '$SCRIPT_BASE/logcollector.sh journal' +# Test crun on last 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*\*\*\*.*' + + gce_instance: + matrix: + # Images are generated separately, from build_images_task (below) + image_name: "${FEDORA_CACHE_IMAGE_NAME}" + + timeout_in: 120m + + env: + ADD_SECOND_PARTITION: true + OCI_RUNTIME: "/usr/bin/crun" + matrix: + TEST_REMOTE_CLIENT: false + + setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' + 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}' + cache_release_archive_script: >- + [[ "$TEST_REMOTE_CLIENT" == "false" ]] || \ + $SCRIPT_BASE/cache_release_archive.sh |& ${TIMESTAMP} + + on_failure: + failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh' + + always: &crunstandardlogs + ginkgo_node_logs_script: '$SCRIPT_BASE/logcollector.sh ginkgo' + df_script: '$SCRIPT_BASE/logcollector.sh df' + audit_log_script: '$SCRIPT_BASE/logcollector.sh audit' + journal_script: '$SCRIPT_BASE/logcollector.sh journal' + # This task executes tests under unique environments/conditions special_testing_rootless_task: @@ -361,7 +407,6 @@ special_testing_rootless_task: env: ADD_SECOND_PARTITION: true SPECIALMODE: 'rootless' # See docs - matrix: TEST_REMOTE_CLIENT: true TEST_REMOTE_CLIENT: false @@ -429,6 +474,36 @@ special_testing_cross_task: failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh' +special_testing_cgroupv2_task: + + depends_on: + - "gating" + - "varlink_api" + - "vendor" + + only_if: $CIRRUS_CHANGE_MESSAGE !=~ '.*\*\*\*\s*CIRRUS:\s*TEST\s*IMAGES\s*\*\*\*.*' + + gce_instance: + image_name: "${SPECIAL_FEDORA_CACHE_IMAGE_NAME}" + + env: + SPECIALMODE: 'cgroupv2' # See docs + matrix: + TEST_REMOTE_CLIENT: true + TEST_REMOTE_CLIENT: false + + timeout_in: 20m + + setup_environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' + integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}' + + on_failure: + failed_branch_script: '$CIRRUS_WORKING_DIR/$SCRIPT_BASE/notice_branch_failure.sh' + + always: + <<: *standardlogs + + # Test building of new cache-images for future PR testing, in this PR. test_build_cache_images_task: @@ -478,25 +553,35 @@ verify_test_built_images_task: - "test_build_cache_images" gce_instance: - matrix: - # Images are generated separately, from build_images_task (below) - image_name: "fedora-29${BUILT_IMAGE_SUFFIX}" - image_name: "fedora-30${BUILT_IMAGE_SUFFIX}" - image_name: "ubuntu-18${BUILT_IMAGE_SUFFIX}" + # Images generated by test_build_cache_images_task (above) + image_name: "${PACKER_BUILDER_NAME}${BUILT_IMAGE_SUFFIX}" env: ADD_SECOND_PARTITION: true matrix: TEST_REMOTE_CLIENT: true TEST_REMOTE_CLIENT: false + matrix: + # Required env. var. by check_image_script + PACKER_BUILDER_NAME: "fedora-29" + PACKER_BUILDER_NAME: "fedora-30" + PACKER_BUILDER_NAME: "xfedora-30" + PACKER_BUILDER_NAME: "ubuntu-18" + environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' + # Verify expectations once per image + check_image_script: >- + [[ "$TEST_REMOTE_CLIENT" == "false" ]] || \ + $SCRIPT_BASE/check_image.sh |& ${TIMESTAMP} # Note: A truncated form of normal testing. It only needs to confirm new images # "probably" work. A full round of testing will happen again after $*_CACHE_IMAGE_NAME # are updated in this or another PR (w/o '***CIRRUS: TEST IMAGES***'). - environment_script: '$SCRIPT_BASE/setup_environment.sh |& ${TIMESTAMP}' - check_image_script: '$SCRIPT_BASE/check_image.sh' - integration_test_script: '$SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}' - system_test_script: '$SCRIPT_BASE/system_test.sh |& ${TIMESTAMP}' + integration_test_script: >- + [[ "$PACKER_BUILDER_NAME" == "xfedora-30" ]] || \ + $SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP} + system_test_script: >- + [[ "$PACKER_BUILDER_NAME" == "xfedora-30" ]] || \ + $SCRIPT_BASE/system_test.sh |& ${TIMESTAMP} always: <<: *standardlogs @@ -518,8 +603,10 @@ success_task: - "meta" - "image_prune" - "testing" + - "testing_crun" - "special_testing_rootless" - "special_testing_in_podman" + - "special_testing_cgroupv2" - "special_testing_cross" - "test_build_cache_images" - "verify_test_built_images" @@ -556,8 +643,10 @@ release_task: - "meta" - "image_prune" - "testing" + - "testing_crun" - "special_testing_rootless" - "special_testing_in_podman" + - "special_testing_cgroupv2" - "special_testing_cross" - "test_build_cache_images" - "verify_test_built_images" @@ -265,6 +265,8 @@ in the [API.md](https://github.com/containers/libpod/blob/master/API.md) file in [error ErrCtrStopped](#ErrCtrStopped) +[error ErrRequiresCgroupsV2ForRootless](#ErrRequiresCgroupsV2ForRootless) + [error ErrorOccurred](#ErrorOccurred) [error ImageNotFound](#ImageNotFound) @@ -2006,6 +2008,9 @@ ContainerNotFound means the container could not be found by the provided name or ### <a name="ErrCtrStopped"></a>type ErrCtrStopped Container is already stopped +### <a name="ErrRequiresCgroupsV2ForRootless"></a>type ErrRequiresCgroupsV2ForRootless + +This function requires CGroupsV2 to run in rootless mode. ### <a name="ErrorOccurred"></a>type ErrorOccurred ErrorOccurred is a generic error for an error that occurs during the execution. The actual error message @@ -20,6 +20,7 @@ SHAREDIR_CONTAINERS ?= ${PREFIX}/share/containers ETCDIR ?= /etc TMPFILESDIR ?= ${PREFIX}/lib/tmpfiles.d SYSTEMDDIR ?= ${PREFIX}/lib/systemd/system +USERSYSTEMDDIR ?= ${PREFIX}/lib/systemd/user BUILDFLAGS ?= BUILDTAGS ?= \ $(shell hack/apparmor_tag.sh) \ @@ -335,6 +336,7 @@ brew-pkg: install-podman-remote-docs podman-remote-darwin @cp ./bin/podman-remote-darwin ./brew/podman @cp -r ./docs/remote ./brew/docs/ @cp docs/podman-remote.1 ./brew/docs/podman.1 + @cp docs/podman-remote.conf.5 ./brew/docs/podman-remote.conf.5 @sed -i 's/podman\\*-remote/podman/g' ./brew/docs/podman.1 @sed -i 's/Podman\\*-remote/Podman\ for\ Mac/g' ./brew/docs/podman.1 @sed -i 's/podman\.conf/podman\-remote\.conf/g' ./brew/docs/podman.1 @@ -395,9 +397,11 @@ install.docker: docker-docs install ${SELINUXOPT} -m 644 docs/docker*.1 -t $(DESTDIR)$(MANDIR)/man1 install.systemd: - install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR} ${DESTDIR}${TMPFILESDIR} + install ${SELINUXOPT} -m 755 -d ${DESTDIR}${SYSTEMDDIR} ${DESTDIR}${USERSYSTEMDDIR} ${DESTDIR}${TMPFILESDIR} install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.socket ${DESTDIR}${SYSTEMDDIR}/io.podman.socket + install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.socket ${DESTDIR}${USERSYSTEMDDIR}/io.podman.socket install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.service ${DESTDIR}${SYSTEMDDIR}/io.podman.service + install ${SELINUXOPT} -m 644 contrib/varlink/io.podman.service ${DESTDIR}${USERSYSTEMDDIR}/io.podman.service install ${SELINUXOPT} -m 644 contrib/varlink/podman.conf ${DESTDIR}${TMPFILESDIR}/podman.conf uninstall: diff --git a/cmd/podman/shared/container.go b/cmd/podman/shared/container.go index 7f53f5ec9..1d35ac17b 100644 --- a/cmd/podman/shared/container.go +++ b/cmd/podman/shared/container.go @@ -660,7 +660,7 @@ func formatGroup(key string, start, last int32) string { } // portsToString converts the ports used to a string of the from "port1, port2" -// and also groups continuous list of ports in readable format. +// and also groups a continuous list of ports into a readable format. func portsToString(ports []ocicni.PortMapping) string { type portGroup struct { first int32 @@ -750,7 +750,7 @@ func GetRunlabel(label string, runlabelImage string, ctx context.Context, runtim return runLabel, imageName, err } -// GenerateRunlabelCommand generates the command that will eventually be execucted by podman. +// GenerateRunlabelCommand generates the command that will eventually be execucted by Podman. func GenerateRunlabelCommand(runLabel, imageName, name string, opts map[string]string, extraArgs []string, globalOpts string) ([]string, []string, error) { // If no name is provided, we use the image's basename instead. if name == "" { @@ -809,7 +809,7 @@ func envSliceToMap(env []string) map[string]string { return m } -// GenerateKube generates kubernetes yaml based on a pod or container +// GenerateKube generates kubernetes yaml based on a pod or container. func GenerateKube(name string, service bool, r *libpod.Runtime) (*v1.Pod, *v1.Service, error) { var ( pod *libpod.Pod diff --git a/cmd/podman/varlink/io.podman.varlink b/cmd/podman/varlink/io.podman.varlink index b867dccc1..4a4c97e99 100644 --- a/cmd/podman/varlink/io.podman.varlink +++ b/cmd/podman/varlink/io.podman.varlink @@ -1277,3 +1277,6 @@ error WantsMoreRequired (reason: string) # Container is already stopped error ErrCtrStopped (id: string) + +# This function requires CGroupsV2 to run in rootless mode. +error ErrRequiresCgroupsV2ForRootless(reason: string)
\ No newline at end of file diff --git a/contrib/cirrus/README.md b/contrib/cirrus/README.md index 18ef3e7f7..ada362d95 100644 --- a/contrib/cirrus/README.md +++ b/contrib/cirrus/README.md @@ -69,6 +69,13 @@ Confirm that cross-compile of podman-remote functions for both `windows` and `darwin` targets. +### ``special_testing_cgroupv2`` Task + +Use the latest Fedora release with the required kernel options pre-set for +exercising cgroups v2 with podman integration tests. Also depends on +having `SPECIALMODE` set to 'cgroupv2` + + ### ``test_build_cache_images_task`` Task Modifying the contents of cache-images is tested by making changes to @@ -266,5 +273,6 @@ values follows: and utilized for testing. * `in_podman`: Causes testing to occur within a container executed by podman on the host. +* `cgroupv2`: The kernel on this VM was prepared with options to enable v2 cgroups * `windows`: See **darwin** * `darwin`: Signals the ``special_testing_cross`` task to cross-compile the remote client. diff --git a/contrib/cirrus/check_image.sh b/contrib/cirrus/check_image.sh index 8a9fbae1d..ad9a12f49 100755 --- a/contrib/cirrus/check_image.sh +++ b/contrib/cirrus/check_image.sh @@ -4,6 +4,8 @@ set -eo pipefail source $(dirname $0)/lib.sh +req_env_var PACKER_BUILDER_NAME TEST_REMOTE_CLIENT EVIL_UNITS OS_RELEASE_ID + NFAILS=0 echo "Validating VM image" @@ -20,6 +22,9 @@ item_test 'Minimum available memory' $MEM_FREE -ge $MIN_MEM_MB || let "NFAILS+=1 # binary anywhere; that could potentially taint our results. item_test "remove_packaged_podman_files() did it's job" -z "$(type -P podman)" || let "NFAILS+=1" +# Integration Tests require varlink in Fedora +item_test "The varlink executable is present" -x "$(type -P varlink)" || let "NFAILS+=1" + MIN_ZIP_VER='3.0' VER_RE='.+([[:digit:]]+\.[[:digit:]]+).+' ACTUAL_VER=$(zip --version 2>&1 | egrep -m 1 "Zip$VER_RE" | sed -r -e "s/$VER_RE/\\1/") @@ -49,5 +54,16 @@ then item_test "On ubuntu /usr/bin/runc is /usr/lib/cri-o-runc/sbin/runc" "$SAMESAME" -eq "0" || let "NFAILS+=1" fi +echo "Checking items specific to ${PACKER_BUILDER_NAME}${BUILT_IMAGE_SUFFIX}" +case "$PACKER_BUILDER_NAME" in + xfedora*) + echo "Kernel Command-line: $(cat /proc/cmdline)" + item_test \ + "On ${PACKER_BUILDER_NAME} images, the /sys/fs/cgroup/unified directory does NOT exist" \ + "!" "-d" "/sys/fs/cgroup/unified" || let "NFAILS+=1" + ;; + *) echo "No vm-image specific items to check" +esac + echo "Total failed tests: $NFAILS" exit $NFAILS diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh index cfaf33b85..8a43176e4 100755 --- a/contrib/cirrus/integration_test.sh +++ b/contrib/cirrus/integration_test.sh @@ -36,6 +36,13 @@ case "$SPECIALMODE" in -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \ -o CheckHostIP=no $GOSRC/$SCRIPT_BASE/rootless_test.sh ${TESTSUITE} ;; + cgroupv2) + make + make install PREFIX=/usr ETCDIR=/etc + make test-binaries + echo "WARNING: Integration tests not yet ready for cgroups V2" + #TODO: make local${TESTSUITE} + ;; none) make make install PREFIX=/usr ETCDIR=/etc @@ -52,5 +59,5 @@ case "$SPECIALMODE" in warn '' "No $SPECIALMODE remote client integration tests configured" ;; *) - die 110 "Unsupported \$SPECIAL_MODE: $SPECIALMODE" + die 110 "Unsupported \$SPECIALMODE: $SPECIALMODE" esac diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index ffb7cd45b..a20ee5a62 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -55,9 +55,9 @@ PACKER_VER="1.3.5" # CSV of cache-image names to build (see $PACKER_BASE/libpod_images.json) # Base-images rarely change, define them here so they're out of the way. -export PACKER_BUILDS="${PACKER_BUILDS:-ubuntu-18,fedora-30,fedora-29}" +export PACKER_BUILDS="${PACKER_BUILDS:-ubuntu-18,fedora-30,xfedora-30,fedora-29}" # Google-maintained base-image names -export UBUNTU_BASE_IMAGE="ubuntu-1804-bionic-v20181203a" +export UBUNTU_BASE_IMAGE="ubuntu-1804-bionic-v20190722a" # Manually produced base-image names (see $SCRIPT_BASE/README.md) export FEDORA_BASE_IMAGE="fedora-cloud-base-30-1-2-1559164849" export PRIOR_FEDORA_BASE_IMAGE="fedora-cloud-base-29-1-2-1559164849" diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh index e9b145391..0e1a82cc0 100644 --- a/contrib/cirrus/packer/fedora_setup.sh +++ b/contrib/cirrus/packer/fedora_setup.sh @@ -8,7 +8,7 @@ set -e # Load in library (copied by packer, before this script was run) source /tmp/libpod/$SCRIPT_BASE/lib.sh -req_env_var SCRIPT_BASE +req_env_var SCRIPT_BASE PACKER_BUILDER_NAME GOSRC install_ooe @@ -53,6 +53,7 @@ ooe.sh sudo dnf install -y \ libseccomp \ libseccomp-devel \ libselinux-devel \ + libvarlink-util \ lsof \ make \ nmap-ncat \ @@ -85,6 +86,17 @@ systemd_banish sudo /tmp/libpod/hack/install_catatonit.sh +# Same script is used for several related contexts +case "$PACKER_BUILDER_NAME" in + xfedora*) + echo "Configuring CGroups v2 enabled on next boot" + sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1" + ;& # continue to next matching item + *) + echo "Finalizing $PACKER_BUILDER_NAME VM image" + ;; +esac + rh_finalize echo "SUCCESS!" diff --git a/contrib/cirrus/packer/libpod_images.yml b/contrib/cirrus/packer/libpod_images.yml index 2e2b21426..cae5d4138 100644 --- a/contrib/cirrus/packer/libpod_images.yml +++ b/contrib/cirrus/packer/libpod_images.yml @@ -48,6 +48,10 @@ builders: source_image: '{{user `FEDORA_BASE_IMAGE`}}' - <<: *gce_hosted_image + name: 'xfedora-30' + source_image: '{{user `FEDORA_BASE_IMAGE`}}' + + - <<: *gce_hosted_image name: 'fedora-29' source_image: '{{user `PRIOR_FEDORA_BASE_IMAGE`}}' @@ -60,6 +64,7 @@ provisioners: - type: 'shell' script: '{{user `GOSRC`}}/{{user `PACKER_BASE`}}/{{split build_name "-" 0}}_setup.sh' environment_vars: + - 'PACKER_BUILDER_NAME={{build_name}}' - 'GOSRC=/tmp/libpod' - 'SCRIPT_BASE={{user `SCRIPT_BASE`}}' diff --git a/contrib/cirrus/packer/ubuntu_setup.sh b/contrib/cirrus/packer/ubuntu_setup.sh index dba191ad2..00d92570f 100644 --- a/contrib/cirrus/packer/ubuntu_setup.sh +++ b/contrib/cirrus/packer/ubuntu_setup.sh @@ -15,6 +15,9 @@ install_ooe export GOPATH="$(mktemp -d)" trap "sudo rm -rf $GOPATH" EXIT +# Ensure there are no disruptive periodic services enabled by default in image +systemd_banish + echo "Updating/configuring package repositories." $LILTO $SUDOAPTGET update $LILTO $SUDOAPTGET install software-properties-common @@ -62,6 +65,7 @@ $BIGTO $SUDOAPTGET install \ libnet1-dev \ libnl-3-dev \ libostree-dev \ + libvarlink \ libprotobuf-c0-dev \ libprotobuf-dev \ libseccomp-dev \ @@ -100,9 +104,6 @@ ooe.sh sudo update-grub sudo /tmp/libpod/hack/install_catatonit.sh ooe.sh sudo make -C /tmp/libpod install.libseccomp.sudo -# Ensure there are no disruptive periodic services enabled by default in image -systemd_banish - ubuntu_finalize echo "SUCCESS!" diff --git a/contrib/cirrus/packer/xfedora_setup.sh b/contrib/cirrus/packer/xfedora_setup.sh new file mode 120000 index 000000000..5e9f1ec77 --- /dev/null +++ b/contrib/cirrus/packer/xfedora_setup.sh @@ -0,0 +1 @@ +fedora_setup.sh
\ No newline at end of file diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 5d350263e..03acaf1da 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -44,6 +44,11 @@ case "${OS_REL_VER}" in ;; fedora-30) ;& # continue to next item fedora-29) + # There is no crun package on Fedora29 + if test "${OS_REL_VER}" != "fedora-29"; then + yum install -y crun + fi + if [[ "$ADD_SECOND_PARTITION" == "true" ]]; then bash "$SCRIPT_BASE/add_second_partition.sh"; fi ;; @@ -62,9 +67,12 @@ install_test_configs make install.tools case "$SPECIALMODE" in - none) + cgroupv2) remove_packaged_podman_files # we're building from source ;; + none) + remove_packaged_podman_files + ;; rootless) # Only do this once, even if ROOTLESS_USER (somehow) changes if ! grep -q 'ROOTLESS_USER' /etc/environment @@ -85,5 +93,5 @@ case "$SPECIALMODE" in windows) ;& # for podman-remote building only darwin) ;; *) - die 111 "Unsupported \$SPECIAL_MODE: $SPECIALMODE" + die 111 "Unsupported \$SPECIALMODE: $SPECIALMODE" esac diff --git a/contrib/imgprune/Dockerfile b/contrib/imgprune/Dockerfile index 26329e828..b0dc77da5 100644 --- a/contrib/imgprune/Dockerfile +++ b/contrib/imgprune/Dockerfile @@ -1,4 +1,4 @@ -FROM libpod/imgts:latest +FROM quay.io/libpod/imgts:latest RUN yum -y update && \ yum clean all diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in index 0de797f2b..35f3b2014 100644 --- a/contrib/spec/podman.spec.in +++ b/contrib/spec/podman.spec.in @@ -389,6 +389,7 @@ popd %install install -dp %{buildroot}%{_unitdir} +install -dp %{buildroot}%{_usr}/lib/systemd/user PODMAN_VERSION=%{version} %{__make} PREFIX=%{buildroot}%{_prefix} ETCDIR=%{buildroot}%{_sysconfdir} \ install.bin \ install.remote \ @@ -487,6 +488,8 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath} %{_datadir}/containers/%{repo}.conf %{_unitdir}/io.podman.service %{_unitdir}/io.podman.socket +%{_usr}/lib/systemd/user/io.podman.service +%{_usr}/lib/systemd/user/io.podman.socket %{_usr}/lib/tmpfiles.d/%{name}.conf %if 0%{?with_devel} diff --git a/contrib/varlink/io.podman.service b/contrib/varlink/io.podman.service index c524ce815..725198e79 100644 --- a/contrib/varlink/io.podman.service +++ b/contrib/varlink/io.podman.service @@ -6,7 +6,8 @@ Documentation=man:podman-varlink(1) [Service] Type=simple -ExecStart=/usr/bin/podman varlink unix:/run/podman/io.podman +ExecStart=/usr/bin/podman varlink unix:%t/podman/io.podman +KillMode=none [Install] WantedBy=multi-user.target diff --git a/contrib/varlink/io.podman.socket b/contrib/varlink/io.podman.socket index 0f09fe3ef..f6a3ddc49 100644 --- a/contrib/varlink/io.podman.socket +++ b/contrib/varlink/io.podman.socket @@ -3,7 +3,7 @@ Description=Podman Remote API Socket Documentation=man:podman-varlink(1) [Socket] -ListenStream=/run/podman/io.podman +ListenStream=%t/podman/io.podman SocketMode=0600 [Install] diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh index 90e3aea8e..e1588d570 100755 --- a/hack/get_ci_vm.sh +++ b/hack/get_ci_vm.sh @@ -68,9 +68,10 @@ delvm() { } image_hints() { + _BIS=$(egrep -m 1 '_BUILT_IMAGE_SUFFIX:[[:space:]+"[[:print:]]+"' "$LIBPODROOT/.cirrus.yml" | cut -d: -f 2 | tr -d '"[:blank:]') egrep '[[:space:]]+[[:alnum:]].+_CACHE_IMAGE_NAME:[[:space:]+"[[:print:]]+"' \ "$LIBPODROOT/.cirrus.yml" | cut -d: -f 2 | tr -d '"[:blank:]' | \ - grep -v 'notready' | sort -u + sed -r -e "s/\\\$[{]_BUILT_IMAGE_SUFFIX[}]/$_BIS/" | sort -u } show_usage() { diff --git a/install.md b/install.md index 49a67f984..d8d70a7b6 100644 --- a/install.md +++ b/install.md @@ -26,6 +26,14 @@ Built-in, no need to install sudo emerge app-emulation/libpod ``` +#### [MacOS](https://www.apple.com/macos) + +Using [Homebrew](https://brew.sh/): + +```bash +brew cask install podman +``` + #### [openSUSE](https://www.opensuse.org) ```bash diff --git a/libpod/events/journal_linux.go b/libpod/events/journal_linux.go index 7d195dc79..3bc3f6de7 100644 --- a/libpod/events/journal_linux.go +++ b/libpod/events/journal_linux.go @@ -4,6 +4,7 @@ package events import ( "fmt" + "strconv" "time" "github.com/coreos/go-systemd/journal" @@ -42,6 +43,9 @@ func (e EventJournalD) Write(ee Event) error { m["PODMAN_IMAGE"] = ee.Image m["PODMAN_NAME"] = ee.Name m["PODMAN_ID"] = ee.ID + if ee.ContainerExitCode != 0 { + m["PODMAN_EXIT_CODE"] = strconv.Itoa(ee.ContainerExitCode) + } case Volume: m["PODMAN_NAME"] = ee.Name } @@ -150,6 +154,14 @@ func newEventFromJournalEntry(entry *sdjournal.JournalEntry) (*Event, error) { / case Container, Pod: newEvent.ID = entry.Fields["PODMAN_ID"] newEvent.Image = entry.Fields["PODMAN_IMAGE"] + if code, ok := entry.Fields["PODMAN_EXIT_CODE"]; ok { + intCode, err := strconv.Atoi(code) + if err != nil { + logrus.Errorf("Error parsing event exit code %s", code) + } else { + newEvent.ContainerExitCode = intCode + } + } case Image: newEvent.ID = entry.Fields["PODMAN_ID"] } diff --git a/libpod/image/docker_registry_options.go b/libpod/image/docker_registry_options.go index c191a3ca2..60bb3c33f 100644 --- a/libpod/image/docker_registry_options.go +++ b/libpod/image/docker_registry_options.go @@ -1,8 +1,12 @@ package image import ( + "fmt" + "github.com/containers/image/docker/reference" "github.com/containers/image/types" + + podmanVersion "github.com/containers/libpod/version" ) // DockerRegistryOptions encapsulates settings that affect how we connect or @@ -36,6 +40,7 @@ func (o DockerRegistryOptions) GetSystemContext(parent *types.SystemContext, add sc.SignaturePolicyPath = parent.SignaturePolicyPath sc.AuthFilePath = parent.AuthFilePath sc.DirForceCompress = parent.DirForceCompress + sc.DockerRegistryUserAgent = parent.DockerRegistryUserAgent } return sc } @@ -48,5 +53,7 @@ func GetSystemContext(signaturePolicyPath, authFilePath string, forceCompress bo } sc.AuthFilePath = authFilePath sc.DirForceCompress = forceCompress + sc.DockerRegistryUserAgent = fmt.Sprintf("libpod/%s", podmanVersion.Version) + return sc } diff --git a/pkg/adapter/containers.go b/pkg/adapter/containers.go index b712bd9aa..45a9a54a3 100644 --- a/pkg/adapter/containers.go +++ b/pkg/adapter/containers.go @@ -342,7 +342,7 @@ func (r *LocalRuntime) Run(ctx context.Context, c *cliconfig.RunValues, exitCode if err := ctr.Start(ctx, c.IsSet("pod")); err != nil { // This means the command did not exist exitCode = 127 - if strings.Contains(err.Error(), "permission denied") { + if strings.Contains(err.Error(), "permission denied") || strings.Contains(err.Error(), "file not found") { exitCode = 126 } return exitCode, err diff --git a/pkg/varlinkapi/containers.go b/pkg/varlinkapi/containers.go index bb66ff962..c7aa5233f 100644 --- a/pkg/varlinkapi/containers.go +++ b/pkg/varlinkapi/containers.go @@ -19,6 +19,8 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/logs" "github.com/containers/libpod/pkg/adapter/shortcuts" + "github.com/containers/libpod/pkg/cgroups" + "github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/varlinkapi/virtwriter" "github.com/containers/storage/pkg/archive" "github.com/pkg/errors" @@ -317,6 +319,13 @@ func (i *LibpodAPI) ExportContainer(call iopodman.VarlinkCall, name, outPath str // GetContainerStats ... func (i *LibpodAPI) GetContainerStats(call iopodman.VarlinkCall, name string) error { + cgroupv2, err := cgroups.IsCgroup2UnifiedMode() + if err != nil { + return call.ReplyErrorOccurred(err.Error()) + } + if rootless.IsRootless() && !cgroupv2 { + return call.ReplyErrRequiresCgroupsV2ForRootless("rootless containers cannot report container stats") + } ctr, err := i.Runtime.LookupContainer(name) if err != nil { return call.ReplyContainerNotFound(name, err.Error()) diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go index 6cf78a25c..3f9639fda 100644 --- a/test/e2e/exec_test.go +++ b/test/e2e/exec_test.go @@ -179,6 +179,8 @@ var _ = Describe("Podman exec", func() { }) It("podman exec cannot be invoked", func() { + SkipIfNotRunc() + setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) @@ -189,6 +191,8 @@ var _ = Describe("Podman exec", func() { }) It("podman exec command not found", func() { + SkipIfNotRunc() + setup := podmanTest.RunTopContainer("test1") setup.WaitWithDefaultTimeout() Expect(setup.ExitCode()).To(Equal(0)) diff --git a/test/e2e/libpod_suite_remoteclient_test.go b/test/e2e/libpod_suite_remoteclient_test.go index 7f33fec87..a6cedfc58 100644 --- a/test/e2e/libpod_suite_remoteclient_test.go +++ b/test/e2e/libpod_suite_remoteclient_test.go @@ -28,6 +28,13 @@ func SkipIfRootless() { } } +func SkipIfNotRunc() { + runtime := os.Getenv("OCI_RUNTIME") + if runtime != "" && filepath.Base(runtime) != "runc" { + ginkgo.Skip("Not using runc as runtime") + } +} + // Podman is the exec call to podman on the filesystem func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration { podmanSession := p.PodmanBase(args, false, false) diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go index 1df59dbe3..22cc14d6b 100644 --- a/test/e2e/libpod_suite_test.go +++ b/test/e2e/libpod_suite_test.go @@ -21,6 +21,13 @@ func SkipIfRootless() { } } +func SkipIfNotRunc() { + runtime := os.Getenv("OCI_RUNTIME") + if runtime != "" && filepath.Base(runtime) != "runc" { + ginkgo.Skip("Not using runc as runtime") + } +} + // Podman is the exec call to podman on the filesystem func (p *PodmanTestIntegration) Podman(args []string) *PodmanSessionIntegration { podmanSession := p.PodmanBase(args, false, false) diff --git a/test/e2e/run_exit_test.go b/test/e2e/run_exit_test.go index 861d6b3b7..b05849ddb 100644 --- a/test/e2e/run_exit_test.go +++ b/test/e2e/run_exit_test.go @@ -41,12 +41,16 @@ var _ = Describe("Podman run exit", func() { }) It("podman run exit 126", func() { + SkipIfNotRunc() + result := podmanTest.Podman([]string{"run", ALPINE, "/etc"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(126)) }) It("podman run exit 127", func() { + SkipIfNotRunc() + result := podmanTest.Podman([]string{"run", ALPINE, "foobar"}) result.WaitWithDefaultTimeout() Expect(result.ExitCode()).To(Equal(127)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index f66d1d2fa..1420a8403 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -353,6 +353,8 @@ var _ = Describe("Podman run", func() { It("podman run notify_socket", func() { SkipIfRemote() + SkipIfNotRunc() + host := GetHostDistributionInfo() if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" { Skip("this test requires a working runc") @@ -563,6 +565,7 @@ var _ = Describe("Podman run", func() { }) It("podman run exit code on failure to exec", func() { + SkipIfNotRunc() session := podmanTest.Podman([]string{"run", ALPINE, "/etc"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(126)) diff --git a/test/e2e/start_test.go b/test/e2e/start_test.go index fc1203ed1..2dbb9545b 100644 --- a/test/e2e/start_test.go +++ b/test/e2e/start_test.go @@ -101,6 +101,8 @@ var _ = Describe("Podman start", func() { }) It("podman failed to start with --rm should delete the container", func() { + SkipIfNotRunc() + session := podmanTest.Podman([]string{"create", "-it", "--rm", ALPINE, "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -114,6 +116,8 @@ var _ = Describe("Podman start", func() { }) It("podman failed to start without --rm should NOT delete the container", func() { + SkipIfNotRunc() + session := podmanTest.Podman([]string{"create", "-it", ALPINE, "foo"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) |