summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile23
-rw-r--r--cmd/podman/common/create.go8
-rw-r--r--cmd/podman/containers/create.go16
-rw-r--r--cmd/podman/pods/create.go10
-rw-r--r--cmd/podman/system/version.go2
-rwxr-xr-xcontrib/cirrus/runner.sh1
-rw-r--r--contrib/spec/podman.spec.in1
-rw-r--r--docs/source/markdown/podman-create.1.md10
-rw-r--r--docs/source/markdown/podman-pause.1.md2
-rw-r--r--docs/source/markdown/podman-pod-create.1.md2
-rw-r--r--docs/source/markdown/podman-run.1.md10
-rw-r--r--go.mod8
-rw-r--r--go.sum17
-rw-r--r--libpod/container_internal.go12
-rw-r--r--libpod/container_internal_linux.go1
-rw-r--r--libpod/container_log_linux.go33
-rw-r--r--libpod/container_path_resolution.go2
-rw-r--r--libpod/kube.go15
-rw-r--r--libpod/networking_slirp4netns.go39
-rw-r--r--libpod/oci_conmon_linux.go2
-rw-r--r--libpod/runtime.go2
-rw-r--r--pause/pause.c69
-rw-r--r--pkg/api/handlers/libpod/pods.go17
-rw-r--r--pkg/api/handlers/libpod/volumes.go17
-rw-r--r--pkg/cgroups/cgroups.go2
-rw-r--r--pkg/domain/entities/pods.go3
-rw-r--r--pkg/domain/entities/volumes.go4
-rw-r--r--pkg/machine/ignition.go18
-rw-r--r--pkg/specgen/generate/pod_create.go97
-rw-r--r--pkg/specgen/generate/storage.go3
-rw-r--r--pkg/specgenutil/volumes.go12
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_volume.py67
-rw-r--r--test/e2e/logs_test.go69
-rw-r--r--test/e2e/play_kube_test.go19
-rw-r--r--test/e2e/push_test.go4
-rw-r--r--test/e2e/run_networking_test.go20
-rw-r--r--test/e2e/run_test.go14
-rw-r--r--test/e2e/system_reset_test.go2
-rw-r--r--test/e2e/systemd_test.go17
-rw-r--r--test/registries.conf6
-rw-r--r--test/system/070-build.bats9
-rw-r--r--test/system/200-pod.bats30
-rw-r--r--utils/utils.go20
-rw-r--r--vendor/github.com/containers/common/libimage/filters.go32
-rw-r--r--vendor/github.com/containers/common/libimage/image.go36
-rw-r--r--vendor/github.com/containers/common/libimage/search.go2
-rw-r--r--vendor/github.com/containers/common/pkg/config/config.go2
-rw-r--r--vendor/github.com/containers/common/pkg/flag/flag.go174
-rw-r--r--vendor/github.com/godbus/dbus/v5/auth.go2
-rw-r--r--vendor/github.com/godbus/dbus/v5/conn.go22
-rw-r--r--vendor/github.com/godbus/dbus/v5/message.go4
-rw-r--r--vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go14
-rw-r--r--vendor/modules.txt9
53 files changed, 858 insertions, 174 deletions
diff --git a/Makefile b/Makefile
index 3b70c4f4f..00afd1dfd 100644
--- a/Makefile
+++ b/Makefile
@@ -185,6 +185,10 @@ ifdef HOMEBREW_PREFIX
endif
endif
+# For building pause/pause.c
+GCC ?= gcc
+PAUSE_CFLAGS = -Os -static -Wall -Werror -DVERSION=v$(RELEASE_VERSION)
+
###
### Primary entry-point targets
###
@@ -196,7 +200,7 @@ default: all
all: binaries docs
.PHONY: binaries
-binaries: podman podman-remote rootlessport ## Build podman, podman-remote and rootlessport binaries
+binaries: podman podman-remote rootlessport pause
# Extract text following double-# for targets, as their description for
# the `help` target. Otherwise These simple-substitutions are resolved
@@ -374,6 +378,12 @@ bin/rootlessport: .gopathok $(SOURCES) go.mod go.sum
.PHONY: rootlessport
rootlessport: bin/rootlessport
+bin/pause: pause/pause.c
+ $(GCC) $(PAUSE_CFLAGS) pause/pause.c -o bin/pause
+
+.PHONY: pause
+pause: bin/pause
+
###
### Secondary binary-build targets
###
@@ -733,7 +743,7 @@ install.remote-nobuild:
install.remote: podman-remote install.remote-nobuild
.PHONY: install.bin-nobuild
-install.bin-nobuild:
+install.bin-nobuild: install.pause
install ${SELINUXOPT} -d -m 755 $(DESTDIR)$(BINDIR)
install ${SELINUXOPT} -m 755 bin/podman $(DESTDIR)$(BINDIR)/podman
test -z "${SELINUXOPT}" || chcon --verbose --reference=$(DESTDIR)$(BINDIR)/podman bin/podman
@@ -787,8 +797,10 @@ install.docker-docs-nobuild:
.PHONY: install.docker-docs
install.docker-docs: docker-docs install.docker-docs-nobuild
-.PHONY: install.docker-full
-install.docker-full: install.docker install.docker-docs
+.PHONY: install.pause
+install.pause: pause
+ install ${SELINUXOPT} -m 755 -d $(DESTDIR)$(LIBEXECPODMAN)/pause
+ install ${SELINUXOPT} -m 755 bin/pause $(DESTDIR)$(LIBEXECPODMAN)/pause/pause
.PHONY: install.systemd
ifneq (,$(findstring systemd,$(BUILDTAGS)))
@@ -819,6 +831,9 @@ else
install.systemd:
endif
+.PHONY: install.pause
+install.pause: pause
+
.PHONY: install.tools
install.tools: .install.goimports .install.gitvalidation .install.md2man .install.ginkgo .install.golangci-lint .install.bats ## Install needed tools
diff --git a/cmd/podman/common/create.go b/cmd/podman/common/create.go
index 6270bad16..fbc8fb8ab 100644
--- a/cmd/podman/common/create.go
+++ b/cmd/podman/common/create.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/common/pkg/auth"
"github.com/containers/common/pkg/completion"
+ commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
@@ -589,12 +590,9 @@ func DefineCreateFlags(cmd *cobra.Command, cf *entities.ContainerCreateOptions,
)
_ = cmd.RegisterFlagCompletionFunc(timeoutFlagName, completion.AutocompleteNone)
- // Flag for TLS verification, so that `run` and `create` commands can make use of it.
- // Make sure to use `=` while using this flag i.e `--tls-verify=false/true`
- tlsVerifyFlagName := "tls-verify"
- createFlags.BoolVar(
+ commonFlag.OptionalBoolFlag(createFlags,
&cf.TLSVerify,
- tlsVerifyFlagName, true,
+ "tls-verify",
"Require HTTPS and verify certificates when contacting registries for pulling images",
)
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index bfeeb7ebe..d35c1a192 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -303,6 +303,11 @@ func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (strin
}
}
+ skipTLSVerify := types.OptionalBoolUndefined
+ if cliVals.TLSVerify.Present() {
+ skipTLSVerify = types.NewOptionalBool(!cliVals.TLSVerify.Value())
+ }
+
pullReport, pullErr := registry.ImageEngine().Pull(registry.GetContext(), imageName, entities.ImagePullOptions{
Authfile: cliVals.Authfile,
Quiet: cliVals.Quiet,
@@ -311,7 +316,7 @@ func PullImage(imageName string, cliVals entities.ContainerCreateOptions) (strin
Variant: cliVals.Variant,
SignaturePolicy: cliVals.SignaturePolicy,
PullPolicy: pullPolicy,
- SkipTLSVerify: types.NewOptionalBool(!cliVals.TLSVerify), // If Flag changed for TLS Verification
+ SkipTLSVerify: skipTLSVerify,
})
if pullErr != nil {
return "", pullErr
@@ -372,15 +377,10 @@ func createPodIfNecessary(s *specgen.SpecGenerator, netOpts *entities.NetOptions
}
infraOpts := entities.ContainerCreateOptions{ImageVolume: "bind", Net: netOpts, Quiet: true}
- rawImageName := config.DefaultInfraImage
- name, err := PullImage(rawImageName, infraOpts)
- if err != nil {
- fmt.Println(err)
- }
- imageName := name
+ imageName := config.DefaultInfraImage
podGen.InfraImage = imageName
podGen.InfraContainerSpec = specgen.NewSpecGenerator(imageName, false)
- podGen.InfraContainerSpec.RawImageName = rawImageName
+ podGen.InfraContainerSpec.RawImageName = imageName
podGen.InfraContainerSpec.NetworkOptions = podGen.NetworkOptions
err = specgenutil.FillOutSpecGen(podGen.InfraContainerSpec, &infraOpts, []string{})
if err != nil {
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index 7c2c72171..0a0d43b53 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -242,16 +242,6 @@ func create(cmd *cobra.Command, args []string) error {
}
if createOptions.Infra {
rawImageName = img
- if !infraOptions.RootFS {
- curr := infraOptions.Quiet
- infraOptions.Quiet = true
- name, err := containers.PullImage(imageName, infraOptions)
- if err != nil {
- fmt.Println(err)
- }
- imageName = name
- infraOptions.Quiet = curr
- }
podSpec.InfraImage = imageName
if infraOptions.Entrypoint != nil {
createOptions.InfraCommand = infraOptions.Entrypoint
diff --git a/cmd/podman/system/version.go b/cmd/podman/system/version.go
index 4502b156c..3ddd19bae 100644
--- a/cmd/podman/system/version.go
+++ b/cmd/podman/system/version.go
@@ -67,7 +67,7 @@ func version(cmd *cobra.Command, args []string) error {
}
if err := tmpl.Execute(w, versions); err != nil {
// On Failure, assume user is using older version of podman version --format and check client
- row = strings.Replace(row, ".Server.", ".", 1)
+ row = strings.ReplaceAll(row, ".Server.", ".")
tmpl, err := report.NewTemplate("version 1.0.0").Parse(row)
if err != nil {
return err
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index 22a66dd08..8ef2a6e64 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -117,6 +117,7 @@ exec_container() {
set -x
# shellcheck disable=SC2154
exec podman run --rm --privileged --net=host --cgroupns=host \
+ -v `mktemp -d -p /var/tmp`:/tmp:Z \
-v /dev/fuse:/dev/fuse \
-v "$GOPATH:$GOPATH:Z" \
--workdir "$GOSRC" \
diff --git a/contrib/spec/podman.spec.in b/contrib/spec/podman.spec.in
index 295a953ef..2db8f6e67 100644
--- a/contrib/spec/podman.spec.in
+++ b/contrib/spec/podman.spec.in
@@ -528,6 +528,7 @@ export GOPATH=%{buildroot}/%{gopath}:$(pwd)/vendor:%{gopath}
%{_usr}/lib/tmpfiles.d/podman.conf
%dir %{_libexecdir}/%{name}
%{_libexecdir}/%{name}/rootlessport
+%{_libexecdir}/%{name}/pause/pause
%if 0%{?with_devel}
%files -n libpod-devel -f devel.file-list
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index ea9042861..3ff736adb 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -638,6 +638,16 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
. U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ Options specific to devpts:
+
+ · uid: UID of the file owner (default 0).
+
+ · gid: GID of the file owner (default 0).
+
+ · mode: permission mask for the file (default 600).
+
+ · max: maximum number of PTYs (default 1048576).
+
#### **--name**=*name*
Assign a name to the container
diff --git a/docs/source/markdown/podman-pause.1.md b/docs/source/markdown/podman-pause.1.md
index 123362822..90ea1e32e 100644
--- a/docs/source/markdown/podman-pause.1.md
+++ b/docs/source/markdown/podman-pause.1.md
@@ -31,7 +31,7 @@ podman pause 860a4b23
Pause all **running** containers.
```
-podman stop -a
+podman pause -a
```
## SEE ALSO
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 08ac19b8b..061727559 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -112,7 +112,7 @@ The command that will be run to start the infra container. Default: "/pause".
#### **--infra-image**=*image*
-The image that will be created for the infra container. Default: "k8s.gcr.io/pause:3.1".
+The custom image that will be used for the infra container. Unless specified, Podman builds a custom local image which does not require pulling down an image.
#### **--infra-name**=*name*
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index b5f3130fe..a1170253f 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -665,6 +665,16 @@ Current supported mount TYPEs are **bind**, **volume**, **image**, **tmpfs** and
. U, chown: true or false (default). Change recursively the owner and group of the source volume based on the UID and GID of the container.
+ Options specific to devpts:
+
+ · uid: UID of the file owner (default 0).
+
+ · gid: GID of the file owner (default 0).
+
+ · mode: permission mask for the file (default 600).
+
+ · max: maximum number of PTYs (default 1048576).
+
#### **--name**=*name*
Assign a name to the container.
diff --git a/go.mod b/go.mod
index 65a1e0226..9212a83e0 100644
--- a/go.mod
+++ b/go.mod
@@ -12,7 +12,7 @@ require (
github.com/containernetworking/cni v1.0.1
github.com/containernetworking/plugins v1.0.1
github.com/containers/buildah v1.23.1
- github.com/containers/common v0.46.1-0.20211008123044-d846f5aaec0e
+ github.com/containers/common v0.46.1-0.20211026130826-7abfd453c86f
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.16.1
github.com/containers/ocicrypt v1.1.2
@@ -31,7 +31,7 @@ require (
github.com/dtylman/scp v0.0.0-20181017070807-f3000a34aef4
github.com/fsnotify/fsnotify v1.5.1
github.com/ghodss/yaml v1.0.0
- github.com/godbus/dbus/v5 v5.0.5
+ github.com/godbus/dbus/v5 v5.0.6
github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf
github.com/google/uuid v1.3.0
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33
@@ -68,6 +68,6 @@ require (
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210910150752-751e447fb3d0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
- k8s.io/api v0.22.2
- k8s.io/apimachinery v0.22.2
+ k8s.io/api v0.22.3
+ k8s.io/apimachinery v0.22.3
)
diff --git a/go.sum b/go.sum
index 9b5a185b1..8a18541d7 100644
--- a/go.sum
+++ b/go.sum
@@ -258,8 +258,8 @@ github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNB
github.com/containers/buildah v1.23.1 h1:Tpc9DsRuU+0Oofewpxb6OJVNQjCu7yloN/obUqzfDTY=
github.com/containers/buildah v1.23.1/go.mod h1:4WnrN0yrA7ab0ppgunixu2WM1rlD2rG8QLJAKbEkZlQ=
github.com/containers/common v0.44.2/go.mod h1:7sdP4vmI5Bm6FPFxb3lvAh1Iktb6tiO1MzjUzhxdoGo=
-github.com/containers/common v0.46.1-0.20211008123044-d846f5aaec0e h1:lYazDued7KBcMq5IJzRIbX47SSLRg/yYxvM/P9LaVhE=
-github.com/containers/common v0.46.1-0.20211008123044-d846f5aaec0e/go.mod h1:ggZks97KCmjBcHvNTCyLc17SqdjSYoeexW7rnRt9H9Y=
+github.com/containers/common v0.46.1-0.20211026130826-7abfd453c86f h1:jFFIV8QvsPgwkJHh3tjfREFRwSeMq5M8lt8vklkZaOk=
+github.com/containers/common v0.46.1-0.20211026130826-7abfd453c86f/go.mod h1:pVvmLTLCOZE300e4rex/QDmpnRmEM/5aZ/YfCkkjgZo=
github.com/containers/conmon v2.0.20+incompatible h1:YbCVSFSCqFjjVwHTPINGdMX1F6JXHGTUje2ZYobNrkg=
github.com/containers/conmon v2.0.20+incompatible/go.mod h1:hgwZ2mtuDrppv78a/cOBNiCm6O0UMWGx1mu7P00nu5I=
github.com/containers/image/v5 v5.16.0/go.mod h1:XgTpfAPLRGOd1XYyCU5cISFr777bLmOerCSpt/v7+Q4=
@@ -336,7 +336,6 @@ github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BU
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.8+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker v20.10.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.10+incompatible h1:GKkP0T7U4ks6X3lmmHKC2QDprnpRJor2Z5a8m62R9ZM=
github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
@@ -425,8 +424,8 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68Fp
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.0.5 h1:9Eg0XUhQxtkV8ykTMKtMMYY72g4NgxtRq4jgh4Ih5YM=
-github.com/godbus/dbus/v5 v5.0.5/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro=
+github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
@@ -1506,13 +1505,13 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.22.2 h1:M8ZzAD0V6725Fjg53fKeTJxGsJvRbk4TEm/fexHMtfw=
-k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
+k8s.io/api v0.22.3 h1:wOoES2GoSkUsdped2RB4zYypPqWtvprGoKCENTOOjP4=
+k8s.io/api v0.22.3/go.mod h1:azgiXFiXqiWyLCfI62/eYBOu19rj2LKmIhFPP4+33fs=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.22.2 h1:ejz6y/zNma8clPVfNDLnPbleBo6MpoFy/HBiBqCouVk=
-k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
+k8s.io/apimachinery v0.22.3 h1:mrvBG5CZnEfwgpVqWcrRKvdsYECTrhAR6cApAgdsflk=
+k8s.io/apimachinery v0.22.3/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
diff --git a/libpod/container_internal.go b/libpod/container_internal.go
index d4384b791..b9805faa3 100644
--- a/libpod/container_internal.go
+++ b/libpod/container_internal.go
@@ -1513,8 +1513,8 @@ func (c *Container) mountStorage() (_ string, deferredErr error) {
mountPoint := c.config.Rootfs
// Check if overlay has to be created on top of Rootfs
if c.config.RootfsOverlay {
- overlayDest := c.runtime.store.GraphRoot()
- contentDir, err := overlay.GenerateStructure(c.runtime.store.GraphRoot(), c.ID(), "rootfs", c.RootUID(), c.RootGID())
+ overlayDest := c.runtime.RunRoot()
+ contentDir, err := overlay.GenerateStructure(overlayDest, c.ID(), "rootfs", c.RootUID(), c.RootGID())
if err != nil {
return "", errors.Wrapf(err, "rootfs-overlay: failed to create TempDir in the %s directory", overlayDest)
}
@@ -1739,11 +1739,11 @@ func (c *Container) cleanupStorage() error {
// umount rootfs overlay if it was created
if c.config.RootfsOverlay {
- overlayBasePath := filepath.Dir(c.config.StaticDir)
- overlayBasePath = filepath.Join(overlayBasePath, "rootfs")
+ overlayBasePath := filepath.Dir(c.state.Mountpoint)
if err := overlay.Unmount(overlayBasePath); err != nil {
- // If the container can't remove content report the error
- logrus.Errorf("Failed to cleanup overlay mounts for %s: %v", c.ID(), err)
+ if cleanupErr != nil {
+ logrus.Errorf("Failed to cleanup overlay mounts for %s: %v", c.ID(), err)
+ }
cleanupErr = err
}
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index d3151f7e0..2fd519990 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1546,6 +1546,7 @@ func (c *Container) restore(ctx context.Context, options ContainerCheckpointOpti
logrus.Debugf("Restored container %s", c.ID())
c.state.State = define.ContainerStateRunning
+ c.state.Checkpointed = false
if !options.Keep {
// Delete all checkpoint related files. At this point, in theory, all files
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index 562169ce2..4029d0af7 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -121,7 +121,24 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
}()
tailQueue := []*logs.LogLine{} // needed for options.Tail
- doTail := options.Tail > 0
+ doTail := options.Tail >= 0
+ doTailFunc := func() {
+ // Flush *once* we hit the end of the journal.
+ startIndex := int64(len(tailQueue))
+ outputLines := int64(0)
+ for startIndex > 0 && outputLines < options.Tail {
+ startIndex--
+ for startIndex > 0 && tailQueue[startIndex].Partial() {
+ startIndex--
+ }
+ outputLines++
+ }
+ for i := startIndex; i < int64(len(tailQueue)); i++ {
+ logChannel <- tailQueue[i]
+ }
+ tailQueue = nil
+ doTail = false
+ }
lastReadCursor := ""
for {
select {
@@ -152,16 +169,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
// Hit the end of the journal (so far?).
if cursor == lastReadCursor {
if doTail {
- // Flush *once* we hit the end of the journal.
- startIndex := int64(len(tailQueue)-1) - options.Tail
- if startIndex < 0 {
- startIndex = 0
- }
- for i := startIndex; i < int64(len(tailQueue)); i++ {
- logChannel <- tailQueue[i]
- }
- tailQueue = nil
- doTail = false
+ doTailFunc()
}
// Unless we follow, quit.
if !options.Follow {
@@ -194,6 +202,9 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
return
}
if status == events.Exited {
+ if doTail {
+ doTailFunc()
+ }
return
}
continue
diff --git a/libpod/container_path_resolution.go b/libpod/container_path_resolution.go
index bb2ef1a73..7db23b783 100644
--- a/libpod/container_path_resolution.go
+++ b/libpod/container_path_resolution.go
@@ -161,7 +161,7 @@ func isPathOnBindMount(c *Container, containerPath string) bool {
if cleanedContainerPath == filepath.Clean(m.Destination) {
return true
}
- for dest := m.Destination; dest != "/"; dest = filepath.Dir(dest) {
+ for dest := m.Destination; dest != "/" && dest != "."; dest = filepath.Dir(dest) {
if cleanedContainerPath == dest {
return true
}
diff --git a/libpod/kube.go b/libpod/kube.go
index 02ac8ed98..ad5acea78 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -11,6 +11,7 @@ import (
"strings"
"time"
+ "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/libpod/network/types"
"github.com/containers/podman/v3/pkg/env"
@@ -468,11 +469,23 @@ func containerToV1Container(ctx context.Context, c *Container) (v1.Container, []
kubeContainer.Name = removeUnderscores(c.Name())
_, image := c.Image()
+
+ // The infra container may have been created with an overlay root FS
+ // instead of an infra image. If so, set the imageto the default K8s
+ // pause one and make sure it's in the storage by pulling it down if
+ // missing.
+ if image == "" && c.IsInfra() {
+ image = config.DefaultInfraImage
+ if _, err := c.runtime.libimageRuntime.Pull(ctx, image, config.PullPolicyMissing, nil); err != nil {
+ return kubeContainer, nil, nil, nil, err
+ }
+ }
+
kubeContainer.Image = image
kubeContainer.Stdin = c.Stdin()
img, _, err := c.runtime.libimageRuntime.LookupImage(image, nil)
if err != nil {
- return kubeContainer, kubeVolumes, nil, annotations, err
+ return kubeContainer, kubeVolumes, nil, annotations, fmt.Errorf("looking up image %q of container %q: %w", image, c.ID(), err)
}
imgData, err := img.Inspect(ctx, nil)
if err != nil {
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index ffd53ec2b..56e8eca99 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -16,6 +16,7 @@ import (
"syscall"
"time"
+ "github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/podman/v3/pkg/errorhandling"
"github.com/containers/podman/v3/pkg/rootless"
"github.com/containers/podman/v3/pkg/rootlessport"
@@ -58,6 +59,8 @@ type slirp4netnsNetworkOptions struct {
outboundAddr6 string
}
+const ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/default/accept_dad"
+
func checkSlirpFlags(path string) (*slirpFeatures, error) {
cmd := exec.Command(path, "--help")
out, err := cmd.CombinedOutput()
@@ -297,6 +300,39 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
}
cmd.Stdout = logFile
cmd.Stderr = logFile
+
+ var slirpReadyChan (chan struct{})
+
+ if netOptions.enableIPv6 {
+ slirpReadyChan = make(chan struct{})
+ defer close(slirpReadyChan)
+ go func() {
+ err := ns.WithNetNSPath(netnsPath, func(_ ns.NetNS) error {
+ // Duplicate Address Detection slows the ipv6 setup down for 1-2 seconds.
+ // Since slirp4netns is run it is own namespace and not directly routed
+ // we can skip this to make the ipv6 address immediately available.
+ // We change the default to make sure the slirp tap interface gets the
+ // correct value assigned so DAD is disabled for it
+ // Also make sure to change this value back to the original after slirp4netns
+ // is ready in case users rely on this sysctl.
+ orgValue, err := ioutil.ReadFile(ipv6ConfDefaultAcceptDadSysctl)
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, []byte("0"), 0644)
+ if err != nil {
+ return err
+ }
+ // wait for slirp to finish setup
+ <-slirpReadyChan
+ return ioutil.WriteFile(ipv6ConfDefaultAcceptDadSysctl, orgValue, 0644)
+ })
+ if err != nil {
+ logrus.Warnf("failed to set net.ipv6.conf.default.accept_dad sysctl: %v", err)
+ }
+ }()
+ }
+
if err := cmd.Start(); err != nil {
return errors.Wrapf(err, "failed to start slirp4netns process")
}
@@ -310,6 +346,9 @@ func (r *Runtime) setupSlirp4netns(ctr *Container) error {
if err := waitForSync(syncR, cmd, logFile, 1*time.Second); err != nil {
return err
}
+ if slirpReadyChan != nil {
+ slirpReadyChan <- struct{}{}
+ }
// Set a default slirp subnet. Parsing a string with the net helper is easier than building the struct myself
_, ctr.slirp4netnsSubnet, _ = net.ParseCIDR(defaultSlirp4netnsSubnet)
diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go
index 1719b2dfa..db906fabb 100644
--- a/libpod/oci_conmon_linux.go
+++ b/libpod/oci_conmon_linux.go
@@ -1016,7 +1016,7 @@ func (r *ConmonOCIRuntime) createOCIContainer(ctr *Container, restoreOptions *Co
}
if ctr.config.CgroupsMode == cgroupSplit {
- if err := utils.MoveUnderCgroupSubtree("supervisor"); err != nil {
+ if err := utils.MoveUnderCgroupSubtree("runtime"); err != nil {
return err
}
}
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 855f3a9f9..b01f8dd13 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -543,6 +543,8 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
return err
}
if became {
+ // Check if the pause process was created. If it was created, then
+ // move it to its own systemd scope.
utils.MovePauseProcessToScope(pausePid)
os.Exit(ret)
}
diff --git a/pause/pause.c b/pause/pause.c
new file mode 100644
index 000000000..1e363bd7a
--- /dev/null
+++ b/pause/pause.c
@@ -0,0 +1,69 @@
+/*
+Copyright 2016 The Kubernetes Authors.
+Copyright 2021 The Podman Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#define STRINGIFY(x) #x
+#define VERSION_STRING(x) STRINGIFY(x)
+
+#ifndef VERSION
+#define VERSION HEAD
+#endif
+
+static void sigdown(int signo) {
+ psignal(signo, "Shutting down, got signal");
+ exit(0);
+}
+
+static void sigreap(int signo) {
+ while (waitpid(-1, NULL, WNOHANG) > 0)
+ ;
+}
+
+int main(int argc, char **argv) {
+ int i;
+ for (i = 1; i < argc; ++i) {
+ if (!strcasecmp(argv[i], "-v")) {
+ printf("pause.c %s\n", VERSION_STRING(VERSION));
+ return 0;
+ }
+ }
+
+ if (getpid() != 1)
+ /* Not an error because pause sees use outside of infra containers. */
+ fprintf(stderr, "Warning: pause should be the first process\n");
+
+ if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
+ return 1;
+ if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
+ return 2;
+ if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap,
+ .sa_flags = SA_NOCLDSTOP},
+ NULL) < 0)
+ return 3;
+
+ for (;;)
+ pause();
+ fprintf(stderr, "Error: infinite loop terminated\n");
+ return 42;
+}
diff --git a/pkg/api/handlers/libpod/pods.go b/pkg/api/handlers/libpod/pods.go
index 77d026550..1e64de0ee 100644
--- a/pkg/api/handlers/libpod/pods.go
+++ b/pkg/api/handlers/libpod/pods.go
@@ -1,15 +1,12 @@
package libpod
import (
- "context"
"encoding/json"
"fmt"
"net/http"
"strings"
- "github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
- "github.com/containers/image/v5/transports/alltransports"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/api/handlers"
@@ -67,20 +64,6 @@ func PodCreate(w http.ResponseWriter, r *http.Request) {
imageName = config.DefaultInfraImage
rawImageName = config.DefaultInfraImage
}
- curr := infraOptions.Quiet
- infraOptions.Quiet = true
- pullOptions := &libimage.PullOptions{}
- pulledImages, err := runtime.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, pullOptions)
- if err != nil {
- utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "could not pull image"))
- return
- }
- if _, err := alltransports.ParseImageName(imageName); err == nil {
- if len(pulledImages) != 0 {
- imageName = pulledImages[0].ID()
- }
- }
- infraOptions.Quiet = curr
psg.InfraImage = imageName
psg.InfraContainerSpec.Image = imageName
psg.InfraContainerSpec.RawImageName = rawImageName
diff --git a/pkg/api/handlers/libpod/volumes.go b/pkg/api/handlers/libpod/volumes.go
index 3ba39b860..ffdb30551 100644
--- a/pkg/api/handlers/libpod/volumes.go
+++ b/pkg/api/handlers/libpod/volumes.go
@@ -29,12 +29,13 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
}{
// override any golang type defaults
}
- input := entities.VolumeCreateOptions{}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
+
+ input := entities.VolumeCreateOptions{}
// decode params from body
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
@@ -47,9 +48,19 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
if len(input.Driver) > 0 {
volumeOptions = append(volumeOptions, libpod.WithVolumeDriver(input.Driver))
}
- if len(input.Label) > 0 {
- volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(input.Label))
+
+ // Label provided for compatibility.
+ labels := make(map[string]string, len(input.Label)+len(input.Labels))
+ for k, v := range input.Label {
+ labels[k] = v
}
+ for k, v := range input.Labels {
+ labels[k] = v
+ }
+ if len(labels) > 0 {
+ volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(labels))
+ }
+
if len(input.Options) > 0 {
parsedOptions, err := parse.VolumeOptions(input.Options)
if err != nil {
diff --git a/pkg/cgroups/cgroups.go b/pkg/cgroups/cgroups.go
index 1debc020c..d0c090012 100644
--- a/pkg/cgroups/cgroups.go
+++ b/pkg/cgroups/cgroups.go
@@ -464,7 +464,7 @@ func (c *CgroupControl) CreateSystemdUnit(path string) error {
// GetUserConnection returns a user connection to D-BUS
func GetUserConnection(uid int) (*systemdDbus.Conn, error) {
return systemdDbus.NewConnection(func() (*dbus.Conn, error) {
- return dbusAuthConnection(uid, dbus.SessionBusPrivate)
+ return dbusAuthConnection(uid, dbus.SessionBusPrivateNoAutoStartup)
})
}
diff --git a/pkg/domain/entities/pods.go b/pkg/domain/entities/pods.go
index a2f36eaa6..3d8579acf 100644
--- a/pkg/domain/entities/pods.go
+++ b/pkg/domain/entities/pods.go
@@ -5,6 +5,7 @@ import (
"strings"
"time"
+ commonFlag "github.com/containers/common/pkg/flag"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
@@ -241,7 +242,7 @@ type ContainerCreateOptions struct {
Sysctl []string
Systemd string
Timeout uint
- TLSVerify bool
+ TLSVerify commonFlag.OptionalBool
TmpFS []string
TTY bool
Timezone string
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
index 2ecfb4446..9b2a170e2 100644
--- a/pkg/domain/entities/volumes.go
+++ b/pkg/domain/entities/volumes.go
@@ -78,8 +78,10 @@ type VolumeCreateOptions struct {
Name string `schema:"name"`
// Volume driver to use
Driver string `schema:"driver"`
- // User-defined key/value metadata.
+ // User-defined key/value metadata. Provided for compatibility
Label map[string]string `schema:"label"`
+ // User-defined key/value metadata. Preferred field, will override Label
+ Labels map[string]string `schema:"labels"`
// Mapping of driver options and values.
Options map[string]string `schema:"opts"`
}
diff --git a/pkg/machine/ignition.go b/pkg/machine/ignition.go
index e211f5ea6..42d729458 100644
--- a/pkg/machine/ignition.go
+++ b/pkg/machine/ignition.go
@@ -304,6 +304,24 @@ machine_enabled=true
},
})
+ setDockerHost := `export DOCKER_HOST="unix://$(podman info -f "{{.Host.RemoteSocket.Path}}")"
+`
+
+ files = append(files, File{
+ Node: Node{
+ Group: getNodeGrp("root"),
+ Path: "/etc/profile.d/docker-host.sh",
+ User: getNodeUsr("root"),
+ },
+ FileEmbedded1: FileEmbedded1{
+ Append: nil,
+ Contents: Resource{
+ Source: encodeDataURLPtr(setDockerHost),
+ },
+ Mode: intToPtr(0644),
+ },
+ })
+
return files
}
diff --git a/pkg/specgen/generate/pod_create.go b/pkg/specgen/generate/pod_create.go
index a4027eae7..88ebc7ae3 100644
--- a/pkg/specgen/generate/pod_create.go
+++ b/pkg/specgen/generate/pod_create.go
@@ -2,8 +2,12 @@ package generate
import (
"context"
+ "fmt"
+ "io/ioutil"
"net"
+ "os"
+ buildahDefine "github.com/containers/buildah/define"
"github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
@@ -14,10 +18,102 @@ import (
"github.com/sirupsen/logrus"
)
+func buildPauseImage(rt *libpod.Runtime, rtConfig *config.Config) (string, error) {
+ version, err := define.GetVersion()
+ if err != nil {
+ return "", err
+ }
+ imageName := fmt.Sprintf("localhost/podman-pause:%s-%d", version.Version, version.Built)
+
+ // First check if the image has already been built.
+ if _, _, err := rt.LibimageRuntime().LookupImage(imageName, nil); err == nil {
+ return imageName, nil
+ }
+
+ // NOTE: Having the pause binary in its own directory keeps the door
+ // open for replacing the image building with using an overlay root FS.
+ // The latter turned out to be complex and error prone (see #11956) but
+ // we may be able to come up with a proper solution at a later point in
+ // time.
+ pausePath, err := rtConfig.FindHelperBinary("pause/pause", false)
+ if err != nil {
+ return "", fmt.Errorf("finding pause binary: %w", err)
+ }
+
+ buildContent := fmt.Sprintf(`FROM scratch
+COPY %s /pause
+ENTRYPOINT ["/pause"]`, pausePath)
+
+ tmpF, err := ioutil.TempFile("", "pause.containerfile")
+ if err != nil {
+ return "", err
+ }
+ if _, err := tmpF.WriteString(buildContent); err != nil {
+ return "", err
+ }
+ if err := tmpF.Close(); err != nil {
+ return "", err
+ }
+ defer os.Remove(tmpF.Name())
+
+ buildOptions := buildahDefine.BuildOptions{
+ CommonBuildOpts: &buildahDefine.CommonBuildOptions{},
+ Output: imageName,
+ Quiet: true,
+ IIDFile: "/dev/null", // prevents Buildah from writing the ID on stdout
+ }
+ if _, _, err := rt.Build(context.Background(), buildOptions, tmpF.Name()); err != nil {
+ return "", err
+ }
+
+ return imageName, nil
+}
+
+func pullOrBuildInfraImage(p *entities.PodSpec, rt *libpod.Runtime) error {
+ if p.PodSpecGen.NoInfra {
+ return nil
+ }
+
+ rtConfig, err := rt.GetConfigNoCopy()
+ if err != nil {
+ return err
+ }
+
+ // NOTE: we need pull down the infra image if it was explicitly set by
+ // the user (or containers.conf) to the non-default one.
+ imageName := p.PodSpecGen.InfraImage
+ if imageName == "" {
+ imageName = rtConfig.Engine.InfraImage
+ }
+
+ if imageName != config.DefaultInfraImage {
+ _, err := rt.LibimageRuntime().Pull(context.Background(), imageName, config.PullPolicyMissing, nil)
+ if err != nil {
+ return err
+ }
+ } else {
+ name, err := buildPauseImage(rt, rtConfig)
+ if err != nil {
+ return fmt.Errorf("building local pause image: %w", err)
+ }
+ imageName = name
+ }
+
+ p.PodSpecGen.InfraImage = imageName
+ p.PodSpecGen.InfraContainerSpec.RawImageName = imageName
+
+ return nil
+}
+
func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
if err := p.PodSpecGen.Validate(); err != nil {
return nil, err
}
+
+ if err := pullOrBuildInfraImage(p, rt); err != nil {
+ return nil, err
+ }
+
if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil {
var err error
p.PodSpecGen.InfraContainerSpec, err = MapSpec(&p.PodSpecGen)
@@ -35,7 +131,6 @@ func MakePod(p *entities.PodSpec, rt *libpod.Runtime) (*libpod.Pod, error) {
return nil, err
}
if !p.PodSpecGen.NoInfra && p.PodSpecGen.InfraContainerSpec != nil {
- p.PodSpecGen.InfraContainerSpec.ContainerCreateCommand = []string{} // we do NOT want os.Args as the command, will display the pod create cmd
if p.PodSpecGen.InfraContainerSpec.Name == "" {
p.PodSpecGen.InfraContainerSpec.Name = pod.ID()[:12] + "-infra"
}
diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go
index 3fde1a1b4..30248a886 100644
--- a/pkg/specgen/generate/storage.go
+++ b/pkg/specgen/generate/storage.go
@@ -214,9 +214,6 @@ func getImageVolumes(ctx context.Context, img *libimage.Image, s *specgen.SpecGe
}
for volume := range inspect.Config.Volumes {
logrus.Debugf("Image has volume at %q", volume)
- if err = parse.ValidateVolumeCtrDir(volume); err != nil {
- return nil, nil, err
- }
cleanDest := filepath.Clean(volume)
switch mode {
case "", "anonymous":
diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index 3ce96164f..184bfadf8 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -360,7 +360,7 @@ func getBindMount(args []string) (spec.Mount, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, kv[0])
+ return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
}
}
@@ -460,7 +460,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, kv[0])
+ return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
}
}
@@ -483,6 +483,8 @@ func getDevptsMount(args []string) (spec.Mount, error) {
for _, val := range args {
kv := strings.SplitN(val, "=", 2)
switch kv[0] {
+ case "uid", "gid", "mode", "ptxmode", "newinstance", "max":
+ newMount.Options = append(newMount.Options, val)
case "target", "dst", "destination":
if len(kv) == 1 {
return newMount, errors.Wrapf(optionArgError, kv[0])
@@ -493,7 +495,7 @@ func getDevptsMount(args []string) (spec.Mount, error) {
newMount.Destination = filepath.Clean(kv[1])
setDest = true
default:
- return newMount, errors.Wrapf(util.ErrBadMntOption, kv[0])
+ return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
}
}
@@ -573,7 +575,7 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return nil, errors.Wrapf(util.ErrBadMntOption, kv[0])
+ return nil, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
}
}
@@ -624,7 +626,7 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) {
// Since Docker ignores this option so shall we.
continue
default:
- return nil, errors.Wrapf(util.ErrBadMntOption, kv[0])
+ return nil, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0])
}
}
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_volume.py b/test/apiv2/python/rest_api/test_v2_0_0_volume.py
index f5231e17c..2156318b0 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_volume.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_volume.py
@@ -7,7 +7,7 @@ from .fixtures import APITestCase
class VolumeTestCase(APITestCase):
- def test_volume(self):
+ def test_volume_crud(self):
name = f"Volume_{random.getrandbits(160):x}"
ls = requests.get(self.podman_url + "/v1.40/volumes")
@@ -70,6 +70,71 @@ class VolumeTestCase(APITestCase):
self.assertIn(name, payload["VolumesDeleted"])
self.assertGreater(payload["SpaceReclaimed"], 0)
+ def test_volume_label(self):
+ name = f"Volume_{random.getrandbits(160):x}"
+ expected = {
+ "Production": "False",
+ "Database": "Foxbase",
+ }
+
+ create = requests.post(
+ self.podman_url + "/v4.0.0/libpod/volumes/create",
+ json={"name": name, "label": expected},
+ )
+ self.assertEqual(create.status_code, 201, create.text)
+
+ inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
+ self.assertEqual(inspect.status_code, 200, inspect.text)
+
+ volume = inspect.json()
+ self.assertIn("Labels", volume)
+ self.assertNotIn("Label", volume)
+ self.assertDictEqual(expected, volume["Labels"])
+
+ def test_volume_labels(self):
+ name = f"Volume_{random.getrandbits(160):x}"
+ expected = {
+ "Production": "False",
+ "Database": "Foxbase",
+ }
+
+ create = requests.post(
+ self.podman_url + "/v4.0.0/libpod/volumes/create",
+ json={"name": name, "labels": expected},
+ )
+ self.assertEqual(create.status_code, 201, create.text)
+
+ inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
+ self.assertEqual(inspect.status_code, 200, inspect.text)
+
+ volume = inspect.json()
+ self.assertIn("Labels", volume)
+ self.assertDictEqual(expected, volume["Labels"])
+
+ def test_volume_label_override(self):
+ name = f"Volume_{random.getrandbits(160):x}"
+ create = requests.post(
+ self.podman_url + "/v4.0.0/libpod/volumes/create",
+ json={
+ "Name": name,
+ "Label": {
+ "Database": "dbase",
+ },
+ "Labels": {
+ "Database": "sqlserver",
+ },
+ },
+ )
+ self.assertEqual(create.status_code, 201, create.text)
+
+ inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
+ self.assertEqual(inspect.status_code, 200, inspect.text)
+
+ volume = inspect.json()
+ self.assertIn("Labels", volume)
+ self.assertNotIn("Label", volume)
+ self.assertDictEqual({"Database": "sqlserver"}, volume["Labels"])
+
if __name__ == "__main__":
unittest.main()
diff --git a/test/e2e/logs_test.go b/test/e2e/logs_test.go
index 314e09b9a..3beabec4b 100644
--- a/test/e2e/logs_test.go
+++ b/test/e2e/logs_test.go
@@ -13,6 +13,19 @@ import (
. "github.com/onsi/gomega/gexec"
)
+func isEventBackendJournald(podmanTest *PodmanTestIntegration) bool {
+ if !podmanTest.RemoteTest {
+ // If not remote test, '--events-backend' is set to 'file' or 'none'
+ return false
+ }
+ info := podmanTest.Podman([]string{"info", "--format", "{{.Host.EventLogger}}"})
+ info.WaitWithDefaultTimeout()
+ if info.OutputToString() == "journald" {
+ return true
+ }
+ return false
+}
+
var _ = Describe("Podman logs", func() {
var (
tempdir string
@@ -38,8 +51,18 @@ var _ = Describe("Podman logs", func() {
})
for _, log := range []string{"k8s-file", "journald", "json-file"} {
+ // This is important to move the 'log' var to the correct scope under Ginkgo flow.
+ log := log
+
+ skipIfJournaldInContainer := func() {
+ if log == "journald" {
+ SkipIfInContainer("journalctl inside a container doesn't work correctly")
+ }
+ }
It("all lines: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -53,6 +76,8 @@ var _ = Describe("Podman logs", func() {
})
It("tail two lines: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -65,6 +90,8 @@ var _ = Describe("Podman logs", func() {
})
It("tail zero lines: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -77,6 +104,8 @@ var _ = Describe("Podman logs", func() {
})
It("tail 99 lines: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -89,6 +118,8 @@ var _ = Describe("Podman logs", func() {
})
It("tail 800 lines: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "i=1; while [ \"$i\" -ne 1000 ]; do echo \"line $i\"; i=$((i + 1)); done"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -101,6 +132,8 @@ var _ = Describe("Podman logs", func() {
})
It("tail 2 lines with timestamps: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -113,6 +146,8 @@ var _ = Describe("Podman logs", func() {
})
It("since time 2017-08-07: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -125,6 +160,8 @@ var _ = Describe("Podman logs", func() {
})
It("since duration 10m: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -137,6 +174,8 @@ var _ = Describe("Podman logs", func() {
})
It("until duration 10m: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -149,6 +188,7 @@ var _ = Describe("Podman logs", func() {
})
It("until time NOW: "+log, func() {
+ skipIfJournaldInContainer()
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
logc.WaitWithDefaultTimeout()
@@ -165,13 +205,17 @@ var _ = Describe("Podman logs", func() {
})
It("latest and container name should fail: "+log, func() {
+ skipIfJournaldInContainer()
+
results := podmanTest.Podman([]string{"logs", "-l", "foobar"})
results.WaitWithDefaultTimeout()
Expect(results).To(ExitWithError())
})
It("two containers showing short container IDs: "+log, func() {
+ skipIfJournaldInContainer()
SkipIfRemote("FIXME: podman-remote logs does not support showing two containers at the same time")
+
log1 := podmanTest.Podman([]string{"run", "--log-driver", log, "-dt", ALPINE, "sh", "-c", "echo podman; echo podman; echo podman"})
log1.WaitWithDefaultTimeout()
Expect(log1).Should(Exit(0))
@@ -192,6 +236,8 @@ var _ = Describe("Podman logs", func() {
})
It("podman logs on a created container should result in 0 exit code: "+log, func() {
+ skipIfJournaldInContainer()
+
session := podmanTest.Podman([]string{"create", "--log-driver", log, "-t", "--name", "log", ALPINE})
session.WaitWithDefaultTimeout()
Expect(session).To(Exit(0))
@@ -202,6 +248,8 @@ var _ = Describe("Podman logs", func() {
})
It("streaming output: "+log, func() {
+ skipIfJournaldInContainer()
+
containerName := "logs-f"
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", containerName, "-dt", ALPINE, "sh", "-c", "echo podman-1; sleep 1; echo podman-2"})
@@ -210,6 +258,14 @@ var _ = Describe("Podman logs", func() {
results := podmanTest.Podman([]string{"logs", "-f", containerName})
results.WaitWithDefaultTimeout()
+
+ if log == "journald" && !isEventBackendJournald(podmanTest) {
+ // --follow + journald log-driver is only supported with journald events-backend(PR #10431)
+ Expect(results).To(Exit(125))
+ Expect(results.ErrorToString()).To(ContainSubstring("using --follow with the journald --log-driver but without the journald --events-backend"))
+ return
+ }
+
Expect(results).To(Exit(0))
Expect(results.OutputToString()).To(ContainSubstring("podman-1"))
@@ -233,6 +289,8 @@ var _ = Describe("Podman logs", func() {
})
It("follow output stopped container: "+log, func() {
+ skipIfJournaldInContainer()
+
containerName := "logs-f"
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", containerName, "-d", ALPINE, "true"})
@@ -241,10 +299,17 @@ var _ = Describe("Podman logs", func() {
results := podmanTest.Podman([]string{"logs", "-f", containerName})
results.WaitWithDefaultTimeout()
+ if log == "journald" && !isEventBackendJournald(podmanTest) {
+ // --follow + journald log-driver is only supported with journald events-backend(PR #10431)
+ Expect(results).To(Exit(125))
+ return
+ }
Expect(results).To(Exit(0))
})
It("using container with container log-size: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--log-opt=max-size=10k", "-d", ALPINE, "sh", "-c", "echo podman podman podman"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -266,6 +331,8 @@ var _ = Describe("Podman logs", func() {
})
It("Make sure logs match expected length: "+log, func() {
+ skipIfJournaldInContainer()
+
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "-t", "--name", "test", ALPINE, "sh", "-c", "echo 1; echo 2"})
logc.WaitWithDefaultTimeout()
Expect(logc).To(Exit(0))
@@ -284,6 +351,8 @@ var _ = Describe("Podman logs", func() {
})
It("podman logs test stdout and stderr: "+log, func() {
+ skipIfJournaldInContainer()
+
cname := "log-test"
logc := podmanTest.Podman([]string{"run", "--log-driver", log, "--name", cname, ALPINE, "sh", "-c", "echo stdout; echo stderr >&2"})
logc.WaitWithDefaultTimeout()
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index d5b913743..b0b927445 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -11,7 +11,6 @@ import (
"text/template"
"time"
- "github.com/containers/common/pkg/config"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/util"
. "github.com/containers/podman/v3/test/utils"
@@ -1120,24 +1119,6 @@ var _ = Describe("Podman play kube", func() {
Expect(label).To(ContainSubstring("unconfined_u:system_r:spc_t:s0"))
})
- It("podman play kube should use default infra_image", func() {
- err := writeYaml(checkInfraImagePodYaml, kubeYaml)
- Expect(err).To(BeNil())
-
- kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
- kube.WaitWithDefaultTimeout()
- Expect(kube).Should(Exit(0))
-
- podInspect := podmanTest.Podman([]string{"inspect", "check-infra-image", "--format", "{{ .InfraContainerID }}"})
- podInspect.WaitWithDefaultTimeout()
- infraContainerID := podInspect.OutputToString()
-
- conInspect := podmanTest.Podman([]string{"inspect", infraContainerID, "--format", "{{ .ImageName }}"})
- conInspect.WaitWithDefaultTimeout()
- infraContainerImage := conInspect.OutputToString()
- Expect(infraContainerImage).To(Equal(config.DefaultInfraImage))
- })
-
It("podman play kube --no-host", func() {
err := writeYaml(checkInfraImagePodYaml, kubeYaml)
Expect(err).To(BeNil())
diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go
index b7e8309fb..7b35acd35 100644
--- a/test/e2e/push_test.go
+++ b/test/e2e/push_test.go
@@ -146,7 +146,7 @@ var _ = Describe("Podman push", func() {
session = podmanTest.Podman([]string{"logs", "registry"})
session.WaitWithDefaultTimeout()
- push := podmanTest.Podman([]string{"push", "--format=v2s2", "--creds=podmantest:test", ALPINE, "localhost:5000/tlstest"})
+ push := podmanTest.Podman([]string{"push", "--tls-verify=true", "--format=v2s2", "--creds=podmantest:test", ALPINE, "localhost:5000/tlstest"})
push.WaitWithDefaultTimeout()
Expect(push).To(ExitWithError())
@@ -163,7 +163,7 @@ var _ = Describe("Podman push", func() {
if !IsRemote() {
// remote does not support --cert-dir
- push = podmanTest.Podman([]string{"push", "--creds=podmantest:test", "--cert-dir=fakedir", ALPINE, "localhost:5000/certdirtest"})
+ push = podmanTest.Podman([]string{"push", "--tls-verify=true", "--creds=podmantest:test", "--cert-dir=fakedir", ALPINE, "localhost:5000/certdirtest"})
push.WaitWithDefaultTimeout()
Expect(push).To(ExitWithError())
}
diff --git a/test/e2e/run_networking_test.go b/test/e2e/run_networking_test.go
index ca242a17c..bdf3ce5d6 100644
--- a/test/e2e/run_networking_test.go
+++ b/test/e2e/run_networking_test.go
@@ -357,6 +357,26 @@ var _ = Describe("Podman run networking", func() {
Expect(ncBusy).To(ExitWithError())
})
+ It("podman run slirp4netns verify net.ipv6.conf.default.accept_dad=0", func() {
+ session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:enable_ipv6=true", ALPINE, "ip", "addr"})
+ session.Wait(30)
+ Expect(session).Should(Exit(0))
+ // check the ipv6 setup id done without delay (https://github.com/containers/podman/issues/11062)
+ Expect(session.OutputToString()).To(ContainSubstring("inet6 fd00::"))
+
+ const ipv6ConfDefaultAcceptDadSysctl = "/proc/sys/net/ipv6/conf/all/accept_dad"
+
+ cat := SystemExec("cat", []string{ipv6ConfDefaultAcceptDadSysctl})
+ cat.Wait(30)
+ Expect(cat).Should(Exit(0))
+ sysctlValue := cat.OutputToString()
+
+ session = podmanTest.Podman([]string{"run", "--network", "slirp4netns:enable_ipv6=true", ALPINE, "cat", ipv6ConfDefaultAcceptDadSysctl})
+ session.Wait(30)
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(Equal(sysctlValue))
+ })
+
It("podman run network expose host port 18082 to container port 8000 using slirp4netns port handler", func() {
session := podmanTest.Podman([]string{"run", "--network", "slirp4netns:port_handler=slirp4netns", "-dt", "-p", "18082:8000", ALPINE, "/bin/sh"})
session.Wait(30)
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 8502879ff..95660bfc9 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -188,6 +188,12 @@ var _ = Describe("Podman run", func() {
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))
Expect(podmanTest.NumberOfContainers()).To(Equal(3))
+
+ // Now registries.conf will be consulted where localhost:5000
+ // is set to be insecure.
+ run = podmanTest.Podman([]string{"run", ALPINE})
+ run.WaitWithDefaultTimeout()
+ Expect(run).Should(Exit(0))
})
It("podman run a container with a --rootfs", func() {
@@ -1192,6 +1198,14 @@ USER mail`, BB)
Expect(session.OutputToString()).To(ContainSubstring("devpts"))
})
+ It("podman run --mount type=devpts,target=/dev/pts with uid, gid and mode", func() {
+ // runc doesn't seem to honor uid= so avoid testing it
+ session := podmanTest.Podman([]string{"run", "-t", "--mount", "type=devpts,target=/dev/pts,uid=1000,gid=1001,mode=123", fedoraMinimal, "stat", "-c%g-%a", "/dev/pts/0"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("1001-123"))
+ })
+
It("podman run --pod automatically", func() {
session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8686"})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/system_reset_test.go b/test/e2e/system_reset_test.go
index 102526a46..93ab166cd 100644
--- a/test/e2e/system_reset_test.go
+++ b/test/e2e/system_reset_test.go
@@ -60,6 +60,8 @@ var _ = Describe("podman system reset", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
+ Expect(session.ErrorToString()).To(Not(ContainSubstring("Failed to add pause process")))
+
// If remote then the API service should have exited
// On local tests this is a noop
podmanTest.StartRemoteService()
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index a1b25b723..98def3d8f 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -4,7 +4,6 @@ import (
"io/ioutil"
"os"
"strings"
- "time"
. "github.com/containers/podman/v3/test/utils"
. "github.com/onsi/ginkgo"
@@ -82,27 +81,13 @@ WantedBy=multi-user.target
run := podmanTest.Podman([]string{"run", "--name", ctrName, "-t", "-i", "-d", ubi_init, "/sbin/init"})
run.WaitWithDefaultTimeout()
Expect(run).Should(Exit(0))
- ctrID := run.OutputToString()
logs := podmanTest.Podman([]string{"logs", ctrName})
logs.WaitWithDefaultTimeout()
Expect(logs).Should(Exit(0))
// Give container 10 seconds to start
- started := false
- for i := 0; i < 10; i++ {
- runningCtrs := podmanTest.Podman([]string{"ps", "-q", "--no-trunc"})
- runningCtrs.WaitWithDefaultTimeout()
- Expect(runningCtrs).Should(Exit(0))
-
- if strings.Contains(runningCtrs.OutputToString(), ctrID) {
- started = true
- break
- }
-
- time.Sleep(1 * time.Second)
- }
-
+ started := podmanTest.WaitContainerReady(ctrName, "Reached target Multi-User System.", 30, 1)
Expect(started).To(BeTrue())
systemctl := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "systemctl", "status", "--no-pager"})
diff --git a/test/registries.conf b/test/registries.conf
index 0559c9e52..8e4671760 100644
--- a/test/registries.conf
+++ b/test/registries.conf
@@ -15,3 +15,9 @@ location="mirror.gcr.io"
[[registry]]
prefix="docker.io/library"
location="quay.io/libpod"
+
+# For testing #11933 to make sure that registries.conf is consulted unless
+# --tls-verify is used during container creation.
+[[registry]]
+location="localhost:5000"
+insecure=true
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index d3dc14d81..1d24eef15 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -39,6 +39,7 @@ EOF
cat >$dockerfile <<EOF
FROM $IMAGE
RUN echo $rand_content > /$rand_filename
+VOLUME ['/etc/foo', '/etc/bar']
EOF
run_podman buildx build --load -t build_test --format=docker $tmpdir
@@ -47,6 +48,14 @@ EOF
run_podman run --rm build_test cat /$rand_filename
is "$output" "$rand_content" "reading generated file in image"
+ # Make sure the volumes are created at surprising yet Docker-compatible
+ # destinations (see bugzilla.redhat.com/show_bug.cgi?id=2014149).
+ run_podman run --rm build_test find /[ /etc/bar\] -print
+ is "$output" "/\[
+/\[/etc
+/\[/etc/foo,
+/etc/bar]" "weird VOLUME gets converted to directories with brackets and comma"
+
run_podman rmi -f build_test
}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index 86f3610ab..09a419914 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -60,6 +60,10 @@ function teardown() {
run_podman pod rm -f -t 0 $podid
}
+function rm_podman_pause_image() {
+ run_podman version --format "{{.Server.Version}}-{{.Server.Built}}"
+ run_podman rmi -f "localhost/podman-pause:$output"
+}
@test "podman pod - communicating between pods" {
podname=pod$(random_string)
@@ -100,19 +104,14 @@ function teardown() {
# Clean up. First the nc -l container...
run_podman rm $cid1
- # ...then, from pause container, find the image ID of the pause image...
- run_podman pod inspect --format '{{(index .Containers 0).ID}}' $podname
- pause_cid="$output"
- run_podman container inspect --format '{{.Image}}' $pause_cid
- pause_iid="$output"
-
# ...then rm the pod, then rmi the pause image so we don't leave strays.
run_podman pod rm $podname
- run_podman rmi $pause_iid
# Pod no longer exists
run_podman 1 pod exists $podid
run_podman 1 pod exists $podname
+
+ rm_podman_pause_image
}
@test "podman pod - communicating via /dev/shm " {
@@ -133,6 +132,10 @@ function teardown() {
# Pod no longer exists
run_podman 1 pod exists $podid
run_podman 1 pod exists $podname
+
+ # Pause image hasn't been pulled
+ run_podman 1 image exists k8s.gcr.io/pause:3.5
+ rm_podman_pause_image
}
# Random byte
@@ -303,16 +306,25 @@ EOF
run_podman rm $cid
run_podman pod rm -t 0 -f mypod
run_podman rmi $infra_image
-
}
@test "podman pod create should fail when infra-name is already in use" {
local infra_name="infra_container_$(random_string 10 | tr A-Z a-z)"
- run_podman pod create --infra-name "$infra_name"
+ local pod_name="$(random_string 10 | tr A-Z a-z)"
+
+ # Note that the internal pause image is built even when --infra-image is
+ # set to the K8s one.
+ run_podman pod create --name $pod_name --infra-name "$infra_name" --infra-image "k8s.gcr.io/pause:3.5"
run_podman '?' pod create --infra-name "$infra_name"
if [ $status -eq 0 ]; then
die "Podman should fail when user try to create two pods with the same infra-name value"
fi
+ run_podman pod rm -f $pod_name
+ run_podman images -a
+
+ # Pause image hasn't been pulled
+ run_podman 1 image exists k8s.gcr.io/pause:3.5
+ rm_podman_pause_image
}
# vim: filetype=sh
diff --git a/utils/utils.go b/utils/utils.go
index b08630d2f..109ae088b 100644
--- a/utils/utils.go
+++ b/utils/utils.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/storage/pkg/archive"
+ "github.com/godbus/dbus/v5"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
@@ -177,13 +178,26 @@ func RunsOnSystemd() bool {
func moveProcessToScope(pidPath, slice, scope string) error {
data, err := ioutil.ReadFile(pidPath)
if err != nil {
+ // do not raise an error if the file doesn't exist
+ if os.IsNotExist(err) {
+ return nil
+ }
return errors.Wrapf(err, "cannot read pid file %s", pidPath)
}
pid, err := strconv.ParseUint(string(data), 10, 0)
if err != nil {
return errors.Wrapf(err, "cannot parse pid file %s", pidPath)
}
- return RunUnderSystemdScope(int(pid), slice, scope)
+ err = RunUnderSystemdScope(int(pid), slice, scope)
+
+ // If the PID is not valid anymore, do not return an error.
+ if dbusErr, ok := err.(dbus.Error); ok {
+ if dbusErr.Name == "org.freedesktop.DBus.Error.UnixProcessIdUnknown" {
+ return nil
+ }
+ }
+
+ return err
}
// MovePauseProcessToScope moves the pause process used for rootless mode to keep the namespaces alive to
@@ -191,8 +205,8 @@ func moveProcessToScope(pidPath, slice, scope string) error {
func MovePauseProcessToScope(pausePidPath string) {
err := moveProcessToScope(pausePidPath, "user.slice", "podman-pause.scope")
if err != nil {
- unified, err := cgroups.IsCgroup2UnifiedMode()
- if err != nil {
+ unified, err2 := cgroups.IsCgroup2UnifiedMode()
+ if err2 != nil {
logrus.Warnf("Failed to detect if running with cgroup unified: %v", err)
}
if RunsOnSystemd() && unified {
diff --git a/vendor/github.com/containers/common/libimage/filters.go b/vendor/github.com/containers/common/libimage/filters.go
index 833f940cc..521af5d06 100644
--- a/vendor/github.com/containers/common/libimage/filters.go
+++ b/vendor/github.com/containers/common/libimage/filters.go
@@ -50,6 +50,18 @@ func filterImages(images []*Image, filters []filterFunc) ([]*Image, error) {
func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOptions) ([]filterFunc, error) {
logrus.Tracef("Parsing image filters %s", options.Filters)
+ var tree *layerTree
+ getTree := func() (*layerTree, error) {
+ if tree == nil {
+ t, err := r.layerTree()
+ if err != nil {
+ return nil, err
+ }
+ tree = t
+ }
+ return tree, nil
+ }
+
filterFuncs := []filterFunc{}
for _, filter := range options.Filters {
var key, value string
@@ -93,7 +105,11 @@ func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOp
if err != nil {
return nil, errors.Wrapf(err, "non-boolean value %q for dangling filter", value)
}
- filterFuncs = append(filterFuncs, filterDangling(ctx, dangling))
+ t, err := getTree()
+ if err != nil {
+ return nil, err
+ }
+ filterFuncs = append(filterFuncs, filterDangling(ctx, dangling, t))
case "id":
filterFuncs = append(filterFuncs, filterID(value))
@@ -103,7 +119,11 @@ func (r *Runtime) compileImageFilters(ctx context.Context, options *ListImagesOp
if err != nil {
return nil, errors.Wrapf(err, "non-boolean value %q for intermediate filter", value)
}
- filterFuncs = append(filterFuncs, filterIntermediate(ctx, intermediate))
+ t, err := getTree()
+ if err != nil {
+ return nil, err
+ }
+ filterFuncs = append(filterFuncs, filterIntermediate(ctx, intermediate, t))
case "label":
filterFuncs = append(filterFuncs, filterLabel(ctx, value))
@@ -221,9 +241,9 @@ func filterContainers(value string, fn IsExternalContainerFunc) filterFunc {
}
// filterDangling creates a dangling filter for matching the specified value.
-func filterDangling(ctx context.Context, value bool) filterFunc {
+func filterDangling(ctx context.Context, value bool, tree *layerTree) filterFunc {
return func(img *Image) (bool, error) {
- isDangling, err := img.IsDangling(ctx)
+ isDangling, err := img.isDangling(ctx, tree)
if err != nil {
return false, err
}
@@ -241,9 +261,9 @@ func filterID(value string) filterFunc {
// filterIntermediate creates an intermediate filter for images. An image is
// considered to be an intermediate image if it is dangling (i.e., no tags) and
// has no children (i.e., no other image depends on it).
-func filterIntermediate(ctx context.Context, value bool) filterFunc {
+func filterIntermediate(ctx context.Context, value bool, tree *layerTree) filterFunc {
return func(img *Image) (bool, error) {
- isIntermediate, err := img.IsIntermediate(ctx)
+ isIntermediate, err := img.isIntermediate(ctx, tree)
if err != nil {
return false, err
}
diff --git a/vendor/github.com/containers/common/libimage/image.go b/vendor/github.com/containers/common/libimage/image.go
index 00a2d620e..bf3310da2 100644
--- a/vendor/github.com/containers/common/libimage/image.go
+++ b/vendor/github.com/containers/common/libimage/image.go
@@ -128,10 +128,16 @@ func (i *Image) IsReadOnly() bool {
// IsDangling returns true if the image is dangling, that is an untagged image
// without children.
func (i *Image) IsDangling(ctx context.Context) (bool, error) {
+ return i.isDangling(ctx, nil)
+}
+
+// isDangling returns true if the image is dangling, that is an untagged image
+// without children. If tree is nil, it will created for this invocation only.
+func (i *Image) isDangling(ctx context.Context, tree *layerTree) (bool, error) {
if len(i.Names()) > 0 {
return false, nil
}
- children, err := i.getChildren(ctx, false)
+ children, err := i.getChildren(ctx, false, tree)
if err != nil {
return false, err
}
@@ -141,10 +147,17 @@ func (i *Image) IsDangling(ctx context.Context) (bool, error) {
// IsIntermediate returns true if the image is an intermediate image, that is
// an untagged image with children.
func (i *Image) IsIntermediate(ctx context.Context) (bool, error) {
+ return i.isIntermediate(ctx, nil)
+}
+
+// isIntermediate returns true if the image is an intermediate image, that is
+// an untagged image with children. If tree is nil, it will created for this
+// invocation only.
+func (i *Image) isIntermediate(ctx context.Context, tree *layerTree) (bool, error) {
if len(i.Names()) > 0 {
return false, nil
}
- children, err := i.getChildren(ctx, false)
+ children, err := i.getChildren(ctx, false, tree)
if err != nil {
return false, err
}
@@ -189,7 +202,7 @@ func (i *Image) Parent(ctx context.Context) (*Image, error) {
// HasChildren returns indicates if the image has children.
func (i *Image) HasChildren(ctx context.Context) (bool, error) {
- children, err := i.getChildren(ctx, false)
+ children, err := i.getChildren(ctx, false, nil)
if err != nil {
return false, err
}
@@ -198,7 +211,7 @@ func (i *Image) HasChildren(ctx context.Context) (bool, error) {
// Children returns the image's children.
func (i *Image) Children(ctx context.Context) ([]*Image, error) {
- children, err := i.getChildren(ctx, true)
+ children, err := i.getChildren(ctx, true, nil)
if err != nil {
return nil, err
}
@@ -206,13 +219,16 @@ func (i *Image) Children(ctx context.Context) ([]*Image, error) {
}
// getChildren returns a list of imageIDs that depend on the image. If all is
-// false, only the first child image is returned.
-func (i *Image) getChildren(ctx context.Context, all bool) ([]*Image, error) {
- tree, err := i.runtime.layerTree()
- if err != nil {
- return nil, err
+// false, only the first child image is returned. If tree is nil, it will be
+// created for this invocation only.
+func (i *Image) getChildren(ctx context.Context, all bool, tree *layerTree) ([]*Image, error) {
+ if tree == nil {
+ t, err := i.runtime.layerTree()
+ if err != nil {
+ return nil, err
+ }
+ tree = t
}
-
return tree.children(ctx, i, all)
}
diff --git a/vendor/github.com/containers/common/libimage/search.go b/vendor/github.com/containers/common/libimage/search.go
index 7e20e4331..ece81531a 100644
--- a/vendor/github.com/containers/common/libimage/search.go
+++ b/vendor/github.com/containers/common/libimage/search.go
@@ -244,7 +244,7 @@ func (r *Runtime) searchImageInRegistry(ctx context.Context, term, registry stri
name = index + "/library/" + results[i].Name
}
params := SearchResult{
- Index: index,
+ Index: registry,
Name: name,
Description: description,
Official: official,
diff --git a/vendor/github.com/containers/common/pkg/config/config.go b/vendor/github.com/containers/common/pkg/config/config.go
index d5be77edd..45230703d 100644
--- a/vendor/github.com/containers/common/pkg/config/config.go
+++ b/vendor/github.com/containers/common/pkg/config/config.go
@@ -574,7 +574,7 @@ func readConfigFromFile(path string, config *Config) error {
}
keys := meta.Undecoded()
if len(keys) > 0 {
- logrus.Warningf("Failed to decode the keys %q from %q.", keys, path)
+ logrus.Debugf("Failed to decode the keys %q from %q.", keys, path)
}
return nil
diff --git a/vendor/github.com/containers/common/pkg/flag/flag.go b/vendor/github.com/containers/common/pkg/flag/flag.go
new file mode 100644
index 000000000..52eb50da0
--- /dev/null
+++ b/vendor/github.com/containers/common/pkg/flag/flag.go
@@ -0,0 +1,174 @@
+package flag
+
+import (
+ "strconv"
+
+ "github.com/spf13/pflag"
+)
+
+// OptionalBool is a boolean with a separate presence flag and value.
+type OptionalBool struct {
+ present bool
+ value bool
+}
+
+// Present returns the bool's presence flag.
+func (ob *OptionalBool) Present() bool {
+ return ob.present
+}
+
+// Present returns the bool's value. Should only be used if Present() is true.
+func (ob *OptionalBool) Value() bool {
+ return ob.value
+}
+
+// optionalBool is a cli.Generic == flag.Value implementation equivalent to
+// the one underlying flag.Bool, except that it records whether the flag has been set.
+// This is distinct from optionalBool to (pretend to) force callers to use
+// optionalBoolFlag
+type optionalBoolValue OptionalBool
+
+// OptionalBoolFlag creates new flag for an optional in the specified flag with
+// the specified name and usage.
+func OptionalBoolFlag(fs *pflag.FlagSet, p *OptionalBool, name, usage string) *pflag.Flag {
+ flag := fs.VarPF(internalNewOptionalBoolValue(p), name, "", usage)
+ flag.NoOptDefVal = "true"
+ flag.DefValue = "false"
+ return flag
+}
+
+// WARNING: Do not directly use this method to define optionalBool flag.
+// Caller should use optionalBoolFlag
+func internalNewOptionalBoolValue(p *OptionalBool) pflag.Value {
+ p.present = false
+ return (*optionalBoolValue)(p)
+}
+
+// Set parses the string to a bool and sets it.
+func (ob *optionalBoolValue) Set(s string) error {
+ v, err := strconv.ParseBool(s)
+ if err != nil {
+ return err
+ }
+ ob.value = v
+ ob.present = true
+ return nil
+}
+
+// String returns the string representation of the string.
+func (ob *optionalBoolValue) String() string {
+ if !ob.present {
+ return "" // This is, sadly, not round-trip safe: --flag is interpreted as --flag=true
+ }
+ return strconv.FormatBool(ob.value)
+}
+
+// Type returns the type.
+func (ob *optionalBoolValue) Type() string {
+ return "bool"
+}
+
+// IsBoolFlag indicates that it's a bool flag.
+func (ob *optionalBoolValue) IsBoolFlag() bool {
+ return true
+}
+
+// OptionalString is a string with a separate presence flag.
+type OptionalString struct {
+ present bool
+ value string
+}
+
+// Present returns the strings's presence flag.
+func (os *OptionalString) Present() bool {
+ return os.present
+}
+
+// Present returns the string's value. Should only be used if Present() is true.
+func (os *OptionalString) Value() string {
+ return os.value
+}
+
+// optionalString is a cli.Generic == flag.Value implementation equivalent to
+// the one underlying flag.String, except that it records whether the flag has been set.
+// This is distinct from optionalString to (pretend to) force callers to use
+// newoptionalString
+type optionalStringValue OptionalString
+
+// NewOptionalStringValue returns a pflag.Value fo the string.
+func NewOptionalStringValue(p *OptionalString) pflag.Value {
+ p.present = false
+ return (*optionalStringValue)(p)
+}
+
+// Set sets the string.
+func (ob *optionalStringValue) Set(s string) error {
+ ob.value = s
+ ob.present = true
+ return nil
+}
+
+// String returns the string if present.
+func (ob *optionalStringValue) String() string {
+ if !ob.present {
+ return "" // This is, sadly, not round-trip safe: --flag= is interpreted as {present:true, value:""}
+ }
+ return ob.value
+}
+
+// Type returns the string type.
+func (ob *optionalStringValue) Type() string {
+ return "string"
+}
+
+// OptionalInt is a int with a separate presence flag.
+type OptionalInt struct {
+ present bool
+ value int
+}
+
+// Present returns the int's presence flag.
+func (oi *OptionalInt) Present() bool {
+ return oi.present
+}
+
+// Present returns the int's value. Should only be used if Present() is true.
+func (oi *OptionalInt) Value() int {
+ return oi.value
+}
+
+// optionalInt is a cli.Generic == flag.Value implementation equivalent to
+// the one underlying flag.Int, except that it records whether the flag has been set.
+// This is distinct from optionalInt to (pretend to) force callers to use
+// newoptionalIntValue
+type optionalIntValue OptionalInt
+
+// NewOptionalIntValue returns the pflag.Value of the int.
+func NewOptionalIntValue(p *OptionalInt) pflag.Value {
+ p.present = false
+ return (*optionalIntValue)(p)
+}
+
+// Set parses the string to an int and sets it.
+func (ob *optionalIntValue) Set(s string) error {
+ v, err := strconv.ParseInt(s, 0, strconv.IntSize)
+ if err != nil {
+ return err
+ }
+ ob.value = int(v)
+ ob.present = true
+ return nil
+}
+
+// String returns the string representation of the int.
+func (ob *optionalIntValue) String() string {
+ if !ob.present {
+ return "" // If the value is not present, just return an empty string, any other value wouldn't make sense.
+ }
+ return strconv.Itoa(int(ob.value))
+}
+
+// Type returns the int's type.
+func (ob *optionalIntValue) Type() string {
+ return "int"
+}
diff --git a/vendor/github.com/godbus/dbus/v5/auth.go b/vendor/github.com/godbus/dbus/v5/auth.go
index eb0b2f434..a59b4c0eb 100644
--- a/vendor/github.com/godbus/dbus/v5/auth.go
+++ b/vendor/github.com/godbus/dbus/v5/auth.go
@@ -53,7 +53,7 @@ type Auth interface {
// bus. Auth must not be called on shared connections.
func (conn *Conn) Auth(methods []Auth) error {
if methods == nil {
- uid := strconv.Itoa(os.Getuid())
+ uid := strconv.Itoa(os.Geteuid())
methods = []Auth{AuthExternal(uid), AuthCookieSha1(uid, getHomeDir())}
}
in := bufio.NewReader(conn.transport)
diff --git a/vendor/github.com/godbus/dbus/v5/conn.go b/vendor/github.com/godbus/dbus/v5/conn.go
index cb8966a74..76fc5cde3 100644
--- a/vendor/github.com/godbus/dbus/v5/conn.go
+++ b/vendor/github.com/godbus/dbus/v5/conn.go
@@ -73,7 +73,7 @@ func SessionBus() (conn *Conn, err error) {
return
}
-func getSessionBusAddress() (string, error) {
+func getSessionBusAddress(autolaunch bool) (string, error) {
if address := os.Getenv("DBUS_SESSION_BUS_ADDRESS"); address != "" && address != "autolaunch:" {
return address, nil
@@ -81,12 +81,26 @@ func getSessionBusAddress() (string, error) {
os.Setenv("DBUS_SESSION_BUS_ADDRESS", address)
return address, nil
}
+ if !autolaunch {
+ return "", errors.New("dbus: couldn't determine address of session bus")
+ }
return getSessionBusPlatformAddress()
}
// SessionBusPrivate returns a new private connection to the session bus.
func SessionBusPrivate(opts ...ConnOption) (*Conn, error) {
- address, err := getSessionBusAddress()
+ address, err := getSessionBusAddress(true)
+ if err != nil {
+ return nil, err
+ }
+
+ return Dial(address, opts...)
+}
+
+// SessionBusPrivate returns a new private connection to the session bus. If
+// the session bus is not already open, do not attempt to launch it.
+func SessionBusPrivateNoAutoStartup(opts ...ConnOption) (*Conn, error) {
+ address, err := getSessionBusAddress(false)
if err != nil {
return nil, err
}
@@ -121,7 +135,7 @@ func SystemBus() (conn *Conn, err error) {
// ConnectSessionBus connects to the session bus.
func ConnectSessionBus(opts ...ConnOption) (*Conn, error) {
- address, err := getSessionBusAddress()
+ address, err := getSessionBusAddress(true)
if err != nil {
return nil, err
}
@@ -180,7 +194,7 @@ func Dial(address string, opts ...ConnOption) (*Conn, error) {
//
// Deprecated: use Dial with options instead.
func DialHandler(address string, handler Handler, signalHandler SignalHandler) (*Conn, error) {
- return Dial(address, WithSignalHandler(signalHandler))
+ return Dial(address, WithHandler(handler), WithSignalHandler(signalHandler))
}
// ConnOption is a connection option.
diff --git a/vendor/github.com/godbus/dbus/v5/message.go b/vendor/github.com/godbus/dbus/v5/message.go
index dd86aff4f..16693eb30 100644
--- a/vendor/github.com/godbus/dbus/v5/message.go
+++ b/vendor/github.com/godbus/dbus/v5/message.go
@@ -279,8 +279,8 @@ func (msg *Message) EncodeToWithFDs(out io.Writer, order binary.ByteOrder) (fds
// be either binary.LittleEndian or binary.BigEndian. If the message is not
// valid or an error occurs when writing, an error is returned.
func (msg *Message) EncodeTo(out io.Writer, order binary.ByteOrder) (err error) {
- _, err = msg.EncodeToWithFDs(out, order);
- return err;
+ _, err = msg.EncodeToWithFDs(out, order)
+ return err
}
// IsValid checks whether msg is a valid message and returns an
diff --git a/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go b/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go
new file mode 100644
index 000000000..af7bafdf9
--- /dev/null
+++ b/vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go
@@ -0,0 +1,14 @@
+package dbus
+
+import "io"
+
+func (t *unixTransport) SendNullByte() error {
+ n, _, err := t.UnixConn.WriteMsgUnix([]byte{0}, nil, nil)
+ if err != nil {
+ return err
+ }
+ if n != 1 {
+ return io.ErrShortWrite
+ }
+ return nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index afe18287d..3fd9cbcc8 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -95,7 +95,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.46.1-0.20211008123044-d846f5aaec0e
+# github.com/containers/common v0.46.1-0.20211026130826-7abfd453c86f
github.com/containers/common/libimage
github.com/containers/common/libimage/manifests
github.com/containers/common/pkg/apparmor
@@ -108,6 +108,7 @@ github.com/containers/common/pkg/completion
github.com/containers/common/pkg/config
github.com/containers/common/pkg/defaultnet
github.com/containers/common/pkg/filters
+github.com/containers/common/pkg/flag
github.com/containers/common/pkg/manifests
github.com/containers/common/pkg/parse
github.com/containers/common/pkg/report
@@ -345,7 +346,7 @@ github.com/ghodss/yaml
github.com/go-logr/logr
# github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0
github.com/go-task/slim-sprig
-# github.com/godbus/dbus/v5 v5.0.5
+# github.com/godbus/dbus/v5 v5.0.6
github.com/godbus/dbus/v5
# github.com/gogo/protobuf v1.3.2
github.com/gogo/protobuf/gogoproto
@@ -798,10 +799,10 @@ gopkg.in/tomb.v1
gopkg.in/yaml.v2
# gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gopkg.in/yaml.v3
-# k8s.io/api v0.22.2
+# k8s.io/api v0.22.3
k8s.io/api/apps/v1
k8s.io/api/core/v1
-# k8s.io/apimachinery v0.22.2
+# k8s.io/apimachinery v0.22.3
k8s.io/apimachinery/pkg/api/resource
k8s.io/apimachinery/pkg/apis/meta/v1
k8s.io/apimachinery/pkg/conversion