summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml4
-rw-r--r--.gitignore2
-rw-r--r--Makefile7
-rw-r--r--README.md34
-rw-r--r--cmd/podman/common/create.go7
-rw-r--r--cmd/podman/common/create_opts.go1
-rw-r--r--cmd/podman/common/specgen.go7
-rw-r--r--completions/bash/podman5
-rwxr-xr-xcontrib/cirrus/logformatter28
-rwxr-xr-xcontrib/cirrus/logformatter.t17
-rw-r--r--contrib/cirrus/packer/Makefile4
-rw-r--r--contrib/cirrus/packer/fedora_packaging.sh5
-rw-r--r--contrib/cirrus/packer/libpod_images.yml12
-rw-r--r--contrib/cirrus/packer/ubuntu_packaging.sh6
-rwxr-xr-xcontrib/cirrus/setup_environment.sh1
-rw-r--r--docs/source/markdown/podman-create.1.md4
-rw-r--r--docs/source/markdown/podman-run.1.md4
-rw-r--r--go.mod6
-rw-r--r--go.sum8
-rw-r--r--libpod/container.go6
-rw-r--r--libpod/container_exec.go4
-rw-r--r--libpod/container_inspect.go8
-rw-r--r--libpod/container_internal_linux.go10
-rw-r--r--libpod/define/config.go2
-rw-r--r--libpod/define/container_inspect.go2
-rw-r--r--libpod/healthcheck.go5
-rw-r--r--libpod/options.go14
-rw-r--r--pkg/domain/infra/abi/play.go15
-rw-r--r--pkg/specgen/container_validate.go4
-rw-r--r--pkg/specgen/generate/container_create.go3
-rw-r--r--pkg/specgen/generate/oci.go7
-rw-r--r--pkg/specgen/generate/security.go30
-rw-r--r--pkg/specgen/specgen.go2
-rw-r--r--test/e2e/attach_test.go5
-rw-r--r--test/e2e/build_test.go5
-rw-r--r--test/e2e/common_test.go27
-rw-r--r--test/e2e/config/containers.conf2
-rw-r--r--test/e2e/containers_conf_test.go11
-rw-r--r--test/e2e/create_staticip_test.go2
-rw-r--r--test/e2e/create_test.go43
-rw-r--r--test/e2e/generate_kube_test.go2
-rw-r--r--test/e2e/libpod_suite_remote_test.go2
-rw-r--r--test/e2e/libpod_suite_test.go26
-rw-r--r--test/e2e/load_test.go4
-rw-r--r--test/e2e/login_logout_test.go2
-rw-r--r--test/e2e/namespace_test.go3
-rw-r--r--test/e2e/network_create_test.go3
-rw-r--r--test/e2e/play_kube_test.go124
-rw-r--r--test/e2e/pod_infra_container_test.go5
-rw-r--r--test/e2e/pod_pod_namespaces.go3
-rw-r--r--test/e2e/pod_stats_test.go2
-rw-r--r--test/e2e/pod_top_test.go3
-rw-r--r--test/e2e/port_test.go11
-rw-r--r--test/e2e/pull_test.go6
-rw-r--r--test/e2e/run_apparmor_test.go158
-rw-r--r--test/e2e/run_cleanup_test.go3
-rw-r--r--test/e2e/run_cpu_test.go2
-rw-r--r--test/e2e/run_device_test.go2
-rw-r--r--test/e2e/run_dns_test.go2
-rw-r--r--test/e2e/run_entrypoint_test.go8
-rw-r--r--test/e2e/run_env_test.go2
-rw-r--r--test/e2e/run_memory_test.go2
-rw-r--r--test/e2e/run_networking_test.go11
-rw-r--r--test/e2e/run_ns_test.go2
-rw-r--r--test/e2e/run_passwd_test.go2
-rw-r--r--test/e2e/run_privileged_test.go2
-rw-r--r--test/e2e/run_restart_test.go7
-rw-r--r--test/e2e/run_seccomp.go2
-rw-r--r--test/e2e/run_security_labels.go3
-rw-r--r--test/e2e/run_selinux_test.go2
-rw-r--r--test/e2e/run_staticip_test.go2
-rw-r--r--test/e2e/run_test.go70
-rw-r--r--test/e2e/run_userns_test.go2
-rw-r--r--test/e2e/run_volume_test.go8
-rw-r--r--test/e2e/runlabel_test.go4
-rw-r--r--test/e2e/search_test.go6
-rw-r--r--test/e2e/system_df_test.go3
-rw-r--r--test/e2e/systemd_test.go2
-rw-r--r--test/e2e/top_test.go10
-rw-r--r--test/e2e/volume_prune_test.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go24
-rw-r--r--vendor/github.com/containers/common/pkg/config/default.go9
-rw-r--r--vendor/github.com/containers/common/version/version.go2
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/drivers/devmapper/deviceset.go2
-rw-r--r--vendor/github.com/containers/storage/pkg/archive/archive.go4
-rw-r--r--vendor/github.com/containers/storage/pkg/unshare/unshare.go27
-rw-r--r--vendor/github.com/opencontainers/runtime-tools/generate/generate.go77
-rw-r--r--vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go14
-rw-r--r--vendor/modules.txt6
90 files changed, 808 insertions, 243 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index b1aa1b475..37c9108eb 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -39,7 +39,7 @@ env:
UBUNTU_NAME: "ubuntu-20"
PRIOR_UBUNTU_NAME: "ubuntu-19"
- _BUILT_IMAGE_SUFFIX: "libpod-6508632441356288"
+ _BUILT_IMAGE_SUFFIX: "podman-5869602141896704"
FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}"
@@ -71,7 +71,7 @@ env:
# Service-account client_email - needed to build images
SERVICE_ACCOUNT: ENCRYPTED[702a8e07e27a6faf7988fcddcc068c2ef2bb182a5aa671f5ccb7fbbfb891c823aa4a7856fb17240766845dbd68bd3f90]
# Service account username part of client_email - for ssh'ing into VMs
- GCE_SSH_USERNAME: ENCRYPTED[d579f2d3000bb678c9af37c3615e92bcf3726e9afc47748c129cef23ee799faaafd4baba64048329205d162069d90060]
+ GCE_SSH_USERNAME: 'cirrus-ci'
# Default VM to use unless set or modified by task
gce_instance:
diff --git a/.gitignore b/.gitignore
index f0fdf4dc8..434a12759 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,8 @@
/conmon/
contrib/spec/podman.spec
*.coverprofile
+coverprofile
+/.coverage
/docs/*.[158]
/docs/*.[158].gz
/docs/build/
diff --git a/Makefile b/Makefile
index 132dde939..983ab46be 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,7 @@ export GO111MODULE=off
export GOPROXY=https://proxy.golang.org
GO ?= go
+COVERAGE_PATH ?= .coverage
DESTDIR ?=
EPOCH_TEST_COMMIT ?= $(shell git merge-base $${DEST_BRANCH:-master} HEAD)
HEAD ?= HEAD
@@ -308,14 +309,20 @@ testunit: libpodimage ## Run unittest on the built image
.PHONY: localunit
localunit: test/goecho/goecho varlink_generate
hack/check_root.sh make localunit
+ rm -rf ${COVERAGE_PATH} && mkdir -p ${COVERAGE_PATH}
ginkgo \
-r \
$(TESTFLAGS) \
--skipPackage test/e2e,pkg/apparmor,test/endpoint,pkg/bindings,hack \
--cover \
--covermode atomic \
+ --coverprofile coverprofile \
+ --outputdir ${COVERAGE_PATH} \
--tags "$(BUILDTAGS)" \
--succinct
+ $(GO) tool cover -html=${COVERAGE_PATH}/coverprofile -o ${COVERAGE_PATH}/coverage.html
+ $(GO) tool cover -func=${COVERAGE_PATH}/coverprofile > ${COVERAGE_PATH}/functions
+ cat ${COVERAGE_PATH}/functions | sed -n 's/\(total:\).*\([0-9][0-9].[0-9]\)/\1 \2/p'
.PHONY: ginkgo
ginkgo:
diff --git a/README.md b/README.md
index 82e2d3af9..21b30fdbd 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
![PODMAN logo](logo/podman-logo-source.svg)
-# Library and tool for running OCI-based containers in Pods
+# Podman: A tool for managing OCI containers and pods
-Libpod provides a library for applications looking to use the Container Pod concept,
-popularized by Kubernetes. Libpod also contains the Pod Manager tool `(Podman)`. Podman manages pods, containers, container images, and container volumes.
+Podman (the POD MANager) is a tool for managing containers and images, volumes mounted into those containers, and pods made from groups of containers.
+Podman is based on libpod, a library for container lifecycle management that is also contained in this repository. The libpod library provides APIs for managing containers, pods, container images, and volumes.
* [Latest Version: 2.0.2](https://github.com/containers/libpod/releases/latest)
* Latest Remote client for Windows
@@ -15,26 +15,24 @@ popularized by Kubernetes. Libpod also contains the Pod Manager tool `(Podman)`
## Overview and scope
-At a high level, the scope of libpod and Podman is the following:
+At a high level, the scope of Podman and libpod is the following:
-* Support multiple image formats including the OCI and Docker image formats.
-* Support for multiple means to download images including trust & image verification.
-* Container image management (managing image layers, overlay filesystems, etc).
-* Full management of container lifecycle.
-* Support for pods to manage groups of containers together.
+* Support for multiple container image formats, including OCI and Docker images.
+* Full management of those images, including pulling from various sources (including trust and verification), creating (built via Containerfile or Dockerfile or committed from a container), and pushing to registries and other storage backends.
+* Full management of container lifecycle, including creation (both from an image and from an exploded root filesystem), running, checkpointing and restoring (via CRIU), and removal.
+* Support for pods, groups of containers that share resources and are managed together.
* Resource isolation of containers and pods.
-* Support for a Docker-compatible CLI interface through Podman.
+* Support for a Docker-compatible CLI interface.
* Support for a REST API providing both a Docker-compatible interface and an improved interface exposing advanced Podman functionality.
-* Integration with CRI-O to share containers and backend code.
+* In the future, integration with [CRI-O](https://github.com/cri-o/cri-o) to share containers and backend code.
Podman presently only supports running containers on Linux. However, we are building a remote client which can run on Windows and OS X and manage Podman containers on a Linux system via the REST API using SSH tunneling.
## Roadmap
-1. Complete the Podman REST API and Podman v2, which will be able to connect to remote Podman instances via this API
-1. Integrate libpod into CRI-O to replace its existing container management backend
-1. Further work on the podman pod command
-1. Further improvements on rootless containers
+1. Further improvements to the REST API, with a focus on bugfixes and implementing missing functionality
+1. Integrate libpod into [CRI-O](https://github.com/cri-o/cri-o) to replace its existing container management backend
+1. Improvements on rootless containers, with a focus on improving the user experience and exposing presently-unavailable features when possible
## Communications
@@ -67,10 +65,10 @@ A little configuration by an administrator is required before rootless Podman ca
## Out of scope
-* Specializing in signing and pushing images to various storage backends.
+* Specialized signing and pushing of images to various storage backends.
See [Skopeo](https://github.com/containers/skopeo/) for those tasks.
-* Container runtimes daemons for working with the Kubernetes CRI interface.
- [CRI-O](https://github.com/cri-o/cri-o) specializes in that.
+* Support for the Kubernetes CRI interface for container management.
+ The [CRI-O](https://github.com/cri-o/cri-o) daemon specializes in that.
* Supporting `docker-compose`. We believe that Kubernetes is the defacto
standard for composing Pods and for orchestrating containers, making
Kubernetes YAML a defacto standard file format. Hence, Podman allows the
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 6ebf58204..e248e621f 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -405,7 +405,7 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
)
createFlags.StringArrayVar(
&cf.SecurityOpt,
- "security-opt", containerConfig.SecurityOptions(),
+ "security-opt", []string{},
"Security Options",
)
createFlags.String(
@@ -463,6 +463,11 @@ func GetCreateFlags(cf *ContainerCLIOpts) *pflag.FlagSet {
"tz", containerConfig.TZ(),
"Set timezone in container",
)
+ createFlags.StringVar(
+ &cf.Umask,
+ "umask", containerConfig.Umask(),
+ "Set umask in container",
+ )
createFlags.StringSliceVar(
&cf.UIDMap,
"uidmap", []string{},
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index a544846aa..2bea8b0b4 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -93,6 +93,7 @@ type ContainerCLIOpts struct {
TmpFS []string
TTY bool
Timezone string
+ Umask string
UIDMap []string
Ulimit []string
User string
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 416c6f6ec..e694317cc 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -512,10 +512,8 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.ContainerSecurityConfig.SelinuxOpts = append(s.ContainerSecurityConfig.SelinuxOpts, con[1])
s.Annotations[define.InspectAnnotationLabel] = strings.Join(s.ContainerSecurityConfig.SelinuxOpts, ",label=")
case "apparmor":
- if !c.Privileged {
- s.ContainerSecurityConfig.ApparmorProfile = con[1]
- s.Annotations[define.InspectAnnotationApparmor] = con[1]
- }
+ s.ContainerSecurityConfig.ApparmorProfile = con[1]
+ s.Annotations[define.InspectAnnotationApparmor] = con[1]
case "seccomp":
s.SeccompProfilePath = con[1]
s.Annotations[define.InspectAnnotationSeccomp] = con[1]
@@ -613,6 +611,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *ContainerCLIOpts, args []string
s.Remove = c.Rm
s.StopTimeout = &c.StopTimeout
s.Timezone = c.Timezone
+ s.Umask = c.Umask
return nil
}
diff --git a/completions/bash/podman b/completions/bash/podman
index 458090ac4..eb727ef63 100644
--- a/completions/bash/podman
+++ b/completions/bash/podman
@@ -2119,12 +2119,13 @@ _podman_container_run() {
--shm-size
--stop-signal
--stop-timeout
- --tmpfs
- --tz
--subgidname
--subuidname
--sysctl
--systemd
+ --tmpfs
+ --tz
+ --umask
--uidmap
--ulimit
--user -u
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 60c1e5985..b56a829c5 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -303,14 +303,15 @@ END_HTML
# (bindings test sometimes emits 'Running' with leading bullet char)
elsif ($line =~ /^•?Running:/) {
# Highlight the important (non-boilerplate) podman command.
+ $line =~ s/\s+--remote\s+/ /g; # --remote takes no args
# Strip out the global podman options, but show them on hover
- $line =~ s{(\S+\/podman)((\s+--(root|runroot|runtime|tmpdir|storage-opt|conmon|cgroup-manager|cni-config-dir|storage-driver|events-backend) \S+)*)(.*)}{
- my ($full_path, $options, $args) = ($1, $2, $5);
+ $line =~ s{(\S+\/podman(-remote)?)((\s+--(root|runroot|runtime|tmpdir|storage-opt|conmon|cgroup-manager|cni-config-dir|storage-driver|events-backend|url) \S+)*)(.*)}{
+ my ($full_path, $remote, $options, $args) = ($1, $2||'', $3, $6);
$options =~ s/^\s+//;
# Separate each '--foo bar' with newlines for readability
$options =~ s/ --/\n--/g;
- qq{<span title="$full_path"><b>podman</b></span> <span class=\"boring\" title=\"$options\">[options]</span><b>$args</b>};
+ qq{<span title="$full_path"><b>podman$remote</b></span> <span class=\"boring\" title=\"$options\">[options]</span><b>$args</b>};
}e;
$current_output = '';
}
@@ -418,10 +419,27 @@ END_HTML
}
}
- # FIXME: if Cirrus magic envariables are available, write a link to results
+ # If Cirrus magic envariables are available, write a link to results.
+ # FIXME: it'd be so nice to make this a clickable live link.
+ #
+ # STATIC_MAGIC_BLOB is the name of a google-storage bucket. It is
+ # unlikely to change often, but if it does you will suddenly start
+ # seeing errors when trying to view formatted logs:
+ #
+ # AccessDeniedAccess denied.Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.
+ #
+ # This happened in July 2020 when github.com/containers/libpod was
+ # renamed to podman. If something like that ever happens again, you
+ # will need to get the new magic blob value from:
+ #
+ # https://console.cloud.google.com/storage/browser?project=libpod-218412
+ #
+ # You will also probably need to set the bucket Public by clicking on
+ # the bucket name, then the Permissions tab. This is safe, since this
+ # project is fully open-source.
if ($have_formatted_log && $ENV{CIRRUS_TASK_ID}) {
my $URL_BASE = "https://storage.googleapis.com";
- my $STATIC_MAGIC_BLOB = "cirrus-ci-5385732420009984-fcae48";
+ my $STATIC_MAGIC_BLOB = "cirrus-ci-6707778565701632-fcae48";
my $ARTIFACT_NAME = "html";
my $URL = "${URL_BASE}/${STATIC_MAGIC_BLOB}/artifacts/$ENV{CIRRUS_REPO_FULL_NAME}/$ENV{CIRRUS_TASK_ID}/${ARTIFACT_NAME}/${outfile}";
diff --git a/contrib/cirrus/logformatter.t b/contrib/cirrus/logformatter.t
index d2193cc6c..440299cc2 100755
--- a/contrib/cirrus/logformatter.t
+++ b/contrib/cirrus/logformatter.t
@@ -132,6 +132,8 @@ $SCRIPT_BASE/integration_test.sh |& ${TIMESTAMP}
[+0103s] /var/tmp/go/src/github.com/containers/libpod/test/e2e/pod_restart_test.go:28
[+0103s] Running: /var/tmp/go/src/github.com/containers/libpod/bin/podman --storage-opt vfs.imagestore=/tmp/podman/imagecachedir --root /tmp/podman_test553496330/crio --runroot /tmp/podman_test553496330/crio-run --runtime /usr/bin/runc --conmon /usr/bin/conmon --cni-config-dir /etc/cni/net.d --cgroup-manager systemd --tmpdir /tmp/podman_test553496330 --events-backend file --storage-driver vfs pod rm -fa
[+0103s] 4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89
+[+0104s] Running: /var/tmp/go/src/github.com/containers/libpod/bin/podman-remote --storage-opt vfs.imagestore=/tmp/podman/imagecachedir --root /tmp/podman_test553496330/crio --runroot /tmp/podman_test553496330/crio-run --runtime /usr/bin/runc --conmon /usr/bin/conmon --cni-config-dir /etc/cni/net.d --cgroup-manager systemd --tmpdir /tmp/podman_test553496330 --events-backend file --storage-driver vfs --remote --url unix:/run/user/12345/podman-xyz.sock pod rm -fa
+[+0104s] 4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89 again
[+0107s] •
[+0107s] ------------------------------
[+0107s] podman system reset
@@ -186,6 +188,21 @@ $SCRIPT_BASE/integration_test.sh |&amp; ${TIMESTAMP}
--events-backend file
--storage-driver vfs">[options]</span><b> pod rm -fa</b>
<span class="timestamp"> </span>4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89
+
+<span class="timestamp">[+0104s] </span>Running: <span title="/var/tmp/go/src/github.com/containers/libpod/bin/podman-remote"><b>podman-remote</b></span> <span class="boring" title="--storage-opt vfs.imagestore=/tmp/podman/imagecachedir
+--root /tmp/podman_test553496330/crio
+--runroot /tmp/podman_test553496330/crio-run
+--runtime /usr/bin/runc
+--conmon /usr/bin/conmon
+--cni-config-dir /etc/cni/net.d
+--cgroup-manager systemd
+--tmpdir /tmp/podman_test553496330
+--events-backend file
+--storage-driver vfs
+--url unix:/run/user/12345/podman-xyz.sock">[options]</span><b> pod rm -fa</b>
+<span class="timestamp"> </span>4810be0cfbd42241e349dbe7d50fbc54405cd320a6637c65fd5323f34d64af89 again
+
+
<span class="timestamp">[+0107s] </span>•
</pre>
<hr />
diff --git a/contrib/cirrus/packer/Makefile b/contrib/cirrus/packer/Makefile
index a911cafdb..c5a8e4cac 100644
--- a/contrib/cirrus/packer/Makefile
+++ b/contrib/cirrus/packer/Makefile
@@ -5,7 +5,8 @@ PACKER_DIST_FILENAME := packer_${PACKER_VER}_linux_${GOARCH}.zip
# Only needed for libpod_base_images target
TIMESTAMP := $(shell date +%s)
-GOSRC ?= $(shell realpath "./../../../")
+GOPATH ?= /var/tmp/go
+GOSRC ?= $(GOPATH)/src/github.com/containers/libpod
PACKER_BASE ?= contrib/cirrus/packer
SCRIPT_BASE ?= contrib/cirrus
POST_MERGE_BUCKET_SUFFIX ?=
@@ -54,6 +55,7 @@ libpod_images: guard-PACKER_BUILDS libpod_images.json packer
./packer build \
-force \
$(shell test -z "${PACKER_BUILDS}" || echo "-only=${PACKER_BUILDS}") \
+ -var GOPATH=$(GOPATH) \
-var GOSRC=$(GOSRC) \
-var PACKER_BASE=$(PACKER_BASE) \
-var SCRIPT_BASE=$(SCRIPT_BASE) \
diff --git a/contrib/cirrus/packer/fedora_packaging.sh b/contrib/cirrus/packer/fedora_packaging.sh
index aecaaef93..b4a3a2062 100644
--- a/contrib/cirrus/packer/fedora_packaging.sh
+++ b/contrib/cirrus/packer/fedora_packaging.sh
@@ -74,6 +74,7 @@ INSTALL_PACKAGES=(\
gpgme-devel
grubby
hostname
+ httpd-tools
iproute
iptables
jq
@@ -168,5 +169,9 @@ fi
echo "Installing runtime tooling"
# Save some runtime by having these already available
cd $GOSRC
+# Required since initially go was not installed
+source $GOSRC/$SCRIPT_BASE/lib.sh
+echo "Go environment has been setup:"
+go env
$SUDO make install.tools
$SUDO $GOSRC/hack/install_catatonit.sh
diff --git a/contrib/cirrus/packer/libpod_images.yml b/contrib/cirrus/packer/libpod_images.yml
index 754626a2e..38f5a8250 100644
--- a/contrib/cirrus/packer/libpod_images.yml
+++ b/contrib/cirrus/packer/libpod_images.yml
@@ -3,6 +3,7 @@
# All of these are required
variables:
BUILT_IMAGE_SUFFIX: '{{env `BUILT_IMAGE_SUFFIX`}}'
+ GOPATH: '{{env `GOPATH`}}'
GOSRC: '{{env `GOSRC`}}'
PACKER_BASE: '{{env `PACKER_BASE`}}'
SCRIPT_BASE: '{{env `SCRIPT_BASE`}}'
@@ -62,15 +63,22 @@ builders:
# The brains of the operation, making actual modifications to the base-image.
provisioners:
+ - type: 'shell'
+ inline:
+ - 'set -ex'
+ # The 'file' provisioner item (below) will create the final component
+ - 'mkdir -vp $(dirname {{user `GOSRC`}})'
+
- type: 'file'
source: '{{user `GOSRC`}}'
- destination: '/tmp/libpod'
+ destination: '{{user `GOSRC`}}'
- type: 'shell'
script: '{{user `GOSRC`}}/{{user `PACKER_BASE`}}/{{split build_name "-" 0}}_setup.sh'
environment_vars:
- 'PACKER_BUILDER_NAME={{build_name}}'
- - 'GOSRC=/tmp/libpod'
+ - 'GOPATH={{user `GOPATH`}}'
+ - 'GOSRC={{user `GOSRC`}}'
- 'PACKER_BASE={{user `PACKER_BASE`}}'
- 'SCRIPT_BASE={{user `SCRIPT_BASE`}}'
diff --git a/contrib/cirrus/packer/ubuntu_packaging.sh b/contrib/cirrus/packer/ubuntu_packaging.sh
index 09f9aab9f..d11c612c5 100644
--- a/contrib/cirrus/packer/ubuntu_packaging.sh
+++ b/contrib/cirrus/packer/ubuntu_packaging.sh
@@ -36,6 +36,7 @@ ooe.sh curl -L -o /tmp/Release.key "https://download.opensuse.org/repositories/d
ooe.sh $SUDO apt-key add - < /tmp/Release.key
INSTALL_PACKAGES=(\
+ apache2-utils
apparmor
aufs-tools
autoconf
@@ -153,7 +154,12 @@ if [[ ${#DOWNLOAD_PACKAGES[@]} -gt 0 ]]; then
fi
echo "Installing runtime tooling"
+# Save some runtime by having these already available
cd $GOSRC
+# Required since initially go was not installed
+source $GOSRC/$SCRIPT_BASE/lib.sh
+echo "Go environment has been setup:"
+go env
$SUDO hack/install_catatonit.sh
$SUDO make install.libseccomp.sudo
$SUDO make install.tools
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index ea2c7d8e0..fbdae83fa 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -41,7 +41,6 @@ case "${OS_RELEASE_ID}" in
ubuntu)
apt-get update
apt-get install -y containers-common
- sed -ie 's/^\(# \)\?apparmor_profile =.*/apparmor_profile = ""/' /etc/containers/containers.conf
if [[ "$OS_RELEASE_VER" == "19" ]]; then
apt-get purge -y --auto-remove golang*
apt-get install -y golang-1.13
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 03f23aec0..b4456225e 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -839,6 +839,10 @@ standard input.
Set timezone in container. This flag takes area-based timezones, GMT time, as well as `local`, which sets the timezone in the container to match the host machine. See `/usr/share/zoneinfo/` for valid timezones.
+**--umask**=*umask*
+
+Set the umask inside the container. Defaults to `0022`.
+
**--uidmap**=*container_uid:host_uid:amount*
UID map for the user namespace. Using this flag will run the container with user namespace enabled. It conflicts with the `--userns` and `--subuidname` flags.
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 88f457bdf..303d025b0 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -880,6 +880,10 @@ standard input.
Set timezone in container. This flag takes area-based timezones, GMT time, as well as `local`, which sets the timezone in the container to match the host machine. See `/usr/share/zoneinfo/` for valid timezones.
+**--umask**=*umask*
+
+Set the umask inside the container. Defaults to `0022`.
+
**--uidmap**=*container_uid*:*host_uid*:*amount*
Run the container in a new user namespace using the supplied mapping. This option conflicts
diff --git a/go.mod b/go.mod
index bf9718dea..e165b92f4 100644
--- a/go.mod
+++ b/go.mod
@@ -11,11 +11,11 @@ require (
github.com/containernetworking/cni v0.7.2-0.20200304161608-4fae32b84921
github.com/containernetworking/plugins v0.8.6
github.com/containers/buildah v1.15.1-0.20200708111410-d2ea9429455d
- github.com/containers/common v0.16.0
+ github.com/containers/common v0.17.0
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.1
+ github.com/containers/storage v1.21.2
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
@@ -41,7 +41,7 @@ require (
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
- github.com/opencontainers/runtime-tools v0.9.0
+ github.com/opencontainers/runtime-tools v0.9.1-0.20200714183735-07406c5828aa
github.com/opencontainers/selinux v1.6.0
github.com/opentracing/opentracing-go v1.2.0
github.com/pkg/errors v0.9.1
diff --git a/go.sum b/go.sum
index 7f95292ac..ec04d7073 100644
--- a/go.sum
+++ b/go.sum
@@ -73,8 +73,8 @@ github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHV
github.com/containers/buildah v1.15.1-0.20200708111410-d2ea9429455d h1:HgJJn1UBFjM464NpEmgLwVje5vSF/fBYAdLLoww9HgU=
github.com/containers/buildah v1.15.1-0.20200708111410-d2ea9429455d/go.mod h1:HUAiD1mCGPFPcIuk5zls1LElLhXo7Q3hWDwheojjyAs=
github.com/containers/common v0.15.2/go.mod h1:rhpXuGLTEKsk/xX/x0iKGHjRadMHpBd2ZiNDugwXPEM=
-github.com/containers/common v0.16.0 h1:zAxDJ2tA2wBEjXwV/+ddC8s1f3MfqulH3waSjKxlX3o=
-github.com/containers/common v0.16.0/go.mod h1:siKqOA03Bhh7Ss2m7fCsbVvbjwaNqrI+gZtC9FUp+DI=
+github.com/containers/common v0.17.0 h1:3wkcSLw92UYPEhPSHeG1szyIe1qFgi9Jtj18l/tTii0=
+github.com/containers/common v0.17.0/go.mod h1:bG22Wvr0iyWJ8UvIkL5dA5OEZFDqAJx1MejmWZb51HE=
github.com/containers/conmon v2.0.19+incompatible h1:1bDVRvHy2MUNTUT/SW6LlHsJHQBTSwXvnKNdcB/a1vQ=
github.com/containers/conmon v2.0.19+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.5.1 h1:h1FCOXH6Ux9/p/E4rndsQOC4yAdRU0msRTfLVeQ7FDQ=
@@ -88,6 +88,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.1 h1:FGA2c7+0Bn8ndrlrj+HHmKeVjFD3yVhvYa0gijsrg1M=
github.com/containers/storage v1.21.1/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw=
+github.com/containers/storage v1.21.2 h1:bf9IqA+g6ClBviqVG5lVCp5tTH9lvWwjYws7mVYSti0=
+github.com/containers/storage v1.21.2/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=
@@ -342,6 +344,8 @@ github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.m
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.0 h1:FYgwVsKRI/H9hU32MJ/4MLOzXWodKK5zsQavY8NPMkU=
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
+github.com/opencontainers/runtime-tools v0.9.1-0.20200714183735-07406c5828aa h1:iyj+fFHVBn0xOalz9UChYzSU1K0HJ+d75b4YqShBRhI=
+github.com/opencontainers/runtime-tools v0.9.1-0.20200714183735-07406c5828aa/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
diff --git a/libpod/container.go b/libpod/container.go
index fda018640..8a69df685 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -437,6 +437,9 @@ type ContainerConfig struct {
// Timezone is the timezone inside the container.
// Local means it has the same timezone as the host machine
Timezone string `json:"timezone,omitempty"`
+
+ // Umask is the umask inside the container.
+ Umask string `json:"umask,omitempty"`
}
// ContainerNamedVolume is a named volume that will be mounted into the
@@ -1276,5 +1279,8 @@ func (c *Container) AutoRemove() bool {
func (c *Container) Timezone() string {
return c.config.Timezone
+}
+func (c *Container) Umask() string {
+ return c.config.Umask
}
diff --git a/libpod/container_exec.go b/libpod/container_exec.go
index bd04ee9b9..a16aea06d 100644
--- a/libpod/container_exec.go
+++ b/libpod/container_exec.go
@@ -729,10 +729,6 @@ func (c *Container) Exec(config *ExecConfig, streams *define.AttachStreams, resi
return -1, err
}
- if exitCode != 0 {
- return exitCode, errors.Wrapf(define.ErrOCIRuntime, "exec session exited with non-zero exit code %d", exitCode)
- }
-
return exitCode, nil
}
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 680776dba..a0d223c8c 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -325,6 +325,14 @@ func (c *Container) generateInspectContainerConfig(spec *spec.Spec) *define.Insp
ctrConfig.Timezone = c.config.Timezone
+ // Pad Umask to 4 characters
+ if len(c.config.Umask) < 4 {
+ pad := strings.Repeat("0", 4-len(c.config.Umask))
+ ctrConfig.Umask = pad + c.config.Umask
+ } else {
+ ctrConfig.Umask = c.config.Umask
+ }
+
return ctrConfig
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 1c21f2ff9..09bf33728 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -250,7 +250,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
}
// Apply AppArmor checks and load the default profile if needed.
- if !c.config.Privileged {
+ if len(c.config.Spec.Process.ApparmorProfile) > 0 {
updatedProfile, err := apparmor.CheckProfileAndLoadDefault(c.config.Spec.Process.ApparmorProfile)
if err != nil {
return nil, err
@@ -355,6 +355,14 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
g.SetProcessGID(uint32(execUser.Gid))
}
+ if c.config.Umask != "" {
+ decVal, err := strconv.ParseUint(c.config.Umask, 8, 32)
+ if err != nil {
+ return nil, errors.Wrapf(err, "Invalid Umask Value")
+ }
+ g.SetProcessUmask(uint32(decVal))
+ }
+
// Add addition groups if c.config.GroupAdd is not empty
if len(c.config.Groups) > 0 {
gids, err := lookup.GetContainerGroups(c.config.Groups, c.state.Mountpoint, overrides)
diff --git a/libpod/define/config.go b/libpod/define/config.go
index 64b24d9e2..6c426f2ec 100644
--- a/libpod/define/config.go
+++ b/libpod/define/config.go
@@ -20,6 +20,8 @@ var (
NameRegex = regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9_.-]*$")
// RegexError is thrown in presence of an invalid container/pod name.
RegexError = errors.Wrapf(ErrInvalidArg, "names must match [a-zA-Z0-9][a-zA-Z0-9_.-]*")
+ // UmaskRegex is a regular expression to validate Umask.
+ UmaskRegex = regexp.MustCompile(`^[0-7]{1,4}$`)
)
const (
diff --git a/libpod/define/container_inspect.go b/libpod/define/container_inspect.go
index fbd9da3e7..a08cb3de6 100644
--- a/libpod/define/container_inspect.go
+++ b/libpod/define/container_inspect.go
@@ -61,6 +61,8 @@ type InspectContainerConfig struct {
// systemd mode, the container configuration is customized to optimize
// running systemd in the container.
SystemdMode bool `json:"SystemdMode,omitempty"`
+ // Umask is the umask inside the container.
+ Umask string `json:"Umask,omitempty"`
}
// InspectRestartPolicy holds information about the container's restart policy.
diff --git a/libpod/healthcheck.go b/libpod/healthcheck.go
index b04742974..4818f8dc4 100644
--- a/libpod/healthcheck.go
+++ b/libpod/healthcheck.go
@@ -92,7 +92,7 @@ func (c *Container) runHealthCheck() (define.HealthCheckStatus, error) {
hcResult := define.HealthCheckSuccess
config := new(ExecConfig)
config.Command = newCommand
- _, hcErr := c.Exec(config, streams, nil)
+ exitCode, hcErr := c.Exec(config, streams, nil)
if hcErr != nil {
errCause := errors.Cause(hcErr)
hcResult = define.HealthCheckFailure
@@ -104,6 +104,9 @@ func (c *Container) runHealthCheck() (define.HealthCheckStatus, error) {
} else {
returnCode = 125
}
+ } else if exitCode != 0 {
+ hcResult = define.HealthCheckFailure
+ returnCode = 1
}
timeEnd := time.Now()
if c.HealthCheckConfig().StartPeriod > 0 {
diff --git a/libpod/options.go b/libpod/options.go
index 40cf452db..41b0d7212 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -1607,6 +1607,20 @@ func WithTimezone(path string) CtrCreateOption {
}
}
+// WithUmask sets the umask in the container
+func WithUmask(umask string) CtrCreateOption {
+ return func(ctr *Container) error {
+ if ctr.valid {
+ return define.ErrCtrFinalized
+ }
+ if !define.UmaskRegex.MatchString(umask) {
+ return errors.Wrapf(define.ErrInvalidArg, "Invalid umask string %s", umask)
+ }
+ ctr.config.Umask = umask
+ return nil
+ }
+}
+
// Pod Creation Options
// WithPodName sets the name of the pod.
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index f82da2c95..52a62a25d 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -340,9 +340,7 @@ func getPodPorts(containers []v1.Container) []ocicni.PortMapping {
HostPort: p.HostPort,
ContainerPort: p.ContainerPort,
Protocol: strings.ToLower(string(p.Protocol)),
- }
- if p.HostIP != "" {
- logrus.Debug("HostIP on port bindings is not supported")
+ HostIP: p.HostIP,
}
// only hostPort is utilized in podman context, all container ports
// are accessible inside the shared network namespace
@@ -453,11 +451,16 @@ func kubeContainerToCreateConfig(ctx context.Context, containerYAML v1.Container
containerConfig.Command = []string{}
if imageData != nil && imageData.Config != nil {
- containerConfig.Command = append(containerConfig.Command, imageData.Config.Entrypoint...)
+ containerConfig.Command = imageData.Config.Entrypoint
}
if len(containerYAML.Command) != 0 {
- containerConfig.Command = append(containerConfig.Command, containerYAML.Command...)
- } else if imageData != nil && imageData.Config != nil {
+ containerConfig.Command = containerYAML.Command
+ }
+ // doc https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes
+ if len(containerYAML.Args) != 0 {
+ containerConfig.Command = append(containerConfig.Command, containerYAML.Args...)
+ } else if len(containerYAML.Command) == 0 {
+ // Add the Cmd from the image config only if containerYAML.Command and containerYAML.Args are empty
containerConfig.Command = append(containerConfig.Command, imageData.Config.Cmd...)
}
if imageData != nil && len(containerConfig.Command) == 0 {
diff --git a/pkg/specgen/container_validate.go b/pkg/specgen/container_validate.go
index 622313a04..eddc4ad5d 100644
--- a/pkg/specgen/container_validate.go
+++ b/pkg/specgen/container_validate.go
@@ -81,10 +81,6 @@ func (s *SpecGenerator) Validate() error {
if len(s.CapAdd) > 0 && s.Privileged {
return exclusiveOptions("CapAdd", "privileged")
}
- // apparmor and privileged are exclusive
- if len(s.ApparmorProfile) > 0 && s.Privileged {
- return exclusiveOptions("AppArmorProfile", "privileged")
- }
// userns and idmappings conflict
if s.UserNS.IsPrivate() && s.IDMappings == nil {
return errors.Wrap(ErrInvalidSpecConfig, "IDMappings are required when not creating a User namespace")
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 6dbc45c16..934d5fbac 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -145,6 +145,9 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
if s.Timezone != "" {
options = append(options, libpod.WithTimezone(s.Timezone))
}
+ if s.Umask != "" {
+ options = append(options, libpod.WithUmask(s.Umask))
+ }
useSystemd := false
switch s.Systemd {
diff --git a/pkg/specgen/generate/oci.go b/pkg/specgen/generate/oci.go
index 4953735b1..f279aac1c 100644
--- a/pkg/specgen/generate/oci.go
+++ b/pkg/specgen/generate/oci.go
@@ -285,13 +285,6 @@ func SpecGenToOCI(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Runt
}
}
- // SECURITY OPTS
- g.SetProcessNoNewPrivileges(s.NoNewPrivileges)
-
- if !s.Privileged {
- g.SetProcessApparmorProfile(s.ApparmorProfile)
- }
-
BlockAccessToKernelFilesystems(s.Privileged, s.PidNS.IsHost(), &g)
for name, val := range s.Env {
diff --git a/pkg/specgen/generate/security.go b/pkg/specgen/generate/security.go
index 70493cd5f..fcd1622f9 100644
--- a/pkg/specgen/generate/security.go
+++ b/pkg/specgen/generate/security.go
@@ -3,6 +3,7 @@ package generate
import (
"strings"
+ "github.com/containers/common/pkg/apparmor"
"github.com/containers/common/pkg/capabilities"
"github.com/containers/common/pkg/config"
"github.com/containers/libpod/v2/libpod"
@@ -56,6 +57,28 @@ func setLabelOpts(s *specgen.SpecGenerator, runtime *libpod.Runtime, pidConfig s
return nil
}
+func setupApparmor(s *specgen.SpecGenerator, rtc *config.Config, g *generate.Generator) error {
+ hasProfile := len(s.ApparmorProfile) > 0
+ if !apparmor.IsEnabled() {
+ if hasProfile {
+ return errors.Errorf("Apparmor profile %q specified, but Apparmor is not enabled on this system", s.ApparmorProfile)
+ }
+ return nil
+ }
+ // If privileged and caller did not specify apparmor profiles return
+ if s.Privileged && !hasProfile {
+ return nil
+ }
+ if !hasProfile {
+ s.ApparmorProfile = rtc.Containers.ApparmorProfile
+ }
+ if len(s.ApparmorProfile) > 0 {
+ g.SetProcessApparmorProfile(s.ApparmorProfile)
+ }
+
+ return nil
+}
+
func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator, newImage *image.Image, rtc *config.Config) error {
var (
caplist []string
@@ -105,6 +128,13 @@ func securityConfigureGenerator(s *specgen.SpecGenerator, g *generate.Generator,
}
}
}
+
+ g.SetProcessNoNewPrivileges(s.NoNewPrivileges)
+
+ if err := setupApparmor(s, rtc, g); err != nil {
+ return err
+ }
+
configSpec := g.Config
configSpec.Process.Capabilities.Bounding = caplist
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index c6079be33..84a6c36a0 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -287,6 +287,8 @@ type ContainerSecurityConfig struct {
// ReadOnlyFilesystem indicates that everything will be mounted
// as read-only
ReadOnlyFilesystem bool `json:"read_only_filesystem,omittempty"`
+ // Umask is the umask the init process of the container will be run with.
+ Umask string `json:"umask,omitempty"`
}
// ContainerCgroupConfig contains configuration information about a container's
diff --git a/test/e2e/attach_test.go b/test/e2e/attach_test.go
index 9fd1466aa..827b7568d 100644
--- a/test/e2e/attach_test.go
+++ b/test/e2e/attach_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -42,6 +40,7 @@ var _ = Describe("Podman attach", func() {
})
It("podman attach to non-running container", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"create", "--name", "test1", "-d", "-i", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -52,6 +51,7 @@ var _ = Describe("Podman attach", func() {
})
It("podman container attach to non-running container", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"container", "create", "--name", "test1", "-d", "-i", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -87,6 +87,7 @@ var _ = Describe("Podman attach", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(1))
})
It("podman attach to the latest container", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", ALPINE, "/bin/sh", "-c", "while true; do echo test1; sleep 1; done"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go
index 9c8078f16..c72d2243a 100644
--- a/test/e2e/build_test.go
+++ b/test/e2e/build_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -40,6 +38,7 @@ var _ = Describe("Podman build", func() {
// Let's first do the most simple build possible to make sure stuff is
// happy and then clean up after ourselves to make sure that works too.
It("podman build and remove basic alpine", func() {
+ SkipIfRemote()
session := podmanTest.PodmanNoCache([]string{"build", "build/basicalpine"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -69,6 +68,7 @@ var _ = Describe("Podman build", func() {
// Check that builds with different values for the squash options
// create the appropriate number of layers, then clean up after.
It("podman build basic alpine with squash", func() {
+ SkipIfRemote()
session := podmanTest.PodmanNoCache([]string{"build", "-f", "build/squash/Dockerfile.squash-a", "-t", "test-squash-a:latest", "build/squash"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -154,6 +154,7 @@ var _ = Describe("Podman build", func() {
})
It("podman build basic alpine and print id to external file", func() {
+ SkipIfRemote()
// Switch to temp dir and restore it afterwards
cwd, err := os.Getwd()
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index aa0e9635a..4fc5b3da9 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -14,6 +14,7 @@ import (
"time"
"github.com/containers/libpod/v2/libpod/define"
+ "github.com/containers/libpod/v2/pkg/cgroups"
"github.com/containers/libpod/v2/pkg/inspect"
"github.com/containers/libpod/v2/pkg/rootless"
. "github.com/containers/libpod/v2/test/utils"
@@ -151,6 +152,8 @@ var _ = SynchronizedBeforeSuite(func() []byte {
return []byte(path)
}, func(data []byte) {
+ cwd, _ := os.Getwd()
+ INTEGRATION_ROOT = filepath.Join(cwd, "../../")
LockTmpDir = string(data)
})
@@ -599,3 +602,27 @@ func SkipIfNotFedora() {
func isRootless() bool {
return os.Geteuid() != 0
}
+
+func SkipIfCgroupV1() {
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if !cgroupsv2 {
+ Skip("Skip on systems with cgroup V1 systems")
+ }
+}
+
+func SkipIfCgroupV2() {
+ cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
+ Expect(err).To(BeNil())
+
+ if cgroupsv2 {
+ Skip("Skip on systems with cgroup V2 systems")
+ }
+}
+
+// PodmanAsUser is the exec call to podman on the filesystem with the specified uid/gid and environment
+func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, cwd string, env []string) *PodmanSessionIntegration {
+ podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env, false, false, nil)
+ return &PodmanSessionIntegration{podmanSession}
+}
diff --git a/test/e2e/config/containers.conf b/test/e2e/config/containers.conf
index 0a07676c4..5f852468d 100644
--- a/test/e2e/config/containers.conf
+++ b/test/e2e/config/containers.conf
@@ -50,3 +50,5 @@ dns_servers=[ "1.2.3.4", ]
dns_options=[ "debug", ]
tz = "Pacific/Honolulu"
+
+umask = "0002"
diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go
index 23d8dd197..aebbca855 100644
--- a/test/e2e/containers_conf_test.go
+++ b/test/e2e/containers_conf_test.go
@@ -218,6 +218,17 @@ var _ = Describe("Podman run", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("HST"))
+ })
+ It("podman run containers.conf umask", func() {
+ //containers.conf umask set to 0002
+ if !strings.Contains(podmanTest.OCIRuntime, "crun") {
+ Skip("Test only works on crun")
+ }
+ session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("0002"))
})
+
})
diff --git a/test/e2e/create_staticip_test.go b/test/e2e/create_staticip_test.go
index a1a08045a..a6f4f830b 100644
--- a/test/e2e/create_staticip_test.go
+++ b/test/e2e/create_staticip_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/create_test.go b/test/e2e/create_test.go
index f21f17d39..09b4f5911 100644
--- a/test/e2e/create_test.go
+++ b/test/e2e/create_test.go
@@ -5,6 +5,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "strings"
. "github.com/containers/libpod/v2/test/utils"
. "github.com/onsi/ginkgo"
@@ -499,4 +500,46 @@ var _ = Describe("Podman create", func() {
Expect(data[0].Config.Timezone).To(Equal("local"))
})
+ It("podman create --umask", func() {
+ if !strings.Contains(podmanTest.OCIRuntime, "crun") {
+ Skip("Test only works on crun")
+ }
+
+ session := podmanTest.Podman([]string{"create", "--name", "default", ALPINE})
+ session.WaitWithDefaultTimeout()
+ inspect := podmanTest.Podman([]string{"inspect", "default"})
+ inspect.WaitWithDefaultTimeout()
+ data := inspect.InspectContainerToJSON()
+ Expect(len(data)).To(Equal(1))
+ Expect(data[0].Config.Umask).To(Equal("0022"))
+
+ session = podmanTest.Podman([]string{"create", "--umask", "0002", "--name", "umask", ALPINE})
+ session.WaitWithDefaultTimeout()
+ inspect = podmanTest.Podman([]string{"inspect", "umask"})
+ inspect.WaitWithDefaultTimeout()
+ data = inspect.InspectContainerToJSON()
+ Expect(len(data)).To(Equal(1))
+ Expect(data[0].Config.Umask).To(Equal("0002"))
+
+ session = podmanTest.Podman([]string{"create", "--umask", "0077", "--name", "fedora", fedoraMinimal})
+ session.WaitWithDefaultTimeout()
+ inspect = podmanTest.Podman([]string{"inspect", "fedora"})
+ inspect.WaitWithDefaultTimeout()
+ data = inspect.InspectContainerToJSON()
+ Expect(len(data)).To(Equal(1))
+ Expect(data[0].Config.Umask).To(Equal("0077"))
+
+ session = podmanTest.Podman([]string{"create", "--umask", "22", "--name", "umask-short", ALPINE})
+ session.WaitWithDefaultTimeout()
+ inspect = podmanTest.Podman([]string{"inspect", "umask-short"})
+ inspect.WaitWithDefaultTimeout()
+ data = inspect.InspectContainerToJSON()
+ Expect(len(data)).To(Equal(1))
+ Expect(data[0].Config.Umask).To(Equal("0022"))
+
+ session = podmanTest.Podman([]string{"create", "--umask", "9999", "--name", "bad", ALPINE})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask"))
+ })
})
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 577a7562b..7a3bfdf61 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go
index 13f4e1aef..263139064 100644
--- a/test/e2e/libpod_suite_remote_test.go
+++ b/test/e2e/libpod_suite_remote_test.go
@@ -214,5 +214,3 @@ func (p *PodmanTestIntegration) DelayForService() error {
func populateCache(podman *PodmanTestIntegration) {}
func removeCache() {}
-func SkipIfCgroupV1() {}
-func SkipIfCgroupV2() {}
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
index 29ad01363..bfd898108 100644
--- a/test/e2e/libpod_suite_test.go
+++ b/test/e2e/libpod_suite_test.go
@@ -9,32 +9,12 @@ import (
"path/filepath"
"strings"
- "github.com/containers/libpod/v2/pkg/cgroups"
. "github.com/onsi/ginkgo"
- . "github.com/onsi/gomega"
)
func SkipIfRemote() {
}
-func SkipIfCgroupV1() {
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
- if !cgroupsv2 {
- Skip("Skip on systems with cgroup V1 systems")
- }
-}
-
-func SkipIfCgroupV2() {
- cgroupsv2, err := cgroups.IsCgroup2UnifiedMode()
- Expect(err).To(BeNil())
-
- if cgroupsv2 {
- Skip("Skip on systems with cgroup V2 systems")
- }
-}
-
func SkipIfRootless() {
if os.Geteuid() != 0 {
Skip("This function is not enabled for rootless podman")
@@ -66,12 +46,6 @@ func (p *PodmanTestIntegration) PodmanNoEvents(args []string) *PodmanSessionInte
return &PodmanSessionIntegration{podmanSession}
}
-// PodmanAsUser is the exec call to podman on the filesystem with the specified uid/gid and environment
-func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, cwd string, env []string) *PodmanSessionIntegration {
- podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env, false, false, nil)
- return &PodmanSessionIntegration{podmanSession}
-}
-
func (p *PodmanTestIntegration) setDefaultRegistriesConfigEnv() {
defaultFile := filepath.Join(INTEGRATION_ROOT, "test/registries.conf")
os.Setenv("REGISTRIES_CONFIG_PATH", defaultFile)
diff --git a/test/e2e/load_test.go b/test/e2e/load_test.go
index df2613334..879291c36 100644
--- a/test/e2e/load_test.go
+++ b/test/e2e/load_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -125,6 +123,7 @@ var _ = Describe("Podman load", func() {
})
It("podman load directory", func() {
+ SkipIfRemote()
outdir := filepath.Join(podmanTest.TempDir, "alpine")
save := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-dir", "-o", outdir, ALPINE})
@@ -228,6 +227,7 @@ var _ = Describe("Podman load", func() {
})
It("podman load localhost registry from dir", func() {
+ SkipIfRemote()
outfile := filepath.Join(podmanTest.TempDir, "load")
setup := podmanTest.PodmanNoCache([]string{"tag", BB, "hello:world"})
diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go
index 3bdce970b..66f764925 100644
--- a/test/e2e/login_logout_test.go
+++ b/test/e2e/login_logout_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/namespace_test.go b/test/e2e/namespace_test.go
index 70472f384..5756a8fa2 100644
--- a/test/e2e/namespace_test.go
+++ b/test/e2e/namespace_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -35,6 +33,7 @@ var _ = Describe("Podman namespaces", func() {
})
It("podman namespace test", func() {
+ SkipIfRemote()
podman1 := podmanTest.Podman([]string{"--namespace", "test1", "run", "-d", ALPINE, "echo", "hello"})
podman1.WaitWithDefaultTimeout()
Expect(podman1.ExitCode()).To(Equal(0))
diff --git a/test/e2e/network_create_test.go b/test/e2e/network_create_test.go
index 83b0ce32c..24f711ae7 100644
--- a/test/e2e/network_create_test.go
+++ b/test/e2e/network_create_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -140,6 +138,7 @@ var _ = Describe("Podman network create", func() {
})
It("podman network create with name and subnet", func() {
+ SkipIfRemote()
var (
results []network.NcList
)
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 23604f47d..052db3842 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -8,6 +6,7 @@ import (
"io/ioutil"
"os"
"path/filepath"
+ "strings"
"text/template"
. "github.com/containers/libpod/v2/test/utils"
@@ -50,6 +49,10 @@ spec:
{{ range .Cmd }}
- {{.}}
{{ end }}
+ args:
+ {{ range .Arg }}
+ - {{.}}
+ {{ end }}
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
@@ -82,6 +85,11 @@ spec:
{{ end }}
privileged: false
readOnlyRootFilesystem: false
+ ports:
+ - containerPort: {{ .Port }}
+ hostIP: {{ .HostIP }}
+ hostPort: {{ .Port }}
+ protocol: TCP
workingDir: /
{{ end }}
{{ end }}
@@ -129,6 +137,10 @@ spec:
{{ range .Cmd }}
- {{.}}
{{ end }}
+ args:
+ {{ range .Arg }}
+ - {{.}}
+ {{ end }}
env:
- name: PATH
value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
@@ -171,6 +183,7 @@ spec:
var (
defaultCtrName = "testCtr"
defaultCtrCmd = []string{"top"}
+ defaultCtrArg = []string{"-d", "1.5"}
defaultCtrImage = ALPINE
defaultPodName = "testPod"
defaultDeploymentName = "testDeployment"
@@ -322,17 +335,20 @@ type Ctr struct {
Name string
Image string
Cmd []string
+ Arg []string
SecurityContext bool
Caps bool
CapAdd []string
CapDrop []string
PullPolicy string
+ HostIP string
+ Port string
}
// getCtr takes a list of ctrOptions and returns a Ctr with sane defaults
// and the configured options
func getCtr(options ...ctrOption) *Ctr {
- c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, true, false, nil, nil, ""}
+ c := Ctr{defaultCtrName, defaultCtrImage, defaultCtrCmd, defaultCtrArg, true, false, nil, nil, "", "", ""}
for _, option := range options {
option(&c)
}
@@ -347,6 +363,12 @@ func withCmd(cmd []string) ctrOption {
}
}
+func withArg(arg []string) ctrOption {
+ return func(c *Ctr) {
+ c.Arg = arg
+ }
+}
+
func withImage(img string) ctrOption {
return func(c *Ctr) {
c.Image = img
@@ -379,6 +401,13 @@ func withPullPolicy(policy string) ctrOption {
}
}
+func withHostIP(ip string, port string) ctrOption {
+ return func(c *Ctr) {
+ c.HostIP = ip
+ c.Port = port
+ }
+}
+
func getCtrNameInPod(pod *Pod) string {
return fmt.Sprintf("%s-%s", pod.Name, defaultCtrName)
}
@@ -430,6 +459,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube test correct command", func() {
+ SkipIfRemote()
pod := getPod()
err := generatePodKubeYaml(pod, kubeYaml)
Expect(err).To(BeNil())
@@ -438,14 +468,52 @@ var _ = Describe("Podman generate kube", func() {
kube.WaitWithDefaultTimeout()
Expect(kube.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod)})
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ // Use the defined command to override the image's command
+ correctCmd := "[" + strings.Join(defaultCtrCmd, " ") + " " + strings.Join(defaultCtrArg, " ")
+ Expect(inspect.OutputToString()).To(ContainSubstring(correctCmd))
+ })
+
+ It("podman play kube test correct command with only set command in yaml file", func() {
+ SkipIfRemote()
+ pod := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg(nil))))
+ err := generatePodKubeYaml(pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0]))
+ // Use the defined command to override the image's command, and don't set the args
+ // so the full command in result should not contains the image's command
+ Expect(inspect.OutputToString()).To(ContainSubstring(`[echo hello]`))
+ })
+
+ It("podman play kube test correct command with only set args in yaml file", func() {
+ pod := getPod(withCtr(getCtr(withImage(redis), withCmd(nil), withArg([]string{"echo", "hello"}))))
+ err := generatePodKubeYaml(pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(pod), "--format", "'{{ .Config.Cmd }}'"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ // this image's ENTRYPOINT is called `docker-entrypoint.sh`
+ // so result should be `docker-entrypoint.sh + withArg(...)`
+ Expect(inspect.OutputToString()).To(ContainSubstring(`[docker-entrypoint.sh echo hello]`))
})
It("podman play kube test correct output", func() {
- p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}))))
+ SkipIfRemote()
+ p := getPod(withCtr(getCtr(withCmd([]string{"echo", "hello"}), withArg([]string{"world"}))))
err := generatePodKubeYaml(p, kubeYaml)
Expect(err).To(BeNil())
@@ -457,12 +525,12 @@ var _ = Describe("Podman generate kube", func() {
logs := podmanTest.Podman([]string{"logs", getCtrNameInPod(p)})
logs.WaitWithDefaultTimeout()
Expect(logs.ExitCode()).To(Equal(0))
- Expect(logs.OutputToString()).To(ContainSubstring("hello"))
+ Expect(logs.OutputToString()).To(ContainSubstring("hello world"))
inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(p), "--format", "'{{ .Config.Cmd }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
- Expect(inspect.OutputToString()).To(ContainSubstring("hello"))
+ Expect(inspect.OutputToString()).To(ContainSubstring(`[echo hello world]`))
})
It("podman play kube test hostname", func() {
@@ -498,7 +566,7 @@ var _ = Describe("Podman generate kube", func() {
It("podman play kube cap add", func() {
capAdd := "CAP_SYS_ADMIN"
- ctr := getCtr(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"}))
+ ctr := getCtr(withCapAdd([]string{capAdd}), withCmd([]string{"cat", "/proc/self/status"}), withArg(nil))
pod := getPod(withCtr(ctr))
err := generatePodKubeYaml(pod, kubeYaml)
@@ -548,6 +616,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube seccomp container level", func() {
+ SkipIfRemote()
// expect play kube is expected to set a seccomp label if it's applied as an annotation
jsonFile, err := podmanTest.CreateSeccompJson(seccompPwdEPERM)
if err != nil {
@@ -556,7 +625,7 @@ var _ = Describe("Podman generate kube", func() {
}
ctrAnnotation := "container.seccomp.security.alpha.kubernetes.io/" + defaultCtrName
- ctr := getCtr(withCmd([]string{"pwd"}))
+ ctr := getCtr(withCmd([]string{"pwd"}), withArg(nil))
pod := getPod(withCtr(ctr), withAnnotation(ctrAnnotation, "localhost/"+filepath.Base(jsonFile)))
err = generatePodKubeYaml(pod, kubeYaml)
@@ -574,6 +643,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman play kube seccomp pod level", func() {
+ SkipIfRemote()
// expect play kube is expected to set a seccomp label if it's applied as an annotation
jsonFile, err := podmanTest.CreateSeccompJson(seccompPwdEPERM)
if err != nil {
@@ -582,7 +652,7 @@ var _ = Describe("Podman generate kube", func() {
}
defer os.Remove(jsonFile)
- ctr := getCtr(withCmd([]string{"pwd"}))
+ ctr := getCtr(withCmd([]string{"pwd"}), withArg(nil))
pod := getPod(withCtr(ctr), withAnnotation("seccomp.security.alpha.kubernetes.io/pod", "localhost/"+filepath.Base(jsonFile)))
err = generatePodKubeYaml(pod, kubeYaml)
@@ -725,6 +795,7 @@ spec:
// Deployment related tests
It("podman play kube deployment 1 replica test correct command", func() {
+ SkipIfRemote()
deployment := getDeployment()
err := generateDeploymentKubeYaml(deployment, kubeYaml)
Expect(err).To(BeNil())
@@ -734,13 +805,16 @@ spec:
Expect(kube.ExitCode()).To(Equal(0))
podNames := getPodNamesInDeployment(deployment)
- inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[0])})
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[0]), "--format", "'{{ .Config.Cmd }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0]))
+ // yaml's command shuold override the image's Entrypoint
+ correctCmd := "[" + strings.Join(defaultCtrCmd, " ") + " " + strings.Join(defaultCtrArg, " ")
+ Expect(inspect.OutputToString()).To(ContainSubstring(correctCmd))
})
It("podman play kube deployment more than 1 replica test correct command", func() {
+ SkipIfRemote()
var i, numReplicas int32
numReplicas = 5
deployment := getDeployment(withReplicas(numReplicas))
@@ -752,11 +826,31 @@ spec:
Expect(kube.ExitCode()).To(Equal(0))
podNames := getPodNamesInDeployment(deployment)
+ correctCmd := "[" + strings.Join(defaultCtrCmd, " ") + " " + strings.Join(defaultCtrArg, " ")
for i = 0; i < numReplicas; i++ {
- inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i])})
+ inspect := podmanTest.Podman([]string{"inspect", getCtrNameInPod(&podNames[i]), "--format", "'{{ .Config.Cmd }}'"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
- Expect(inspect.OutputToString()).To(ContainSubstring(defaultCtrCmd[0]))
+ Expect(inspect.OutputToString()).To(ContainSubstring(correctCmd))
}
})
+
+ It("podman play kube test with network portbindings", func() {
+ ip := "127.0.0.100"
+ port := "5000"
+ ctr := getCtr(withHostIP(ip, port), withImage(BB))
+
+ pod := getPod(withCtr(ctr))
+ err := generatePodKubeYaml(pod, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube.ExitCode()).To(Equal(0))
+
+ inspect := podmanTest.Podman([]string{"port", getCtrNameInPod(pod)})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect.ExitCode()).To(Equal(0))
+ Expect(inspect.OutputToString()).To(Equal("5000/tcp -> 127.0.0.100:5000"))
+ })
})
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index 49105310b..a5fa21187 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -227,6 +225,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container can override pod pid NS", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"pod", "create", "--share", "pid"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -258,6 +257,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container can override pod not sharing pid", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"pod", "create", "--share", "net"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -283,6 +283,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container can override pod ipc NS", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"pod", "create", "--share", "ipc"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_pod_namespaces.go b/test/e2e/pod_pod_namespaces.go
index fce131e20..7a6223158 100644
--- a/test/e2e/pod_pod_namespaces.go
+++ b/test/e2e/pod_pod_namespaces.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -63,6 +61,7 @@ var _ = Describe("Podman pod create", func() {
})
It("podman pod container dontshare PIDNS", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"pod", "create"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/pod_stats_test.go b/test/e2e/pod_stats_test.go
index 74d1c1838..04068de06 100644
--- a/test/e2e/pod_stats_test.go
+++ b/test/e2e/pod_stats_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/pod_top_test.go b/test/e2e/pod_top_test.go
index f86d23d84..40e8d77d8 100644
--- a/test/e2e/pod_top_test.go
+++ b/test/e2e/pod_top_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -58,6 +56,7 @@ var _ = Describe("Podman top", func() {
})
It("podman pod top on pod", func() {
+ SkipIfRemote()
_, ec, podid := podmanTest.CreatePod("")
Expect(ec).To(Equal(0))
diff --git a/test/e2e/port_test.go b/test/e2e/port_test.go
index 897505588..b247fcaa3 100644
--- a/test/e2e/port_test.go
+++ b/test/e2e/port_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -49,6 +47,7 @@ var _ = Describe("Podman port", func() {
})
It("podman port -l nginx", func() {
+ SkipIfRemote()
session, cid := podmanTest.RunNginxWithHealthCheck("")
Expect(session.ExitCode()).To(Equal(0))
@@ -64,6 +63,7 @@ var _ = Describe("Podman port", func() {
})
It("podman container port -l nginx", func() {
+ SkipIfRemote()
session, cid := podmanTest.RunNginxWithHealthCheck("")
Expect(session.ExitCode()).To(Equal(0))
@@ -79,6 +79,7 @@ var _ = Describe("Podman port", func() {
})
It("podman port -l port nginx", func() {
+ SkipIfRemote()
session, cid := podmanTest.RunNginxWithHealthCheck("")
Expect(session.ExitCode()).To(Equal(0))
@@ -127,18 +128,18 @@ var _ = Describe("Podman port", func() {
lock2 := GetPortLock("5001")
defer lock2.Unlock()
- setup := podmanTest.Podman([]string{"run", "-dt", "-p", "5000:5000", "-p", "5001:5001", ALPINE, "top"})
+ setup := podmanTest.Podman([]string{"run", "--name", "test", "-dt", "-p", "5000:5000", "-p", "5001:5001", ALPINE, "top"})
setup.WaitWithDefaultTimeout()
Expect(setup.ExitCode()).To(BeZero())
// Check that the first port was honored
- result1 := podmanTest.Podman([]string{"port", "-l", "5000"})
+ result1 := podmanTest.Podman([]string{"port", "test", "5000"})
result1.WaitWithDefaultTimeout()
Expect(result1.ExitCode()).To(BeZero())
Expect(result1.LineInOuputStartsWith("0.0.0.0:5000")).To(BeTrue())
// Check that the second port was honored
- result2 := podmanTest.Podman([]string{"port", "-l", "5001"})
+ result2 := podmanTest.Podman([]string{"port", "test", "5001"})
result2.WaitWithDefaultTimeout()
Expect(result2.ExitCode()).To(BeZero())
Expect(result2.LineInOuputStartsWith("0.0.0.0:5001")).To(BeTrue())
diff --git a/test/e2e/pull_test.go b/test/e2e/pull_test.go
index eec2877e8..665cd1b55 100644
--- a/test/e2e/pull_test.go
+++ b/test/e2e/pull_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -237,6 +235,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from docker-archive", func() {
+ SkipIfRemote()
podmanTest.RestoreArtifact(ALPINE)
tarfn := filepath.Join(podmanTest.TempDir, "alp.tar")
session := podmanTest.PodmanNoCache([]string{"save", "-o", tarfn, "alpine"})
@@ -255,6 +254,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from oci-archive", func() {
+ SkipIfRemote()
podmanTest.RestoreArtifact(ALPINE)
tarfn := filepath.Join(podmanTest.TempDir, "oci-alp.tar")
session := podmanTest.PodmanNoCache([]string{"save", "--format", "oci-archive", "-o", tarfn, "alpine"})
@@ -273,6 +273,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from local directory", func() {
+ SkipIfRemote()
podmanTest.RestoreArtifact(ALPINE)
dirpath := filepath.Join(podmanTest.TempDir, "alpine")
os.MkdirAll(dirpath, os.ModePerm)
@@ -297,6 +298,7 @@ var _ = Describe("Podman pull", func() {
})
It("podman pull from local OCI directory", func() {
+ SkipIfRemote()
podmanTest.RestoreArtifact(ALPINE)
dirpath := filepath.Join(podmanTest.TempDir, "alpine")
os.MkdirAll(dirpath, os.ModePerm)
diff --git a/test/e2e/run_apparmor_test.go b/test/e2e/run_apparmor_test.go
new file mode 100644
index 000000000..344309b93
--- /dev/null
+++ b/test/e2e/run_apparmor_test.go
@@ -0,0 +1,158 @@
+// +build !remote
+
+package integration
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+
+ "github.com/containers/common/pkg/apparmor"
+ . "github.com/containers/libpod/v2/test/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+)
+
+func skipIfAppArmorEnabled() {
+ if apparmor.IsEnabled() {
+ Skip("Apparmor is enabled")
+ }
+}
+func skipIfAppArmorDisabled() {
+ if !apparmor.IsEnabled() {
+ Skip("Apparmor is not enabled")
+ }
+}
+
+var _ = Describe("Podman run", func() {
+ var (
+ tempdir string
+ err error
+ podmanTest *PodmanTestIntegration
+ )
+
+ BeforeEach(func() {
+ tempdir, err = CreateTempDirInTempDir()
+ if err != nil {
+ os.Exit(1)
+ }
+ podmanTest = PodmanTestCreate(tempdir)
+ podmanTest.Setup()
+ podmanTest.SeedImages()
+ })
+
+ AfterEach(func() {
+ podmanTest.Cleanup()
+ f := CurrentGinkgoTestDescription()
+ processTestResult(f)
+
+ })
+
+ It("podman run apparmor default", func() {
+ skipIfAppArmorDisabled()
+ session := podmanTest.Podman([]string{"create", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal(apparmor.Profile))
+ })
+
+ It("podman run no apparmor --privileged", func() {
+ skipIfAppArmorDisabled()
+ session := podmanTest.Podman([]string{"create", "--privileged", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal(""))
+ })
+
+ It("podman run no apparmor --security-opt=apparmor.Profile --privileged", func() {
+ skipIfAppArmorDisabled()
+ session := podmanTest.Podman([]string{"create", "--security-opt", fmt.Sprintf("apparmor=%s", apparmor.Profile), "--privileged", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal(apparmor.Profile))
+ })
+
+ It("podman run apparmor aa-test-profile", func() {
+ skipIfAppArmorDisabled()
+ aaProfile := `
+#include <tunables/global>
+profile aa-test-profile flags=(attach_disconnected,mediate_deleted) {
+ #include <abstractions/base>
+ deny mount,
+ deny /sys/[^f]*/** wklx,
+ deny /sys/f[^s]*/** wklx,
+ deny /sys/fs/[^c]*/** wklx,
+ deny /sys/fs/c[^g]*/** wklx,
+ deny /sys/fs/cg[^r]*/** wklx,
+ deny /sys/firmware/efi/efivars/** rwklx,
+ deny /sys/kernel/security/** rwklx,
+}
+`
+ aaFile := filepath.Join(os.TempDir(), "aaFile")
+ Expect(ioutil.WriteFile(aaFile, []byte(aaProfile), 0755)).To(BeNil())
+ parse := SystemExec("apparmor_parser", []string{"-Kr", aaFile})
+ Expect(parse.ExitCode()).To(Equal(0))
+
+ session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=aa-test-profile", "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal("aa-test-profile"))
+ })
+
+ It("podman run apparmor invalid", func() {
+ skipIfAppArmorDisabled()
+ session := podmanTest.Podman([]string{"run", "--security-opt", "apparmor=invalid", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).ToNot(Equal(0))
+ })
+
+ It("podman run apparmor unconfined", func() {
+ skipIfAppArmorDisabled()
+ session := podmanTest.Podman([]string{"create", "--security-opt", "apparmor=unconfined", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal("unconfined"))
+ })
+
+ It("podman run apparmor disabled --security-opt apparmor fails", func() {
+ skipIfAppArmorEnabled()
+ // Should fail if user specifies apparmor on disabled system
+ session := podmanTest.Podman([]string{"create", "--security-opt", fmt.Sprintf("apparmor=%s", apparmor.Profile), ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).ToNot(Equal(0))
+ })
+
+ It("podman run apparmor disabled no default", func() {
+ skipIfAppArmorEnabled()
+ // Should succeed if user specifies apparmor on disabled system
+ session := podmanTest.Podman([]string{"create", ALPINE, "ls"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+
+ cid := session.OutputToString()
+ // Verify that apparmor.Profile is being set
+ inspect := podmanTest.InspectContainer(cid)
+ Expect(inspect[0].AppArmorProfile).To(Equal(""))
+ })
+})
diff --git a/test/e2e/run_cleanup_test.go b/test/e2e/run_cleanup_test.go
index 7c83acc40..596c224aa 100644
--- a/test/e2e/run_cleanup_test.go
+++ b/test/e2e/run_cleanup_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -35,6 +33,7 @@ var _ = Describe("Podman run exit", func() {
})
It("podman run -d mount cleanup test", func() {
+ SkipIfRemote()
SkipIfRootless()
result := podmanTest.Podman([]string{"run", "-dt", ALPINE, "top"})
diff --git a/test/e2e/run_cpu_test.go b/test/e2e/run_cpu_test.go
index b4785c513..b1fb0e628 100644
--- a/test/e2e/run_cpu_test.go
+++ b/test/e2e/run_cpu_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_device_test.go b/test/e2e/run_device_test.go
index b1a4c9cb2..8798b2dc1 100644
--- a/test/e2e/run_device_test.go
+++ b/test/e2e/run_device_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_dns_test.go b/test/e2e/run_dns_test.go
index beed80fd2..a44fb7187 100644
--- a/test/e2e/run_dns_test.go
+++ b/test/e2e/run_dns_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_entrypoint_test.go b/test/e2e/run_entrypoint_test.go
index 741019770..f6019b37a 100644
--- a/test/e2e/run_entrypoint_test.go
+++ b/test/e2e/run_entrypoint_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -46,6 +44,7 @@ CMD []
})
It("podman run entrypoint", func() {
+ SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -57,6 +56,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with cmd", func() {
+ SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
@@ -69,6 +69,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with user cmd overrides image cmd", func() {
+ SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD [ "-v"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
@@ -81,6 +82,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run entrypoint with user cmd no image cmd", func() {
+ SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
`
@@ -92,6 +94,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run user entrypoint overrides image entrypoint and image cmd", func() {
+ SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
@@ -109,6 +112,7 @@ ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
})
It("podman run user entrypoint with command overrides image entrypoint and image cmd", func() {
+ SkipIfRemote()
dockerfile := `FROM docker.io/library/alpine:latest
CMD ["-i"]
ENTRYPOINT ["grep", "Alpine", "/etc/os-release"]
diff --git a/test/e2e/run_env_test.go b/test/e2e/run_env_test.go
index c6fb1ad1b..305e37c12 100644
--- a/test/e2e/run_env_test.go
+++ b/test/e2e/run_env_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_memory_test.go b/test/e2e/run_memory_test.go
index 5ae45b62f..379e74629 100644
--- a/test/e2e/run_memory_test.go
+++ b/test/e2e/run_memory_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index 317f760db..a22f79180 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -265,10 +263,10 @@ var _ = Describe("Podman run networking", func() {
})
It("podman run network expose ports in image metadata", func() {
- session := podmanTest.Podman([]string{"create", "-dt", "-P", nginx})
+ session := podmanTest.Podman([]string{"create", "--name", "test", "-dt", "-P", nginx})
session.Wait(90)
Expect(session.ExitCode()).To(Equal(0))
- results := podmanTest.Podman([]string{"inspect", "-l"})
+ results := podmanTest.Podman([]string{"inspect", "test"})
results.Wait(30)
Expect(results.ExitCode()).To(Equal(0))
Expect(results.OutputToString()).To(ContainSubstring(`"80/tcp":`))
@@ -277,11 +275,11 @@ var _ = Describe("Podman run networking", func() {
It("podman run network expose duplicate host port results in error", func() {
SkipIfRootless()
- session := podmanTest.Podman([]string{"run", "-dt", "-p", "80", ALPINE, "/bin/sh"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", "-dt", "-p", "80", ALPINE, "/bin/sh"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- inspect := podmanTest.Podman([]string{"inspect", "-l"})
+ inspect := podmanTest.Podman([]string{"inspect", "test"})
inspect.WaitWithDefaultTimeout()
Expect(inspect.ExitCode()).To(Equal(0))
@@ -436,6 +434,7 @@ var _ = Describe("Podman run networking", func() {
})
It("podman run in custom CNI network with --static-ip", func() {
+ SkipIfRemote()
SkipIfRootless()
netName := "podmantestnetwork"
ipAddr := "10.20.30.128"
diff --git a/test/e2e/run_ns_test.go b/test/e2e/run_ns_test.go
index 96ca2fc56..181b453c1 100644
--- a/test/e2e/run_ns_test.go
+++ b/test/e2e/run_ns_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_passwd_test.go b/test/e2e/run_passwd_test.go
index 3152f166b..40385e3ad 100644
--- a/test/e2e/run_passwd_test.go
+++ b/test/e2e/run_passwd_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_privileged_test.go b/test/e2e/run_privileged_test.go
index 03fb71656..8efbe0690 100644
--- a/test/e2e/run_privileged_test.go
+++ b/test/e2e/run_privileged_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_restart_test.go b/test/e2e/run_restart_test.go
index 0a1c7e134..fa9cb2495 100644
--- a/test/e2e/run_restart_test.go
+++ b/test/e2e/run_restart_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -35,11 +33,12 @@ var _ = Describe("Podman run restart containers", func() {
})
It("Podman start after successful run", func() {
- session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
+ SkipIfRemote()
+ session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- session2 := podmanTest.Podman([]string{"start", "--attach", "--latest"})
+ session2 := podmanTest.Podman([]string{"start", "--attach", "test"})
session2.WaitWithDefaultTimeout()
Expect(session2.ExitCode()).To(Equal(0))
})
diff --git a/test/e2e/run_seccomp.go b/test/e2e/run_seccomp.go
index a6a14618c..ec688135b 100644
--- a/test/e2e/run_seccomp.go
+++ b/test/e2e/run_seccomp.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_security_labels.go b/test/e2e/run_security_labels.go
index 148b18daa..50209a989 100644
--- a/test/e2e/run_security_labels.go
+++ b/test/e2e/run_security_labels.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -129,6 +127,7 @@ var _ = Describe("Podman generate kube", func() {
})
It("podman container runlabel (podman --version)", func() {
+ SkipIfRemote()
PodmanDockerfile := `
FROM alpine:latest
LABEL io.containers.capabilities=chown,mknod`
diff --git a/test/e2e/run_selinux_test.go b/test/e2e/run_selinux_test.go
index 7c1946534..c88441fbc 100644
--- a/test/e2e/run_selinux_test.go
+++ b/test/e2e/run_selinux_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_staticip_test.go b/test/e2e/run_staticip_test.go
index 8377636cf..de7663cc2 100644
--- a/test/e2e/run_staticip_test.go
+++ b/test/e2e/run_staticip_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 9d48f1540..4f4eb1028 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -160,10 +158,10 @@ var _ = Describe("Podman run", func() {
})
It("podman run a container with --init", func() {
- session := podmanTest.Podman([]string{"run", "--init", ALPINE, "ls"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"inspect", "-l"})
+ result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
conData := result.InspectContainerToJSON()
@@ -172,10 +170,10 @@ var _ = Describe("Podman run", func() {
})
It("podman run a container with --init and --init-path", func() {
- session := podmanTest.Podman([]string{"run", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"inspect", "-l"})
+ result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
conData := result.InspectContainerToJSON()
@@ -184,10 +182,10 @@ var _ = Describe("Podman run", func() {
})
It("podman run a container without --init", func() {
- session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"inspect", "-l"})
+ result := podmanTest.Podman([]string{"inspect", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
conData := result.InspectContainerToJSON()
@@ -259,11 +257,14 @@ var _ = Describe("Podman run", func() {
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
+ })
+ It("podman run user capabilities test with image", func() {
+ SkipIfRemote()
dockerfile := `FROM busybox
USER bin`
podmanTest.BuildImage(dockerfile, "test", "false")
- session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"})
+ session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
@@ -510,6 +511,7 @@ USER bin`
})
It("podman run with secrets", func() {
+ SkipIfRemote()
containersDir := filepath.Join(podmanTest.TempDir, "containers")
err := os.MkdirAll(containersDir, 0755)
Expect(err).To(BeNil())
@@ -674,6 +676,7 @@ USER bin`
})
It("podman run with built-in volume image", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
@@ -820,16 +823,22 @@ USER mail`
})
It("podman run --rm should work", func() {
- session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
+ session = podmanTest.Podman([]string{"wait", "test"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(ExitWithError())
numContainers := podmanTest.NumberOfContainers()
Expect(numContainers).To(Equal(0))
})
It("podman run --rm failed container should delete itself", func() {
- session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "foo"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(ExitWithError())
+ session = podmanTest.Podman([]string{"wait", "test"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
@@ -841,6 +850,10 @@ USER mail`
session := podmanTest.Podman([]string{"run", ALPINE, "foo"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
+ // If remote we could have a race condition
+ session = podmanTest.Podman([]string{"wait", "test"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(ExitWithError())
numContainers := podmanTest.NumberOfContainers()
Expect(numContainers).To(Equal(1))
@@ -881,7 +894,7 @@ USER mail`
})
It("podman run with restart-policy always restarts containers", func() {
-
+ SkipIfRemote()
testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
err := os.MkdirAll(testDir, 0755)
Expect(err).To(BeNil())
@@ -995,14 +1008,12 @@ USER mail`
})
It("podman run should fail with nonexist authfile", func() {
- SkipIfRemote()
session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexist", ALPINE, "ls"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Not(Equal(0)))
})
It("podman run --device-cgroup-rule", func() {
- SkipIfRemote()
SkipIfRootless()
deviceCgroupRule := "c 42:* rwm"
session := podmanTest.Podman([]string{"run", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"})
@@ -1081,4 +1092,35 @@ USER mail`
Expect(session.ExitCode()).To(Equal(0))
Expect(session.OutputToString()).To(ContainSubstring(limit))
})
+
+ It("podman run umask", func() {
+ if !strings.Contains(podmanTest.OCIRuntime, "crun") {
+ Skip("Test only works on crun")
+ }
+
+ session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("0022"))
+
+ session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("0002"))
+
+ session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("0077"))
+
+ session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Equal(0))
+ Expect(session.OutputToString()).To(Equal("0022"))
+
+ session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"})
+ session.WaitWithDefaultTimeout()
+ Expect(session.ExitCode()).To(Not(Equal(0)))
+ Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask"))
+ })
})
diff --git a/test/e2e/run_userns_test.go b/test/e2e/run_userns_test.go
index 42f13537d..b82fa7acb 100644
--- a/test/e2e/run_userns_test.go
+++ b/test/e2e/run_userns_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index 2b806ac2b..63aa116f8 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -199,6 +197,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman run with volumes and suid/dev/exec options", func() {
+ SkipIfRemote()
mountPath := filepath.Join(podmanTest.TempDir, "secrets")
os.Mkdir(mountPath, 0755)
@@ -228,6 +227,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman run with tmpfs named volume mounts and unmounts", func() {
+ SkipIfRemote()
SkipIfRootless()
volName := "testvol"
mkVolume := podmanTest.Podman([]string{"volume", "create", "--opt", "type=tmpfs", "--opt", "device=tmpfs", "--opt", "o=nodev", "testvol"})
@@ -315,6 +315,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman run with anonymous volume", func() {
+ SkipIfRemote()
list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"})
list1.WaitWithDefaultTimeout()
Expect(list1.ExitCode()).To(Equal(0))
@@ -333,6 +334,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("podman rm -v removes anonymous volume", func() {
+ SkipIfRemote()
list1 := podmanTest.Podman([]string{"volume", "list", "--quiet"})
list1.WaitWithDefaultTimeout()
Expect(list1.ExitCode()).To(Equal(0))
@@ -434,6 +436,7 @@ var _ = Describe("Podman run with volumes", func() {
})
It("Podman mount over image volume with trailing /", func() {
+ SkipIfRemote()
image := "podman-volume-test:trailing"
dockerfile := `
FROM alpine:latest
@@ -453,6 +456,7 @@ VOLUME /test/`
})
It("podman run with overlay volume flag", func() {
+ SkipIfRemote()
if os.Getenv("container") != "" {
Skip("Overlay mounts not supported when running in a container")
}
diff --git a/test/e2e/runlabel_test.go b/test/e2e/runlabel_test.go
index 3383fbd1e..aae193aa0 100644
--- a/test/e2e/runlabel_test.go
+++ b/test/e2e/runlabel_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -48,6 +46,7 @@ var _ = Describe("podman container runlabel", func() {
})
It("podman container runlabel (podman --version)", func() {
+ SkipIfRemote()
image := "podman-runlabel-test:podman"
podmanTest.BuildImage(PodmanDockerfile, image, "false")
@@ -61,6 +60,7 @@ var _ = Describe("podman container runlabel", func() {
})
It("podman container runlabel (ls -la)", func() {
+ SkipIfRemote()
image := "podman-runlabel-test:ls"
podmanTest.BuildImage(LsDockerfile, image, "false")
diff --git a/test/e2e/search_test.go b/test/e2e/search_test.go
index aeab3ac56..65e981bbd 100644
--- a/test/e2e/search_test.go
+++ b/test/e2e/search_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -229,6 +227,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search attempts HTTP if registry is in registries.insecure and force secure is false", func() {
+ SkipIfRemote()
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -269,6 +268,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search doesn't attempt HTTP if force secure is true", func() {
+ SkipIfRemote()
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -307,6 +307,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search doesn't attempt HTTP if registry is not listed as insecure", func() {
+ SkipIfRemote()
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
@@ -345,6 +346,7 @@ registries = ['{{.Host}}:{{.Port}}']`
})
It("podman search doesn't attempt HTTP if one registry is not listed as insecure", func() {
+ SkipIfRemote()
if podmanTest.Host.Arch == "ppc64le" {
Skip("No registry image for ppc64le")
}
diff --git a/test/e2e/system_df_test.go b/test/e2e/system_df_test.go
index f17afaec1..b179a29d4 100644
--- a/test/e2e/system_df_test.go
+++ b/test/e2e/system_df_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -37,6 +35,7 @@ var _ = Describe("podman system df", func() {
})
It("podman system df", func() {
+ SkipIfRemote()
session := podmanTest.Podman([]string{"create", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index 7b9be2275..268f62f5b 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/test/e2e/top_test.go b/test/e2e/top_test.go
index 157a7fe46..f4d1ec857 100644
--- a/test/e2e/top_test.go
+++ b/test/e2e/top_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
@@ -55,22 +53,22 @@ var _ = Describe("Podman top", func() {
})
It("podman top on container", func() {
- session := podmanTest.Podman([]string{"run", "-d", ALPINE, "top", "-d", "2"})
+ session := podmanTest.Podman([]string{"run", "--name", "test", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"top", "-l"})
+ result := podmanTest.Podman([]string{"top", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
})
It("podman container top on container", func() {
- session := podmanTest.Podman([]string{"container", "run", "-d", ALPINE, "top", "-d", "2"})
+ session := podmanTest.Podman([]string{"container", "run", "--name", "test", "-d", ALPINE, "top", "-d", "2"})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(Equal(0))
- result := podmanTest.Podman([]string{"container", "top", "-l"})
+ result := podmanTest.Podman([]string{"container", "top", "test"})
result.WaitWithDefaultTimeout()
Expect(result.ExitCode()).To(Equal(0))
Expect(len(result.OutputToStringArray())).To(BeNumerically(">", 1))
diff --git a/test/e2e/volume_prune_test.go b/test/e2e/volume_prune_test.go
index c4fafa406..d98b02824 100644
--- a/test/e2e/volume_prune_test.go
+++ b/test/e2e/volume_prune_test.go
@@ -1,5 +1,3 @@
-// +build !remote
-
package integration
import (
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index b3278bb28..80c478505 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -622,9 +622,17 @@ func (c *ContainersConfig) Validate() error {
// execution checks. It returns an `error` on validation failure, otherwise
// `nil`.
func (c *NetworkConfig) Validate() error {
- if c.NetworkConfigDir != _cniConfigDir {
- err := isDirectory(c.NetworkConfigDir)
+ expectedConfigDir := _cniConfigDir
+ if unshare.IsRootless() {
+ home, err := unshare.HomeDir()
if err != nil {
+ return err
+ }
+ expectedConfigDir = filepath.Join(home, _cniConfigDirRootless)
+ }
+ if c.NetworkConfigDir != expectedConfigDir {
+ err := isDirectory(c.NetworkConfigDir)
+ if err != nil && !os.IsNotExist(err) {
return errors.Wrapf(err, "invalid network_config_dir: %s", c.NetworkConfigDir)
}
}
@@ -874,6 +882,10 @@ func Default() (*Config, error) {
if config != nil || configErr != nil {
return config, configErr
}
+ return defConfig()
+}
+
+func defConfig() (*Config, error) {
config, configErr = NewConfig("")
return config, configErr
}
@@ -969,13 +981,11 @@ func (c *Config) Write() error {
// the cached containers.conf files.
func Reload() (*Config, error) {
configMutex.Lock()
- configErr = nil
- config = nil
- configMutex.Unlock()
- return Default()
+ defer configMutex.Unlock()
+ return defConfig()
}
-func (c *Config) ActiveDestination() (string, string, error){
+func (c *Config) ActiveDestination() (string, string, error) {
if uri, found := os.LookupEnv("CONTAINER_HOST"); found {
var ident string
if v, found := os.LookupEnv("CONTAINER_SSHKEY"); found {
diff --git a/vendor/github.com/containers/common/pkg/config/default.go b/vendor/github.com/containers/common/pkg/config/default.go
index 12cf1b421..57b703f53 100644
--- a/vendor/github.com/containers/common/pkg/config/default.go
+++ b/vendor/github.com/containers/common/pkg/config/default.go
@@ -92,8 +92,10 @@ const (
// InstallPrefix is the prefix where podman will be installed.
// It can be overridden at build time.
_installPrefix = "/usr"
- // _cniConfigDir is the directory where cni plugins are found
+ // _cniConfigDir is the directory where cni configuration is found
_cniConfigDir = "/etc/cni/net.d/"
+ // _cniConfigDirRootless is the directory where cni plugins are found
+ _cniConfigDirRootless = ".config/cni/net.d/"
// CgroupfsCgroupsManager represents cgroupfs native cgroup manager
CgroupfsCgroupsManager = "cgroupfs"
// DefaultApparmorProfile specifies the default apparmor profile for the container.
@@ -138,6 +140,8 @@ func DefaultConfig() (*Config, error) {
netns := "bridge"
+ cniConfig := _cniConfigDir
+
defaultEngineConfig.SignaturePolicyPath = DefaultSignaturePolicyPath
if unshare.IsRootless() {
home, err := unshare.HomeDir()
@@ -152,6 +156,7 @@ func DefaultConfig() (*Config, error) {
}
}
netns = "slirp4netns"
+ cniConfig = filepath.Join(home, _cniConfigDirRootless)
}
cgroupNS := "host"
@@ -198,7 +203,7 @@ func DefaultConfig() (*Config, error) {
},
Network: NetworkConfig{
DefaultNetwork: "podman",
- NetworkConfigDir: _cniConfigDir,
+ NetworkConfigDir: cniConfig,
CNIPluginDirs: cniBinDir,
},
Engine: *defaultEngineConfig,
diff --git a/vendor/github.com/containers/common/version/version.go b/vendor/github.com/containers/common/version/version.go
index b75bbe971..2913fe974 100644
--- a/vendor/github.com/containers/common/version/version.go
+++ b/vendor/github.com/containers/common/version/version.go
@@ -1,4 +1,4 @@
package version
// Version is the version of the build.
-const Version = "0.16.0"
+const Version = "0.17.0"
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 284497740..0369d0b1e 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.21.1
+1.21.2
diff --git a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
index b7a95bfc2..cba3d05ea 100644
--- a/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
+++ b/vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
@@ -1749,7 +1749,7 @@ func (devices *DeviceSet) initDevmapper(doInit bool) (retErr error) {
// - Managed by container storage
// - The target of this device is at major <maj> and minor <min>
// - If <inode> is defined, use that file inside the device as a loopback image. Otherwise use the device itself.
- devices.devicePrefix = fmt.Sprintf("container-%d:%d-%d", major(st.Dev), minor(st.Dev), st.Ino)
+ devices.devicePrefix = fmt.Sprintf("container-%d:%d-%d", major(uint64(st.Dev)), minor(uint64(st.Dev)), st.Ino)
logrus.Debugf("devmapper: Generated prefix: %s", devices.devicePrefix)
// Check for the existence of the thin-pool device
diff --git a/vendor/github.com/containers/storage/pkg/archive/archive.go b/vendor/github.com/containers/storage/pkg/archive/archive.go
index 863465456..78744e0f3 100644
--- a/vendor/github.com/containers/storage/pkg/archive/archive.go
+++ b/vendor/github.com/containers/storage/pkg/archive/archive.go
@@ -393,13 +393,15 @@ func fillGo18FileTypeBits(mode int64, fi os.FileInfo) int64 {
// ReadSecurityXattrToTarHeader reads security.capability, security,image
// xattrs from filesystem to a tar header
func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
+ if hdr.Xattrs == nil {
+ hdr.Xattrs = make(map[string]string)
+ }
for _, xattr := range []string{"security.capability", "security.ima"} {
capability, err := system.Lgetxattr(path, xattr)
if err != nil && err != system.EOPNOTSUPP && err != system.ErrNotSupportedPlatform {
return errors.Wrapf(err, "failed to read %q attribute from %q", xattr, path)
}
if capability != nil {
- hdr.Xattrs = make(map[string]string)
hdr.Xattrs[xattr] = string(capability)
}
}
diff --git a/vendor/github.com/containers/storage/pkg/unshare/unshare.go b/vendor/github.com/containers/storage/pkg/unshare/unshare.go
index 1eff82e8e..a08fb674d 100644
--- a/vendor/github.com/containers/storage/pkg/unshare/unshare.go
+++ b/vendor/github.com/containers/storage/pkg/unshare/unshare.go
@@ -4,19 +4,30 @@ import (
"fmt"
"os"
"os/user"
+ "sync"
"github.com/pkg/errors"
)
+var (
+ homeDirOnce sync.Once
+ homeDirErr error
+ homeDir string
+)
+
// HomeDir returns the home directory for the current user.
func HomeDir() (string, error) {
- home := os.Getenv("HOME")
- if home == "" {
- usr, err := user.LookupId(fmt.Sprintf("%d", GetRootlessUID()))
- if err != nil {
- return "", errors.Wrapf(err, "unable to resolve HOME directory")
+ homeDirOnce.Do(func() {
+ home := os.Getenv("HOME")
+ if home == "" {
+ usr, err := user.LookupId(fmt.Sprintf("%d", GetRootlessUID()))
+ if err != nil {
+ homeDir, homeDirErr = "", errors.Wrapf(err, "unable to resolve HOME directory")
+ return
+ }
+ homeDir, homeDirErr = usr.HomeDir, nil
}
- home = usr.HomeDir
- }
- return home, nil
+ homeDir, homeDirErr = home, nil
+ })
+ return homeDir, homeDirErr
}
diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
index 6d3268902..c757c20e0 100644
--- a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
+++ b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go
@@ -29,6 +29,9 @@ var (
type Generator struct {
Config *rspec.Spec
HostSpecific bool
+ // This is used to keep a cache of the ENVs added to improve
+ // performance when adding a huge number of ENV variables
+ envMap map[string]int
}
// ExportOptions have toggles for exporting only certain parts of the specification
@@ -236,7 +239,12 @@ func New(os string) (generator Generator, err error) {
}
}
- return Generator{Config: &config}, nil
+ envCache := map[string]int{}
+ if config.Process != nil {
+ envCache = createEnvCacheMap(config.Process.Env)
+ }
+
+ return Generator{Config: &config, envMap: envCache}, nil
}
// NewFromSpec creates a configuration Generator from a given
@@ -246,8 +254,14 @@ func New(os string) (generator Generator, err error) {
//
// generator := Generator{Config: config}
func NewFromSpec(config *rspec.Spec) Generator {
+ envCache := map[string]int{}
+ if config != nil && config.Process != nil {
+ envCache = createEnvCacheMap(config.Process.Env)
+ }
+
return Generator{
Config: config,
+ envMap: envCache,
}
}
@@ -273,11 +287,27 @@ func NewFromTemplate(r io.Reader) (Generator, error) {
if err := json.NewDecoder(r).Decode(&config); err != nil {
return Generator{}, err
}
+
+ envCache := map[string]int{}
+ if config.Process != nil {
+ envCache = createEnvCacheMap(config.Process.Env)
+ }
+
return Generator{
Config: &config,
+ envMap: envCache,
}, nil
}
+// createEnvCacheMap creates a hash map with the ENV variables given by the config
+func createEnvCacheMap(env []string) map[string]int {
+ envMap := make(map[string]int, len(env))
+ for i, val := range env {
+ envMap[val] = i
+ }
+ return envMap
+}
+
// SetSpec sets the configuration in the Generator g.
//
// Deprecated: Replace with:
@@ -414,6 +444,12 @@ func (g *Generator) SetProcessUsername(username string) {
g.Config.Process.User.Username = username
}
+// SetProcessUmask sets g.Config.Process.User.Umask.
+func (g *Generator) SetProcessUmask(umask uint32) {
+ g.initConfigProcess()
+ g.Config.Process.User.Umask = umask
+}
+
// SetProcessGID sets g.Config.Process.User.GID.
func (g *Generator) SetProcessGID(gid uint32) {
g.initConfigProcess()
@@ -456,21 +492,44 @@ func (g *Generator) ClearProcessEnv() {
return
}
g.Config.Process.Env = []string{}
+ // Clear out the env cache map as well
+ g.envMap = map[string]int{}
}
// AddProcessEnv adds name=value into g.Config.Process.Env, or replaces an
// existing entry with the given name.
func (g *Generator) AddProcessEnv(name, value string) {
+ if name == "" {
+ return
+ }
+
g.initConfigProcess()
+ g.addEnv(fmt.Sprintf("%s=%s", name, value), name)
+}
- env := fmt.Sprintf("%s=%s", name, value)
- for idx := range g.Config.Process.Env {
- if strings.HasPrefix(g.Config.Process.Env[idx], name+"=") {
- g.Config.Process.Env[idx] = env
- return
- }
+// AddMultipleProcessEnv adds multiple name=value into g.Config.Process.Env, or replaces
+// existing entries with the given name.
+func (g *Generator) AddMultipleProcessEnv(envs []string) {
+ g.initConfigProcess()
+
+ for _, val := range envs {
+ split := strings.SplitN(val, "=", 2)
+ g.addEnv(val, split[0])
+ }
+}
+
+// addEnv looks through adds ENV to the Process and checks envMap for
+// any duplicates
+// This is called by both AddMultipleProcessEnv and AddProcessEnv
+func (g *Generator) addEnv(env, key string) {
+ if idx, ok := g.envMap[key]; ok {
+ // The ENV exists in the cache, so change its value in g.Config.Process.Env
+ g.Config.Process.Env[idx] = env
+ } else {
+ // else the env doesn't exist, so add it and add it's index to g.envMap
+ g.Config.Process.Env = append(g.Config.Process.Env, env)
+ g.envMap[key] = len(g.Config.Process.Env) - 1
}
- g.Config.Process.Env = append(g.Config.Process.Env, env)
}
// AddProcessRlimits adds rlimit into g.Config.Process.Rlimits.
@@ -1443,7 +1502,7 @@ func (g *Generator) AddDevice(device rspec.LinuxDevice) {
return
}
if dev.Type == device.Type && dev.Major == device.Major && dev.Minor == device.Minor {
- fmt.Fprintln(os.Stderr, "WARNING: The same type, major and minor should not be used for multiple devices.")
+ fmt.Fprintf(os.Stderr, "WARNING: Creating device %q with same type, major and minor as existing %q.\n", device.Path, dev.Path)
}
}
diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go
index 5fee5a3b2..8a8dc3970 100644
--- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go
+++ b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go
@@ -566,6 +566,20 @@ func DefaultProfile(rs *specs.Spec) *rspec.LinuxSeccomp {
},
}...)
/* Flags parameter of the clone syscall is the 2nd on s390 */
+ syscalls = append(syscalls, []rspec.LinuxSyscall{
+ {
+ Names: []string{"clone"},
+ Action: rspec.ActAllow,
+ Args: []rspec.LinuxSeccompArg{
+ {
+ Index: 1,
+ Value: 2080505856,
+ ValueTwo: 0,
+ Op: rspec.OpMaskedEqual,
+ },
+ },
+ },
+ }...)
}
return &rspec.LinuxSeccomp{
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 913cb71eb..1d97f810a 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -84,7 +84,7 @@ github.com/containers/buildah/pkg/secrets
github.com/containers/buildah/pkg/supplemented
github.com/containers/buildah/pkg/umask
github.com/containers/buildah/util
-# github.com/containers/common v0.16.0
+# github.com/containers/common v0.17.0
github.com/containers/common/pkg/apparmor
github.com/containers/common/pkg/auth
github.com/containers/common/pkg/capabilities
@@ -155,7 +155,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.1
+# github.com/containers/storage v1.21.2
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@@ -421,7 +421,7 @@ github.com/opencontainers/runc/libcontainer/user
github.com/opencontainers/runc/libcontainer/utils
# github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
github.com/opencontainers/runtime-spec/specs-go
-# github.com/opencontainers/runtime-tools v0.9.0
+# github.com/opencontainers/runtime-tools v0.9.1-0.20200714183735-07406c5828aa
github.com/opencontainers/runtime-tools/error
github.com/opencontainers/runtime-tools/filepath
github.com/opencontainers/runtime-tools/generate