summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml31
-rw-r--r--.gitignore1
-rw-r--r--Makefile12
-rw-r--r--cmd/podman/common/create_opts.go110
-rw-r--r--cmd/podman/common/specgen.go2
-rw-r--r--cmd/podman/containers/create.go5
-rw-r--r--cmd/podman/play/kube.go3
-rw-r--r--cmd/podman/registry/config.go7
-rwxr-xr-xcontrib/cirrus/runner.sh3
-rwxr-xr-xcontrib/cirrus/setup_environment.sh30
-rw-r--r--contrib/podmanimage/README.md8
-rw-r--r--docs/source/markdown/podman-create.1.md7
-rw-r--r--docs/source/markdown/podman-play-kube.1.md34
-rw-r--r--go.mod6
-rw-r--r--go.sum16
-rw-r--r--libpod/container.go2
-rw-r--r--libpod/container_config.go2
-rw-r--r--libpod/container_internal_linux.go2
-rw-r--r--libpod/container_log_linux.go2
-rw-r--r--libpod/define/container.go2
-rw-r--r--libpod/networking_linux.go28
-rw-r--r--libpod/options.go4
-rw-r--r--libpod/pod_api.go4
-rw-r--r--libpod/runtime.go10
-rw-r--r--libpod/runtime_volume_linux.go15
-rw-r--r--libpod/shutdown/handler.go2
-rw-r--r--pkg/api/handlers/libpod/images_pull.go7
-rw-r--r--pkg/api/handlers/utils/images.go2
-rw-r--r--pkg/api/server/register_images.go9
-rw-r--r--pkg/bindings/connection.go2
-rw-r--r--pkg/bindings/images/build.go4
-rw-r--r--pkg/domain/entities/play.go2
-rw-r--r--pkg/domain/filters/containers.go2
-rw-r--r--pkg/domain/infra/abi/play.go131
-rw-r--r--pkg/domain/infra/abi/terminal/sigproxy_linux.go6
-rw-r--r--pkg/machine/qemu/machine.go8
-rw-r--r--pkg/rootless/rootless_linux.go3
-rw-r--r--pkg/rootlessport/rootlessport_linux.go35
-rw-r--r--pkg/specgen/generate/storage.go57
-rw-r--r--pkg/specgen/specgen.go2
-rw-r--r--pkg/specgen/volumes.go12
-rw-r--r--pkg/systemd/dbus.go98
-rw-r--r--pkg/util/utils.go6
-rw-r--r--pkg/util/utils_test.go23
-rw-r--r--test/apiv2/20-containers.at11
-rw-r--r--test/apiv2/python/rest_api/test_v2_0_0_image.py21
-rwxr-xr-xtest/buildah-bud/apply-podman-deltas8
-rw-r--r--test/compose/mount_and_label/docker-compose.yml2
-rw-r--r--test/e2e/common_test.go21
-rw-r--r--test/e2e/login_logout_test.go11
-rw-r--r--test/e2e/play_build_test.go243
-rw-r--r--test/e2e/play_kube_test.go15
-rw-r--r--test/e2e/pod_initcontainers_test.go4
-rw-r--r--test/e2e/run_test.go2
-rw-r--r--test/e2e/stats_test.go3
-rw-r--r--test/e2e/systemd_test.go11
-rw-r--r--test/python/requirements.txt2
-rw-r--r--test/system/255-auto-update.bats4
-rw-r--r--test/system/500-networking.bats3
-rw-r--r--test/system/700-play.bats4
-rw-r--r--troubleshooting.md135
-rw-r--r--vendor/github.com/containers/image/v5/version/version.go2
-rw-r--r--vendor/github.com/containers/storage/VERSION2
-rw-r--r--vendor/github.com/containers/storage/drivers/overlay/overlay.go2
-rw-r--r--vendor/github.com/containers/storage/go.mod4
-rw-r--r--vendor/github.com/containers/storage/go.sum8
-rw-r--r--vendor/github.com/containers/storage/layers.go6
-rw-r--r--vendor/github.com/containers/storage/types/utils.go3
-rw-r--r--vendor/github.com/klauspost/compress/README.md10
-rw-r--r--vendor/github.com/klauspost/compress/zstd/enc_best.go30
-rw-r--r--vendor/modules.txt8
71 files changed, 1051 insertions, 281 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index b6ef69a96..3fcf335ed 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -30,20 +30,17 @@ env:
PRIOR_UBUNTU_NAME: "ubuntu-2010"
# Google-cloud VM Images
- # TODO: At the time of this comment, an selinux-policy regression is blocking use of updated
- # Fedora VM images: https://bugzilla.redhat.com/show_bug.cgi?id=1965743
- IMAGE_SUFFIX_UBUNTU: "c5521575421149184"
- IMAGE_SUFFIX: "c5348179051806720"
+ IMAGE_SUFFIX: "c6737534580424704"
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
- UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX_UBUNTU}"
- PRIOR_UBUNTU_CACHE_IMAGE_NAME: "prior-ubuntu-${IMAGE_SUFFIX_UBUNTU}"
+ UBUNTU_CACHE_IMAGE_NAME: "ubuntu-${IMAGE_SUFFIX}"
+ PRIOR_UBUNTU_CACHE_IMAGE_NAME: "prior-ubuntu-${IMAGE_SUFFIX}"
# Container FQIN's
FEDORA_CONTAINER_FQIN: "quay.io/libpod/fedora_podman:${IMAGE_SUFFIX}"
PRIOR_FEDORA_CONTAINER_FQIN: "quay.io/libpod/prior-fedora_podman:${IMAGE_SUFFIX}"
- UBUNTU_CONTAINER_FQIN: "quay.io/libpod/ubuntu_podman:${IMAGE_SUFFIX_UBUNTU}"
- PRIOR_UBUNTU_CONTAINER_FQIN: "quay.io/libpod/prior-ubuntu_podman:${IMAGE_SUFFIX_UBUNTU}"
+ UBUNTU_CONTAINER_FQIN: "quay.io/libpod/ubuntu_podman:${IMAGE_SUFFIX}"
+ PRIOR_UBUNTU_CONTAINER_FQIN: "quay.io/libpod/prior-ubuntu_podman:${IMAGE_SUFFIX}"
####
#### Control variables that determine what to run and how to run it.
@@ -378,8 +375,7 @@ osx_alt_build_task:
always: *binary_artifacts
-# This task is a stub: In the future it will be used to verify
-# podman is compatible with the docker python-module.
+# Verify podman is compatible with the docker python-module.
docker-py_test_task:
name: Docker-py Compat.
alias: docker-py_test
@@ -633,17 +629,11 @@ rootless_system_test_task:
main_script: *main
always: *logs_artifacts
-# FIXME: we may want to consider running this from nightly cron instead of CI.
-# The tests are actually pretty quick (less than a minute) but they do rely
-# on pulling images from quay.io, which means we're subject to network flakes.
-#
-# FIXME: how does this env matrix work, anyway? Does it spin up multiple VMs?
-# We might just want to encode the version matrix in runner.sh instead
upgrade_test_task:
name: "Upgrade test: from $PODMAN_UPGRADE_FROM"
alias: upgrade_test
skip: *tags
- only_if: *not_docs
+ only_if: $CIRRUS_CHANGE_TITLE !=~ '.*CI:DOCS.*' || $CIRRUS_CRON != ''
depends_on:
- local_system_test
matrix:
@@ -678,18 +668,11 @@ meta_task:
image: quay.io/libpod/imgts:$IMAGE_SUFFIX
env:
# Space-separated list of images used by this repository state
- # TODO: Protect commonly tagged ubuntu images from puning in case
- # workaround for BZ1965743 remains in use beyond the 30-days.
- # Ref sha 404d5edb155
IMGNAMES: >-
${FEDORA_CACHE_IMAGE_NAME}
${PRIOR_FEDORA_CACHE_IMAGE_NAME}
${UBUNTU_CACHE_IMAGE_NAME}
${PRIOR_UBUNTU_CACHE_IMAGE_NAME}
- fedora-${IMAGE_SUFFIX_UBUNTU}
- prior-fedora-${IMAGE_SUFFIX_UBUNTU}
- ubuntu-${IMAGE_SUFFIX}
- prior-ubuntu-${IMAGE_SUFFIX}
BUILDID: "${CIRRUS_BUILD_ID}"
REPOREF: "${CIRRUS_REPO_NAME}"
GCPJSON: ENCRYPTED[3a198350077849c8df14b723c0f4c9fece9ebe6408d35982e7adf2105a33f8e0e166ed3ed614875a0887e1af2b8775f4]
diff --git a/.gitignore b/.gitignore
index 0a3caf8ca..08e5309ee 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,6 +33,7 @@ release.txt
/test/goecho/goecho
/test/testvol/testvol
.vscode*
+tags
result
# Necessary to prevent hack/tree-status.sh false-positive
/*runner_stats.log
diff --git a/Makefile b/Makefile
index bda10d0bf..93c7fdf95 100644
--- a/Makefile
+++ b/Makefile
@@ -257,7 +257,7 @@ test/goecho/goecho: .gopathok $(wildcard test/goecho/*.go)
.PHONY: codespell
codespell:
- codespell -S bin,vendor,.git,go.sum,changelog.txt,.cirrus.yml,"RELEASE_NOTES.md,*.xz,*.gz,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" -L uint,iff,od,seeked,splitted,marge,ERRO,hist,ether -w
+ codespell -S bin,vendor,.git,go.sum,changelog.txt,.cirrus.yml,"RELEASE_NOTES.md,*.xz,*.gz,*.ps1,*.tar,*.tgz,bin2img,*ico,*.png,*.1,*.5,copyimg,*.orig,apidoc.go" -L uint,iff,od,seeked,splitted,marge,ERRO,hist,ether -w
.PHONY: validate
validate: gofmt lint .gitvalidation validate.completions man-page-check swagger-check tests-included tests-expect-exit
@@ -493,10 +493,12 @@ validate.completions:
if [ -x /bin/zsh ]; then /bin/zsh completions/zsh/_podman; fi
if [ -x /bin/fish ]; then /bin/fish completions/fish/podman.fish; fi
+# Note: Assumes test/python/requirements.txt is installed & available
.PHONY: run-docker-py-tests
run-docker-py-tests:
- $(eval testLogs=$(shell mktemp podman_tmp_XXXX))
- ./bin/podman run --rm --security-opt label=disable --privileged -v $(testLogs):/testLogs --net=host -e DOCKER_HOST=tcp://localhost:8080 $(DOCKERPY_IMAGE) sh -c "pytest $(DOCKERPY_TEST) "
+ touch test/__init__.py
+ pytest test/python/docker/
+ -rm test/__init__.py
.PHONY: localunit
localunit: test/goecho/goecho
@@ -841,11 +843,13 @@ clean: ## Clean all make artifacts
build \
test/checkseccomp/checkseccomp \
test/goecho/goecho \
+ test/__init__.py \
test/testdata/redis-image \
libpod/container_ffjson.go \
libpod/pod_ffjson.go \
libpod/container_easyjson.go \
libpod/pod_easyjson.go \
.install.goimports \
- docs/build
+ docs/build \
+ venv
make -C docs clean
diff --git a/cmd/podman/common/create_opts.go b/cmd/podman/common/create_opts.go
index 0a969bfd2..0fdf3ce08 100644
--- a/cmd/podman/common/create_opts.go
+++ b/cmd/podman/common/create_opts.go
@@ -356,51 +356,55 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
CPUSetMems: cc.HostConfig.CpusetMems,
// Detach: false, // don't need
// DetachKeys: "", // don't need
- Devices: devices,
- DeviceCGroupRule: nil,
- DeviceReadBPs: readBps,
- DeviceReadIOPs: readIops,
- DeviceWriteBPs: writeBps,
- DeviceWriteIOPs: writeIops,
- Entrypoint: entrypoint,
- Env: cc.Config.Env,
- Expose: expose,
- GroupAdd: cc.HostConfig.GroupAdd,
- Hostname: cc.Config.Hostname,
- ImageVolume: "bind",
- Init: init,
- Interactive: cc.Config.OpenStdin,
- IPC: string(cc.HostConfig.IpcMode),
- Label: stringMaptoArray(cc.Config.Labels),
- LogDriver: cc.HostConfig.LogConfig.Type,
- LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config),
- Name: cc.Name,
- OOMScoreAdj: cc.HostConfig.OomScoreAdj,
- Arch: "",
- OS: "",
- Variant: "",
- PID: string(cc.HostConfig.PidMode),
- PIDsLimit: cc.HostConfig.PidsLimit,
- Privileged: cc.HostConfig.Privileged,
- PublishAll: cc.HostConfig.PublishAllPorts,
- Quiet: false,
- ReadOnly: cc.HostConfig.ReadonlyRootfs,
- ReadOnlyTmpFS: true, // podman default
- Rm: cc.HostConfig.AutoRemove,
- SecurityOpt: cc.HostConfig.SecurityOpt,
- StopSignal: cc.Config.StopSignal,
- StorageOpt: stringMaptoArray(cc.HostConfig.StorageOpt),
- Sysctl: stringMaptoArray(cc.HostConfig.Sysctls),
- Systemd: "true", // podman default
- TmpFS: parsedTmp,
- TTY: cc.Config.Tty,
- User: cc.Config.User,
- UserNS: string(cc.HostConfig.UsernsMode),
- UTS: string(cc.HostConfig.UTSMode),
- Mount: mounts,
- VolumesFrom: cc.HostConfig.VolumesFrom,
- Workdir: cc.Config.WorkingDir,
- Net: &netInfo,
+ Devices: devices,
+ DeviceCGroupRule: nil,
+ DeviceReadBPs: readBps,
+ DeviceReadIOPs: readIops,
+ DeviceWriteBPs: writeBps,
+ DeviceWriteIOPs: writeIops,
+ Entrypoint: entrypoint,
+ Env: cc.Config.Env,
+ Expose: expose,
+ GroupAdd: cc.HostConfig.GroupAdd,
+ Hostname: cc.Config.Hostname,
+ ImageVolume: "bind",
+ Init: init,
+ Interactive: cc.Config.OpenStdin,
+ IPC: string(cc.HostConfig.IpcMode),
+ Label: stringMaptoArray(cc.Config.Labels),
+ LogDriver: cc.HostConfig.LogConfig.Type,
+ LogOptions: stringMaptoArray(cc.HostConfig.LogConfig.Config),
+ Name: cc.Name,
+ OOMScoreAdj: cc.HostConfig.OomScoreAdj,
+ Arch: "",
+ OS: "",
+ Variant: "",
+ PID: string(cc.HostConfig.PidMode),
+ PIDsLimit: cc.HostConfig.PidsLimit,
+ Privileged: cc.HostConfig.Privileged,
+ PublishAll: cc.HostConfig.PublishAllPorts,
+ Quiet: false,
+ ReadOnly: cc.HostConfig.ReadonlyRootfs,
+ ReadOnlyTmpFS: true, // podman default
+ Rm: cc.HostConfig.AutoRemove,
+ SecurityOpt: cc.HostConfig.SecurityOpt,
+ StopSignal: cc.Config.StopSignal,
+ StorageOpt: stringMaptoArray(cc.HostConfig.StorageOpt),
+ Sysctl: stringMaptoArray(cc.HostConfig.Sysctls),
+ Systemd: "true", // podman default
+ TmpFS: parsedTmp,
+ TTY: cc.Config.Tty,
+ User: cc.Config.User,
+ UserNS: string(cc.HostConfig.UsernsMode),
+ UTS: string(cc.HostConfig.UTSMode),
+ Mount: mounts,
+ VolumesFrom: cc.HostConfig.VolumesFrom,
+ Workdir: cc.Config.WorkingDir,
+ Net: &netInfo,
+ HealthInterval: DefaultHealthCheckInterval,
+ HealthRetries: DefaultHealthCheckRetries,
+ HealthTimeout: DefaultHealthCheckTimeout,
+ HealthStartPeriod: DefaultHealthCheckStartPeriod,
}
if !rootless.IsRootless() {
var ulimits []string
@@ -527,10 +531,18 @@ func ContainerCreateToContainerCLIOpts(cc handlers.CreateContainerConfig, rtc *c
finCmd = finCmd[:len(finCmd)-1]
}
cliOpts.HealthCmd = finCmd
- cliOpts.HealthInterval = cc.Config.Healthcheck.Interval.String()
- cliOpts.HealthRetries = uint(cc.Config.Healthcheck.Retries)
- cliOpts.HealthStartPeriod = cc.Config.Healthcheck.StartPeriod.String()
- cliOpts.HealthTimeout = cc.Config.Healthcheck.Timeout.String()
+ if cc.Config.Healthcheck.Interval > 0 {
+ cliOpts.HealthInterval = cc.Config.Healthcheck.Interval.String()
+ }
+ if cc.Config.Healthcheck.Retries > 0 {
+ cliOpts.HealthRetries = uint(cc.Config.Healthcheck.Retries)
+ }
+ if cc.Config.Healthcheck.StartPeriod > 0 {
+ cliOpts.HealthStartPeriod = cc.Config.Healthcheck.StartPeriod.String()
+ }
+ if cc.Config.Healthcheck.Timeout > 0 {
+ cliOpts.HealthTimeout = cc.Config.Healthcheck.Timeout.String()
+ }
}
// specgen assumes the image name is arg[0]
diff --git a/cmd/podman/common/specgen.go b/cmd/podman/common/specgen.go
index 8d6a21cb7..59d32f568 100644
--- a/cmd/podman/common/specgen.go
+++ b/cmd/podman/common/specgen.go
@@ -685,7 +685,7 @@ func makeHealthCheckFromCli(inCmd, interval string, retries uint, timeout, start
concat := ""
if cmdArr[0] == "CMD" || cmdArr[0] == "none" { // this is for compat, we are already split properly for most compat cases
cmdArr = strings.Fields(inCmd)
- } else if cmdArr[0] != "CMD-SHELL" { // this is for podman side of things, wont contain the keywords
+ } else if cmdArr[0] != "CMD-SHELL" { // this is for podman side of things, won't contain the keywords
if isArr && len(cmdArr) > 1 { // an array of consecutive commands
cmdArr = append([]string{"CMD"}, cmdArr...)
} else { // one singular command
diff --git a/cmd/podman/containers/create.go b/cmd/podman/containers/create.go
index 906ae4452..a57488af2 100644
--- a/cmd/podman/containers/create.go
+++ b/cmd/podman/containers/create.go
@@ -13,6 +13,7 @@ import (
"github.com/containers/podman/v3/cmd/podman/common"
"github.com/containers/podman/v3/cmd/podman/registry"
"github.com/containers/podman/v3/cmd/podman/utils"
+ "github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/specgen"
"github.com/containers/podman/v3/pkg/util"
@@ -105,8 +106,8 @@ func create(cmd *cobra.Command, args []string) error {
if !cmd.Flags().Changed("pod") {
return errors.New("must specify pod value with init-ctr")
}
- if !util.StringInSlice(initctr, []string{"always", "oneshot"}) {
- return errors.New("init-ctr value must be 'always' or 'oneshot'")
+ if !util.StringInSlice(initctr, []string{define.AlwaysInitContainer, define.OneShotInitContainer}) {
+ return errors.Errorf("init-ctr value must be '%s' or '%s'", define.AlwaysInitContainer, define.OneShotInitContainer)
}
cliVals.InitContainerType = initctr
}
diff --git a/cmd/podman/play/kube.go b/cmd/podman/play/kube.go
index ece7d1f98..2eebd9f86 100644
--- a/cmd/podman/play/kube.go
+++ b/cmd/podman/play/kube.go
@@ -100,6 +100,9 @@ func init() {
configmapFlagName := "configmap"
flags.StringSliceVar(&kubeOptions.ConfigMaps, configmapFlagName, []string{}, "`Pathname` of a YAML file containing a kubernetes configmap")
_ = kubeCmd.RegisterFlagCompletionFunc(configmapFlagName, completion.AutocompleteDefault)
+
+ buildFlagName := "build"
+ flags.BoolVar(&kubeOptions.Build, buildFlagName, false, "Build all images in a YAML (given Containerfiles exist)")
}
_ = flags.MarkHidden("signature-policy")
}
diff --git a/cmd/podman/registry/config.go b/cmd/podman/registry/config.go
index b512ba341..50e488b02 100644
--- a/cmd/podman/registry/config.go
+++ b/cmd/podman/registry/config.go
@@ -89,7 +89,12 @@ func newPodmanConfig() {
// use for the containers.conf configuration file.
func setXdgDirs() error {
if !rootless.IsRootless() {
- return nil
+ // unset XDG_RUNTIME_DIR for root
+ // Sometimes XDG_RUNTIME_DIR is set to /run/user/0 sometimes it is unset,
+ // the inconsistency is causing issues for the dnsname plugin.
+ // It is already set to an empty string for conmon so lets do the same
+ // for podman. see #10806 and #10745
+ return os.Unsetenv("XDG_RUNTIME_DIR")
}
// Setup XDG_RUNTIME_DIR
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index da43ffb0a..c1972b90f 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -88,7 +88,8 @@ function _run_bindings() {
}
function _run_docker-py() {
- msg "This is docker-py stub, it is only a stub"
+ source venv/bin/activate
+ make run-docker-py-tests
}
function _run_endpoint() {
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 86b8d78ef..d0c348d58 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -77,6 +77,13 @@ case "$CG_FS_TYPE" in
else
echo "OCI_RUNTIME=runc" >> /etc/ci_environment
fi
+
+ # As a general policy CGv1 + runc should coincide with the "older"
+ # VM Images in CI. Verify this is the case.
+ if [[ -n "$VM_IMAGE_NAME" ]] && [[ ! "$VM_IMAGE_NAME" =~ prior ]]
+ then
+ die "Most recent distro. version should never run with CGv1"
+ fi
fi
;;
cgroup2fs)
@@ -85,6 +92,13 @@ case "$CG_FS_TYPE" in
# which uses runc as the default.
warn "Forcing testing with crun instead of runc"
echo "OCI_RUNTIME=crun" >> /etc/ci_environment
+
+ # As a general policy CGv2 + crun should coincide with the "newer"
+ # VM Images in CI. Verify this is the case.
+ if [[ -n "$VM_IMAGE_NAME" ]] && [[ "$VM_IMAGE_NAME" =~ prior ]]
+ then
+ die "Least recent distro. version should never run with CGv2"
+ fi
fi
;;
*) die_unknown CG_FS_TYPE
@@ -191,12 +205,24 @@ case "$TEST_FLAVOR" in
bigto dnf install -y glibc-minimal-langpack rpm-build
fi
;&
- docker-py) ;&
+ docker-py)
+ remove_packaged_podman_files
+ make install PREFIX=/usr ETCDIR=/etc
+
+ # TODO: Don't install stuff at test runtime! Do this from
+ # cache_images/fedora_packaging.sh in containers/automation_images
+ # and STRONGLY prefer installing RPMs vs pip packages in venv
+ dnf install -y python3-virtualenv python3-pytest4
+ virtualenv venv
+ source venv/bin/activate
+ pip install --upgrade pip
+ pip install --requirement $GOSRC/test/python/requirements.txt
+ ;;
build) make clean ;;
unit) ;;
apiv2) ;& # use next item
compose)
- dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-docker*
+ rpm -ivh $PACKAGE_DOWNLOAD_DIR/podman-docker*
;& # continue with next item
int) ;&
sys) ;&
diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md
index 6effec38b..b7be328c7 100644
--- a/contrib/podmanimage/README.md
+++ b/contrib/podmanimage/README.md
@@ -17,10 +17,10 @@ default to `/`.
The container images are:
* `quay.io/containers/podman:<version>` and `quay.io/podman/stable:<version>` -
- These images are built when a new Podman version becomes available in
- Fedora. These images are intended to be unchanging and stable, they will
- never be updated by automation once they've been pushed. For build details,
- please [see the configuration file](stable/Dockerfile).
+ These images are built daily. They are intended to contain an unchanging
+ and stable version of podman. Though for the most recent `<version>` tag,
+ image contents will be updated to incorporate (especially) security upgrades.
+ For build details, please [see the configuration file](stable/Dockerfile).
* `quay.io/containers/podman:latest` and `quay.io/podman/stable:latest` -
Built daily using the same Dockerfile as above. The Podman version
will remain the "latest" available in Fedora, however the other image
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 723592016..b73f6c05a 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -453,10 +453,9 @@ When using pods, create an init style container, which is run after the infra co
but before regular pod containers are started. Init containers are useful for running
setup operations for the pod's applications.
-Valid values for `init-ctr` type are *always* or *oneshot*. The *always* value
-means the container will run with each and every `pod start`, whereas the *oneshot*
-value means is will ony run once when the pod is started and then the container is
-removed.
+Valid values for `init-ctr` type are *always* or *once*. The *always* value
+means the container will run with each and every `pod start`, whereas the *once*
+value means the container will only run once when the pod is started and then the container is removed.
Init containers are only run on pod `start`. Restarting a pod will not execute any init
containers should they be present. Furthermore, init containers can only be created in a
diff --git a/docs/source/markdown/podman-play-kube.1.md b/docs/source/markdown/podman-play-kube.1.md
index ad5ae7e4c..268e4bbcb 100644
--- a/docs/source/markdown/podman-play-kube.1.md
+++ b/docs/source/markdown/podman-play-kube.1.md
@@ -35,6 +35,36 @@ A Kubernetes PersistentVolumeClaim represents a Podman named volume. Only the Pe
- volume.podman.io/gid
- volume.podman.io/mount-options
+Play kube is capable of building images on the fly given the correct directory layout and Containerfiles. This
+option is not available for remote clients yet. Consider the following excerpt from a YAML file:
+```
+apiVersion: v1
+kind: Pod
+metadata:
+...
+spec:
+ containers:
+ - command:
+ - top
+ - name: container
+ value: podman
+ image: foobar
+...
+```
+
+If there is a directory named `foobar` in the current working directory with a file named `Containerfile` or `Dockerfile`,
+Podman play kube will build that image and name it `foobar`. An example directory structure for this example would look
+like:
+```
+|- mykubefiles
+ |- myplayfile.yaml
+ |- foobar
+ |- Containerfile
+```
+
+The build will consider `foobar` to be the context directory for the build. If there is an image in local storage
+called `foobar`, the image will not be built unless the `--build` flag is used.
+
## OPTIONS
#### **--authfile**=*path*
@@ -45,6 +75,10 @@ If the authorization state is not found there, $HOME/.docker/config.json is chec
Note: You can also override the default path of the authentication file by setting the REGISTRY\_AUTH\_FILE
environment variable. `export REGISTRY_AUTH_FILE=path`
+#### **--build**
+
+Build images even if they are found in the local storage.
+
#### **--cert-dir**=*path*
Use certificates at *path* (\*.crt, \*.cert, \*.key) to connect to the registry.
diff --git a/go.mod b/go.mod
index a9d2b9024..b89854209 100644
--- a/go.mod
+++ b/go.mod
@@ -14,10 +14,10 @@ require (
github.com/containers/buildah v1.22.0
github.com/containers/common v0.42.1
github.com/containers/conmon v2.0.20+incompatible
- github.com/containers/image/v5 v5.15.0
+ github.com/containers/image/v5 v5.15.2
github.com/containers/ocicrypt v1.1.2
github.com/containers/psgo v1.5.2
- github.com/containers/storage v1.34.0
+ github.com/containers/storage v1.34.1
github.com/coreos/go-systemd/v22 v22.3.2
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
github.com/cri-o/ocicni v0.2.1-0.20210621164014-d0acc7862283
@@ -53,7 +53,7 @@ require (
github.com/opencontainers/selinux v1.8.4
github.com/pkg/errors v0.9.1
github.com/pmezard/go-difflib v1.0.0
- github.com/rootless-containers/rootlesskit v0.14.4
+ github.com/rootless-containers/rootlesskit v0.14.5
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.2.1
github.com/spf13/pflag v1.0.5
diff --git a/go.sum b/go.sum
index 279e9fd10..35fe9cdc6 100644
--- a/go.sum
+++ b/go.sum
@@ -245,8 +245,9 @@ github.com/containers/common v0.42.1/go.mod h1:AaF3ipZfgezsctDuhzLkq4Vl+LkEy7J74
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.14.0/go.mod h1:SxiBKOcKuT+4yTjD0AskjO+UwFvNcVOJ9qlAw1HNSPU=
-github.com/containers/image/v5 v5.15.0 h1:NduhN20ptHNlf0uRny5iTJa2OodB9SLMEB4hKKbzBBs=
github.com/containers/image/v5 v5.15.0/go.mod h1:gzdBcooi6AFdiqfzirUqv90hUyHyI0MMdaqKzACKr2s=
+github.com/containers/image/v5 v5.15.2 h1:DKicmVr0h1HGkzs9muoErX+fVbV9sV9W5TyMy5perLE=
+github.com/containers/image/v5 v5.15.2/go.mod h1:8jejVSzTDfyPwr/HXp9rri34n/vbdavYk6IzTiB3TBw=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b h1:Q8ePgVfHDplZ7U33NwHZkrVELsZP5fYj9pM5WBZB2GE=
github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
@@ -260,8 +261,8 @@ github.com/containers/storage v1.23.5/go.mod h1:ha26Q6ngehFNhf3AWoXldvAvwI4jFe3E
github.com/containers/storage v1.32.6/go.mod h1:mdB+b89p+jU8zpzLTVXA0gWMmIo0WrkfGMh1R8O2IQw=
github.com/containers/storage v1.33.0/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY=
github.com/containers/storage v1.33.1/go.mod h1:FUZPF4nJijX8ixdhByZJXf02cvbyLi6dyDwXdIe8QVY=
-github.com/containers/storage v1.34.0 h1:39MhQe+3knl2G6WcaYf24Fpqqz6gbdLK/52Ms5wV+II=
-github.com/containers/storage v1.34.0/go.mod h1:t6I+hTgPU0/tVxQ75vw406wDi/TXwYBqZp4QZV9N7b8=
+github.com/containers/storage v1.34.1 h1:PsBGMH7hwuQ3MOr7qTgPznFrE8ebfIbwQbg2gKvg0lE=
+github.com/containers/storage v1.34.1/go.mod h1:FY2TcbfgCLMU4lYoKnlZeZXeH353TOTbpDEA+sAcqAY=
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/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
@@ -583,8 +584,8 @@ github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
-github.com/klauspost/compress v1.13.3 h1:BtAvtV1+h0YwSVwWoYXMREPpYu9VzTJ9QDI1TEg/iQQ=
-github.com/klauspost/compress v1.13.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s=
+github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -751,7 +752,6 @@ github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwy
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
-github.com/opencontainers/selinux v1.8.3/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
github.com/opencontainers/selinux v1.8.4 h1:krlgQ6/j9CkCXT5oW0yVXdQFOME3NjKuuAZXuR6O7P4=
github.com/opencontainers/selinux v1.8.4/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
github.com/openshift/imagebuilder v1.2.2-0.20210415181909-87f3e48c2656 h1:WaxyNFpmIDu4i6so9r6LVFIbSaXqsj8oitMitt86ae4=
@@ -814,8 +814,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rootless-containers/rootlesskit v0.14.4 h1:pqx9a+OC/6jjV7sIUKy3D1p6NLEC6WIMiJWAGsGMCUM=
-github.com/rootless-containers/rootlesskit v0.14.4/go.mod h1:Ai3detLzryb/4EkzXmNfh8aByUcBXp/qqkQusJs1SO8=
+github.com/rootless-containers/rootlesskit v0.14.5 h1:X4eNt2e1h/uSjlssKqpeTY5fatrjDz9F9FX05RJB7Tw=
+github.com/rootless-containers/rootlesskit v0.14.5/go.mod h1:Ai3detLzryb/4EkzXmNfh8aByUcBXp/qqkQusJs1SO8=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
diff --git a/libpod/container.go b/libpod/container.go
index d5d5ef1a5..80fd35c09 100644
--- a/libpod/container.go
+++ b/libpod/container.go
@@ -240,7 +240,7 @@ type ContainerImageVolume struct {
type ContainerSecret struct {
// Secret is the secret
*secrets.Secret
- // UID is tbe UID of the secret file
+ // UID is the UID of the secret file
UID uint32
// GID is the GID of the secret file
GID uint32
diff --git a/libpod/container_config.go b/libpod/container_config.go
index 72a969fe6..e15030c15 100644
--- a/libpod/container_config.go
+++ b/libpod/container_config.go
@@ -376,6 +376,6 @@ type ContainerMiscConfig struct {
// EnvSecrets are secrets that are set as environment variables
EnvSecrets map[string]*secrets.Secret `json:"secret_env,omitempty"`
// InitContainerType specifies if the container is an initcontainer
- // and if so, what type: always or oneshot are possible non-nil entries
+ // and if so, what type: always or once are possible non-nil entries
InitContainerType string `json:"init_container_type,omitempty"`
}
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go
index 6d2f7bddc..f21aebb09 100644
--- a/libpod/container_internal_linux.go
+++ b/libpod/container_internal_linux.go
@@ -1782,7 +1782,7 @@ func (c *Container) generateResolvConf() (string, error) {
cniResponse := c.state.NetworkStatus
for _, i := range cniResponse {
for _, ip := range i.IPs {
- // Note: only using To16() does not work since it also returns a vaild ip for ipv4
+ // Note: only using To16() does not work since it also returns a valid ip for ipv4
if ip.Address.IP.To4() == nil && ip.Address.IP.To16() != nil {
ipv6 = true
}
diff --git a/libpod/container_log_linux.go b/libpod/container_log_linux.go
index d4afaa52a..11f1be7f9 100644
--- a/libpod/container_log_linux.go
+++ b/libpod/container_log_linux.go
@@ -79,7 +79,7 @@ func (c *Container) readFromJournal(ctx context.Context, options *logs.LogOption
break
}
if cursorError != nil {
- return errors.Wrap(cursorError, "inital journal cursor")
+ return errors.Wrap(cursorError, "initial journal cursor")
}
// We need the container's events in the same journal to guarantee
diff --git a/libpod/define/container.go b/libpod/define/container.go
index f0aca92aa..bb44a6a4a 100644
--- a/libpod/define/container.go
+++ b/libpod/define/container.go
@@ -34,5 +34,5 @@ const (
AlwaysInitContainer = "always"
// OneShotInitContainer is a container that only runs as init once
// and is then deleted.
- OneShotInitContainer = "oneshot"
+ OneShotInitContainer = "once"
)
diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go
index 8e9b5997c..2ed2bb01b 100644
--- a/libpod/networking_linux.go
+++ b/libpod/networking_linux.go
@@ -173,11 +173,27 @@ func (r *RootlessCNI) Do(toRun func() error) error {
// the link target will be available in the mount ns.
// see: https://github.com/containers/podman/issues/10855
resolvePath := "/etc/resolv.conf"
- resolvePath, err = filepath.EvalSymlinks(resolvePath)
- if err != nil {
- return err
+ for i := 0; i < 255; i++ {
+ // Do not use filepath.EvalSymlinks, we only want the first symlink under /run.
+ // If /etc/resolv.conf has more than one symlink under /run, e.g.
+ // -> /run/systemd/resolve/stub-resolv.conf -> /run/systemd/resolve/resolv.conf
+ // we would put the netns resolv.conf file to the last path. However this will
+ // break dns because the second link does not exists in the mount ns.
+ // see https://github.com/containers/podman/issues/11222
+ link, err := os.Readlink(resolvePath)
+ if err != nil {
+ // if there is no symlink exit
+ break
+ }
+ resolvePath = filepath.Join(filepath.Dir(resolvePath), link)
+ if strings.HasPrefix(resolvePath, "/run/") {
+ break
+ }
+ if i == 254 {
+ return errors.New("too many symlinks while resolving /etc/resolv.conf")
+ }
}
- logrus.Debugf("The actual path of /etc/resolv.conf on the host is %q", resolvePath)
+ logrus.Debugf("The path of /etc/resolv.conf in the mount ns is %q", resolvePath)
// When /etc/resolv.conf on the host is a symlink to /run/systemd/resolve/stub-resolv.conf,
// we have to mount an empty filesystem on /run/systemd/resolve in the child namespace,
// so as to isolate the directory from the host mount namespace.
@@ -1219,7 +1235,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
return err
}
- // OCICNI will set the loopback adpter down on teardown so we should set it up again
+ // OCICNI will set the loopback adapter down on teardown so we should set it up again
err = c.state.NetNS.Do(func(_ ns.NetNS) error {
link, err := netlink.LinkByName("lo")
if err != nil {
@@ -1229,7 +1245,7 @@ func (c *Container) NetworkDisconnect(nameOrID, netName string, force bool) erro
return err
})
if err != nil {
- logrus.Warnf("failed to set loopback adpter up in the container: %v", err)
+ logrus.Warnf("failed to set loopback adapter up in the container: %v", err)
}
// Reload ports when there are still connected networks, maybe we removed the network interface with the child ip.
// Reloading without connected networks does not make sense, so we can skip this step.
diff --git a/libpod/options.go b/libpod/options.go
index b94ef88ba..59aec66c6 100644
--- a/libpod/options.go
+++ b/libpod/options.go
@@ -268,7 +268,7 @@ func WithRegistriesConf(path string) RuntimeOption {
logrus.Debugf("Setting custom registries.conf: %q", path)
return func(rt *Runtime) error {
if _, err := os.Stat(path); err != nil {
- return errors.Wrap(err, "error locating specified registries.conf")
+ return errors.Wrap(err, "locating specified registries.conf")
}
if rt.imageContext == nil {
rt.imageContext = &types.SystemContext{
@@ -1453,7 +1453,7 @@ func WithNamedVolumes(volumes []*ContainerNamedVolume) CtrCreateOption {
for _, vol := range volumes {
mountOpts, err := util.ProcessOptions(vol.Options, false, "")
if err != nil {
- return errors.Wrapf(err, "error processing options for named volume %q mounted at %q", vol.Name, vol.Dest)
+ return errors.Wrapf(err, "processing options for named volume %q mounted at %q", vol.Name, vol.Dest)
}
ctr.config.NamedVolumes = append(ctr.config.NamedVolumes, &ContainerNamedVolume{
diff --git a/libpod/pod_api.go b/libpod/pod_api.go
index 6fea2dfd8..716eb2e5b 100644
--- a/libpod/pod_api.go
+++ b/libpod/pod_api.go
@@ -32,14 +32,14 @@ func (p *Pod) startInitContainers(ctx context.Context) error {
if rc != 0 {
return errors.Errorf("init container %s exited with code %d", initCon.ID(), rc)
}
- // If the container is an oneshot init container, we need to remove it
+ // If the container is a once init container, we need to remove it
// after it runs
if initCon.Config().InitContainerType == define.OneShotInitContainer {
icLock := initCon.lock
icLock.Lock()
if err := p.runtime.removeContainer(ctx, initCon, false, false, true); err != nil {
icLock.Unlock()
- return errors.Wrapf(err, "failed to remove oneshot init container %s", initCon.ID())
+ return errors.Wrapf(err, "failed to remove once init container %s", initCon.ID())
}
// Removing a container this way requires an explicit call to clean up the db
if err := p.runtime.state.RemoveContainerFromPod(p, initCon); err != nil {
diff --git a/libpod/runtime.go b/libpod/runtime.go
index 30659a3d4..1f403790f 100644
--- a/libpod/runtime.go
+++ b/libpod/runtime.go
@@ -30,6 +30,7 @@ import (
"github.com/containers/podman/v3/libpod/shutdown"
"github.com/containers/podman/v3/pkg/cgroups"
"github.com/containers/podman/v3/pkg/rootless"
+ "github.com/containers/podman/v3/pkg/systemd"
"github.com/containers/podman/v3/pkg/util"
"github.com/containers/storage"
"github.com/containers/storage/pkg/unshare"
@@ -500,6 +501,15 @@ func makeRuntime(ctx context.Context, runtime *Runtime) (retErr error) {
// no containers running. Create immediately a namespace, as
// we will need to access the storage.
if needsUserns {
+ // warn users if mode is rootless and cgroup manager is systemd
+ // and no valid systemd session is present
+ // warn only whenever new namespace is created
+ if runtime.config.Engine.CgroupManager == config.SystemdCgroupsManager {
+ unified, _ := cgroups.IsCgroup2UnifiedMode()
+ if unified && rootless.IsRootless() && !systemd.IsSystemdSessionValid(rootless.GetRootlessUID()) {
+ logrus.Debug("Invalid systemd user session for current user")
+ }
+ }
aliveLock.Unlock() // Unlock to avoid deadlock as BecomeRootInUserNS will reexec.
pausePid, err := util.GetRootlessPauseProcessPidPathGivenDir(runtime.config.Engine.TmpDir)
if err != nil {
diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go
index 40df98d7c..d1ea7d4fd 100644
--- a/libpod/runtime_volume_linux.go
+++ b/libpod/runtime_volume_linux.go
@@ -255,11 +255,6 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool) error
// Set volume as invalid so it can no longer be used
v.valid = false
- // Remove the volume from the state
- if err := r.state.RemoveVolume(v); err != nil {
- return errors.Wrapf(err, "error removing volume %s", v.Name())
- }
-
var removalErr error
// If we use a volume plugin, we need to remove from the plugin.
@@ -287,11 +282,19 @@ func (r *Runtime) removeVolume(ctx context.Context, v *Volume, force bool) error
req := new(pluginapi.RemoveRequest)
req.Name = v.Name()
if err := v.plugin.RemoveVolume(req); err != nil {
- removalErr = errors.Wrapf(err, "volume %s could not be removed from plugin %s, but it has been removed from Podman", v.Name(), v.Driver())
+ return errors.Wrapf(err, "volume %s could not be removed from plugin %s", v.Name(), v.Driver())
}
}
}
+ // Remove the volume from the state
+ if err := r.state.RemoveVolume(v); err != nil {
+ if removalErr != nil {
+ logrus.Errorf("Error removing volume %s from plugin %s: %v", v.Name(), v.Driver(), removalErr)
+ }
+ return errors.Wrapf(err, "error removing volume %s", v.Name())
+ }
+
// Free the volume's lock
if err := v.lock.Free(); err != nil {
if removalErr == nil {
diff --git a/libpod/shutdown/handler.go b/libpod/shutdown/handler.go
index 848b6729a..1e8a9ec3b 100644
--- a/libpod/shutdown/handler.go
+++ b/libpod/shutdown/handler.go
@@ -35,7 +35,7 @@ func Start() error {
return nil
}
- sigChan = make(chan os.Signal, 1)
+ sigChan = make(chan os.Signal, 2)
cancelChan = make(chan bool, 1)
stopped = false
diff --git a/pkg/api/handlers/libpod/images_pull.go b/pkg/api/handlers/libpod/images_pull.go
index 04b415638..3c13c6e20 100644
--- a/pkg/api/handlers/libpod/images_pull.go
+++ b/pkg/api/handlers/libpod/images_pull.go
@@ -33,6 +33,7 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
TLSVerify bool `schema:"tlsVerify"`
AllTags bool `schema:"allTags"`
PullPolicy string `schema:"policy"`
+ Quiet bool `schema:"quiet"`
}{
TLSVerify: true,
PullPolicy: "always",
@@ -116,8 +117,10 @@ func ImagesPull(w http.ResponseWriter, r *http.Request) {
select {
case s := <-writer.Chan():
report.Stream = string(s)
- if err := enc.Encode(report); err != nil {
- logrus.Warnf("Failed to encode json: %v", err)
+ if !query.Quiet {
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to encode json: %v", err)
+ }
}
flush()
case <-runCtx.Done():
diff --git a/pkg/api/handlers/utils/images.go b/pkg/api/handlers/utils/images.go
index 1e8edb6dd..1e3647a3e 100644
--- a/pkg/api/handlers/utils/images.go
+++ b/pkg/api/handlers/utils/images.go
@@ -27,7 +27,7 @@ func IsRegistryReference(name string) error {
if imageRef.Transport().Name() == docker.Transport.Name() {
return nil
}
- return errors.Errorf("unsupport transport %s in %q: only docker transport is supported", imageRef.Transport().Name(), name)
+ return errors.Errorf("unsupported transport %s in %q: only docker transport is supported", imageRef.Transport().Name(), name)
}
// ParseStorageReference parses the specified image name to a
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index 866eb2347..2630acac2 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -983,6 +983,15 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: "Mandatory reference to the image (e.g., quay.io/image/name:tag)"
// type: string
// - in: query
+ // name: quiet
+ // description: "silences extra stream data on pull"
+ // type: boolean
+ // default: false
+ // - in: query
+ // name: credentials
+ // description: "username:password for the registry"
+ // type: string
+ // - in: query
// name: Arch
// description: Pull image for the specified architecture.
// type: string
diff --git a/pkg/bindings/connection.go b/pkg/bindings/connection.go
index 62b1655ac..cd118cbb2 100644
--- a/pkg/bindings/connection.go
+++ b/pkg/bindings/connection.go
@@ -117,7 +117,7 @@ func NewConnectionWithIdentity(ctx context.Context, uri string, identity string)
ctx = context.WithValue(ctx, clientKey, &connection)
if err := pingNewConnection(ctx); err != nil {
- return nil, errors.Wrap(err, "cannot connect to the Podman socket, please verify that Podman REST API service is running")
+ return nil, errors.Wrap(err, "cannot connect to the Podman socket, please verify the connection to the Linux system, or use `podman machine` to create/start a Linux VM.")
}
return ctx, nil
}
diff --git a/pkg/bindings/images/build.go b/pkg/bindings/images/build.go
index e1aeae244..39e0fc5df 100644
--- a/pkg/bindings/images/build.go
+++ b/pkg/bindings/images/build.go
@@ -481,9 +481,9 @@ func nTar(excludes []string, sources ...string) (io.ReadCloser, error) {
return nil // skip root dir
}
- name := strings.TrimPrefix(path, s+string(filepath.Separator))
+ name := filepath.ToSlash(strings.TrimPrefix(path, s+string(filepath.Separator)))
- excluded, err := pm.Matches(filepath.ToSlash(name)) // nolint:staticcheck
+ excluded, err := pm.Matches(name) // nolint:staticcheck
if err != nil {
return errors.Wrapf(err, "error checking if %q is excluded", name)
}
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index 89dfc08e9..01de73ebe 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -10,6 +10,8 @@ import (
type PlayKubeOptions struct {
// Authfile - path to an authentication file.
Authfile string
+ // Indicator to build all images with Containerfile or Dockerfile
+ Build bool
// CertDir - to a directory containing TLS certifications and keys.
CertDir string
// Username for authenticating against the registry.
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index dc9fed2a4..269cd2d27 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -214,7 +214,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
networkMode := c.NetworkMode()
// support docker like `--filter network=container:<IDorName>`
// check if networkMode is configured as `container:<ctr>`
- // peform a match against filter `container:<IDorName>`
+ // perform a match against filter `container:<IDorName>`
// networks is already going to be empty if `container:<ctr>` is configured as Mode
if strings.HasPrefix(networkMode, "container:") {
networkModeContainerPart := strings.SplitN(networkMode, ":", 2)
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index d257bad18..6224feff5 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -7,9 +7,11 @@ import (
"io"
"io/ioutil"
"os"
+ "path/filepath"
"strconv"
"strings"
+ buildahDefine "github.com/containers/buildah/define"
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
"github.com/containers/image/v5/types"
@@ -266,39 +268,69 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
}
containers := make([]*libpod.Container, 0, len(podYAML.Spec.Containers))
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
for _, container := range podYAML.Spec.Containers {
// Contains all labels obtained from kube
labels := make(map[string]string)
-
- // NOTE: set the pull policy to "newer". This will cover cases
- // where the "latest" tag requires a pull and will also
- // transparently handle "localhost/" prefixed files which *may*
- // refer to a locally built image OR an image running a
- // registry on localhost.
- pullPolicy := config.PullPolicyNewer
- if len(container.ImagePullPolicy) > 0 {
- // Make sure to lower the strings since K8s pull policy
- // may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905).
- rawPolicy := string(container.ImagePullPolicy)
- pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy))
- if err != nil {
- return nil, err
- }
+ var pulledImage *libimage.Image
+ buildFile, err := getBuildFile(container.Image, cwd)
+ if err != nil {
+ return nil, err
}
- // This ensures the image is the image store
- pullOptions := &libimage.PullOptions{}
- pullOptions.AuthFilePath = options.Authfile
- pullOptions.CertDirPath = options.CertDir
- pullOptions.SignaturePolicyPath = options.SignaturePolicy
- pullOptions.Writer = writer
- pullOptions.Username = options.Username
- pullOptions.Password = options.Password
- pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
-
- pulledImages, err := ic.Libpod.LibimageRuntime().Pull(ctx, container.Image, pullPolicy, pullOptions)
+ existsLocally, err := ic.Libpod.LibimageRuntime().Exists(container.Image)
if err != nil {
return nil, err
}
+ if (len(buildFile) > 0 && !existsLocally) || (len(buildFile) > 0 && options.Build) {
+ buildOpts := new(buildahDefine.BuildOptions)
+ commonOpts := new(buildahDefine.CommonBuildOptions)
+ buildOpts.ConfigureNetwork = buildahDefine.NetworkDefault
+ buildOpts.Isolation = buildahDefine.IsolationChroot
+ buildOpts.CommonBuildOpts = commonOpts
+ buildOpts.Output = container.Image
+ if _, _, err := ic.Libpod.Build(ctx, *buildOpts, []string{buildFile}...); err != nil {
+ return nil, err
+ }
+ i, _, err := ic.Libpod.LibimageRuntime().LookupImage(container.Image, new(libimage.LookupImageOptions))
+ if err != nil {
+ return nil, err
+ }
+ pulledImage = i
+ } else {
+ // NOTE: set the pull policy to "newer". This will cover cases
+ // where the "latest" tag requires a pull and will also
+ // transparently handle "localhost/" prefixed files which *may*
+ // refer to a locally built image OR an image running a
+ // registry on localhost.
+ pullPolicy := config.PullPolicyNewer
+ if len(container.ImagePullPolicy) > 0 {
+ // Make sure to lower the strings since K8s pull policy
+ // may be capitalized (see bugzilla.redhat.com/show_bug.cgi?id=1985905).
+ rawPolicy := string(container.ImagePullPolicy)
+ pullPolicy, err = config.ParsePullPolicy(strings.ToLower(rawPolicy))
+ if err != nil {
+ return nil, err
+ }
+ }
+ // This ensures the image is the image store
+ pullOptions := &libimage.PullOptions{}
+ pullOptions.AuthFilePath = options.Authfile
+ pullOptions.CertDirPath = options.CertDir
+ pullOptions.SignaturePolicyPath = options.SignaturePolicy
+ pullOptions.Writer = writer
+ pullOptions.Username = options.Username
+ pullOptions.Password = options.Password
+ pullOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
+
+ pulledImages, err := ic.Libpod.LibimageRuntime().Pull(ctx, container.Image, pullPolicy, pullOptions)
+ if err != nil {
+ return nil, err
+ }
+ pulledImage = pulledImages[0]
+ }
// Handle kube annotations
for k, v := range annotations {
@@ -318,7 +350,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
specgenOpts := kube.CtrSpecGenOptions{
Container: container,
- Image: pulledImages[0],
+ Image: pulledImage,
Volumes: volumes,
PodID: pod.ID(),
PodName: podName,
@@ -509,3 +541,48 @@ func sortKubeKinds(documentList [][]byte) ([][]byte, error) {
return sortedDocumentList, nil
}
+func imageNamePrefix(imageName string) string {
+ prefix := imageName
+ s := strings.Split(prefix, ":")
+ if len(s) > 0 {
+ prefix = s[0]
+ }
+ s = strings.Split(prefix, "/")
+ if len(s) > 0 {
+ prefix = s[len(s)-1]
+ }
+ s = strings.Split(prefix, "@")
+ if len(s) > 0 {
+ prefix = s[0]
+ }
+ return prefix
+}
+
+func getBuildFile(imageName string, cwd string) (string, error) {
+ buildDirName := imageNamePrefix(imageName)
+ containerfilePath := filepath.Join(cwd, buildDirName, "Containerfile")
+ dockerfilePath := filepath.Join(cwd, buildDirName, "Dockerfile")
+
+ _, err := os.Stat(filepath.Join(containerfilePath))
+ if err == nil {
+ logrus.Debugf("building %s with %s", imageName, containerfilePath)
+ return containerfilePath, nil
+ }
+ // If the error is not because the file does not exist, take
+ // a mulligan and try Dockerfile. If that also fails, return that
+ // error
+ if err != nil && !os.IsNotExist(err) {
+ logrus.Errorf("%v: unable to check for %s", err, containerfilePath)
+ }
+
+ _, err = os.Stat(filepath.Join(dockerfilePath))
+ if err == nil {
+ logrus.Debugf("building %s with %s", imageName, dockerfilePath)
+ return dockerfilePath, nil
+ }
+ // Strike two
+ if os.IsNotExist(err) {
+ return "", nil
+ }
+ return "", err
+}
diff --git a/pkg/domain/infra/abi/terminal/sigproxy_linux.go b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
index 26e199aee..a9bd2d5fb 100644
--- a/pkg/domain/infra/abi/terminal/sigproxy_linux.go
+++ b/pkg/domain/infra/abi/terminal/sigproxy_linux.go
@@ -12,13 +12,17 @@ import (
"github.com/sirupsen/logrus"
)
+// Make sure the signal buffer is sufficiently big.
+// runc is using the same value.
+const signalBufferSize = 2048
+
// ProxySignals ...
func ProxySignals(ctr *libpod.Container) {
// Stop catching the shutdown signals (SIGINT, SIGTERM) - they're going
// to the container now.
shutdown.Stop()
- sigBuffer := make(chan os.Signal, 128)
+ sigBuffer := make(chan os.Signal, signalBufferSize)
signal.CatchAll(sigBuffer)
logrus.Debugf("Enabling signal proxying")
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 7b1ebcb03..a92892957 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -605,10 +605,12 @@ func CheckActiveVM() (bool, string, error) {
// startHostNetworking runs a binary on the host system that allows users
// to setup port forwarding to the podman virtual machine
func (v *MachineVM) startHostNetworking() error {
- binary := filepath.Join("/usr/lib/podman/", machine.ForwarderBinaryName)
- if _, err := os.Stat(binary); os.IsNotExist(err) {
- return errors.Errorf("unable to find %s", binary)
+ // TODO we may wish to configure the directory in containers common
+ binary := filepath.Join("/usr/libexec/podman/", machine.ForwarderBinaryName)
+ if _, err := os.Stat(binary); err != nil {
+ return err
}
+
// Listen on all at port 7777 for setting up and tearing
// down forwarding
listenSocket := "tcp://0.0.0.0:7777"
diff --git a/pkg/rootless/rootless_linux.go b/pkg/rootless/rootless_linux.go
index 9ef56acb4..c046ecde7 100644
--- a/pkg/rootless/rootless_linux.go
+++ b/pkg/rootless/rootless_linux.go
@@ -397,8 +397,6 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
return false, -1, errors.Wrapf(err, "error setting up the process")
}
- c := make(chan os.Signal, 1)
-
signals := []os.Signal{}
for sig := 0; sig < numSig; sig++ {
if sig == int(unix.SIGTSTP) {
@@ -407,6 +405,7 @@ func becomeRootInUserNS(pausePid, fileToRead string, fileOutput *os.File) (_ boo
signals = append(signals, unix.Signal(sig))
}
+ c := make(chan os.Signal, len(signals))
gosignal.Notify(c, signals...)
defer gosignal.Reset()
go func() {
diff --git a/pkg/rootlessport/rootlessport_linux.go b/pkg/rootlessport/rootlessport_linux.go
index ede216bfe..9a2f93f8e 100644
--- a/pkg/rootlessport/rootlessport_linux.go
+++ b/pkg/rootlessport/rootlessport_linux.go
@@ -20,7 +20,6 @@ import (
"net"
"os"
"os/exec"
- "os/signal"
"path/filepath"
"github.com/containernetworking/plugins/pkg/ns"
@@ -106,30 +105,6 @@ func parent() error {
return err
}
- exitC := make(chan os.Signal, 1)
- defer close(exitC)
-
- go func() {
- sigC := make(chan os.Signal, 1)
- signal.Notify(sigC, unix.SIGPIPE)
- defer func() {
- signal.Stop(sigC)
- close(sigC)
- }()
-
- select {
- case s := <-sigC:
- if s == unix.SIGPIPE {
- if f, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755); err == nil {
- unix.Dup2(int(f.Fd()), 1) // nolint:errcheck
- unix.Dup2(int(f.Fd()), 2) // nolint:errcheck
- f.Close()
- }
- }
- case <-exitC:
- }
- }()
-
socketDir := filepath.Join(cfg.TmpDir, "rp")
err = os.MkdirAll(socketDir, 0700)
if err != nil {
@@ -251,8 +226,16 @@ outer:
go serve(socket, driver)
}
- // write and close ReadyFD (convention is same as slirp4netns --ready-fd)
logrus.Info("ready")
+
+ // https://github.com/containers/podman/issues/11248
+ // Copy /dev/null to stdout and stderr to prevent SIGPIPE errors
+ if f, err := os.OpenFile("/dev/null", os.O_WRONLY, 0755); err == nil {
+ unix.Dup2(int(f.Fd()), 1) // nolint:errcheck
+ unix.Dup2(int(f.Fd()), 2) // nolint:errcheck
+ f.Close()
+ }
+ // write and close ReadyFD (convention is same as slirp4netns --ready-fd)
if _, err := readyW.Write([]byte("1")); err != nil {
return err
}
diff --git a/pkg/specgen/generate/storage.go b/pkg/specgen/generate/storage.go
index 13f336594..de655ad7d 100644
--- a/pkg/specgen/generate/storage.go
+++ b/pkg/specgen/generate/storage.go
@@ -10,6 +10,7 @@ import (
"github.com/containers/common/libimage"
"github.com/containers/common/pkg/config"
+ "github.com/containers/common/pkg/parse"
"github.com/containers/podman/v3/libpod"
"github.com/containers/podman/v3/libpod/define"
"github.com/containers/podman/v3/pkg/specgen"
@@ -59,6 +60,9 @@ func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Ru
for _, m := range s.Mounts {
// Ensure that mount dest is clean, so that it can be
// compared against named volumes and avoid duplicate mounts.
+ if err = parse.ValidateVolumeCtrDir(m.Destination); err != nil {
+ return nil, nil, nil, err
+ }
cleanDestination := filepath.Clean(m.Destination)
if _, ok := unifiedMounts[cleanDestination]; ok {
return nil, nil, nil, errors.Wrapf(errDuplicateDest, "conflict in specified mounts - multiple mounts at %q", cleanDestination)
@@ -67,34 +71,54 @@ func finalizeMounts(ctx context.Context, s *specgen.SpecGenerator, rt *libpod.Ru
}
for _, m := range commonMounts {
- if _, ok := unifiedMounts[m.Destination]; !ok {
- unifiedMounts[m.Destination] = m
+ if err = parse.ValidateVolumeCtrDir(m.Destination); err != nil {
+ return nil, nil, nil, err
+ }
+ cleanDestination := filepath.Clean(m.Destination)
+ if _, ok := unifiedMounts[cleanDestination]; !ok {
+ unifiedMounts[cleanDestination] = m
}
}
for _, v := range s.Volumes {
- if _, ok := unifiedVolumes[v.Dest]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, "conflict in specified volumes - multiple volumes at %q", v.Dest)
+ if err = parse.ValidateVolumeCtrDir(v.Dest); err != nil {
+ return nil, nil, nil, err
}
- unifiedVolumes[v.Dest] = v
+ cleanDestination := filepath.Clean(v.Dest)
+ if _, ok := unifiedVolumes[cleanDestination]; ok {
+ return nil, nil, nil, errors.Wrapf(errDuplicateDest, "conflict in specified volumes - multiple volumes at %q", cleanDestination)
+ }
+ unifiedVolumes[cleanDestination] = v
}
for _, v := range commonVolumes {
- if _, ok := unifiedVolumes[v.Dest]; !ok {
- unifiedVolumes[v.Dest] = v
+ if err = parse.ValidateVolumeCtrDir(v.Dest); err != nil {
+ return nil, nil, nil, err
+ }
+ cleanDestination := filepath.Clean(v.Dest)
+ if _, ok := unifiedVolumes[cleanDestination]; !ok {
+ unifiedVolumes[cleanDestination] = v
}
}
for _, v := range s.OverlayVolumes {
- if _, ok := unifiedOverlays[v.Destination]; ok {
- return nil, nil, nil, errors.Wrapf(errDuplicateDest, "conflict in specified volumes - multiple volumes at %q", v.Destination)
+ if err = parse.ValidateVolumeCtrDir(v.Destination); err != nil {
+ return nil, nil, nil, err
}
- unifiedOverlays[v.Destination] = v
+ cleanDestination := filepath.Clean(v.Destination)
+ if _, ok := unifiedOverlays[cleanDestination]; ok {
+ return nil, nil, nil, errors.Wrapf(errDuplicateDest, "conflict in specified volumes - multiple volumes at %q", cleanDestination)
+ }
+ unifiedOverlays[cleanDestination] = v
}
for _, v := range commonOverlayVolumes {
- if _, ok := unifiedOverlays[v.Destination]; ok {
- unifiedOverlays[v.Destination] = v
+ if err = parse.ValidateVolumeCtrDir(v.Destination); err != nil {
+ return nil, nil, nil, err
+ }
+ cleanDestination := filepath.Clean(v.Destination)
+ if _, ok := unifiedOverlays[cleanDestination]; !ok {
+ unifiedOverlays[cleanDestination] = v
}
}
@@ -190,6 +214,9 @@ 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":
@@ -304,9 +331,13 @@ func getVolumesFrom(volumesFrom []string, runtime *libpod.Runtime) (map[string]s
if _, ok := finalMounts[namedVol.Dest]; ok {
logrus.Debugf("Overriding named volume mount to %s with new named volume from container %s", namedVol.Dest, ctr.ID())
}
+ if err = parse.ValidateVolumeCtrDir(namedVol.Dest); err != nil {
+ return nil, nil, err
+ }
+ cleanDest := filepath.Clean(namedVol.Dest)
newVol := new(specgen.NamedVolume)
- newVol.Dest = namedVol.Dest
+ newVol.Dest = cleanDest
newVol.Options = namedVol.Options
newVol.Name = namedVol.Name
diff --git a/pkg/specgen/specgen.go b/pkg/specgen/specgen.go
index fc647227e..2252ef405 100644
--- a/pkg/specgen/specgen.go
+++ b/pkg/specgen/specgen.go
@@ -184,7 +184,7 @@ type ContainerBasicConfig struct {
// Optional.
EnvSecrets map[string]string `json:"secret_env,omitempty"`
// InitContainerType describes if this container is an init container
- // and if so, what type: always or oneshot
+ // and if so, what type: always or once
InitContainerType string `json:"init_container_type"`
// Personality allows users to configure different execution domains.
// Execution domains tell Linux how to map signal numbers into signal actions.
diff --git a/pkg/specgen/volumes.go b/pkg/specgen/volumes.go
index d85d2bdd1..eca8c0c35 100644
--- a/pkg/specgen/volumes.go
+++ b/pkg/specgen/volumes.go
@@ -1,7 +1,6 @@
package specgen
import (
- "path/filepath"
"strings"
"github.com/containers/common/pkg/parse"
@@ -93,11 +92,6 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
return nil, nil, nil, errors.New("host directory cannot be empty")
}
}
- if err := parse.ValidateVolumeCtrDir(dest); err != nil {
- return nil, nil, nil, err
- }
-
- cleanDest := filepath.Clean(dest)
if strings.HasPrefix(src, "/") || strings.HasPrefix(src, ".") {
// This is not a named volume
@@ -120,7 +114,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
if overlayFlag {
// This is a overlay volume
newOverlayVol := new(OverlayVolume)
- newOverlayVol.Destination = cleanDest
+ newOverlayVol.Destination = dest
newOverlayVol.Source = src
newOverlayVol.Options = options
@@ -130,7 +124,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
overlayVolumes[newOverlayVol.Destination] = newOverlayVol
} else {
newMount := spec.Mount{
- Destination: cleanDest,
+ Destination: dest,
Type: "bind",
Source: src,
Options: options,
@@ -144,7 +138,7 @@ func GenVolumeMounts(volumeFlag []string) (map[string]spec.Mount, map[string]*Na
// This is a named volume
newNamedVol := new(NamedVolume)
newNamedVol.Name = src
- newNamedVol.Dest = cleanDest
+ newNamedVol.Dest = dest
newNamedVol.Options = options
if _, ok := volumes[newNamedVol.Dest]; ok {
diff --git a/pkg/systemd/dbus.go b/pkg/systemd/dbus.go
index 718082526..c49f537b6 100644
--- a/pkg/systemd/dbus.go
+++ b/pkg/systemd/dbus.go
@@ -9,8 +9,106 @@ import (
"github.com/containers/podman/v3/pkg/rootless"
"github.com/coreos/go-systemd/v22/dbus"
godbus "github.com/godbus/dbus/v5"
+ "github.com/sirupsen/logrus"
)
+// IsSystemdSessionValid checks if sessions is valid for provided rootless uid.
+func IsSystemdSessionValid(uid int) bool {
+ var conn *godbus.Conn
+ var err error
+ var object godbus.BusObject
+ var seat0Path godbus.ObjectPath
+ dbusDest := "org.freedesktop.login1"
+ dbusInterface := "org.freedesktop.login1.Manager"
+ dbusPath := "/org/freedesktop/login1"
+
+ if rootless.IsRootless() {
+ conn, err = GetLogindConnection(rootless.GetRootlessUID())
+ object = conn.Object(dbusDest, godbus.ObjectPath(dbusPath))
+ if err != nil {
+ //unable to fetch systemd object for logind
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ object = conn.Object(dbusDest, godbus.ObjectPath(dbusPath))
+ if err := object.Call(dbusInterface+".GetSeat", 0, "seat0").Store(&seat0Path); err != nil {
+ //unable to get seat0 path.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ seat0Obj := conn.Object(dbusDest, seat0Path)
+ activeSession, err := seat0Obj.GetProperty(dbusDest + ".Seat.ActiveSession")
+ if err != nil {
+ //unable to get active sessions.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ activeSessionMap, ok := activeSession.Value().([]interface{})
+ if !ok || len(activeSessionMap) < 2 {
+ //unable to get active session map.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ activeSessionPath, ok := activeSessionMap[1].(godbus.ObjectPath)
+ if !ok {
+ //unable to fetch active session path.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ activeSessionObj := conn.Object(dbusDest, activeSessionPath)
+ sessionUser, err := activeSessionObj.GetProperty(dbusDest + ".Session.User")
+ if err != nil {
+ //unable to fetch session user from activeSession path.
+ logrus.Debugf("systemd-logind: %s", err)
+ return false
+ }
+ dbusUser, ok := sessionUser.Value().([]interface{})
+ if !ok {
+ // not a valid user.
+ return false
+ }
+ if len(dbusUser) < 2 {
+ // not a valid session user.
+ return false
+ }
+ activeUID, ok := dbusUser[0].(uint32)
+ if !ok {
+ return false
+ }
+ //active session found which belongs to following rootless user
+ if activeUID == uint32(uid) {
+ return true
+ }
+ return false
+ }
+ return true
+}
+
+// GetDbusConnection returns an user connection to D-BUS
+func GetLogindConnection(uid int) (*godbus.Conn, error) {
+ return dbusAuthConnectionLogind(uid)
+}
+
+func dbusAuthConnectionLogind(uid int) (*godbus.Conn, error) {
+ var conn *godbus.Conn
+ var err error
+ conn, err = godbus.SystemBusPrivate()
+ if err != nil {
+ return nil, err
+ }
+ methods := []godbus.Auth{godbus.AuthExternal(strconv.Itoa(uid))}
+ if err = conn.Auth(methods); err != nil {
+ conn.Close()
+ return nil, err
+ }
+ err = conn.Hello()
+ if err != nil {
+ conn.Close()
+ return nil, err
+ }
+ return conn, nil
+}
+
func dbusAuthRootlessConnection(createBus func(opts ...godbus.ConnOption) (*godbus.Conn, error)) (*godbus.Conn, error) {
conn, err := createBus()
if err != nil {
diff --git a/pkg/util/utils.go b/pkg/util/utils.go
index 774590f44..63fad0286 100644
--- a/pkg/util/utils.go
+++ b/pkg/util/utils.go
@@ -618,6 +618,12 @@ func ValidateSysctls(strSlice []string) (map[string]string, error) {
if len(arr) < 2 {
return nil, errors.Errorf("%s is invalid, sysctl values must be in the form of KEY=VALUE", val)
}
+
+ trimmed := fmt.Sprintf("%s=%s", strings.TrimSpace(arr[0]), strings.TrimSpace(arr[1]))
+ if trimmed != val {
+ return nil, errors.Errorf("'%s' is invalid, extra spaces found", val)
+ }
+
if validSysctlMap[arr[0]] {
sysctl[arr[0]] = arr[1]
continue
diff --git a/pkg/util/utils_test.go b/pkg/util/utils_test.go
index 027acbdab..62de7509f 100644
--- a/pkg/util/utils_test.go
+++ b/pkg/util/utils_test.go
@@ -1,6 +1,7 @@
package util
import (
+ "fmt"
"testing"
"time"
@@ -259,6 +260,28 @@ func TestValidateSysctlBadSysctl(t *testing.T) {
assert.Error(t, err)
}
+func TestValidateSysctlBadSysctlWithExtraSpaces(t *testing.T) {
+ expectedError := "'%s' is invalid, extra spaces found"
+
+ // should fail fast on first sysctl
+ strSlice1 := []string{
+ "net.ipv4.ping_group_range = 0 0",
+ "net.ipv4.ping_group_range=0 0 ",
+ }
+ _, err := ValidateSysctls(strSlice1)
+ assert.Error(t, err)
+ assert.Equal(t, err.Error(), fmt.Sprintf(expectedError, strSlice1[0]))
+
+ // should fail on second sysctl
+ strSlice2 := []string{
+ "net.ipv4.ping_group_range=0 0",
+ "net.ipv4.ping_group_range=0 0 ",
+ }
+ _, err = ValidateSysctls(strSlice2)
+ assert.Error(t, err)
+ assert.Equal(t, err.Error(), fmt.Sprintf(expectedError, strSlice2[1]))
+}
+
func TestCoresToPeriodAndQuota(t *testing.T) {
cores := 1.0
expectedPeriod := DefaultCPUPeriod
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 610d3e36d..e2eb94233 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -356,3 +356,14 @@ t GET containers/$cid/json 200 \
.HostConfig.NetworkMode="bridge"
t DELETE containers/$cid?v=true 204
+
+# Test Compat Create with healthcheck, check default values
+t POST containers/create Image=$IMAGE Cmd='["top"]' Healthcheck='{"Test":["true"]}' 201 \
+ .Id~[0-9a-f]\\{64\\}
+cid=$(jq -r '.Id' <<<"$output")
+t GET containers/$cid/json 200 \
+ .Config.Healthcheck.Interval=30000000000 \
+ .Config.Healthcheck.Timeout=30000000000 \
+ .Config.Healthcheck.Retries=3
+
+t DELETE containers/$cid?v=true 204
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_image.py b/test/apiv2/python/rest_api/test_v2_0_0_image.py
index 3e8ecb1ef..bcacaa935 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_image.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_image.py
@@ -87,6 +87,27 @@ class ImageTestCase(APITestCase):
self.assertTrue(keys["images"], "Expected to find images stanza")
self.assertTrue(keys["stream"], "Expected to find stream progress stanza's")
+ r = requests.post(self.uri("/images/pull?reference=alpine&quiet=true"), timeout=15)
+ self.assertEqual(r.status_code, 200, r.status_code)
+ text = r.text
+ keys = {
+ "error": False,
+ "id": False,
+ "images": False,
+ "stream": False,
+ }
+ # Read and record stanza's from pull
+ for line in str.splitlines(text):
+ obj = json.loads(line)
+ key_list = list(obj.keys())
+ for k in key_list:
+ keys[k] = True
+
+ self.assertFalse(keys["error"], "Expected no errors")
+ self.assertTrue(keys["id"], "Expected to find id stanza")
+ self.assertTrue(keys["images"], "Expected to find images stanza")
+ self.assertFalse(keys["stream"], "Expected to find stream progress stanza's")
+
def test_create(self):
r = requests.post(
self.podman_url + "/v1.40/images/create?fromImage=alpine&platform=linux/amd64/v8",
diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas
index 18b3d56f9..44a33b0b8 100755
--- a/test/buildah-bud/apply-podman-deltas
+++ b/test/buildah-bud/apply-podman-deltas
@@ -165,14 +165,6 @@ skip "FIXME FIXME FIXME: this passes on Ed's laptop, fails in CI??" \
skip "buildah runs with --cgroup-manager=cgroupfs, podman with systemd" \
"bud with --cgroup-parent"
-# see https://github.com/containers/podman/pull/10829
-skip "FIXME FIXME FIXME - requires updated CI images (#10829)" \
- "bud with --runtime and --runtime-flag"
-
-###############################################################################
-# BEGIN tests which are skipped due to actual podman bugs.
-
-
###############################################################################
# BEGIN tests which are skipped because they make no sense under podman-remote
diff --git a/test/compose/mount_and_label/docker-compose.yml b/test/compose/mount_and_label/docker-compose.yml
index 112d7e134..81fda2512 100644
--- a/test/compose/mount_and_label/docker-compose.yml
+++ b/test/compose/mount_and_label/docker-compose.yml
@@ -6,5 +6,7 @@ services:
- '5000:5000'
volumes:
- /tmp/data:/data:ro
+ security_opt:
+ - label=disable
labels:
- "io.podman=the_best"
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 2e48e1763..6b97c4162 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -645,9 +645,13 @@ func isRootless() bool {
return os.Geteuid() != 0
}
+func isCgroupsV1() bool {
+ return !CGROUPSV2
+}
+
func SkipIfCgroupV1(reason string) {
checkReason(reason)
- if !CGROUPSV2 {
+ if isCgroupsV1() {
Skip(reason)
}
}
@@ -841,3 +845,18 @@ func (p *PodmanTestIntegration) buildImage(dockerfile, imageName string, layers
output := session.OutputToStringArray()
return output[len(output)-1]
}
+
+func writeYaml(content string, fileName string) error {
+ f, err := os.Create(fileName)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ _, err = f.WriteString(content)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/test/e2e/login_logout_test.go b/test/e2e/login_logout_test.go
index 7ad1fc1f2..d8ca9cbd9 100644
--- a/test/e2e/login_logout_test.go
+++ b/test/e2e/login_logout_test.go
@@ -79,9 +79,9 @@ var _ = Describe("Podman login and logout", func() {
session = podmanTest.Podman([]string{"run", "-d", "-p", strings.Join([]string{strconv.Itoa(port), strconv.Itoa(port)}, ":"),
"-e", strings.Join([]string{"REGISTRY_HTTP_ADDR=0.0.0.0", strconv.Itoa(port)}, ":"), "--name", "registry", "-v",
- strings.Join([]string{authPath, "/auth"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e",
+ strings.Join([]string{authPath, "/auth:Z"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e",
"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd",
- "-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
+ "-v", strings.Join([]string{certPath, "/certs:Z"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
"-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", "registry:2.6"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
@@ -235,10 +235,13 @@ var _ = Describe("Podman login and logout", func() {
setup.WaitWithDefaultTimeout()
defer os.RemoveAll(certDir)
+ // N/B: This second registry container shares the same auth and cert dirs
+ // as the registry started from BeforeEach(). Since this one starts
+ // second, re-labeling the volumes should keep SELinux happy.
session := podmanTest.Podman([]string{"run", "-d", "-p", "9001:9001", "-e", "REGISTRY_HTTP_ADDR=0.0.0.0:9001", "--name", "registry1", "-v",
- strings.Join([]string{authPath, "/auth"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e",
+ strings.Join([]string{authPath, "/auth:z"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e",
"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd",
- "-v", strings.Join([]string{certPath, "/certs"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
+ "-v", strings.Join([]string{certPath, "/certs:z"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
"-e", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key", "registry:2.6"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
diff --git a/test/e2e/play_build_test.go b/test/e2e/play_build_test.go
new file mode 100644
index 000000000..16f2687f3
--- /dev/null
+++ b/test/e2e/play_build_test.go
@@ -0,0 +1,243 @@
+// +build !remote
+
+// build for play kube is not supported on remote yet.
+
+package integration
+
+import (
+ "os"
+ "path/filepath"
+
+ . "github.com/containers/podman/v3/test/utils"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ . "github.com/onsi/gomega/gexec"
+)
+
+var _ = Describe("Podman play kube with build", 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)
+
+ })
+
+ var testYAML = `
+apiVersion: v1
+kind: Pod
+metadata:
+ creationTimestamp: "2021-08-05T17:55:51Z"
+ labels:
+ app: foobar
+ name: top_pod
+spec:
+ containers:
+ - command:
+ - top
+ env:
+ - name: PATH
+ value: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
+ - name: TERM
+ value: xterm
+ - name: container
+ value: podman
+ image: foobar
+ name: foobar
+ resources: {}
+ securityContext:
+ allowPrivilegeEscalation: true
+ capabilities:
+ drop:
+ - CAP_MKNOD
+ - CAP_NET_RAW
+ - CAP_AUDIT_WRITE
+ privileged: false
+ readOnlyRootFilesystem: false
+ seLinuxOptions: {}
+ tty: true
+ workingDir: /
+ dnsConfig: {}
+status: {}
+`
+
+ var playBuildFile = `
+FROM quay.io/libpod/alpine_nginx:latest
+RUN apk update && apk add strace
+LABEL homer=dad
+`
+ var prebuiltImage = `
+FROM quay.io/libpod/alpine_nginx:latest
+RUN apk update && apk add strace
+LABEL marge=mom
+`
+ It("Check that image is built using Dockerfile", func() {
+ // Setup
+ yamlDir := filepath.Join(tempdir, RandomString(12))
+ err := os.Mkdir(yamlDir, 0755)
+ err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
+ Expect(err).To(BeNil())
+ app1Dir := filepath.Join(yamlDir, "foobar")
+ err = os.Mkdir(app1Dir, 0755)
+ Expect(err).To(BeNil())
+ err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Dockerfile"))
+ Expect(err).To(BeNil())
+
+ // Switch to temp dir and restore it afterwards
+ cwd, err := os.Getwd()
+ Expect(err).To(BeNil())
+ Expect(os.Chdir(yamlDir)).To(BeNil())
+ defer func() { (Expect(os.Chdir(cwd)).To(BeNil())) }()
+
+ session := podmanTest.Podman([]string{"play", "kube", "top.yaml"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ exists := podmanTest.Podman([]string{"image", "exists", "foobar"})
+ exists.WaitWithDefaultTimeout()
+ Expect(exists).Should(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ inspectData := inspect.InspectContainerToJSON()
+ Expect(len(inspectData)).To(BeNumerically(">", 0))
+ Expect(inspectData[0].Config.Labels["homer"]).To(Equal("dad"))
+ })
+
+ It("Check that image is built using Containerfile", func() {
+ // Setup
+ yamlDir := filepath.Join(tempdir, RandomString(12))
+ err := os.Mkdir(yamlDir, 0755)
+ err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
+ Expect(err).To(BeNil())
+ app1Dir := filepath.Join(yamlDir, "foobar")
+ err = os.Mkdir(app1Dir, 0755)
+ Expect(err).To(BeNil())
+ err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
+ Expect(err).To(BeNil())
+
+ // Switch to temp dir and restore it afterwards
+ cwd, err := os.Getwd()
+ Expect(err).To(BeNil())
+ Expect(os.Chdir(yamlDir)).To(BeNil())
+ defer func() { (Expect(os.Chdir(cwd)).To(BeNil())) }()
+
+ session := podmanTest.Podman([]string{"play", "kube", "top.yaml"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ exists := podmanTest.Podman([]string{"image", "exists", "foobar"})
+ exists.WaitWithDefaultTimeout()
+ Expect(exists).Should(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ inspectData := inspect.InspectContainerToJSON()
+ Expect(len(inspectData)).To(BeNumerically(">", 0))
+ Expect(inspectData[0].Config.Labels["homer"]).To(Equal("dad"))
+ })
+
+ It("Do not build image if already in the local store", func() {
+ // Setup
+ yamlDir := filepath.Join(tempdir, RandomString(12))
+ err := os.Mkdir(yamlDir, 0755)
+ err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
+ Expect(err).To(BeNil())
+
+ // build an image called foobar but make sure it doesnt have
+ // the same label as the yaml buildfile, so we can check that
+ // the image is NOT rebuilt.
+ err = writeYaml(prebuiltImage, filepath.Join(yamlDir, "Containerfile"))
+ Expect(err).To(BeNil())
+
+ app1Dir := filepath.Join(yamlDir, "foobar")
+ err = os.Mkdir(app1Dir, 0755)
+ Expect(err).To(BeNil())
+ err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
+ Expect(err).To(BeNil())
+
+ // Switch to temp dir and restore it afterwards
+ cwd, err := os.Getwd()
+ Expect(err).To(BeNil())
+ Expect(os.Chdir(yamlDir)).To(BeNil())
+ defer func() { (Expect(os.Chdir(cwd)).To(BeNil())) }()
+
+ // Build the image into the local store
+ build := podmanTest.Podman([]string{"build", "-t", "foobar", "-f", "Containerfile"})
+ build.WaitWithDefaultTimeout()
+ Expect(build).Should(Exit(0))
+
+ session := podmanTest.Podman([]string{"play", "kube", "top.yaml"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ inspectData := inspect.InspectContainerToJSON()
+ Expect(len(inspectData)).To(BeNumerically(">", 0))
+ Expect(inspectData[0].Config.Labels["homer"]).To(Equal(""))
+ Expect(inspectData[0].Config.Labels["marge"]).To(Equal("mom"))
+ })
+
+ It("--build should override image in store", func() {
+ // Setup
+ yamlDir := filepath.Join(tempdir, RandomString(12))
+ err := os.Mkdir(yamlDir, 0755)
+ err = writeYaml(testYAML, filepath.Join(yamlDir, "top.yaml"))
+ Expect(err).To(BeNil())
+
+ // build an image called foobar but make sure it doesnt have
+ // the same label as the yaml buildfile, so we can check that
+ // the image is NOT rebuilt.
+ err = writeYaml(prebuiltImage, filepath.Join(yamlDir, "Containerfile"))
+ Expect(err).To(BeNil())
+
+ app1Dir := filepath.Join(yamlDir, "foobar")
+ err = os.Mkdir(app1Dir, 0755)
+ Expect(err).To(BeNil())
+ err = writeYaml(playBuildFile, filepath.Join(app1Dir, "Containerfile"))
+ Expect(err).To(BeNil())
+
+ // Switch to temp dir and restore it afterwards
+ cwd, err := os.Getwd()
+ Expect(err).To(BeNil())
+ Expect(os.Chdir(yamlDir)).To(BeNil())
+ defer func() { (Expect(os.Chdir(cwd)).To(BeNil())) }()
+
+ // Build the image into the local store
+ build := podmanTest.Podman([]string{"build", "-t", "foobar", "-f", "Containerfile"})
+ build.WaitWithDefaultTimeout()
+ Expect(build).Should(Exit(0))
+
+ session := podmanTest.Podman([]string{"play", "kube", "--build", "top.yaml"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"container", "inspect", "top_pod-foobar"})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).Should(Exit(0))
+ inspectData := inspect.InspectContainerToJSON()
+ Expect(len(inspectData)).To(BeNumerically(">", 0))
+ Expect(inspectData[0].Config.Labels["homer"]).To(Equal("dad"))
+ Expect(inspectData[0].Config.Labels["marge"]).To(Equal(""))
+ })
+
+})
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index e3096d932..eec4b43a5 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -512,21 +512,6 @@ var (
defaultSecret = []byte(`{"FOO":"Zm9v","BAR":"YmFy"}`)
)
-func writeYaml(content string, fileName string) error {
- f, err := os.Create(fileName)
- if err != nil {
- return err
- }
- defer f.Close()
-
- _, err = f.WriteString(content)
- if err != nil {
- return err
- }
-
- return nil
-}
-
// getKubeYaml returns a kubernetes YAML document.
func getKubeYaml(kind string, object interface{}) (string, error) {
var yamlTemplate string
diff --git a/test/e2e/pod_initcontainers_test.go b/test/e2e/pod_initcontainers_test.go
index 606294f51..11e7ca400 100644
--- a/test/e2e/pod_initcontainers_test.go
+++ b/test/e2e/pod_initcontainers_test.go
@@ -98,10 +98,10 @@ var _ = Describe("Podman init containers", func() {
Expect(checkLog.OutputToString()).To(Equal(content))
})
- It("podman make sure oneshot container is removed", func() {
+ It("podman make sure once container is removed", func() {
filename := filepath.Join("/dev/shm", RandomString(12))
content := RandomString(16)
- session := podmanTest.Podman([]string{"create", "--init-ctr", "oneshot", "--pod", "new:foobar", ALPINE, "bin/sh", "-c", fmt.Sprintf("echo %s > %s", content, filename)})
+ session := podmanTest.Podman([]string{"create", "--init-ctr", "once", "--pod", "new:foobar", ALPINE, "bin/sh", "-c", fmt.Sprintf("echo %s > %s", content, filename)})
session.WaitWithDefaultTimeout()
initContainerID := session.OutputToString()
Expect(session).Should(Exit(0))
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index d68aa6ac4..1fb1a179a 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -946,7 +946,7 @@ USER mail`, BB)
Expect(err).To(BeNil())
mountpoint := "/myvol/"
- session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
+ session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":z", ALPINE, "cat", mountpoint + filename})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
ctrID := session.OutputToString()
diff --git a/test/e2e/stats_test.go b/test/e2e/stats_test.go
index a0be5d462..c0d56fdbc 100644
--- a/test/e2e/stats_test.go
+++ b/test/e2e/stats_test.go
@@ -22,6 +22,9 @@ var _ = Describe("Podman stats", func() {
BeforeEach(func() {
SkipIfRootlessCgroupsV1("stats not supported on cgroupv1 for rootless users")
+ if isContainerized() {
+ SkipIfCgroupV1("stats not supported inside cgroupv1 container environment")
+ }
var err error
tempdir, err = CreateTempDirInTempDir()
if err != nil {
diff --git a/test/e2e/systemd_test.go b/test/e2e/systemd_test.go
index bb51d6ac2..3213a839a 100644
--- a/test/e2e/systemd_test.go
+++ b/test/e2e/systemd_test.go
@@ -6,7 +6,6 @@ import (
"strings"
"time"
- "github.com/containers/podman/v3/pkg/rootless"
. "github.com/containers/podman/v3/test/utils"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -118,11 +117,13 @@ WantedBy=multi-user.target
Expect(len(conData)).To(Equal(1))
Expect(conData[0].Config.SystemdMode).To(BeTrue())
- if CGROUPSV2 || !rootless.IsRootless() {
- stats := podmanTest.Podman([]string{"stats", "--no-stream", ctrName})
- stats.WaitWithDefaultTimeout()
- Expect(stats).Should(Exit(0))
+ // stats not supported w/ CGv1 rootless or containerized
+ if isCgroupsV1() && (isRootless() || isContainerized()) {
+ return
}
+ stats := podmanTest.Podman([]string{"stats", "--no-stream", ctrName})
+ stats.WaitWithDefaultTimeout()
+ Expect(stats).Should(Exit(0))
})
It("podman create container with systemd entrypoint triggers systemd mode", func() {
diff --git a/test/python/requirements.txt b/test/python/requirements.txt
index ee85bf1d1..f177f76fc 100644
--- a/test/python/requirements.txt
+++ b/test/python/requirements.txt
@@ -1,5 +1,5 @@
docker~=4.4.3
-
+requests-mock~=1.9.3
requests~=2.20.0
setuptools~=50.3.2
python-dateutil~=2.8.1
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index 69ebebcd6..8bb32b5b7 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -102,7 +102,7 @@ function _wait_service_ready() {
let timeout=$timeout-1
done
- # Print serivce status as debug information before failed the case
+ # Print service status as debug information before failed the case
systemctl status $sname
die "Timed out waiting for $sname to start"
}
@@ -305,7 +305,7 @@ EOF
fi
done
- # Only check the last service is started. Previous services should already actived.
+ # Only check that the last service is started. Previous services should already be activated.
_wait_service_ready container-$cname.service
run_podman commit --change CMD=/bin/bash $local_cname quay.io/libpod/localtest:latest
# Exit code is expected, due to invalid 'fakevalue'
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 6ffee7eaf..3ebe45e63 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -210,6 +210,9 @@ load helpers
$IMAGE nc -l -n -v -p $myport
cid="$output"
+ # check that dns is working inside the container
+ run_podman exec $cid nslookup google.com
+
# emit random string, and check it
teststring=$(random_string 30)
echo "$teststring" | nc 127.0.0.1 $myport
diff --git a/test/system/700-play.bats b/test/system/700-play.bats
index 3e6961b08..498956b9a 100644
--- a/test/system/700-play.bats
+++ b/test/system/700-play.bats
@@ -94,9 +94,9 @@ RELABEL="system_u:object_r:container_file_t:s0"
mkdir -p $TESTDIR
echo "$testYaml" | sed "s|TESTDIR|${TESTDIR}|g" > $PODMAN_TMPDIR/test.yaml
run_podman 125 play kube --network bridge $PODMAN_TMPDIR/test.yaml
- is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail wth --network host"
+ is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail with --network host"
run_podman 125 play kube --network host $PODMAN_TMPDIR/test.yaml
- is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail wth --network host"
+ is "$output" ".*invalid value passed to --network: bridge or host networking must be configured in YAML" "podman plan-network should fail with --network host"
run_podman play kube --network slirp4netns:port_handler=slirp4netns $PODMAN_TMPDIR/test.yaml
run_podman pod rm -f test_pod
}
diff --git a/troubleshooting.md b/troubleshooting.md
index 24dcb8e35..dcf1d8715 100644
--- a/troubleshooting.md
+++ b/troubleshooting.md
@@ -746,3 +746,138 @@ an Infra container image for CNI-in-slirp4netns must be created. The
instructions for building the Infra container image can be found for
v2.2.1 [here](https://github.com/containers/podman/tree/v2.2.1-rhel/contrib/rootless-cni-infra),
and for v3.0.1 [here](https://github.com/containers/podman/tree/v3.0.1-rhel/contrib/rootless-cni-infra).
+### 29) Container related firewall rules are lost after reloading firewalld
+Container network can't be reached after `firewall-cmd --reload` and `systemctl restart firewalld` Running `podman network reload` will fix it but it has to be done manually.
+
+#### Symptom
+The firewall rules created by podman are lost when the firewall is reloaded.
+
+#### Solution
+[@ranjithrajaram](https://github.com/containers/podman/issues/5431#issuecomment-847758377) has created a systemd-hook to fix this issue
+
+1) For "firewall-cmd --reload", create a systemd unit file with the following
+```
+[Unit]
+Description=firewalld reload hook - run a hook script on firewalld reload
+Wants=dbus.service
+After=dbus.service
+
+[Service]
+Type=simple
+ExecStart=/bin/bash -c '/bin/busctl monitor --system --match "interface=org.fedoraproject.FirewallD1,member=Reloaded" --match "interface=org.fedoraproject.FirewallD1,member=PropertiesChanged" | while read -r line ; do podman network reload --all ; done'
+
+[Install]
+WantedBy=multi-user.target
+```
+2) For "systemctl restart firewalld", create a systemd unit file with the following
+```
+[Unit]
+Description=podman network reload
+Wants=firewalld.service
+After=firewalld.service
+PartOf=firewalld.service
+
+[Service]
+Type=simple
+RemainAfterExit=yes
+ExecStart=/usr/bin/podman network reload --all
+
+[Install]
+WantedBy=multi-user.target
+```
+However, If you use busctl monitor then you can't get machine-readable output on `RHEL 8`.
+Since it doesn't have `busctl -j` as mentioned here by [@yrro](https://github.com/containers/podman/issues/5431#issuecomment-896943018).
+
+For RHEL 8, you can use the following one-liner bash script.
+```
+[Unit]
+Description=Redo podman NAT rules after firewalld starts or reloads
+Wants=dbus.service
+After=dbus.service
+Requires=firewalld.service
+
+[Service]
+Type=simple
+ExecStart=/bin/bash -c "dbus-monitor --profile --system 'type=signal,sender=org.freedesktop.DBus,path=/org/freedesktop/DBus,interface=org.freedesktop.DBus,member=NameAcquired,arg0=org.fedoraproject.FirewallD1' 'type=signal,path=/org/fedoraproject/FirewallD1,interface=org.fedoraproject.FirewallD1,member=Reloaded' | sed -u '/^#/d' | while read -r type timestamp serial sender destination path interface member _junk; do if [[ $type = '#'* ]]; then continue; elif [[ $interface = org.freedesktop.DBus && $member = NameAcquired ]]; then echo 'firewalld started'; podman network reload --all; elif [[ $interface = org.fedoraproject.FirewallD1 && $member = Reloaded ]]; then echo 'firewalld reloaded'; podman network reload --all; fi; done"
+Restart=Always
+
+[Install]
+WantedBy=multi-user.target
+```
+`busctl-monitor` is almost usable in `RHEL 8`, except that it always outputs two bogus events when it starts up,
+one of which is (in its only machine-readable format) indistinguishable from the `NameOwnerChanged` that you get when firewalld starts up.
+This means you would get an extra `podman network reload --all` when this unit starts.
+
+Apart from this, you can use the following systemd service with the python3 code.
+
+```
+[Unit]
+Description=Redo podman NAT rules after firewalld starts or reloads
+Wants=dbus.service
+Requires=firewalld.service
+After=dbus.service
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/python /path/to/python/code/podman-redo-nat.py
+Restart=always
+
+[Install]
+WantedBy=multi-user.target
+```
+The code reloads podman network twice when you use `systemctl restart firewalld`.
+```
+import dbus
+from gi.repository import GLib
+from dbus.mainloop.glib import DBusGMainLoop
+import subprocess
+import sys
+
+# I'm a bit confused on the return values in the code
+# Not sure if they are needed.
+
+def reload_podman_network():
+ try:
+ subprocess.run(["podman","network","reload","--all"],timeout=90)
+ # I'm not sure about this part
+ sys.stdout.write("podman network reload done\n")
+ sys.stdout.flush()
+ except subprocess.TimeoutExpired as t:
+ sys.stderr.write(f"Podman reload failed due to Timeout {t}")
+ except subprocess.CalledProcessError as e:
+ sys.stderr.write(f"Podman reload failed due to {e}")
+ except Exception as e:
+ sys.stderr.write(f"Podman reload failed with an Unhandled Exception {e}")
+
+ return False
+
+def signal_handler(*args, **kwargs):
+ if kwargs.get('member') == "Reloaded":
+ reload_podman_network()
+ elif kwargs.get('member') == "NameOwnerChanged":
+ reload_podman_network()
+ else:
+ return None
+ return None
+
+def signal_listener():
+ try:
+ DBusGMainLoop(set_as_default=True)# Define the loop.
+ loop = GLib.MainLoop()
+ system_bus = dbus.SystemBus()
+ # Listens to systemctl restart firewalld with a filter added, will cause podman network to be reloaded twice
+ system_bus.add_signal_receiver(signal_handler,dbus_interface='org.freedesktop.DBus',arg0='org.fedoraproject.FirewallD1',member_keyword='member')
+ # Listens to firewall-cmd --reload
+ system_bus.add_signal_receiver(signal_handler,dbus_interface='org.fedoraproject.FirewallD1',signal_name='Reloaded',member_keyword='member')
+ loop.run()
+ except KeyboardInterrupt:
+ loop.quit()
+ sys.exit(0)
+ except Exception as e:
+ loop.quit()
+ sys.stderr.write(f"Error occured {e}")
+ sys.exit(1)
+
+if __name__ == "__main__":
+ signal_listener()
+```
diff --git a/vendor/github.com/containers/image/v5/version/version.go b/vendor/github.com/containers/image/v5/version/version.go
index 8936ec087..478a03b05 100644
--- a/vendor/github.com/containers/image/v5/version/version.go
+++ b/vendor/github.com/containers/image/v5/version/version.go
@@ -8,7 +8,7 @@ const (
// VersionMinor is for functionality in a backwards-compatible manner
VersionMinor = 15
// VersionPatch is for backwards-compatible bug fixes
- VersionPatch = 0
+ VersionPatch = 2
// VersionDev indicates development branch. Releases will be empty string.
VersionDev = ""
diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION
index 2b17ffd50..a95a46d9f 100644
--- a/vendor/github.com/containers/storage/VERSION
+++ b/vendor/github.com/containers/storage/VERSION
@@ -1 +1 @@
-1.34.0
+1.34.1
diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
index abb9ab71d..f546f9b10 100644
--- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go
+++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go
@@ -1941,7 +1941,7 @@ func (al *additionalLayer) Info() (io.ReadCloser, error) {
return os.Open(filepath.Join(al.path, "info"))
}
-// Blob returns a reader of the raw contents of this leyer.
+// Blob returns a reader of the raw contents of this layer.
func (al *additionalLayer) Blob() (io.ReadCloser, error) {
return os.Open(filepath.Join(al.path, "blob"))
}
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index ff14799a2..d2d438d93 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -10,7 +10,7 @@ require (
github.com/google/go-intervals v0.0.2
github.com/hashicorp/go-multierror v1.1.1
github.com/json-iterator/go v1.1.11
- github.com/klauspost/compress v1.13.3
+ github.com/klauspost/compress v1.13.4
github.com/klauspost/pgzip v1.2.5
github.com/mattn/go-shellwords v1.0.12
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
@@ -18,7 +18,7 @@ require (
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/runc v1.0.1
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
- github.com/opencontainers/selinux v1.8.3
+ github.com/opencontainers/selinux v1.8.4
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.7.0
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 71ababfb2..da7a8f53e 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -388,8 +388,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.13.3 h1:BtAvtV1+h0YwSVwWoYXMREPpYu9VzTJ9QDI1TEg/iQQ=
-github.com/klauspost/compress v1.13.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
+github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s=
+github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -482,8 +482,8 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
-github.com/opencontainers/selinux v1.8.3 h1:tzZR7AuKB5gU1+53uBkoG4XdIFGZzvJTOVoNbRQI8/4=
-github.com/opencontainers/selinux v1.8.3/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
+github.com/opencontainers/selinux v1.8.4 h1:krlgQ6/j9CkCXT5oW0yVXdQFOME3NjKuuAZXuR6O7P4=
+github.com/opencontainers/selinux v1.8.4/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
diff --git a/vendor/github.com/containers/storage/layers.go b/vendor/github.com/containers/storage/layers.go
index fa0dce033..b85ff7e70 100644
--- a/vendor/github.com/containers/storage/layers.go
+++ b/vendor/github.com/containers/storage/layers.go
@@ -27,6 +27,7 @@ import (
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
"github.com/vbatts/tar-split/archive/tar"
"github.com/vbatts/tar-split/tar/asm"
"github.com/vbatts/tar-split/tar/storage"
@@ -1407,7 +1408,7 @@ func (r *layerStore) Diff(from, to string, options *DiffOptions) (io.ReadCloser,
if ad, ok := r.driver.(drivers.AdditionalLayerStoreDriver); ok {
if aLayer, err := ad.LookupAdditionalLayerByID(to); err == nil {
- // This is an additional layer. We leverage blob API for aquiring the reproduced raw blob.
+ // This is an additional layer. We leverage blob API for acquiring the reproduced raw blob.
info, err := aLayer.Info()
if err != nil {
aLayer.Release()
@@ -1529,6 +1530,9 @@ func (r *layerStore) ApplyDiff(to string, diff io.Reader) (size int64, err error
if err != nil {
compressor = pgzip.NewWriter(&tsdata)
}
+ if err := compressor.SetConcurrency(1024*1024, 1); err != nil { // 1024*1024 is the hard-coded default; we're not changing that
+ logrus.Infof("error setting compression concurrency threads to 1: %v; ignoring", err)
+ }
metadata := storage.NewJSONPacker(compressor)
uncompressed, err := archive.DecompressStream(defragmented)
if err != nil {
diff --git a/vendor/github.com/containers/storage/types/utils.go b/vendor/github.com/containers/storage/types/utils.go
index 5dbbb4403..b7ab07342 100644
--- a/vendor/github.com/containers/storage/types/utils.go
+++ b/vendor/github.com/containers/storage/types/utils.go
@@ -160,9 +160,6 @@ func expandEnvPath(path string, rootlessUID int) (string, error) {
path = os.ExpandEnv(path)
newpath, err := filepath.EvalSymlinks(path)
if err != nil {
- if !os.IsNotExist(err) {
- return "", err
- }
newpath = filepath.Clean(path)
}
return newpath, nil
diff --git a/vendor/github.com/klauspost/compress/README.md b/vendor/github.com/klauspost/compress/README.md
index 48851e0ce..d6a26466c 100644
--- a/vendor/github.com/klauspost/compress/README.md
+++ b/vendor/github.com/klauspost/compress/README.md
@@ -5,6 +5,7 @@ This package provides various compression algorithms.
* [zstandard](https://github.com/klauspost/compress/tree/master/zstd#zstd) compression and decompression in pure Go.
* [S2](https://github.com/klauspost/compress/tree/master/s2#s2-compression) is a high performance replacement for Snappy.
* Optimized [deflate](https://godoc.org/github.com/klauspost/compress/flate) packages which can be used as a dropin replacement for [gzip](https://godoc.org/github.com/klauspost/compress/gzip), [zip](https://godoc.org/github.com/klauspost/compress/zip) and [zlib](https://godoc.org/github.com/klauspost/compress/zlib).
+* [snappy](https://github.com/klauspost/compress/tree/master/snappy) is a drop-in replacement for `github.com/golang/snappy` offering better compression and concurrent streams.
* [huff0](https://github.com/klauspost/compress/tree/master/huff0) and [FSE](https://github.com/klauspost/compress/tree/master/fse) implementations for raw entropy encoding.
* [gzhttp](https://github.com/klauspost/compress/tree/master/gzhttp) Provides client and server wrappers for handling gzipped requests efficiently.
* [pgzip](https://github.com/klauspost/pgzip) is a separate package that provides a very fast parallel gzip implementation.
@@ -16,6 +17,15 @@ This package provides various compression algorithms.
# changelog
+* Aug 3, 2021 (v1.13.3)
+
+ * zstd: Improve Best compression [#404](https://github.com/klauspost/compress/pull/404)
+ * zstd: Fix WriteTo error forwarding [#411](https://github.com/klauspost/compress/pull/411)
+ * gzhttp: Return http.HandlerFunc instead of http.Handler. Unlikely breaking change. [#406](https://github.com/klauspost/compress/pull/406)
+ * s2sx: Fix max size error [#399](https://github.com/klauspost/compress/pull/399)
+ * zstd: Add optional stream content size on reset [#401](https://github.com/klauspost/compress/pull/401)
+ * zstd: use SpeedBestCompression for level >= 10 [#410](https://github.com/klauspost/compress/pull/410)
+
* Jun 14, 2021 (v1.13.1)
* s2: Add full Snappy output support [#396](https://github.com/klauspost/compress/pull/396)
diff --git a/vendor/github.com/klauspost/compress/zstd/enc_best.go b/vendor/github.com/klauspost/compress/zstd/enc_best.go
index 41025d62b..96028ecd8 100644
--- a/vendor/github.com/klauspost/compress/zstd/enc_best.go
+++ b/vendor/github.com/klauspost/compress/zstd/enc_best.go
@@ -5,6 +5,7 @@
package zstd
import (
+ "bytes"
"fmt"
"github.com/klauspost/compress"
@@ -208,6 +209,11 @@ encodeLoop:
if s-offset >= e.maxMatchOff || load3232(src, offset) != first {
return match{s: s, est: highScore}
}
+ if debugAsserts {
+ if !bytes.Equal(src[s:s+4], src[offset:offset+4]) {
+ panic(fmt.Sprintf("first match mismatch: %v != %v, first: %08x", src[s:s+4], src[offset:offset+4], first))
+ }
+ }
m := match{offset: offset, s: s, length: 4 + e.matchlen(s+4, offset+4, src), rep: rep}
m.estBits(bitsPerByte)
return m
@@ -218,17 +224,17 @@ encodeLoop:
best = bestOf(best, matchAt(candidateS.prev-e.cur, s, uint32(cv), -1))
if canRepeat && best.length < goodEnough {
- cv := uint32(cv >> 8)
+ cv32 := uint32(cv >> 8)
spp := s + 1
- best = bestOf(best, matchAt(spp-offset1, spp, cv, 1))
- best = bestOf(best, matchAt(spp-offset2, spp, cv, 2))
- best = bestOf(best, matchAt(spp-offset3, spp, cv, 3))
+ best = bestOf(best, matchAt(spp-offset1, spp, cv32, 1))
+ best = bestOf(best, matchAt(spp-offset2, spp, cv32, 2))
+ best = bestOf(best, matchAt(spp-offset3, spp, cv32, 3))
if best.length > 0 {
- cv >>= 16
+ cv32 = uint32(cv >> 24)
spp += 2
- best = bestOf(best, matchAt(spp-offset1, spp, cv, 1))
- best = bestOf(best, matchAt(spp-offset2, spp, cv, 2))
- best = bestOf(best, matchAt(spp-offset3, spp, cv, 3))
+ best = bestOf(best, matchAt(spp-offset1, spp, cv32, 1))
+ best = bestOf(best, matchAt(spp-offset2, spp, cv32, 2))
+ best = bestOf(best, matchAt(spp-offset3, spp, cv32, 3))
}
}
// Load next and check...
@@ -281,6 +287,12 @@ encodeLoop:
}
}
+ if debugAsserts {
+ if !bytes.Equal(src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]) {
+ panic(fmt.Sprintf("match mismatch: %v != %v", src[best.s:best.s+best.length], src[best.offset:best.offset+best.length]))
+ }
+ }
+
// We have a match, we can store the forward value
if best.rep > 0 {
s = best.s
@@ -356,7 +368,7 @@ encodeLoop:
panic(fmt.Sprintf("s (%d) <= t (%d)", s, t))
}
- if debugAsserts && canRepeat && int(offset1) > len(src) {
+ if debugAsserts && int(offset1) > len(src) {
panic("invalid offset")
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 64de28cc3..678a884ea 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -126,7 +126,7 @@ github.com/containers/common/pkg/umask
github.com/containers/common/version
# github.com/containers/conmon v2.0.20+incompatible
github.com/containers/conmon/runner/config
-# github.com/containers/image/v5 v5.15.0
+# github.com/containers/image/v5 v5.15.2
github.com/containers/image/v5/copy
github.com/containers/image/v5/directory
github.com/containers/image/v5/directory/explicitfilepath
@@ -198,7 +198,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.34.0
+# github.com/containers/storage v1.34.1
github.com/containers/storage
github.com/containers/storage/drivers
github.com/containers/storage/drivers/aufs
@@ -405,7 +405,7 @@ github.com/json-iterator/go
# github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a
github.com/juju/ansiterm
github.com/juju/ansiterm/tabwriter
-# github.com/klauspost/compress v1.13.3
+# github.com/klauspost/compress v1.13.4
github.com/klauspost/compress
github.com/klauspost/compress/flate
github.com/klauspost/compress/fse
@@ -557,7 +557,7 @@ github.com/prometheus/procfs/internal/fs
github.com/prometheus/procfs/internal/util
# github.com/rivo/uniseg v0.2.0
github.com/rivo/uniseg
-# github.com/rootless-containers/rootlesskit v0.14.4
+# github.com/rootless-containers/rootlesskit v0.14.5
github.com/rootless-containers/rootlesskit/pkg/api
github.com/rootless-containers/rootlesskit/pkg/msgutil
github.com/rootless-containers/rootlesskit/pkg/port