diff options
92 files changed, 511 insertions, 179 deletions
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 621430670..1a7153848 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -12,6 +12,9 @@ documented on the top of Podman's [README.md](../README.md). If they differ, pl update your version of Podman to the latest possible and retry your command before creating an issue. +Also, there is a running list of known issues in the [Podman Troubleshooting Guide](https://github.com/containers/podman/blob/master/troubleshooting.md), +please reference that page before opening a new issue. + If you are filing a bug against `podman build`, please instead file a bug against Buildah (https://github.com/containers/buildah/issues). Podman build executes Buildah to perform container builds, and as such the Buildah @@ -64,4 +67,8 @@ Briefly describe the problem you are having in a few paragraphs. (paste your output here) ``` +**Have you tested with the latest version of Podman and have you checked the Podman Troubleshooting Guide?** + +Yes/No + **Additional environment details (AWS, VirtualBox, physical, etc.):** diff --git a/contrib/build_rpm.sh b/contrib/build_rpm.sh index a4f1817b9..6a82b131f 100755 --- a/contrib/build_rpm.sh +++ b/contrib/build_rpm.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -euxo pipefail # returned path can vary: /usr/bin/dnf /bin/dnf ... diff --git a/contrib/cirrus/add_second_partition.sh b/contrib/cirrus/add_second_partition.sh index 73db192c5..3c2f9f056 100644 --- a/contrib/cirrus/add_second_partition.sh +++ b/contrib/cirrus/add_second_partition.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/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! diff --git a/contrib/cirrus/apiv2_test.sh b/contrib/cirrus/apiv2_test.sh index 546fe8e30..dbee078b6 100755 --- a/contrib/cirrus/apiv2_test.sh +++ b/contrib/cirrus/apiv2_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/build_release.sh b/contrib/cirrus/build_release.sh index 45634f368..46fe9781f 100755 --- a/contrib/cirrus/build_release.sh +++ b/contrib/cirrus/build_release.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/build_swagger.sh b/contrib/cirrus/build_swagger.sh index 0471f0c10..eb9288dcd 100755 --- a/contrib/cirrus/build_swagger.sh +++ b/contrib/cirrus/build_swagger.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/build_vm_images.sh b/contrib/cirrus/build_vm_images.sh index 543f83a14..be1c82185 100755 --- a/contrib/cirrus/build_vm_images.sh +++ b/contrib/cirrus/build_vm_images.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e source $(dirname $0)/lib.sh diff --git a/contrib/cirrus/check_image.sh b/contrib/cirrus/check_image.sh index 13172fe1c..04867ca64 100755 --- a/contrib/cirrus/check_image.sh +++ b/contrib/cirrus/check_image.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -eo pipefail diff --git a/contrib/cirrus/container_test.sh b/contrib/cirrus/container_test.sh index b56a12232..8ea66e63c 100644 --- a/contrib/cirrus/container_test.sh +++ b/contrib/cirrus/container_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -xeo pipefail export GOPATH=/var/tmp/go diff --git a/contrib/cirrus/integration_test.sh b/contrib/cirrus/integration_test.sh index c65f5e25f..636d67411 100755 --- a/contrib/cirrus/integration_test.sh +++ b/contrib/cirrus/integration_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 968b2de39..3292e9d14 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -376,7 +376,7 @@ install_scl_git() { echo "Installing SoftwareCollections updated 'git' version." ooe.sh $SUDO yum -y install rh-git29 cat << "EOF" | $SUDO tee /usr/bin/git -#!/bin/bash +#!/usr/bin/env bash scl enable rh-git29 -- git $@ EOF diff --git a/contrib/cirrus/lib.sh.t b/contrib/cirrus/lib.sh.t index 8f4080dd5..204af1245 100755 --- a/contrib/cirrus/lib.sh.t +++ b/contrib/cirrus/lib.sh.t @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Unit tests for some functions in lib.sh # diff --git a/contrib/cirrus/logcollector.sh b/contrib/cirrus/logcollector.sh index 859da2966..fd5017b44 100755 --- a/contrib/cirrus/logcollector.sh +++ b/contrib/cirrus/logcollector.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/networking.sh b/contrib/cirrus/networking.sh index 2546fab71..824d03e44 100755 --- a/contrib/cirrus/networking.sh +++ b/contrib/cirrus/networking.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script attempts basic confirmation of functional networking # by connecting to a set of essential external servers and failing diff --git a/contrib/cirrus/notice_branch_failure.sh b/contrib/cirrus/notice_branch_failure.sh index f030c12e5..b810bd266 100755 --- a/contrib/cirrus/notice_branch_failure.sh +++ b/contrib/cirrus/notice_branch_failure.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/ooe.sh b/contrib/cirrus/ooe.sh index 3c8a0409d..0966b5ce8 100755 --- a/contrib/cirrus/ooe.sh +++ b/contrib/cirrus/ooe.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script executes a command while logging all output to a temporary # file. If the command exits non-zero, then all output is sent to the console, diff --git a/contrib/cirrus/packer/fedora_base-setup.sh b/contrib/cirrus/packer/fedora_base-setup.sh index f271abee0..bf29a1aec 100644 --- a/contrib/cirrus/packer/fedora_base-setup.sh +++ b/contrib/cirrus/packer/fedora_base-setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # N/B: This script is not intended to be run by humans. It is used to configure the # fedora base image for importing, so that it will boot in GCE diff --git a/contrib/cirrus/packer/fedora_packaging.sh b/contrib/cirrus/packer/fedora_packaging.sh index 4a8f62e45..fcf9eb93f 100644 --- a/contrib/cirrus/packer/fedora_packaging.sh +++ b/contrib/cirrus/packer/fedora_packaging.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is called from fedora_setup.sh and various Dockerfiles. # It's not intended to be used outside of those contexts. It assumes the lib.sh diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh index 25b568e8a..16ae87d8a 100644 --- a/contrib/cirrus/packer/fedora_setup.sh +++ b/contrib/cirrus/packer/fedora_setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is called by packer on the subject fedora VM, to setup the podman # build/test environment. It's not intended to be used outside of this context. diff --git a/contrib/cirrus/packer/image-builder-image_base-setup.sh b/contrib/cirrus/packer/image-builder-image_base-setup.sh index 78772da09..26fbe2903 100644 --- a/contrib/cirrus/packer/image-builder-image_base-setup.sh +++ b/contrib/cirrus/packer/image-builder-image_base-setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is called by packer on a vanilla CentOS VM, to setup the image # used for building images FROM base images. It's not intended to be used diff --git a/contrib/cirrus/packer/make-user-data.sh b/contrib/cirrus/packer/make-user-data.sh index 7f7fa1c1a..676a50f5c 100644 --- a/contrib/cirrus/packer/make-user-data.sh +++ b/contrib/cirrus/packer/make-user-data.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is utilized by Makefile, it's not intended to be run by humans diff --git a/contrib/cirrus/packer/prior-fedora_base-setup.sh b/contrib/cirrus/packer/prior-fedora_base-setup.sh index f271abee0..bf29a1aec 100644 --- a/contrib/cirrus/packer/prior-fedora_base-setup.sh +++ b/contrib/cirrus/packer/prior-fedora_base-setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # N/B: This script is not intended to be run by humans. It is used to configure the # fedora base image for importing, so that it will boot in GCE diff --git a/contrib/cirrus/packer/systemd_banish.sh b/contrib/cirrus/packer/systemd_banish.sh index 6e2dd9c3e..2219f2a4f 100755 --- a/contrib/cirrus/packer/systemd_banish.sh +++ b/contrib/cirrus/packer/systemd_banish.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set +e # Not all of these exist on every platform diff --git a/contrib/cirrus/packer/ubuntu_packaging.sh b/contrib/cirrus/packer/ubuntu_packaging.sh index 935e81147..c478028b5 100644 --- a/contrib/cirrus/packer/ubuntu_packaging.sh +++ b/contrib/cirrus/packer/ubuntu_packaging.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is called from ubuntu_setup.sh and various Dockerfiles. # It's not intended to be used outside of those contexts. It assumes the lib.sh diff --git a/contrib/cirrus/packer/ubuntu_setup.sh b/contrib/cirrus/packer/ubuntu_setup.sh index 2febbd265..d650e6c76 100644 --- a/contrib/cirrus/packer/ubuntu_setup.sh +++ b/contrib/cirrus/packer/ubuntu_setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is called by packer on the subject Ubuntu VM, to setup the podman # build/test environment. It's not intended to be used outside of this context. diff --git a/contrib/cirrus/packer/xfedora_setup.sh b/contrib/cirrus/packer/xfedora_setup.sh index 25b568e8a..16ae87d8a 100644 --- a/contrib/cirrus/packer/xfedora_setup.sh +++ b/contrib/cirrus/packer/xfedora_setup.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script is called by packer on the subject fedora VM, to setup the podman # build/test environment. It's not intended to be used outside of this context. diff --git a/contrib/cirrus/rootless_test.sh b/contrib/cirrus/rootless_test.sh index 63cbec69b..31db18302 100755 --- a/contrib/cirrus/rootless_test.sh +++ b/contrib/cirrus/rootless_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/setup_container_environment.sh b/contrib/cirrus/setup_container_environment.sh index c268c162e..72542df17 100755 --- a/contrib/cirrus/setup_container_environment.sh +++ b/contrib/cirrus/setup_container_environment.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e source $(dirname $0)/lib.sh diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh index 0b9d686d3..eeae96469 100755 --- a/contrib/cirrus/setup_environment.sh +++ b/contrib/cirrus/setup_environment.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/success.sh b/contrib/cirrus/success.sh index 3b171757f..8783f6b81 100755 --- a/contrib/cirrus/success.sh +++ b/contrib/cirrus/success.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/system_test.sh b/contrib/cirrus/system_test.sh index 546fe8e30..dbee078b6 100755 --- a/contrib/cirrus/system_test.sh +++ b/contrib/cirrus/system_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/unit_test.sh b/contrib/cirrus/unit_test.sh index 2852c31ae..17a618a1c 100755 --- a/contrib/cirrus/unit_test.sh +++ b/contrib/cirrus/unit_test.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/cirrus/update_meta.sh b/contrib/cirrus/update_meta.sh index 618cd670c..6e4a473e9 100755 --- a/contrib/cirrus/update_meta.sh +++ b/contrib/cirrus/update_meta.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash source $(dirname $0)/lib.sh diff --git a/contrib/cirrus/upload_release_archive.sh b/contrib/cirrus/upload_release_archive.sh index e1b8937b7..2e2f4ddde 100755 --- a/contrib/cirrus/upload_release_archive.sh +++ b/contrib/cirrus/upload_release_archive.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -eo pipefail diff --git a/contrib/gate/entrypoint.sh b/contrib/gate/entrypoint.sh index ab6528e00..102d012e5 100755 --- a/contrib/gate/entrypoint.sh +++ b/contrib/gate/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/imgprune/entrypoint.sh b/contrib/imgprune/entrypoint.sh index b0f006332..fd80d9b26 100755 --- a/contrib/imgprune/entrypoint.sh +++ b/contrib/imgprune/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/imgts/entrypoint.sh b/contrib/imgts/entrypoint.sh index 9c653eda0..b089e1e9b 100755 --- a/contrib/imgts/entrypoint.sh +++ b/contrib/imgts/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/imgts/lib_entrypoint.sh b/contrib/imgts/lib_entrypoint.sh index 3f6b11128..6eb5cdc2f 100644 --- a/contrib/imgts/lib_entrypoint.sh +++ b/contrib/imgts/lib_entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/contrib/upldrel/entrypoint.sh b/contrib/upldrel/entrypoint.sh index dc0e69676..6eb1b8f94 100755 --- a/contrib/upldrel/entrypoint.sh +++ b/contrib/upldrel/entrypoint.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/docs/remote-docs.sh b/docs/remote-docs.sh index 4774b94a3..6d520fae6 100755 --- a/docs/remote-docs.sh +++ b/docs/remote-docs.sh @@ -1,5 +1,6 @@ -#!/bin/bash -e +#!/usr/bin/env bash # Assemble remote man pages for darwin or windows from markdown files +set -e PLATFORM=$1 ## linux, windows or darwin TARGET=${2} ## where to output files @@ -15,7 +15,7 @@ require ( github.com/containers/conmon v2.0.19+incompatible github.com/containers/image/v5 v5.5.1 github.com/containers/psgo v1.5.1 - github.com/containers/storage v1.21.2 + github.com/containers/storage v1.23.0 github.com/coreos/go-systemd/v22 v22.1.0 github.com/cri-o/ocicni v0.2.0 github.com/cyphar/filepath-securejoin v0.2.2 @@ -62,7 +62,7 @@ require ( golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 - k8s.io/api v0.18.6 + k8s.io/api v0.18.8 k8s.io/apimachinery v0.18.8 k8s.io/client-go v0.0.0-20190620085101-78d2af792bab ) @@ -81,7 +81,6 @@ github.com/containers/image/v5 v5.5.1 h1:h1FCOXH6Ux9/p/E4rndsQOC4yAdRU0msRTfLVeQ github.com/containers/image/v5 v5.5.1/go.mod h1:4PyNYR0nwlGq/ybVJD9hWlhmIsNra4Q8uOQX2s6E2uM= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE= github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= -github.com/containers/ocicrypt v1.0.2 h1:Q0/IPs8ohfbXNxEfyJ2pFVmvJu5BhqJUAmc6ES9NKbo= github.com/containers/ocicrypt v1.0.2/go.mod h1:nsOhbP19flrX6rE7ieGFvBlr7modwmNjsqWarIUce4M= github.com/containers/ocicrypt v1.0.3 h1:vYgl+RZ9Q3DPMuTfxmN+qp0X2Bj52uuY2vnt6GzVe1c= github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g= @@ -90,6 +89,8 @@ github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzP github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc= github.com/containers/storage v1.21.2 h1:bf9IqA+g6ClBviqVG5lVCp5tTH9lvWwjYws7mVYSti0= github.com/containers/storage v1.21.2/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw= +github.com/containers/storage v1.23.0 h1:gYyNkBiihC2FvGiHOjOjpnfojYwgxpLVooTUlmD6pxs= +github.com/containers/storage v1.23.0/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38= @@ -146,13 +147,11 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= -github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/go-dockerclient v1.6.5 h1:vuFDnPcds3LvTWGYb9h0Rty14FLgkjHZdwLDROCdgsw= github.com/fsouza/go-dockerclient v1.6.5/go.mod h1:GOdftxWLWIbIWKbIMDroKFJzPdg6Iw7r+jX1DDZdVsA= -github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -641,11 +640,9 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A= -k8s.io/api v0.18.6 h1:osqrAXbOQjkKIWDTjrqxWQ3w0GkKb1KA1XkUGHHYpeE= -k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI= +k8s.io/api v0.18.8 h1:aIKUzJPb96f3fKec2lxtY7acZC9gQNDLVhfSGpxBAC4= +k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY= k8s.io/apimachinery v0.0.0-20190612205821-1799e75a0719/go.mod h1:I4A+glKBHiTgiEjQiCCQfCAIcIMFGt291SmsvcrFzJA= -k8s.io/apimachinery v0.18.6 h1:RtFHnfGNfd1N0LeSrKCUznz5xtUP1elRGvHJbL3Ntag= -k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= k8s.io/apimachinery v0.18.8 h1:jimPrycCqgx2QPearX3to1JePz7wSbVLq+7PdBTTwQ0= k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMig= k8s.io/client-go v0.0.0-20190620085101-78d2af792bab h1:E8Fecph0qbNsAbijJJQryKu4Oi9QTp5cVpjTE+nqg6g= diff --git a/hack/apparmor_tag.sh b/hack/apparmor_tag.sh index 0fd222210..794370e79 100755 --- a/hack/apparmor_tag.sh +++ b/hack/apparmor_tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if pkg-config libapparmor 2> /dev/null ; then echo apparmor fi diff --git a/hack/btrfs_installed_tag.sh b/hack/btrfs_installed_tag.sh index 357f33b8b..c4d99f377 100755 --- a/hack/btrfs_installed_tag.sh +++ b/hack/btrfs_installed_tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cc -E - > /dev/null 2> /dev/null << EOF #include <btrfs/ioctl.h> EOF diff --git a/hack/btrfs_tag.sh b/hack/btrfs_tag.sh index cc48504ab..59cb969ad 100755 --- a/hack/btrfs_tag.sh +++ b/hack/btrfs_tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash cc -E - > /dev/null 2> /dev/null << EOF #include <btrfs/version.h> EOF diff --git a/hack/check_root.sh b/hack/check_root.sh index 203eae9d3..1f53887ff 100755 --- a/hack/check_root.sh +++ b/hack/check_root.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if ! [ $(id -u) = 0 ]; then echo "Please run as root! '$@' requires root privileges." exit 1 diff --git a/hack/get_ci_vm.sh b/hack/get_ci_vm.sh index 05b7a4a6d..b37dba508 100755 --- a/hack/get_ci_vm.sh +++ b/hack/get_ci_vm.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/hack/get_release_info.sh b/hack/get_release_info.sh index c1c694a44..69cf8cd57 100755 --- a/hack/get_release_info.sh +++ b/hack/get_release_info.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # This script produces various bits of metadata needed by Makefile. Using # a script allows uniform behavior across multiple environments and diff --git a/hack/golangci-lint.sh b/hack/golangci-lint.sh index 8c81a3743..03c29c89a 100755 --- a/hack/golangci-lint.sh +++ b/hack/golangci-lint.sh @@ -1,6 +1,7 @@ -#!/bin/bash -e +#!/usr/bin/env bash # Need to run linter twice to cover all the build tags code paths +set -e declare -A BUILD_TAGS # TODO: add systemd tag diff --git a/hack/install_bats.sh b/hack/install_bats.sh index 00ded07a9..d30e3daf8 100755 --- a/hack/install_bats.sh +++ b/hack/install_bats.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/hack/install_catatonit.sh b/hack/install_catatonit.sh index 7fd7592a9..8837db3a8 100755 --- a/hack/install_catatonit.sh +++ b/hack/install_catatonit.sh @@ -1,7 +1,8 @@ -#!/bin/bash -e +#!/usr/bin/env bash BASE_PATH="/usr/libexec/podman" CATATONIT_PATH="${BASE_PATH}/catatonit" CATATONIT_VERSION="v0.1.4" +set -e if [ -f $CATATONIT_PATH ]; then echo "skipping ... catatonit is already installed" diff --git a/hack/install_golangci.sh b/hack/install_golangci.sh index 6ef8ce823..57cdd2e4d 100755 --- a/hack/install_golangci.sh +++ b/hack/install_golangci.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e diff --git a/hack/libdm_tag.sh b/hack/libdm_tag.sh index d1f83ba10..d3668aab1 100755 --- a/hack/libdm_tag.sh +++ b/hack/libdm_tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash tmpdir="$PWD/tmp.$RANDOM" mkdir -p "$tmpdir" trap 'rm -fr "$tmpdir"' EXIT diff --git a/hack/man-page-checker b/hack/man-page-checker index d2cc6c6e1..45f9edbd1 100755 --- a/hack/man-page-checker +++ b/hack/man-page-checker @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # man-page-checker - validate and cross-reference man page names # diff --git a/hack/podman-commands.sh b/hack/podman-commands.sh index da4d446aa..587cac782 100755 --- a/hack/podman-commands.sh +++ b/hack/podman-commands.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Compare commands listed by 'podman help' against those in 'man podman'. # Recurse into subcommands as well. diff --git a/hack/podmanv2-retry b/hack/podmanv2-retry index ea77486ff..1f3be0731 100755 --- a/hack/podmanv2-retry +++ b/hack/podmanv2-retry @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # podman-try - try running a command via PODMAN1; use PODMAN2 as fallback # diff --git a/hack/selinux_tag.sh b/hack/selinux_tag.sh index ff80fda04..993630ad6 100755 --- a/hack/selinux_tag.sh +++ b/hack/selinux_tag.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash if pkg-config libselinux 2> /dev/null ; then echo selinux fi diff --git a/hack/tree_status.sh b/hack/tree_status.sh index ac874a347..2f56cdcd3 100755 --- a/hack/tree_status.sh +++ b/hack/tree_status.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash set -e SUGGESTION="${SUGGESTION:-sync the vendor.conf and commit all changes.}" diff --git a/libpod/container_config.go b/libpod/container_config.go index 5f89395c1..3fc058d52 100644 --- a/libpod/container_config.go +++ b/libpod/container_config.go @@ -310,7 +310,11 @@ type ContainerMiscConfig struct { // 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 + // 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 diff --git a/libpod/options.go b/libpod/options.go index 16b05d9b6..dccbb8741 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -2130,3 +2130,23 @@ func WithPodHostNetwork() PodCreateOption { return nil } } + +// WithPodInfraExitCommand sets an exit command for the pod's infra container. +// Semantics are identical to WithExitCommand() above - the ID of the container +// will be appended to the end of the provided command (note that this will +// specifically be the ID of the infra container *and not the pod's id*. +func WithPodInfraExitCommand(exitCmd []string) PodCreateOption { + return func(pod *Pod) error { + if pod.valid { + return define.ErrPodFinalized + } + + if !pod.config.InfraContainer.HasInfraContainer { + return errors.Wrapf(define.ErrInvalidArg, "cannot configure pod infra container exit command as no infra container is being created") + } + + pod.config.InfraContainer.ExitCommand = exitCmd + + return nil + } +} diff --git a/libpod/pod.go b/libpod/pod.go index 76d50db4e..422966b94 100644 --- a/libpod/pod.go +++ b/libpod/pod.go @@ -81,7 +81,15 @@ type podState struct { InfraContainerID string } -// InfraContainerConfig is the configuration for the pod's infra container +// InfraContainerConfig is the configuration for the pod's infra container. +// Generally speaking, these are equivalent to container configuration options +// you will find in container_config.go (and even named identically), save for +// HasInfraContainer (which determines if an infra container is even created - +// if it is false, no other options in this struct will be used) and HostNetwork +// (this involves the created OCI spec, and as such is not represented directly +// in container_config.go). +// Generally speaking, aside from those two exceptions, these options will set +// the equivalent field in the container's configuration. type InfraContainerConfig struct { ConmonPidFile string `json:"conmonPidFile"` HasInfraContainer bool `json:"makeInfraContainer"` @@ -96,6 +104,7 @@ type InfraContainerConfig struct { UseImageHosts bool `json:"useImageHosts,omitempty"` HostAdd []string `json:"hostsAdd,omitempty"` Networks []string `json:"networks,omitempty"` + ExitCommand []string `json:"exitCommand,omitempty"` } // ID retrieves the pod's ID diff --git a/libpod/pod_api.go b/libpod/pod_api.go index 4cb604683..ec4cc08f7 100644 --- a/libpod/pod_api.go +++ b/libpod/pod_api.go @@ -11,20 +11,20 @@ import ( "github.com/sirupsen/logrus" ) -// Start starts all containers within a pod -// It combines the effects of Init() and Start() on a container +// Start starts all containers within a pod. +// It combines the effects of Init() and Start() on a container. // If a container has already been initialized it will be started, // otherwise it will be initialized then started. // Containers that are already running or have been paused are ignored // All containers are started independently, in order dictated by their // dependencies. -// An error and a map[string]error are returned +// An error and a map[string]error are returned. // If the error is not nil and the map is nil, an error was encountered before -// any containers were started +// any containers were started. // If map is not nil, an error was encountered when starting one or more // containers. The container ID is mapped to the error encountered. The error is -// set to ErrCtrExists -// If both error and the map are nil, all containers were started successfully +// set to ErrPodPartialFail. +// If both error and the map are nil, all containers were started successfully. func (p *Pod) Start(ctx context.Context) (map[string]error, error) { p.lock.Lock() defer p.lock.Unlock() @@ -72,20 +72,20 @@ func (p *Pod) Stop(ctx context.Context, cleanup bool) (map[string]error, error) } // StopWithTimeout stops all containers within a pod that are not already stopped -// Each container will use its own stop timeout +// Each container will use its own stop timeout. // Only running containers will be stopped. Paused, stopped, or created // containers will be ignored. // If cleanup is true, mounts and network namespaces will be cleaned up after // the container is stopped. // All containers are stopped independently. An error stopping one container // will not prevent other containers being stopped. -// An error and a map[string]error are returned +// An error and a map[string]error are returned. // If the error is not nil and the map is nil, an error was encountered before -// any containers were stopped +// any containers were stopped. // If map is not nil, an error was encountered when stopping one or more // containers. The container ID is mapped to the error encountered. The error is -// set to ErrCtrExists -// If both error and the map are nil, all containers were stopped without error +// set to ErrPodPartialFail. +// If both error and the map are nil, all containers were stopped without error. func (p *Pod) StopWithTimeout(ctx context.Context, cleanup bool, timeout int) (map[string]error, error) { p.lock.Lock() defer p.lock.Unlock() @@ -138,10 +138,82 @@ func (p *Pod) StopWithTimeout(ctx context.Context, cleanup bool, timeout int) (m ctr.lock.Unlock() } + p.newPodEvent(events.Stop) + if len(ctrErrors) > 0 { return ctrErrors, errors.Wrapf(define.ErrPodPartialFail, "error stopping some containers") } - defer p.newPodEvent(events.Stop) + return nil, nil +} + +// Cleanup cleans up all containers within a pod that have stopped. +// All containers are cleaned up independently. An error with one container will +// not prevent other containers being cleaned up. +// An error and a map[string]error are returned. +// If the error is not nil and the map is nil, an error was encountered before +// any containers were cleaned up. +// If map is not nil, an error was encountered when working on one or more +// containers. The container ID is mapped to the error encountered. The error is +// set to ErrPodPartialFail. +// If both error and the map are nil, all containers were paused without error +func (p *Pod) Cleanup(ctx context.Context) (map[string]error, error) { + p.lock.Lock() + defer p.lock.Unlock() + + if !p.valid { + return nil, define.ErrPodRemoved + } + + allCtrs, err := p.runtime.state.PodContainers(p) + if err != nil { + return nil, err + } + + ctrErrors := make(map[string]error) + + // Clean up all containers + for _, ctr := range allCtrs { + ctr.lock.Lock() + + if err := ctr.syncContainer(); err != nil { + ctr.lock.Unlock() + ctrErrors[ctr.ID()] = err + continue + } + + // Ignore containers that are running/paused + if !ctr.ensureState(define.ContainerStateConfigured, define.ContainerStateCreated, define.ContainerStateStopped, define.ContainerStateExited) { + ctr.lock.Unlock() + continue + } + + // Check for running exec sessions, ignore containers with them. + sessions, err := ctr.getActiveExecSessions() + if err != nil { + ctr.lock.Unlock() + ctrErrors[ctr.ID()] = err + continue + } + if len(sessions) > 0 { + ctr.lock.Unlock() + continue + } + + // TODO: Should we handle restart policy here? + + ctr.newContainerEvent(events.Cleanup) + + if err := ctr.cleanup(ctx); err != nil { + ctrErrors[ctr.ID()] = err + } + + ctr.lock.Unlock() + } + + if len(ctrErrors) > 0 { + return ctrErrors, errors.Wrapf(define.ErrPodPartialFail, "error cleaning up some containers") + } + return nil, nil } @@ -150,12 +222,12 @@ func (p *Pod) StopWithTimeout(ctx context.Context, cleanup bool, timeout int) (m // containers will be ignored. // All containers are paused independently. An error pausing one container // will not prevent other containers being paused. -// An error and a map[string]error are returned +// An error and a map[string]error are returned. // If the error is not nil and the map is nil, an error was encountered before -// any containers were paused +// any containers were paused. // If map is not nil, an error was encountered when pausing one or more // containers. The container ID is mapped to the error encountered. The error is -// set to ErrCtrExists +// set to ErrPodPartialFail. // If both error and the map are nil, all containers were paused without error func (p *Pod) Pause() (map[string]error, error) { p.lock.Lock() @@ -219,13 +291,13 @@ func (p *Pod) Pause() (map[string]error, error) { // containers will be ignored. // All containers are unpaused independently. An error unpausing one container // will not prevent other containers being unpaused. -// An error and a map[string]error are returned +// An error and a map[string]error are returned. // If the error is not nil and the map is nil, an error was encountered before -// any containers were unpaused +// any containers were unpaused. // If map is not nil, an error was encountered when unpausing one or more // containers. The container ID is mapped to the error encountered. The error is -// set to ErrCtrExists -// If both error and the map are nil, all containers were unpaused without error +// set to ErrPodPartialFail. +// If both error and the map are nil, all containers were unpaused without error. func (p *Pod) Unpause() (map[string]error, error) { p.lock.Lock() defer p.lock.Unlock() @@ -280,13 +352,13 @@ func (p *Pod) Unpause() (map[string]error, error) { // All containers are started independently, in order dictated by their // dependencies. An error restarting one container // will not prevent other containers being restarted. -// An error and a map[string]error are returned +// An error and a map[string]error are returned. // If the error is not nil and the map is nil, an error was encountered before -// any containers were restarted +// any containers were restarted. // If map is not nil, an error was encountered when restarting one or more // containers. The container ID is mapped to the error encountered. The error is -// set to ErrCtrExists -// If both error and the map are nil, all containers were restarted without error +// set to ErrPodPartialFail. +// If both error and the map are nil, all containers were restarted without error. func (p *Pod) Restart(ctx context.Context) (map[string]error, error) { p.lock.Lock() defer p.lock.Unlock() @@ -328,17 +400,17 @@ func (p *Pod) Restart(ctx context.Context) (map[string]error, error) { return nil, nil } -// Kill sends a signal to all running containers within a pod +// Kill sends a signal to all running containers within a pod. // Signals will only be sent to running containers. Containers that are not // running will be ignored. All signals are sent independently, and sending will // continue even if some containers encounter errors. -// An error and a map[string]error are returned +// An error and a map[string]error are returned. // If the error is not nil and the map is nil, an error was encountered before -// any containers were signalled +// any containers were signalled. // If map is not nil, an error was encountered when signalling one or more // containers. The container ID is mapped to the error encountered. The error is -// set to ErrCtrExists -// If both error and the map are nil, all containers were signalled successfully +// set to ErrPodPartialFail. +// If both error and the map are nil, all containers were signalled successfully. func (p *Pod) Kill(signal uint) (map[string]error, error) { p.lock.Lock() defer p.lock.Unlock() @@ -393,8 +465,8 @@ func (p *Pod) Kill(signal uint) (map[string]error, error) { return nil, nil } -// Status gets the status of all containers in the pod -// Returns a map of Container ID to Container Status +// Status gets the status of all containers in the pod. +// Returns a map of Container ID to Container Status. func (p *Pod) Status() (map[string]define.ContainerStatus, error) { p.lock.Lock() defer p.lock.Unlock() @@ -430,7 +502,7 @@ func containerStatusFromContainers(allCtrs []*Container) (map[string]define.Cont return status, nil } -// Inspect returns a PodInspect struct to describe the pod +// Inspect returns a PodInspect struct to describe the pod. func (p *Pod) Inspect() (*define.InspectPodData, error) { p.lock.Lock() defer p.lock.Unlock() diff --git a/libpod/runtime_pod_infra_linux.go b/libpod/runtime_pod_infra_linux.go index 4d149a6eb..b2f21d946 100644 --- a/libpod/runtime_pod_infra_linux.go +++ b/libpod/runtime_pod_infra_linux.go @@ -83,6 +83,9 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm return nil, errors.Wrapf(err, "error removing network namespace from pod %s infra container", p.ID()) } + // For each option in InfraContainerConfig - if set, pass into + // the infra container we're creating with the appropriate + // With... option. if p.config.InfraContainer.StaticIP != nil { options = append(options, WithStaticIP(p.config.InfraContainer.StaticIP)) } @@ -107,6 +110,9 @@ func (r *Runtime) makeInfraContainer(ctx context.Context, p *Pod, imgName, rawIm if len(p.config.InfraContainer.HostAdd) > 0 { options = append(options, WithHosts(p.config.InfraContainer.HostAdd)) } + if len(p.config.InfraContainer.ExitCommand) > 0 { + options = append(options, WithExitCommand(p.config.InfraContainer.ExitCommand)) + } } g.SetRootReadonly(true) diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go index 10e0d4ce9..6e704fe65 100644 --- a/pkg/api/handlers/libpod/pods.go +++ b/pkg/api/handlers/libpod/pods.go @@ -123,10 +123,17 @@ func PodStop(w http.ResponseWriter, r *http.Request) { } else { responses, stopError = pod.Stop(r.Context(), false) } - if stopError != nil { + if stopError != nil && errors.Cause(stopError) != define.ErrPodPartialFail { utils.Error(w, "Something went wrong", http.StatusInternalServerError, err) return } + // Try to clean up the pod - but only warn on failure, it's nonfatal. + if cleanupCtrs, cleanupErr := pod.Cleanup(r.Context()); cleanupErr != nil { + logrus.Errorf("Error cleaning up pod %s: %v", pod.ID(), cleanupErr) + for id, err := range cleanupCtrs { + logrus.Errorf("Error cleaning up pod %s container %s: %v", pod.ID(), id, err) + } + } var errs []error //nolint for _, err := range responses { errs = append(errs, err) diff --git a/pkg/bindings/test/pods_test.go b/pkg/bindings/test/pods_test.go index 27f648384..8498de020 100644 --- a/pkg/bindings/test/pods_test.go +++ b/pkg/bindings/test/pods_test.go @@ -244,7 +244,7 @@ var _ = Describe("Podman pods", func() { Expect(response.State).To(Equal(define.PodStateExited)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). - To(Equal(define.ContainerStateStopped)) + To(Equal(define.ContainerStateExited)) } // Stop an already stopped pod @@ -309,7 +309,7 @@ var _ = Describe("Podman pods", func() { Expect(response.State).To(Equal(define.PodStateExited)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). - To(Equal(define.ContainerStateStopped)) + To(Equal(define.ContainerStateExited)) } _, err = pods.Stop(bt.conn, newpod2, nil) Expect(err).To(BeNil()) @@ -318,7 +318,7 @@ var _ = Describe("Podman pods", func() { Expect(response.State).To(Equal(define.PodStateExited)) for _, i := range response.Containers { Expect(define.StringToContainerStatus(i.State)). - To(Equal(define.ContainerStateStopped)) + To(Equal(define.ContainerStateExited)) } _, err = pods.Prune(bt.conn) Expect(err).To(BeNil()) diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 0183a90d8..c06714cbb 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -191,7 +191,7 @@ func createBridge(r *libpod.Runtime, name string, options entities.NetworkCreate var plugins []network.CNIPlugins var routes []network.IPAMRoute - defaultRoute, err := network.NewIPAMDefaultRoute() + defaultRoute, err := network.NewIPAMDefaultRoute(network.IsIPv6(subnet.IP)) if err != nil { return "", err } diff --git a/pkg/network/ip.go b/pkg/network/ip.go index 1798cd939..ba93a0d05 100644 --- a/pkg/network/ip.go +++ b/pkg/network/ip.go @@ -12,3 +12,8 @@ func CalcGatewayIP(ipn *net.IPNet) net.IP { nid := ipn.IP.Mask(ipn.Mask) return ip.NextIP(nid) } + +// IsIPv6 returns if netIP is IPv6. +func IsIPv6(netIP net.IP) bool { + return netIP != nil && netIP.To4() == nil +} diff --git a/pkg/network/netconflist.go b/pkg/network/netconflist.go index 4271d3f54..8187fdb39 100644 --- a/pkg/network/netconflist.go +++ b/pkg/network/netconflist.go @@ -6,6 +6,11 @@ import ( "path/filepath" ) +const ( + defaultIPv4Route = "0.0.0.0/0" + defaultIPv6Route = "::/0" +) + // NcList describes a generic map type NcList map[string]interface{} @@ -86,9 +91,13 @@ func NewIPAMRoute(r *net.IPNet) IPAMRoute { //nolint:interfacer } // NewIPAMDefaultRoute creates a new IPAMDefault route of -// 0.0.0.0/0 -func NewIPAMDefaultRoute() (IPAMRoute, error) { - _, n, err := net.ParseCIDR("0.0.0.0/0") +// 0.0.0.0/0 for IPv4 or ::/0 for IPv6 +func NewIPAMDefaultRoute(isIPv6 bool) (IPAMRoute, error) { + route := defaultIPv4Route + if isIPv6 { + route = defaultIPv6Route + } + _, n, err := net.ParseCIDR(route) if err != nil { return IPAMRoute{}, err } diff --git a/pkg/network/netconflist_test.go b/pkg/network/netconflist_test.go new file mode 100644 index 000000000..a82a0140a --- /dev/null +++ b/pkg/network/netconflist_test.go @@ -0,0 +1,38 @@ +package network + +import ( + "reflect" + "testing" +) + +func TestNewIPAMDefaultRoute(t *testing.T) { + + tests := []struct { + name string + isIPv6 bool + want IPAMRoute + }{ + { + name: "IPv4 default route", + isIPv6: false, + want: IPAMRoute{defaultIPv4Route}, + }, + { + name: "IPv6 default route", + isIPv6: true, + want: IPAMRoute{defaultIPv6Route}, + }, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + got, err := NewIPAMDefaultRoute(tt.isIPv6) + if err != nil { + t.Errorf("no errorr expected: %v", err) + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("NewIPAMDefaultRoute() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go index 0cbfca2db..0bd39d5a4 100644 --- a/pkg/specgen/generate/pod_create.go +++ b/pkg/specgen/generate/pod_create.go @@ -13,14 +13,14 @@ func MakePod(p *specgen.PodSpecGenerator, rt *libpod.Runtime) (*libpod.Pod, erro if err := p.Validate(); err != nil { return nil, err } - options, err := createPodOptions(p) + options, err := createPodOptions(p, rt) if err != nil { return nil, err } return rt.NewPod(context.Background(), options...) } -func createPodOptions(p *specgen.PodSpecGenerator) ([]libpod.PodCreateOption, error) { +func createPodOptions(p *specgen.PodSpecGenerator, rt *libpod.Runtime) ([]libpod.PodCreateOption, error) { var ( options []libpod.PodCreateOption ) @@ -31,6 +31,18 @@ func createPodOptions(p *specgen.PodSpecGenerator) ([]libpod.PodCreateOption, er return nil, err } options = append(options, nsOptions...) + + // Make our exit command + storageConfig := rt.StorageConfig() + runtimeConfig, err := rt.GetConfig() + if err != nil { + return nil, err + } + exitCommand, err := CreateExitCommandArgs(storageConfig, runtimeConfig, logrus.IsLevelEnabled(logrus.DebugLevel), false, false) + if err != nil { + return nil, errors.Wrapf(err, "error creating infra container exit command") + } + options = append(options, libpod.WithPodInfraExitCommand(exitCommand)) } if len(p.CgroupParent) > 0 { options = append(options, libpod.WithPodCgroupParent(p.CgroupParent)) diff --git a/test/apiv2/test-apiv2 b/test/apiv2/test-apiv2 index d0bf28b9a..2f01783ff 100755 --- a/test/apiv2/test-apiv2 +++ b/test/apiv2/test-apiv2 @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Usage: test-apiv2 [PORT] # diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go index fcd324cd1..f97e6c1f1 100644 --- a/test/e2e/network_create_test.go +++ b/test/e2e/network_create_test.go @@ -178,6 +178,47 @@ var _ = Describe("Podman network create", func() { Expect(subnet.Contains(containerIP)).To(BeTrue()) }) + It("podman network create with name and IPv6 subnet", func() { + SkipIfRemote() + var ( + results []network.NcList + ) + nc := podmanTest.Podman([]string{"network", "create", "--subnet", "fd00:1:2:3:4::/64", "newIPv6network"}) + nc.WaitWithDefaultTimeout() + Expect(nc.ExitCode()).To(BeZero()) + + defer podmanTest.removeCNINetwork("newIPv6network") + + // Inspect the network configuration + inspect := podmanTest.Podman([]string{"network", "inspect", "newIPv6network"}) + inspect.WaitWithDefaultTimeout() + + // JSON the network configuration into something usable + err := json.Unmarshal([]byte(inspect.OutputToString()), &results) + Expect(err).To(BeNil()) + result := results[0] + Expect(result["name"]).To(Equal("newIPv6network")) + + // JSON the bridge info + bridgePlugin, err := genericPluginsToBridge(result["plugins"], "bridge") + Expect(err).To(BeNil()) + Expect(bridgePlugin.IPAM.Routes[0].Dest).To(Equal("::/0")) + + // Once a container executes a new network, the nic will be created. We should clean those up + // best we can + defer removeNetworkDevice(bridgePlugin.BrName) + + try := podmanTest.Podman([]string{"run", "-it", "--rm", "--network", "newIPv6network", ALPINE, "sh", "-c", "ip addr show eth0 | grep global | awk ' /inet6 / {print $2}'"}) + try.WaitWithDefaultTimeout() + + _, subnet, err := net.ParseCIDR("fd00:1:2:3:4::/64") + Expect(err).To(BeNil()) + containerIP, _, err := net.ParseCIDR(try.OutputToString()) + Expect(err).To(BeNil()) + // Ensure that the IP the container got is within the subnet the user asked for + Expect(subnet.Contains(containerIP)).To(BeTrue()) + }) + It("podman network create with invalid subnet", func() { nc := podmanTest.Podman([]string{"network", "create", "--subnet", "10.11.12.0/17000", "fail"}) nc.WaitWithDefaultTimeout() diff --git a/test/system/260-sdnotify.bats b/test/system/260-sdnotify.bats index c37eea15a..6bc9fc02e 100644 --- a/test/system/260-sdnotify.bats +++ b/test/system/260-sdnotify.bats @@ -12,8 +12,15 @@ _SOCAT_LOG= function setup() { skip_if_remote - # TODO: remove this once CI systems have newer crun and container-selinux - skip "TEMPORARY SKIP - until CI systems get new crun, container-selinux" + # Skip if systemd is not running + systemctl list-units &>/dev/null || skip "systemd not available" + + # sdnotify fails with runc 1.0.0-3-dev2 on Ubuntu. Let's just + # assume that we work only with crun, nothing else. + run_podman info --format '{{ .Host.OCIRuntime.Name }}' + if [[ "$output" != "crun" ]]; then + skip "this test only works with crun, not '$output'" + fi basic_setup } @@ -107,7 +114,7 @@ function _assert_mainpid_is_conmon() { @test "sdnotify : container" { # Sigh... we need to pull a humongous image because it has systemd-notify. # FIXME: is there a smaller image we could use? - _FEDORA=registry.fedoraproject.org/fedora:latest + _FEDORA=registry.fedoraproject.org/fedora:31 # Pull that image. Retry in case of flakes. run_podman pull $_FEDORA || \ diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats index 1b2d14554..142d7dcd9 100644 --- a/test/system/400-unprivileged-access.bats +++ b/test/system/400-unprivileged-access.bats @@ -23,7 +23,7 @@ load helpers # as a user, the parent directory must be world-readable. test_script=$PODMAN_TMPDIR/fail-if-writable cat >$test_script <<"EOF" -#!/bin/bash +#!/usr/bin/env bash path="$1" diff --git a/test/system/helpers.t b/test/system/helpers.t index bee09505c..7a331174b 100755 --- a/test/system/helpers.t +++ b/test/system/helpers.t @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # regression tests for helpers.bash # diff --git a/test/test_podman_baseline.sh b/test/test_podman_baseline.sh index d205f544a..3624d24c2 100755 --- a/test/test_podman_baseline.sh +++ b/test/test_podman_baseline.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # test_podman_baseline.sh # A script to be run at the command line with Podman installed. # This should be run against a new kit to provide base level testing @@ -215,7 +215,7 @@ podman run $image ls / ######## FILE=./runecho.sh /bin/cat <<EOM >$FILE -#!/bin/bash +#!/usr/bin/env bash for i in {1..9}; do echo "This is a new container pull ipbabble [" \$i "]" diff --git a/test/test_podman_build.sh b/test/test_podman_build.sh index e3e53cae6..29b7354b1 100644 --- a/test/test_podman_build.sh +++ b/test/test_podman_build.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # test_podman_build.sh # diff --git a/test/test_podman_pods.sh b/test/test_podman_pods.sh index f2f47f510..c19f4fcab 100755 --- a/test/test_podman_pods.sh +++ b/test/test_podman_pods.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # test_podman_pods.sh # A script to be run at the command line with Podman installed. # This should be run against a new kit to provide base level testing diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml index ce99cb0a5..fe611f085 100644 --- a/vendor/github.com/containers/storage/.cirrus.yml +++ b/vendor/github.com/containers/storage/.cirrus.yml @@ -62,8 +62,10 @@ testing_task: - lint # Not all $TEST_DRIVER combinations are valid for all OS types. - # Note: Nested-variable resolution happens at runtime, not eval. time. - # Use verbose logic for ease of reading/maintaining. + # N/B: As of the addition of this note, nested-variable resolution + # does not happen for boolean `only_if` expressions. Since $VM_IMAGE + # contains nested variables, we must filter based on that and not the + # actual distro/version value. only_if: >- ( $VM_IMAGE =~ '.*UBUNTU.*' && $TEST_DRIVER == "vfs" ) || ( $VM_IMAGE =~ '.*UBUNTU.*' && $TEST_DRIVER == "aufs" ) || @@ -146,3 +148,15 @@ vendor_task: folder: $GOPATH/pkg/mod build_script: make vendor test_script: hack/tree_status.sh + +# Represent overall pass/fail status from required dependent tasks +success_task: + depends_on: + - lint + - testing + - meta + - vendor + container: + image: golang:1.14 + clone_script: 'mkdir -p "$CIRRUS_WORKING_DIR"' # Source code not needed + script: /bin/true diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 0369d0b1e..4d1e5d262 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.21.2 +1.23.1-dev diff --git a/vendor/github.com/containers/storage/images.go b/vendor/github.com/containers/storage/images.go index ef95598b8..2808f579f 100644 --- a/vendor/github.com/containers/storage/images.go +++ b/vendor/github.com/containers/storage/images.go @@ -10,6 +10,7 @@ import ( "github.com/containers/storage/pkg/ioutils" "github.com/containers/storage/pkg/stringid" + "github.com/containers/storage/pkg/stringutils" "github.com/containers/storage/pkg/truncindex" digest "github.com/opencontainers/go-digest" "github.com/pkg/errors" @@ -465,6 +466,19 @@ func (r *imageStore) addMappedTopLayer(id, layer string) error { return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id) } +func (r *imageStore) removeMappedTopLayer(id, layer string) error { + if image, ok := r.lookup(id); ok { + initialLen := len(image.MappedTopLayers) + image.MappedTopLayers = stringutils.RemoveFromSlice(image.MappedTopLayers, layer) + // No layer was removed. No need to save. + if initialLen == len(image.MappedTopLayers) { + return nil + } + return r.Save() + } + return errors.Wrapf(ErrImageUnknown, "error locating image with ID %q", id) +} + func (r *imageStore) Metadata(id string) (string, error) { if image, ok := r.lookup(id); ok { return image.Metadata, nil diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go index 78744e0f3..ac0f5f336 100644 --- a/vendor/github.com/containers/storage/pkg/archive/archive.go +++ b/vendor/github.com/containers/storage/pkg/archive/archive.go @@ -602,7 +602,7 @@ func (ta *tarAppender) addTarFile(path, name string) error { return nil } -func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *idtools.IDPair, inUserns, ignoreChownErrors bool) error { +func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, Lchown bool, chownOpts *idtools.IDPair, inUserns, ignoreChownErrors bool, buffer []byte) error { // hdr.Mode is in linux format, which we can use for sycalls, // but for os.Foo() calls we need the mode converted to os.FileMode, // so use hdrInfo.Mode() (they differ for e.g. setuid bits) @@ -626,7 +626,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L if err != nil { return err } - if _, err := io.Copy(file, reader); err != nil { + if _, err := io.CopyBuffer(file, reader, buffer); err != nil { file.Close() return err } @@ -942,6 +942,7 @@ func Unpack(decompressedArchive io.Reader, dest string, options *TarOptions) err idMappings := idtools.NewIDMappingsFromMaps(options.UIDMaps, options.GIDMaps) rootIDs := idMappings.RootPair() whiteoutConverter := getWhiteoutConverter(options.WhiteoutFormat, options.WhiteoutData) + buffer := make([]byte, 1<<20) // Iterate through the files in the archive. loop: @@ -1038,7 +1039,7 @@ loop: chownOpts = &idtools.IDPair{UID: hdr.Uid, GID: hdr.Gid} } - if err := createTarFile(path, dest, hdr, trBuf, !options.NoLchown, chownOpts, options.InUserNS, options.IgnoreChownErrors); err != nil { + if err := createTarFile(path, dest, hdr, trBuf, !options.NoLchown, chownOpts, options.InUserNS, options.IgnoreChownErrors, buffer); err != nil { return err } diff --git a/vendor/github.com/containers/storage/pkg/archive/changes_unix.go b/vendor/github.com/containers/storage/pkg/archive/changes_unix.go index 805fb960a..1cc1910f8 100644 --- a/vendor/github.com/containers/storage/pkg/archive/changes_unix.go +++ b/vendor/github.com/containers/storage/pkg/archive/changes_unix.go @@ -18,9 +18,11 @@ func statDifferent(oldStat *system.StatT, oldInfo *FileInfo, newStat *system.Sta if cuid, cgid, err := newInfo.idMappings.ToContainer(idtools.IDPair{UID: int(uid), GID: int(gid)}); err == nil { uid = uint32(cuid) gid = uint32(cgid) - if oldcuid, oldcgid, err := oldInfo.idMappings.ToContainer(idtools.IDPair{UID: int(oldUID), GID: int(oldGID)}); err == nil { - oldUID = uint32(oldcuid) - oldGID = uint32(oldcgid) + if oldInfo != nil { + if oldcuid, oldcgid, err := oldInfo.idMappings.ToContainer(idtools.IDPair{UID: int(oldUID), GID: int(oldGID)}); err == nil { + oldUID = uint32(oldcuid) + oldGID = uint32(oldcgid) + } } } ownerChanged := uid != oldUID || gid != oldGID diff --git a/vendor/github.com/containers/storage/pkg/archive/diff.go b/vendor/github.com/containers/storage/pkg/archive/diff.go index 78e3d9102..a12dd4202 100644 --- a/vendor/github.com/containers/storage/pkg/archive/diff.go +++ b/vendor/github.com/containers/storage/pkg/archive/diff.go @@ -37,6 +37,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, aufsTempdir := "" aufsHardlinks := make(map[string]*tar.Header) + buffer := make([]byte, 1<<20) // Iterate through the files in the archive. for { @@ -105,7 +106,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, } defer os.RemoveAll(aufsTempdir) } - if err := createTarFile(filepath.Join(aufsTempdir, basename), dest, hdr, tr, true, nil, options.InUserNS, options.IgnoreChownErrors); err != nil { + if err := createTarFile(filepath.Join(aufsTempdir, basename), dest, hdr, tr, true, nil, options.InUserNS, options.IgnoreChownErrors, buffer); err != nil { return 0, err } } @@ -196,7 +197,7 @@ func UnpackLayer(dest string, layer io.Reader, options *TarOptions) (size int64, return 0, err } - if err := createTarFile(path, dest, srcHdr, srcData, true, nil, options.InUserNS, options.IgnoreChownErrors); err != nil { + if err := createTarFile(path, dest, srcHdr, srcData, true, nil, options.InUserNS, options.IgnoreChownErrors, buffer); err != nil { return 0, err } diff --git a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go index 90f196371..e5faf9aad 100644 --- a/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go +++ b/vendor/github.com/containers/storage/pkg/fileutils/fileutils.go @@ -262,7 +262,7 @@ func (p *Pattern) compile() error { } } - regStr += "(/.*)?$" + regStr += "(" + escSL + ".*)?$" re, err := regexp.Compile(regStr) if err != nil { diff --git a/vendor/github.com/containers/storage/pkg/stringutils/stringutils.go b/vendor/github.com/containers/storage/pkg/stringutils/stringutils.go index 8c4c39875..66a59c85d 100644 --- a/vendor/github.com/containers/storage/pkg/stringutils/stringutils.go +++ b/vendor/github.com/containers/storage/pkg/stringutils/stringutils.go @@ -56,13 +56,24 @@ func Truncate(s string, maxlen int) string { // Comparison is case insensitive func InSlice(slice []string, s string) bool { for _, ss := range slice { - if strings.ToLower(s) == strings.ToLower(ss) { + if strings.EqualFold(s, ss) { return true } } return false } +// RemoveFromSlice removes a string from a slice. The string can be present +// multiple times. The entire slice is iterated. +func RemoveFromSlice(slice []string, s string) (ret []string) { + for _, ss := range slice { + if !strings.EqualFold(s, ss) { + ret = append(ret, ss) + } + } + return ret +} + func quote(word string, buf *bytes.Buffer) { // Bail out early for "simple" strings if word != "" && !strings.ContainsAny(word, "\\'\"`${[|&;<>()~*?! \t\n") { diff --git a/vendor/github.com/containers/storage/pkg/unshare/unshare.c b/vendor/github.com/containers/storage/pkg/unshare/unshare.c index dc7b9d570..c0e359b27 100644 --- a/vendor/github.com/containers/storage/pkg/unshare/unshare.c +++ b/vendor/github.com/containers/storage/pkg/unshare/unshare.c @@ -292,6 +292,7 @@ static int containers_reexec(int flags) { fprintf(stderr, "Error during reexec(...): %m\n"); return -1; } + close(fd); return 0; } diff --git a/vendor/github.com/containers/storage/storage_test.conf b/vendor/github.com/containers/storage/storage_test.conf new file mode 100644 index 000000000..9b682fe15 --- /dev/null +++ b/vendor/github.com/containers/storage/storage_test.conf @@ -0,0 +1,35 @@ +# This file is is a TEST configuration file for all tools +# that use the containers/storage library. +# See man 5 containers-storage.conf for more information +# The "container storage" table contains all of the server options. +[storage] + +# Default Storage Driver +driver = "" + +# Temporary storage location +runroot = "$HOME/$UID/containers/storage" + +# Primary Read/Write location of container storage +graphroot = "$HOME/$UID/containers/storage" + +# Storage path for rootless users +# +rootless_storage_path = "$HOME/$UID/containers/storage" + +[storage.options] +# Storage options to be passed to underlying storage drivers + +# AdditionalImageStores is used to pass paths to additional Read/Only image stores +# Must be comma separated list. +additionalimagestores = [ +] + +[storage.options.overlay] + +# mountopt specifies comma separated list of extra mount options +mountopt = "nodev" + + +[storage.options.thinpool] +# Storage Options for thinpool diff --git a/vendor/github.com/containers/storage/store.go b/vendor/github.com/containers/storage/store.go index 56e1e545b..937bf8c3a 100644 --- a/vendor/github.com/containers/storage/store.go +++ b/vendor/github.com/containers/storage/store.go @@ -2223,16 +2223,23 @@ func (s *store) DeleteLayer(id string) error { } for _, layer := range layers { if layer.Parent == id { - return ErrLayerHasChildren + return errors.Wrapf(ErrLayerHasChildren, "used by layer %v", layer.ID) } } images, err := ristore.Images() if err != nil { return err } + for _, image := range images { - if image.TopLayer == id || stringutils.InSlice(image.MappedTopLayers, id) { - return errors.Wrapf(ErrLayerUsedByImage, "Layer %v used by image %v", id, image.ID) + if image.TopLayer == id { + return errors.Wrapf(ErrLayerUsedByImage, "layer %v used by image %v", id, image.ID) + } + if stringutils.InSlice(image.MappedTopLayers, id) { + // No write access to the image store, fail before the layer is deleted + if _, ok := ristore.(*imageStore); !ok { + return errors.Wrapf(ErrLayerUsedByImage, "layer %v used by image %v", id, image.ID) + } } } containers, err := rcstore.Containers() @@ -2241,10 +2248,25 @@ func (s *store) DeleteLayer(id string) error { } for _, container := range containers { if container.LayerID == id { - return errors.Wrapf(ErrLayerUsedByContainer, "Layer %v used by container %v", id, container.ID) + return errors.Wrapf(ErrLayerUsedByContainer, "layer %v used by container %v", id, container.ID) } } - return rlstore.Delete(id) + if err := rlstore.Delete(id); err != nil { + return errors.Wrapf(err, "delete layer %v", id) + } + + // The check here is used to avoid iterating the images if we don't need to. + // There is already a check above for the imageStore to be writeable when the layer is part of MappedTopLayers. + if istore, ok := ristore.(*imageStore); ok { + for _, image := range images { + if stringutils.InSlice(image.MappedTopLayers, id) { + if err = istore.removeMappedTopLayer(image.ID, id); err != nil { + return errors.Wrapf(err, "remove mapped top layer %v from image %v", id, image.ID) + } + } + } + } + return nil } return ErrNotALayer } diff --git a/vendor/github.com/containers/storage/userns.go b/vendor/github.com/containers/storage/userns.go index e2b56da2f..5ba8cc418 100644 --- a/vendor/github.com/containers/storage/userns.go +++ b/vendor/github.com/containers/storage/userns.go @@ -252,7 +252,7 @@ func subtractHostIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDMap { } r2 := idtools.IDMap{ ContainerID: used.ContainerID + used.Size, - HostID: used.HostID + used.Size, + HostID: avail.HostID + (used.HostID - avail.HostID), Size: avail.HostID + avail.Size - used.HostID - used.Size, } return []idtools.IDMap{r1, r2} @@ -297,7 +297,7 @@ func subtractContainerIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDM } r2 := idtools.IDMap{ ContainerID: used.ContainerID + used.Size, - HostID: avail.HostID + used.Size, + HostID: avail.HostID + (used.ContainerID - avail.ContainerID), Size: avail.ContainerID + avail.Size - used.ContainerID - used.Size, } return []idtools.IDMap{r1, r2} @@ -314,22 +314,17 @@ func subtractContainerIDs(avail idtools.IDMap, used idtools.IDMap) []idtools.IDM // subtractAll subtracts all usedIDs from the available IDs. func subtractAll(availableIDs, usedIDs []idtools.IDMap, host bool) []idtools.IDMap { for _, u := range usedIDs { - for i := 0; i < len(availableIDs); { - var prev []idtools.IDMap - if i > 0 { - prev = availableIDs[:i-1] - } - next := availableIDs[i+1:] - cur := availableIDs[i] + var newAvailableIDs []idtools.IDMap + for _, cur := range availableIDs { var newRanges []idtools.IDMap if host { newRanges = subtractHostIDs(cur, u) } else { newRanges = subtractContainerIDs(cur, u) } - availableIDs = append(append(prev, newRanges...), next...) - i += len(newRanges) + newAvailableIDs = append(newAvailableIDs, newRanges...) } + availableIDs = newAvailableIDs } return availableIDs } @@ -361,6 +356,7 @@ func findAvailableIDRange(size uint32, availableIDs, usedIDs []idtools.IDMap) ([ return avail[:i+1], nil } remaining -= uint32(avail[i].Size) + currentID += avail[i].Size } return nil, errors.New("could not find enough available IDs") @@ -452,6 +448,5 @@ func (s *store) getAutoUserNS(id string, options *AutoUserNsOptions, image *Imag if len(options.AdditionalGIDMappings) > 0 { availableGIDs = subtractAll(availableGIDs, options.AdditionalGIDMappings, false) } - return append(availableUIDs, options.AdditionalUIDMappings...), append(availableGIDs, options.AdditionalGIDMappings...), nil } diff --git a/vendor/github.com/containers/storage/utils.go b/vendor/github.com/containers/storage/utils.go index 101f5cc7a..d65d52718 100644 --- a/vendor/github.com/containers/storage/utils.go +++ b/vendor/github.com/containers/storage/utils.go @@ -5,9 +5,7 @@ import ( "io/ioutil" "os" "os/exec" - "os/user" "path/filepath" - "regexp" "strconv" "strings" @@ -234,8 +232,9 @@ func DefaultStoreOptionsAutoDetectUID() (StoreOptions, error) { return DefaultStoreOptions(uid != 0, uid) } -// DefaultStoreOptions returns the default storage ops for containers -func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) { +// defaultStoreOptionsIsolated is an internal implementation detail of DefaultStoreOptions to allow testing. +// Everyone but the tests this is intended for should only call DefaultStoreOptions, never this function. +func defaultStoreOptionsIsolated(rootless bool, rootlessUID int, storageConf string) (StoreOptions, error) { var ( defaultRootlessRunRoot string defaultRootlessGraphRoot string @@ -248,11 +247,6 @@ func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) { return storageOpts, err } } - - storageConf, err := DefaultConfigFile(rootless && rootlessUID != 0) - if err != nil { - return storageOpts, err - } _, err = os.Stat(storageConf) if err != nil && !os.IsNotExist(err) { return storageOpts, errors.Wrapf(err, "cannot stat %s", storageConf) @@ -263,6 +257,20 @@ func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) { storageOpts = StoreOptions{} reloadConfigurationFileIfNeeded(storageConf, &storageOpts) } + if storageOpts.RunRoot != "" { + runRoot, err := expandEnvPath(storageOpts.RunRoot, rootlessUID) + if err != nil { + return storageOpts, err + } + storageOpts.RunRoot = runRoot + } + if storageOpts.GraphRoot != "" { + graphRoot, err := expandEnvPath(storageOpts.GraphRoot, rootlessUID) + if err != nil { + return storageOpts, err + } + storageOpts.GraphRoot = graphRoot + } if rootless && rootlessUID != 0 { if err == nil { @@ -276,16 +284,10 @@ func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) { storageOpts.GraphRoot = defaultRootlessGraphRoot } if storageOpts.RootlessStoragePath != "" { - if err = validRootlessStoragePathFormat(storageOpts.RootlessStoragePath); err != nil { - return storageOpts, err - } - rootlessStoragePath := strings.Replace(storageOpts.RootlessStoragePath, "$HOME", homedir.Get(), -1) - rootlessStoragePath = strings.Replace(rootlessStoragePath, "$UID", strconv.Itoa(rootlessUID), -1) - usr, err := user.LookupId(strconv.Itoa(rootlessUID)) + rootlessStoragePath, err := expandEnvPath(storageOpts.RootlessStoragePath, rootlessUID) if err != nil { return storageOpts, err } - rootlessStoragePath = strings.Replace(rootlessStoragePath, "$USER", usr.Username, -1) storageOpts.GraphRoot = rootlessStoragePath } } @@ -293,22 +295,19 @@ func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) { return storageOpts, nil } -// validRootlessStoragePathFormat checks if the environments contained in the path are accepted -func validRootlessStoragePathFormat(path string) error { - if !strings.Contains(path, "$") { - return nil +// DefaultStoreOptions returns the default storage ops for containers +func DefaultStoreOptions(rootless bool, rootlessUID int) (StoreOptions, error) { + storageConf, err := DefaultConfigFile(rootless && rootlessUID != 0) + if err != nil { + return defaultStoreOptions, err } + return defaultStoreOptionsIsolated(rootless, rootlessUID, storageConf) +} - splitPaths := strings.SplitAfter(path, "$") - validEnv := regexp.MustCompile(`^(HOME|USER|UID)([^a-zA-Z]|$)`).MatchString - if len(splitPaths) > 1 { - for _, p := range splitPaths[1:] { - if !validEnv(p) { - return errors.Errorf("Unrecognized environment variable") - } - } - } - return nil +func expandEnvPath(path string, rootlessUID int) (string, error) { + path = strings.Replace(path, "$UID", strconv.Itoa(rootlessUID), -1) + path = os.ExpandEnv(path) + return path, nil } func validateMountOptions(mountOptions []string) error { diff --git a/vendor/modules.txt b/vendor/modules.txt index 83ea53197..0ab37e30c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -156,7 +156,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.21.2 +# github.com/containers/storage v1.23.0 github.com/containers/storage github.com/containers/storage/drivers github.com/containers/storage/drivers/aufs @@ -693,7 +693,7 @@ gopkg.in/tomb.v1 gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c gopkg.in/yaml.v3 -# k8s.io/api v0.18.6 +# k8s.io/api v0.18.8 k8s.io/api/apps/v1 k8s.io/api/core/v1 # k8s.io/apimachinery v0.18.8 |