summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml13
-rw-r--r--Makefile47
-rw-r--r--cmd/podman/containers/pause.go83
-rw-r--r--cmd/podman/containers/unpause.go86
-rw-r--r--cmd/podman/machine/info.go29
-rw-r--r--cmd/podman/machine/ssh.go9
-rw-r--r--cmd/podman/networks/create.go2
-rw-r--r--cmd/podman/networks/inspect.go4
-rw-r--r--cmd/podman/pods/create.go6
-rw-r--r--commands-demo.md14
-rwxr-xr-xcontrib/cirrus/runner.sh1
-rwxr-xr-xcontrib/cirrus/setup_environment.sh23
-rwxr-xr-xdocs/remote-docs.sh4
-rw-r--r--docs/source/markdown/podman-create.1.md9
-rw-r--r--docs/source/markdown/podman-generate-systemd.1.md7
-rw-r--r--docs/source/markdown/podman-import.1.md4
-rw-r--r--docs/source/markdown/podman-kube-play.1.md2
-rw-r--r--docs/source/markdown/podman-network-connect.1.md10
-rw-r--r--docs/source/markdown/podman-network-create.1.md12
-rw-r--r--docs/source/markdown/podman-network-inspect.1.md6
-rw-r--r--docs/source/markdown/podman-network-ls.1.md6
-rw-r--r--docs/source/markdown/podman-network-rm.1.md6
-rw-r--r--docs/source/markdown/podman-network.1.md2
-rw-r--r--docs/source/markdown/podman-pause.1.md50
-rw-r--r--docs/source/markdown/podman-pod-create.1.md11
-rw-r--r--docs/source/markdown/podman-run.1.md9
-rw-r--r--docs/source/markdown/podman-unpause.1.md50
-rw-r--r--docs/tutorials/basic_networking.md6
-rw-r--r--go.mod4
-rw-r--r--go.sum7
-rwxr-xr-xhack/golangci-lint.sh4
-rw-r--r--libpod/container_api.go2
-rw-r--r--libpod/runtime_pod_linux.go98
-rw-r--r--pkg/api/handlers/compat/images.go32
-rw-r--r--pkg/api/handlers/compat/images_build.go1
-rw-r--r--pkg/api/handlers/compat/images_push.go1
-rw-r--r--pkg/api/handlers/compat/images_search.go1
-rw-r--r--pkg/api/handlers/compat/networks.go54
-rw-r--r--pkg/api/handlers/libpod/containers_create.go3
-rw-r--r--pkg/api/handlers/libpod/images.go71
-rw-r--r--pkg/api/handlers/libpod/images_push.go145
-rw-r--r--pkg/api/handlers/libpod/manifests.go1
-rw-r--r--pkg/api/server/register_images.go13
-rw-r--r--pkg/api/server/register_manifest.go10
-rw-r--r--pkg/bindings/images/images.go40
-rw-r--r--pkg/bindings/images/push.go96
-rw-r--r--pkg/bindings/images/types.go2
-rw-r--r--pkg/bindings/images/types_push_options.go15
-rw-r--r--pkg/bindings/test/images_test.go2
-rw-r--r--pkg/domain/entities/containers.go9
-rw-r--r--pkg/domain/entities/images.go15
-rw-r--r--pkg/domain/entities/machine.go22
-rw-r--r--pkg/domain/entities/play.go5
-rw-r--r--pkg/domain/infra/abi/containers.go41
-rw-r--r--pkg/domain/infra/abi/images.go3
-rw-r--r--pkg/domain/infra/abi/play.go80
-rw-r--r--pkg/domain/infra/abi/secrets.go2
-rw-r--r--pkg/domain/infra/tunnel/containers.go26
-rw-r--r--pkg/domain/infra/tunnel/images.go2
-rw-r--r--pkg/k8s.io/api/core/v1/types.go1
-rw-r--r--pkg/machine/e2e/basic_test.go4
-rw-r--r--pkg/machine/e2e/config_basic_test.go (renamed from pkg/machine/e2e/config_basic.go)3
-rw-r--r--pkg/machine/e2e/config_info_test.go (renamed from pkg/machine/e2e/config_info.go)2
-rw-r--r--pkg/machine/e2e/config_init_test.go (renamed from pkg/machine/e2e/config_init.go)6
-rw-r--r--pkg/machine/e2e/config_inspect_test.go (renamed from pkg/machine/e2e/config_inspect.go)2
-rw-r--r--pkg/machine/e2e/config_list_test.go (renamed from pkg/machine/e2e/config_list.go)2
-rw-r--r--pkg/machine/e2e/config_rm_test.go (renamed from pkg/machine/e2e/config_rm.go)8
-rw-r--r--pkg/machine/e2e/config_set_test.go (renamed from pkg/machine/e2e/config_set.go)2
-rw-r--r--pkg/machine/e2e/config_ssh_test.go (renamed from pkg/machine/e2e/config_ssh.go)8
-rw-r--r--pkg/machine/e2e/config_start_test.go (renamed from pkg/machine/e2e/config_start.go)3
-rw-r--r--pkg/machine/e2e/config_stop_test.go (renamed from pkg/machine/e2e/config_stop.go)3
-rw-r--r--pkg/machine/e2e/config_test.go (renamed from pkg/machine/e2e/config.go)26
-rw-r--r--pkg/machine/e2e/info_test.go6
-rw-r--r--pkg/machine/e2e/init_test.go8
-rw-r--r--pkg/machine/e2e/inspect_test.go8
-rw-r--r--pkg/machine/e2e/list_test.go8
-rw-r--r--pkg/machine/e2e/machine_test.go2
-rw-r--r--pkg/machine/e2e/rm_test.go2
-rw-r--r--pkg/machine/e2e/set_test.go8
-rw-r--r--pkg/machine/e2e/ssh_test.go14
-rw-r--r--pkg/machine/e2e/start_test.go2
-rw-r--r--pkg/machine/e2e/stop_test.go2
-rw-r--r--pkg/machine/qemu/machine.go4
-rw-r--r--pkg/specgen/generate/container.go15
-rw-r--r--pkg/specgen/generate/container_create.go4
-rw-r--r--pkg/specgen/generate/kube/kube.go10
-rw-r--r--pkg/specgen/generate/kube/play_test.go2
-rw-r--r--pkg/specgen/generate/kube/volume.go56
-rw-r--r--pkg/specgenutil/specgen.go9
-rw-r--r--test/apiv2/12-imagesMore.at5
-rw-r--r--test/apiv2/15-manifest.at2
-rw-r--r--test/apiv2/20-containers.at3
-rw-r--r--test/apiv2/35-networks.at12
-rwxr-xr-xtest/buildah-bud/apply-podman-deltas4
-rwxr-xr-xtest/compose/test-compose1
-rw-r--r--test/e2e/benchmarks_test.go8
-rw-r--r--test/e2e/build_test.go4
-rw-r--r--test/e2e/checkpoint_image_test.go7
-rw-r--r--test/e2e/checkpoint_test.go10
-rw-r--r--test/e2e/common_test.go8
-rw-r--r--test/e2e/containers_conf_test.go3
-rw-r--r--test/e2e/info_test.go15
-rw-r--r--test/e2e/kill_test.go1
-rw-r--r--test/e2e/libpod_suite_remote_test.go7
-rw-r--r--test/e2e/network_connect_disconnect_test.go2
-rw-r--r--test/e2e/pause_test.go177
-rw-r--r--test/e2e/play_kube_test.go142
-rw-r--r--test/e2e/pod_create_test.go1
-rw-r--r--test/e2e/pod_infra_container_test.go16
-rw-r--r--test/e2e/push_test.go27
-rw-r--r--test/e2e/run_test.go16
-rw-r--r--test/system/005-info.bats17
-rw-r--r--test/system/030-run.bats17
-rw-r--r--test/system/160-volumes.bats8
-rw-r--r--test/system/170-run-userns.bats2
-rw-r--r--test/system/200-pod.bats5
-rw-r--r--test/system/251-system-service.bats4
-rw-r--r--test/system/400-unprivileged-access.bats1
-rw-r--r--test/system/500-networking.bats2
-rw-r--r--test/system/520-checkpoint.bats2
-rw-r--r--test/utils/utils.go7
-rw-r--r--vendor/github.com/containers/common/pkg/secrets/secrets.go8
-rw-r--r--vendor/github.com/containers/storage/go.mod2
-rw-r--r--vendor/github.com/containers/storage/go.sum17
-rw-r--r--vendor/modules.txt4
125 files changed, 1504 insertions, 611 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index b585c41f8..7a488216e 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -29,11 +29,11 @@ env:
####
FEDORA_NAME: "fedora-36"
#PRIOR_FEDORA_NAME: "fedora-35"
- UBUNTU_NAME: "ubuntu-2110"
+ UBUNTU_NAME: "ubuntu-2204"
# Image identifiers
- IMAGE_SUFFIX: "c6211193021923328"
- FEDORA_AMI_ID: "ami-06a41d8a81ab56afa"
+ IMAGE_SUFFIX: "c6013173500215296"
+ FEDORA_AMI_ID: "ami-0f116746f31965e41"
# Complete image names
FEDORA_CACHE_IMAGE_NAME: "fedora-${IMAGE_SUFFIX}"
#PRIOR_FEDORA_CACHE_IMAGE_NAME: "prior-fedora-${IMAGE_SUFFIX}"
@@ -178,8 +178,7 @@ build_task:
DISTRO_NV: ${UBUNTU_NAME}
VM_IMAGE_NAME: ${UBUNTU_CACHE_IMAGE_NAME}
CTR_FQIN: ${UBUNTU_CONTAINER_FQIN}
- # FIXME 2022-07-12: change to runc once #14833 is fixed!
- CI_DESIRED_RUNTIME: crun
+ CI_DESIRED_RUNTIME: runc
env:
TEST_FLAVOR: build
clone_script: *full_clone
@@ -550,6 +549,7 @@ container_integration_test_task:
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
VM_IMAGE_NAME: ${FEDORA_CACHE_IMAGE_NAME}
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
+ CI_DESIRED_RUNTIME: crun
#- env:
#DISTRO_NV: ${PRIOR_FEDORA_NAME}
#_BUILD_CACHE_HANDLE: ${PRIOR_FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
@@ -667,6 +667,7 @@ rootless_remote_system_test_task:
CTR_FQIN: ${FEDORA_CONTAINER_FQIN}
# ID for re-use of build output
_BUILD_CACHE_HANDLE: ${FEDORA_NAME}-build-${CIRRUS_BUILD_ID}
+ CI_DESIRED_RUNTIME: crun
<<: *local_system_test_task
alias: rootless_remote_system_test
depends_on:
@@ -842,7 +843,7 @@ meta_task:
container:
cpu: 2
memory: 2
- image: quay.io/libpod/imgts:$IMAGE_SUFFIX
+ image: quay.io/libpod/imgts:latest
env:
# Space-separated list of images used by this repository state
# Disabled ${PRIOR_FEDORA_CACHE_IMAGE_NAME} for Fedora 35
diff --git a/Makefile b/Makefile
index 0f933ed40..d172f2048 100644
--- a/Makefile
+++ b/Makefile
@@ -146,7 +146,8 @@ CROSS_BUILD_TARGETS := \
# Dereference variable $(1), return value if non-empty, otherwise raise an error.
err_if_empty = $(if $(strip $($(1))),$(strip $($(1))),$(error Required variable $(1) value is undefined, whitespace, or empty))
-# Podman does not work w/o CGO_ENABLED, except in some very specific cases
+# Podman does not work w/o CGO_ENABLED, except in some very specific cases.
+# Windows and Mac (both podman-remote client only) require CGO_ENABLED=0.
CGO_ENABLED ?= 1
# Default to the native OS type and architecture unless otherwise specified
NATIVE_GOOS := $(shell env -u GOOS $(GO) env GOOS)
@@ -157,9 +158,11 @@ GOARCH ?= $(NATIVE_GOARCH)
ifeq ($(call err_if_empty,GOOS),windows)
BINSFX := .exe
SRCBINDIR := bin/windows
+CGO_ENABLED := 0
else ifeq ($(GOOS),darwin)
BINSFX :=
SRCBINDIR := bin/darwin
+CGO_ENABLED := 0
else
BINSFX := -remote
SRCBINDIR := bin
@@ -302,7 +305,8 @@ endif
$(SRCBINDIR):
mkdir -p $(SRCBINDIR)
-$(SRCBINDIR)/podman$(BINSFX): $(SRCBINDIR) $(SOURCES) go.mod go.sum
+# '|' is to ignore SRCBINDIR mtime; see: info make 'Types of Prerequisites'
+$(SRCBINDIR)/podman$(BINSFX): $(SOURCES) go.mod go.sum | $(SRCBINDIR)
$(GOCMD) build \
$(BUILDFLAGS) \
$(GO_LDFLAGS) '$(LDFLAGS_PODMAN)' \
@@ -322,28 +326,13 @@ $(SRCBINDIR)/podman-remote-static: $(SRCBINDIR) $(SOURCES) go.mod go.sum
.PHONY: podman
podman: bin/podman
+# This will map to the right thing on Linux, Windows, and Mac.
.PHONY: podman-remote
-podman-remote: $(SRCBINDIR) $(SRCBINDIR)/podman$(BINSFX) ## Build podman-remote binary
-
-# A wildcard podman-remote-% target incorrectly sets GOOS for release targets
-.PHONY: podman-remote-linux
-podman-remote-linux: ## Build podman-remote for Linux
- $(MAKE) \
- CGO_ENABLED=0 \
- GOOS=linux \
- GOARCH=$(GOARCH) \
- bin/podman-remote
+podman-remote: $(SRCBINDIR)/podman$(BINSFX)
PHONY: podman-remote-static
podman-remote-static: $(SRCBINDIR)/podman-remote-static
-.PHONY: podman-remote-windows
-podman-remote-windows: ## Build podman-remote for Windows
- $(MAKE) \
- CGO_ENABLED=0 \
- GOOS=windows \
- bin/windows/podman.exe
-
.PHONY: podman-winpath
podman-winpath: $(SOURCES) go.mod go.sum
CGO_ENABLED=0 \
@@ -354,14 +343,6 @@ podman-winpath: $(SOURCES) go.mod go.sum
-o bin/windows/winpath.exe \
./cmd/winpath
-.PHONY: podman-remote-darwin
-podman-remote-darwin: podman-mac-helper ## Build podman-remote for macOS
- $(MAKE) \
- CGO_ENABLED=$(DARWIN_GCO) \
- GOOS=darwin \
- GOARCH=$(GOARCH) \
- bin/darwin/podman
-
.PHONY: podman-mac-helper
podman-mac-helper: ## Build podman-mac-helper for macOS
CGO_ENABLED=0 \
@@ -456,8 +437,10 @@ docdir:
docs: $(MANPAGES) ## Generate documentation
# docs/remote-docs.sh requires a locally executable 'podman-remote' binary
-# in addition to the target-archetecture binary (if any).
-podman-remote-%-docs: podman-remote-$(call err_if_empty,NATIVE_GOOS)
+# in addition to the target-architecture binary (if different). That's
+# what the NATIVE_GOOS make does in the first line.
+podman-remote-%-docs: podman-remote
+ $(MAKE) podman-remote GOOS=$(NATIVE_GOOS)
$(eval GOOS := $*)
$(MAKE) docs $(MANPAGES)
rm -rf docs/build/remote
@@ -685,9 +668,9 @@ podman-remote-release-%.zip: test/version/version ## Build podman-remote for %=$
clean-binaries podman-remote-$(GOOS)-docs
if [[ "$(GOARCH)" != "$(NATIVE_GOARCH)" ]]; then \
$(MAKE) CGO_ENABLED=0 $(GOPLAT) BUILDTAGS="$(BUILDTAGS_CROSS)" \
- clean-binaries podman-remote-$(GOOS); \
+ clean-binaries podman-remote; \
else \
- $(MAKE) $(GOPLAT) podman-remote-$(GOOS); \
+ $(MAKE) $(GOPLAT) podman-remote; \
fi
cp -r ./docs/build/remote/$(GOOS) "$(TMPDIR)/$(SUBDIR)/docs/"
cp ./contrib/remote/containers.conf "$(TMPDIR)/$(SUBDIR)/"
@@ -700,7 +683,7 @@ podman-remote-release-%.zip: test/version/version ## Build podman-remote for %=$
.PHONY: podman.msi
podman.msi: test/version/version ## Build podman-remote, package for installation on Windows
$(MAKE) podman-v$(call err_if_empty,RELEASE_NUMBER).msi
-podman-v%.msi: test/version/version podman-remote-windows podman-remote-windows-docs podman-winpath win-sshproxy
+podman-v%.msi: test/version/version podman-remote podman-remote-windows-docs podman-winpath win-sshproxy
$(eval DOCFILE := docs/build/remote/windows)
find $(DOCFILE) -print | \
wixl-heat --var var.ManSourceDir --component-group ManFiles \
diff --git a/cmd/podman/containers/pause.go b/cmd/podman/containers/pause.go
index af6f740f2..53aa423ac 100644
--- a/cmd/podman/containers/pause.go
+++ b/cmd/podman/containers/pause.go
@@ -2,61 +2,88 @@ package containers
import (
"context"
- "errors"
"fmt"
+ "io/ioutil"
+ "strings"
+ "github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/utils"
+ "github.com/containers/podman/v4/cmd/podman/validate"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
)
var (
pauseDescription = `Pauses one or more running containers. The container name or ID can be used.`
pauseCommand = &cobra.Command{
- Use: "pause [options] CONTAINER [CONTAINER...]",
- Short: "Pause all the processes in one or more containers",
- Long: pauseDescription,
- RunE: pause,
+ Use: "pause [options] CONTAINER [CONTAINER...]",
+ Short: "Pause all the processes in one or more containers",
+ Long: pauseDescription,
+ RunE: pause,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile")
+ },
ValidArgsFunction: common.AutocompleteContainersRunning,
Example: `podman pause mywebserver
podman pause 860a4b23
- podman pause -a`,
+ podman pause --all`,
}
containerPauseCommand = &cobra.Command{
- Use: pauseCommand.Use,
- Short: pauseCommand.Short,
- Long: pauseCommand.Long,
- RunE: pauseCommand.RunE,
+ Use: pauseCommand.Use,
+ Short: pauseCommand.Short,
+ Long: pauseCommand.Long,
+ RunE: pauseCommand.RunE,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile")
+ },
ValidArgsFunction: pauseCommand.ValidArgsFunction,
Example: `podman container pause mywebserver
podman container pause 860a4b23
- podman container pause -a`,
+ podman container pause --all`,
}
+)
- pauseOpts = entities.PauseUnPauseOptions{}
+var (
+ pauseOpts = entities.PauseUnPauseOptions{
+ Filters: make(map[string][]string),
+ }
+ pauseCidFiles = []string{}
)
-func pauseFlags(flags *pflag.FlagSet) {
+func pauseFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+
flags.BoolVarP(&pauseOpts.All, "all", "a", false, "Pause all running containers")
+
+ cidfileFlagName := "cidfile"
+ flags.StringArrayVar(&pauseCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
+ _ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
+
+ filterFlagName := "filter"
+ flags.StringSliceVarP(&filters, filterFlagName, "f", []string{}, "Filter output based on conditions given")
+ _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters)
+
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("cidfile")
+ }
}
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: pauseCommand,
})
- flags := pauseCommand.Flags()
- pauseFlags(flags)
+ pauseFlags(pauseCommand)
+ validate.AddLatestFlag(pauseCommand, &pauseOpts.Latest)
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: containerPauseCommand,
Parent: containerCmd,
})
- containerPauseFlags := containerPauseCommand.Flags()
- pauseFlags(containerPauseFlags)
+ pauseFlags(containerPauseCommand)
+ validate.AddLatestFlag(containerPauseCommand, &pauseOpts.Latest)
}
func pause(cmd *cobra.Command, args []string) error {
@@ -64,16 +91,30 @@ func pause(cmd *cobra.Command, args []string) error {
errs utils.OutputErrors
)
- if len(args) < 1 && !pauseOpts.All {
- return errors.New("you must provide at least one container name or id")
+ for _, cidFile := range pauseCidFiles {
+ content, err := ioutil.ReadFile(cidFile)
+ if err != nil {
+ return fmt.Errorf("error reading CIDFile: %w", err)
+ }
+ id := strings.Split(string(content), "\n")[0]
+ args = append(args, id)
+ }
+
+ for _, f := range filters {
+ split := strings.SplitN(f, "=", 2)
+ if len(split) < 2 {
+ return fmt.Errorf("invalid filter %q", f)
+ }
+ pauseOpts.Filters[split[0]] = append(pauseOpts.Filters[split[0]], split[1])
}
+
responses, err := registry.ContainerEngine().ContainerPause(context.Background(), args, pauseOpts)
if err != nil {
return err
}
for _, r := range responses {
if r.Err == nil {
- fmt.Println(r.Id)
+ fmt.Println(r.RawInput)
} else {
errs = append(errs, r.Err)
}
diff --git a/cmd/podman/containers/unpause.go b/cmd/podman/containers/unpause.go
index a5375e737..4282e490e 100644
--- a/cmd/podman/containers/unpause.go
+++ b/cmd/podman/containers/unpause.go
@@ -4,59 +4,87 @@ import (
"context"
"errors"
"fmt"
+ "io/ioutil"
+ "strings"
"github.com/containers/common/pkg/cgroups"
+ "github.com/containers/common/pkg/completion"
"github.com/containers/podman/v4/cmd/podman/common"
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/utils"
+ "github.com/containers/podman/v4/cmd/podman/validate"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/spf13/cobra"
- "github.com/spf13/pflag"
)
var (
unpauseDescription = `Unpauses one or more previously paused containers. The container name or ID can be used.`
unpauseCommand = &cobra.Command{
- Use: "unpause [options] CONTAINER [CONTAINER...]",
- Short: "Unpause the processes in one or more containers",
- Long: unpauseDescription,
- RunE: unpause,
+ Use: "unpause [options] CONTAINER [CONTAINER...]",
+ Short: "Unpause the processes in one or more containers",
+ Long: unpauseDescription,
+ RunE: unpause,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile")
+ },
ValidArgsFunction: common.AutocompleteContainersPaused,
Example: `podman unpause ctrID
podman unpause --all`,
}
- unPauseOptions = entities.PauseUnPauseOptions{}
containerUnpauseCommand = &cobra.Command{
- Use: unpauseCommand.Use,
- Short: unpauseCommand.Short,
- Long: unpauseCommand.Long,
- RunE: unpauseCommand.RunE,
+ Use: unpauseCommand.Use,
+ Short: unpauseCommand.Short,
+ Long: unpauseCommand.Long,
+ RunE: unpauseCommand.RunE,
+ Args: func(cmd *cobra.Command, args []string) error {
+ return validate.CheckAllLatestAndIDFile(cmd, args, false, "cidfile")
+ },
ValidArgsFunction: unpauseCommand.ValidArgsFunction,
Example: `podman container unpause ctrID
podman container unpause --all`,
}
)
-func unpauseFlags(flags *pflag.FlagSet) {
- flags.BoolVarP(&unPauseOptions.All, "all", "a", false, "Pause all running containers")
+var (
+ unpauseOpts = entities.PauseUnPauseOptions{
+ Filters: make(map[string][]string),
+ }
+ unpauseCidFiles = []string{}
+)
+
+func unpauseFlags(cmd *cobra.Command) {
+ flags := cmd.Flags()
+
+ flags.BoolVarP(&unpauseOpts.All, "all", "a", false, "Unpause all paused containers")
+
+ cidfileFlagName := "cidfile"
+ flags.StringArrayVar(&unpauseCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
+ _ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
+
+ filterFlagName := "filter"
+ flags.StringSliceVarP(&filters, filterFlagName, "f", []string{}, "Filter output based on conditions given")
+ _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters)
+
+ if registry.IsRemote() {
+ _ = flags.MarkHidden("cidfile")
+ }
}
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: unpauseCommand,
})
- flags := unpauseCommand.Flags()
- unpauseFlags(flags)
+ unpauseFlags(unpauseCommand)
+ validate.AddLatestFlag(unpauseCommand, &unpauseOpts.Latest)
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: containerUnpauseCommand,
Parent: containerCmd,
})
-
- unpauseCommandFlags := containerUnpauseCommand.Flags()
- unpauseFlags(unpauseCommandFlags)
+ unpauseFlags(containerUnpauseCommand)
+ validate.AddLatestFlag(containerUnpauseCommand, &unpauseOpts.Latest)
}
func unpause(cmd *cobra.Command, args []string) error {
@@ -69,16 +97,32 @@ func unpause(cmd *cobra.Command, args []string) error {
return errors.New("unpause is not supported for cgroupv1 rootless containers")
}
}
- if len(args) < 1 && !unPauseOptions.All {
- return errors.New("you must provide at least one container name or id")
+
+ for _, cidFile := range unpauseCidFiles {
+ content, err := ioutil.ReadFile(cidFile)
+ if err != nil {
+ return fmt.Errorf("error reading CIDFile: %w", err)
+ }
+ id := strings.Split(string(content), "\n")[0]
+ args = append(args, id)
+ }
+
+ for _, f := range filters {
+ split := strings.SplitN(f, "=", 2)
+ if len(split) < 2 {
+ return fmt.Errorf("invalid filter %q", f)
+ }
+ unpauseOpts.Filters[split[0]] = append(unpauseOpts.Filters[split[0]], split[1])
}
- responses, err := registry.ContainerEngine().ContainerUnpause(context.Background(), args, unPauseOptions)
+
+ responses, err := registry.ContainerEngine().ContainerUnpause(context.Background(), args, unpauseOpts)
if err != nil {
return err
}
+
for _, r := range responses {
if r.Err == nil {
- fmt.Println(r.Id)
+ fmt.Println(r.RawInput)
} else {
errs = append(errs, r.Err)
}
diff --git a/cmd/podman/machine/info.go b/cmd/podman/machine/info.go
index 9932027d8..418060675 100644
--- a/cmd/podman/machine/info.go
+++ b/cmd/podman/machine/info.go
@@ -16,6 +16,7 @@ import (
"github.com/containers/podman/v4/cmd/podman/registry"
"github.com/containers/podman/v4/cmd/podman/validate"
"github.com/containers/podman/v4/libpod/define"
+ "github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/machine"
"github.com/ghodss/yaml"
"github.com/spf13/cobra"
@@ -40,26 +41,6 @@ var (
inFormat string
)
-// Info contains info on the machine host and version info
-type Info struct {
- Host *HostInfo `json:"Host"`
- Version define.Version `json:"Version"`
-}
-
-// HostInfo contains info on the machine host
-type HostInfo struct {
- Arch string `json:"Arch"`
- CurrentMachine string `json:"CurrentMachine"`
- DefaultMachine string `json:"DefaultMachine"`
- EventsDir string `json:"EventsDir"`
- MachineConfigDir string `json:"MachineConfigDir"`
- MachineImageDir string `json:"MachineImageDir"`
- MachineState string `json:"MachineState"`
- NumberOfMachines int `json:"NumberOfMachines"`
- OS string `json:"OS"`
- VMType string `json:"VMType"`
-}
-
func init() {
registry.Commands = append(registry.Commands, registry.CliCommand{
Command: infoCmd,
@@ -69,11 +50,11 @@ func init() {
flags := infoCmd.Flags()
formatFlagName := "format"
flags.StringVarP(&inFormat, formatFlagName, "f", "", "Change the output format to JSON or a Go template")
- _ = infoCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&define.Info{}))
+ _ = infoCmd.RegisterFlagCompletionFunc(formatFlagName, common.AutocompleteFormat(&entities.MachineInfo{}))
}
func info(cmd *cobra.Command, args []string) error {
- info := Info{}
+ info := entities.MachineInfo{}
version, err := define.GetVersion()
if err != nil {
return fmt.Errorf("error getting version info %w", err)
@@ -112,8 +93,8 @@ func info(cmd *cobra.Command, args []string) error {
return nil
}
-func hostInfo() (*HostInfo, error) {
- host := HostInfo{}
+func hostInfo() (*entities.MachineHostInfo, error) {
+ host := entities.MachineHostInfo{}
host.Arch = runtime.GOARCH
host.OS = runtime.GOOS
diff --git a/cmd/podman/machine/ssh.go b/cmd/podman/machine/ssh.go
index cb2f62f51..8534b8efa 100644
--- a/cmd/podman/machine/ssh.go
+++ b/cmd/podman/machine/ssh.go
@@ -80,6 +80,11 @@ func ssh(cmd *cobra.Command, args []string) error {
}
}
+ vm, err = provider.LoadVMByName(vmName)
+ if err != nil {
+ return fmt.Errorf("vm %s not found: %w", vmName, err)
+ }
+
if !validVM && sshOpts.Username == "" {
sshOpts.Username, err = remoteConnectionUsername()
if err != nil {
@@ -87,10 +92,6 @@ func ssh(cmd *cobra.Command, args []string) error {
}
}
- vm, err = provider.LoadVMByName(vmName)
- if err != nil {
- return fmt.Errorf("vm %s not found: %w", vmName, err)
- }
err = vm.SSH(vmName, sshOpts)
return utils.HandleOSExecError(err)
}
diff --git a/cmd/podman/networks/create.go b/cmd/podman/networks/create.go
index 2cf7023f3..8b0ebeb2b 100644
--- a/cmd/podman/networks/create.go
+++ b/cmd/podman/networks/create.go
@@ -17,7 +17,7 @@ import (
)
var (
- networkCreateDescription = `create CNI networks for containers and pods`
+ networkCreateDescription = `create networks for containers and pods`
networkCreateCommand = &cobra.Command{
Use: "create [options] [NAME]",
Short: "network create",
diff --git a/cmd/podman/networks/inspect.go b/cmd/podman/networks/inspect.go
index 1a8444147..14f62cbd1 100644
--- a/cmd/podman/networks/inspect.go
+++ b/cmd/podman/networks/inspect.go
@@ -13,8 +13,8 @@ var (
networkinspectDescription = `Inspect network`
networkinspectCommand = &cobra.Command{
Use: "inspect [options] NETWORK [NETWORK...]",
- Short: "Displays the raw CNI network configuration for one or more networks.",
- Long: networkinspectDescription,
+ Long: "Displays the network configuration for one or more networks.",
+ Short: networkinspectDescription,
RunE: networkInspect,
Example: `podman network inspect podman`,
Args: cobra.MinimumNArgs(1),
diff --git a/cmd/podman/pods/create.go b/cmd/podman/pods/create.go
index aea8a7229..4f1f66ad6 100644
--- a/cmd/podman/pods/create.go
+++ b/cmd/podman/pods/create.go
@@ -134,6 +134,12 @@ func create(cmd *cobra.Command, args []string) error {
imageName = infraImage
}
img := imageName
+
+ if !cmd.Flag("infra").Changed && (share == "none" || share == "") {
+ // we do not want an infra container when not sharing namespaces
+ createOptions.Infra = false
+ }
+
if !createOptions.Infra {
if cmd.Flag("no-hosts").Changed {
return fmt.Errorf("cannot specify --no-hosts without an infra container")
diff --git a/commands-demo.md b/commands-demo.md
index c1413dd9e..dac279192 100644
--- a/commands-demo.md
+++ b/commands-demo.md
@@ -45,13 +45,13 @@
| [podman-logout(1)](https://podman.readthedocs.io/en/latest/markdown/podman-logout.1.html) | Logout of a container registry |
| [podman-logs(1)](https://podman.readthedocs.io/en/latest/markdown/podman-logs.1.html) | Display the logs of one or more containers |
| [podman-mount(1)](https://podman.readthedocs.io/en/latest/markdown/podman-mount.1.html) | Mount a working container's root filesystem |
-| [podman-network(1)](https://podman.readthedocs.io/en/latest/network.html) | Manage Podman CNI networks |
-| [podman-network-create(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-create.1.html) | Create a CNI network |
-| [podman-network-connect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-connect.1.html) | Connect a container to a CNI network |
-| [podman-network-disconnect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-disconnect.1.html) | Disconnect a container from a CNI network |
-| [podman-network-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-inspect.1.html) | Displays the raw CNI network configuration for one or more networks |
-| [podman-network-ls(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-ls.1.html) | Display a summary of CNI networks |
-| [podman-network-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-rm.1.html) | Remove one or more CNI networks |
+| [podman-network(1)](https://podman.readthedocs.io/en/latest/network.html) | Manage Podman networks |
+| [podman-network-create(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-create.1.html) | Create a network |
+| [podman-network-connect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-connect.1.html) | Connect a container to a network |
+| [podman-network-disconnect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-disconnect.1.html) | Disconnect a container from a network |
+| [podman-network-inspect(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-inspect.1.html) | Displays the network configuration for one or more networks |
+| [podman-network-ls(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-ls.1.html) | Display a summary of networks |
+| [podman-network-rm(1)](https://podman.readthedocs.io/en/latest/markdown/podman-network-rm.1.html) | Remove one or more networks |
| [podman-pause(1)](https://podman.readthedocs.io/en/latest/markdown/podman-pause.1.html) | Pause one or more running containers | [![...](/docs/source/markdown/play.png)](https://podman.io/asciinema/podman/pause_unpause/) | [Here](https://github.com/containers/Demos/blob/master/podman_cli/podman_pause_unpause.sh) |
| [podman-play(1)](https://podman.readthedocs.io/en/latest/play.html) | Play a pod |
| [podman-play-kube(1)](https://podman.readthedocs.io/en/latest/markdown/podman-play-kube.1.html) | Create pods and containers based on Kubernetes YAML |
diff --git a/contrib/cirrus/runner.sh b/contrib/cirrus/runner.sh
index 939cc33ce..1956968ea 100755
--- a/contrib/cirrus/runner.sh
+++ b/contrib/cirrus/runner.sh
@@ -246,6 +246,7 @@ function _run_build() {
if [[ "$runtime" != "$CI_DESIRED_RUNTIME" ]]; then
die "Built podman is using '$runtime'; this CI environment requires $CI_DESIRED_RUNTIME"
fi
+ msg "Built podman is using expected runtime='$runtime'"
}
function _run_altbuild() {
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index d5044816d..c3b7811bc 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -71,27 +71,20 @@ fi
cd "${GOSRC}/"
-# Defined by lib.sh: Does the host support cgroups v1 or v2
+# Defined by lib.sh: Does the host support cgroups v1 or v2? Use runc or crun
+# respectively.
+# **IMPORTANT**: $OCI_RUNTIME is a fakeout! It is used only in e2e tests.
+# For actual podman, as in system tests, we force runtime in containers.conf
case "$CG_FS_TYPE" in
tmpfs)
if ((CONTAINER==0)); then
warn "Forcing testing with runc instead of crun"
- if [[ "$OS_RELEASE_ID" == "ubuntu" ]]; then
- # Need b/c using cri-o-runc package from OBS
- echo "OCI_RUNTIME=/usr/lib/cri-o-runc/sbin/runc" \
- >> /etc/ci_environment
- else
- echo "OCI_RUNTIME=runc" >> /etc/ci_environment
- fi
+ echo "OCI_RUNTIME=runc" >> /etc/ci_environment
+ printf "[engine]\nruntime=\"runc\"\n" >>/etc/containers/containers.conf
fi
;;
cgroup2fs)
- if ((CONTAINER==0)); then
- # This is necessary since we've built/installed from source,
- # which uses runc as the default.
- warn "Forcing testing with crun instead of runc"
- echo "OCI_RUNTIME=crun" >> /etc/ci_environment
- fi
+ # Nothing to do: podman defaults to crun
;;
*) die_unknown CG_FS_TYPE
esac
@@ -368,7 +361,7 @@ case "$TEST_FLAVOR" in
slug="gitlab.com/gitlab-org/gitlab-runner"
helper_fqin="registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:x86_64-latest-pwsh"
ssh="ssh $ROOTLESS_USER@localhost -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o CheckHostIP=no env GOPATH=$GOPATH"
- showrun $ssh go get -u github.com/jstemmer/go-junit-report
+ showrun $ssh go install github.com/jstemmer/go-junit-report/v2@v2.0.0
showrun $ssh git clone https://$slug $GOPATH/src/$slug
showrun $ssh make -C $GOPATH/src/$slug development_setup
showrun $ssh bash -c "'cd $GOPATH/src/$slug && GOPATH=$GOPATH go get .'"
diff --git a/docs/remote-docs.sh b/docs/remote-docs.sh
index 4c2602f80..f281c19ff 100755
--- a/docs/remote-docs.sh
+++ b/docs/remote-docs.sh
@@ -6,7 +6,9 @@ PLATFORM=$1 ## linux, windows or darwin
TARGET=${2} ## where to output files
SOURCES=${@:3} ## directories to find markdown files
-# Overridden for testing. Native podman-remote binary expected filepaths
+# This is a *native* binary, one we can run on this host. (This script can be
+# invoked in a cross-compilation environment, so even if PLATFORM=windows
+# we need an actual executable that we can invoke).
if [[ -z "$PODMAN" ]]; then
case $(env -i HOME=$HOME PATH=$PATH go env GOOS) in
windows)
diff --git a/docs/source/markdown/podman-create.1.md b/docs/source/markdown/podman-create.1.md
index 67bb573e2..6a951b421 100644
--- a/docs/source/markdown/podman-create.1.md
+++ b/docs/source/markdown/podman-create.1.md
@@ -738,9 +738,12 @@ Valid _mode_ values are:
#### **--network-alias**=*alias*
-Add a network-scoped alias for the container, setting the alias for all networks that the container joins. To set a name only for a specific network, use the alias option as described under the **--network** option.
-Network aliases work only with the bridge networking mode. This option can be specified multiple times.
-NOTE: A container will only have access to aliases on the first network that it joins. This is a limitation that will be removed in a later release.
+Add a network-scoped alias for the container, setting the alias for all networks that the container joins. To set a
+name only for a specific network, use the alias option as described under the **--network** option.
+If the network has DNS enabled (`podman network inspect -f {{.DNSEnabled}} <name>`),
+these aliases can be used for name resolution on the given network. This option can be specified multiple times.
+NOTE: When using CNI a container will only have access to aliases on the first network that it joins. This limitation does
+not exist with netavark/aardvark-dns.
#### **--no-healthcheck**
diff --git a/docs/source/markdown/podman-generate-systemd.1.md b/docs/source/markdown/podman-generate-systemd.1.md
index 50881a509..fc2ce171e 100644
--- a/docs/source/markdown/podman-generate-systemd.1.md
+++ b/docs/source/markdown/podman-generate-systemd.1.md
@@ -14,6 +14,13 @@ Generating unit files for a pod requires the pod to be created with an infra con
_Note: If you use this command with the remote client, including Mac and Windows (excluding WSL2) machines, you would still have to place the generated units on the remote system. Moreover, please make sure that the XDG_RUNTIME_DIR environment variable is set. If unset, you may set it via `export XDG_RUNTIME_DIR=/run/user/$(id -u)`._
+_Note: The generated `podman run` command contains an `--sdnotify` option with the value taken from the container.
+If the container does not have any explicitly set value or the value is set to __ignore__, the value __conmon__ is used.
+The reason for overriding the default value __container__ is that almost no container workloads send notify messages.
+Systemd would wait for a ready message that never comes, if the value __container__ is used for a container
+that does not send notify messages. The use of the default value might have been unintentional by the user,
+therefore the overridden default value._
+
### Kubernetes Integration
A Kubernetes YAML can be executed in systemd via the `podman-kube@.service` systemd template. The template's argument is the path to the YAML file. Given a `workload.yaml` file in the home directory, it can be executed as follows:
diff --git a/docs/source/markdown/podman-import.1.md b/docs/source/markdown/podman-import.1.md
index 4002f5255..8d482b961 100644
--- a/docs/source/markdown/podman-import.1.md
+++ b/docs/source/markdown/podman-import.1.md
@@ -50,10 +50,6 @@ Shows progress on the import
Set variant of the imported image.
-**--verbose**
-
-Print additional debugging information
-
## EXAMPLES
```
diff --git a/docs/source/markdown/podman-kube-play.1.md b/docs/source/markdown/podman-kube-play.1.md
index f52989623..25248ce99 100644
--- a/docs/source/markdown/podman-kube-play.1.md
+++ b/docs/source/markdown/podman-kube-play.1.md
@@ -322,7 +322,7 @@ $ podman kube play demo.yml --network net1:ip=10.89.1.5 --network net2:ip=10.89.
52182811df2b1e73f36476003a66ec872101ea59034ac0d4d3a7b40903b955a6
```
-Please take into account that CNI networks must be created first using podman-network-create(1).
+Please take into account that networks must be created first using podman-network-create(1).
## SEE ALSO
**[podman(1)](podman.1.md)**, **[podman-kube(1)](podman-kube.1.md)**, **[podman-network-create(1)](podman-network-create.1.md)**, **[podman-generate-kube(1)](podman-generate-kube.1.md)**, **[containers-certs.d(5)](https://github.com/containers/image/blob/main/docs/containers-certs.d.5.md)**
diff --git a/docs/source/markdown/podman-network-connect.1.md b/docs/source/markdown/podman-network-connect.1.md
index c3eef4038..d1718b812 100644
--- a/docs/source/markdown/podman-network-connect.1.md
+++ b/docs/source/markdown/podman-network-connect.1.md
@@ -12,10 +12,10 @@ Once connected, the container can communicate with other containers in the same
## OPTIONS
#### **--alias**=*name*
-Add network-scoped alias for the container. If the network is using the `dnsname` CNI plugin, these aliases
-can be used for name resolution on the given network. Multiple *--alias* options may be specified as input.
-NOTE: A container will only have access to aliases on the first network that it joins. This is a limitation
-that will be removed in a later release.
+Add network-scoped alias for the container. If the network has DNS enabled (`podman network inspect -f {{.DNSEnabled}} <NAME>`),
+these aliases can be used for name resolution on the given network. Multiple *--alias* options may be specified as input.
+NOTE: When using CNI a container will only have access to aliases on the first network that it joins. This limitation does
+not exist with netavark/aardvark-dns.
#### **--ip**=*address*
Set a static ipv4 address for this container on this network.
@@ -44,7 +44,7 @@ podman network connect --ip 10.89.1.13 test web
```
## SEE ALSO
-**[podman(1)](podman.1.md)**, **[podman-network(1)](podman-network.1.md)**, **[podman-network-disconnect(1)](podman-network-disconnect.1.md)**
+**[podman(1)](podman.1.md)**, **[podman-network(1)](podman-network.1.md)**, **[podman-network-inspect(1)](podman-network-inspect.1.md)**, **[podman-network-disconnect(1)](podman-network-disconnect.1.md)**
## HISTORY
November 2020, Originally compiled by Brent Baude <bbaude@redhat.com>
diff --git a/docs/source/markdown/podman-network-create.1.md b/docs/source/markdown/podman-network-create.1.md
index 0ccc540f8..3836ea05c 100644
--- a/docs/source/markdown/podman-network-create.1.md
+++ b/docs/source/markdown/podman-network-create.1.md
@@ -7,11 +7,9 @@ podman\-network-create - Create a Podman network
**podman network create** [*options*] [*name*]
## DESCRIPTION
-Create a CNI-network configuration for use with Podman. By default, Podman creates a bridge connection.
+Create a network configuration for use with Podman. By default, Podman creates a bridge connection.
A *Macvlan* connection can be created with the *-d macvlan* option. A parent device for macvlan can
-be designated with the *-o parent=`<device>`* option. In the case of *Macvlan* connections, the
-CNI *dhcp* plugin needs to be activated or the container image must have a DHCP client to interact
-with the host network's DHCP server.
+be designated with the *-o parent=`<device>`* option.
If no options are provided, Podman will assign a free subnet and name for your network.
@@ -54,7 +52,7 @@ The argument order of the **--subnet**, **--gateway** and **--ip-range** options
Set the ipam driver (IP Address Management Driver) for the network. When unset podman will choose an
ipam driver automatically based on the network driver. Valid values are:
- `host-local`: IP addresses are assigned locally.
- - `dhcp`: IP addresses are assigned from a dhcp server on your network. This driver is not yet supported with netavark.
+ - `dhcp`: IP addresses are assigned from a dhcp server on your network. This driver is not yet supported with netavark. For CNI the *dhcp* plugin needs to be activated before.
- `none`: No ip addresses are assigned to the interfaces.
You can see the driver in the **podman network inspect** output under the `ipam_options` field.
@@ -94,7 +92,7 @@ This is useful to set a static ipv4 and ipv6 subnet.
Create a network with no options.
```
$ podman network create
-cni-podman2
+podman2
```
Create a network named *newnet* that uses *192.5.0.0/16* for its subnet.
@@ -118,7 +116,7 @@ newnet
Create a network that uses a *192.168.55.0/24** subnet and has an IP address range of *192.168.55.129 - 192.168.55.254*.
```
$ podman network create --subnet 192.168.55.0/24 --ip-range 192.168.55.128/25
-cni-podman5
+podman5
```
Create a network with a static ipv4 and ipv6 subnet and set a gateway.
diff --git a/docs/source/markdown/podman-network-inspect.1.md b/docs/source/markdown/podman-network-inspect.1.md
index ba9cc94d5..2ba4a63cb 100644
--- a/docs/source/markdown/podman-network-inspect.1.md
+++ b/docs/source/markdown/podman-network-inspect.1.md
@@ -1,13 +1,13 @@
% podman-network-inspect(1)
## NAME
-podman\-network\-inspect - Displays the raw network configuration for one or more networks
+podman\-network\-inspect - Displays the network configuration for one or more networks
## SYNOPSIS
**podman network inspect** [*options*] *network* [*network* ...]
## DESCRIPTION
-Display the raw (JSON format) network configuration.
+Display the (JSON format) network configuration.
## OPTIONS
#### **--format**, **-f**=*format*
@@ -40,7 +40,7 @@ $ podman network inspect podman
"name": "podman",
"id": "2f259bab93aaaaa2542ba43ef33eb990d0999ee1b9924b557b7be53c0b7a1bb9",
"driver": "bridge",
- "network_interface": "cni-podman0",
+ "network_interface": "podman0",
"created": "2021-06-03T12:04:33.088567413+02:00",
"subnets": [
{
diff --git a/docs/source/markdown/podman-network-ls.1.md b/docs/source/markdown/podman-network-ls.1.md
index 3c696d404..c7ea24b9b 100644
--- a/docs/source/markdown/podman-network-ls.1.md
+++ b/docs/source/markdown/podman-network-ls.1.md
@@ -77,8 +77,8 @@ Display networks
$ podman network ls
NETWORK ID NAME DRIVER
88a7120ee19d podman bridge
-6dd508dbf8cd cni-podman6 bridge
-8e35c2cd3bf6 cni-podman5 macvlan
+6dd508dbf8cd podman6 bridge
+8e35c2cd3bf6 podman5 macvlan
```
Display only network names
@@ -101,7 +101,7 @@ List networks with their subnets
```
$ podman network ls --format "{{.Name}}: {{range .Subnets}}{{.Subnet}} {{end}}"
podman: 10.88.0.0/16
-cni-podman3: 10.89.30.0/24 fde4:f86f:4aab:e68f::/64
+podman3: 10.89.30.0/24 fde4:f86f:4aab:e68f::/64
macvlan:
```
diff --git a/docs/source/markdown/podman-network-rm.1.md b/docs/source/markdown/podman-network-rm.1.md
index c6e33c571..880f1d0c7 100644
--- a/docs/source/markdown/podman-network-rm.1.md
+++ b/docs/source/markdown/podman-network-rm.1.md
@@ -21,11 +21,11 @@ Seconds to wait before forcibly stopping the running containers that are using t
## EXAMPLE
-Delete the `cni-podman9` network
+Delete the `podman9` network
```
-# podman network rm cni-podman9
-Deleted: cni-podman9
+# podman network rm podman9
+Deleted: podman9
```
Delete the `fred` network and all containers associated with the network.
diff --git a/docs/source/markdown/podman-network.1.md b/docs/source/markdown/podman-network.1.md
index bc75cce3b..f58bd5d5c 100644
--- a/docs/source/markdown/podman-network.1.md
+++ b/docs/source/markdown/podman-network.1.md
@@ -27,7 +27,7 @@ so networks have to be created again after a backend change.
| create | [podman-network-create(1)](podman-network-create.1.md) | Create a Podman network |
| disconnect | [podman-network-disconnect(1)](podman-network-disconnect.1.md) | Disconnect a container from a network |
| exists | [podman-network-exists(1)](podman-network-exists.1.md) | Check if the given network exists |
-| inspect | [podman-network-inspect(1)](podman-network-inspect.1.md) | Displays the raw network configuration for one or more networks |
+| inspect | [podman-network-inspect(1)](podman-network-inspect.1.md) | Displays the network configuration for one or more networks |
| ls | [podman-network-ls(1)](podman-network-ls.1.md) | Display a summary of networks |
| prune | [podman-network-prune(1)](podman-network-prune.1.md) | Remove all unused networks |
| reload | [podman-network-reload(1)](podman-network-reload.1.md) | Reload network configuration for containers |
diff --git a/docs/source/markdown/podman-pause.1.md b/docs/source/markdown/podman-pause.1.md
index 863be9ed4..f374d96f3 100644
--- a/docs/source/markdown/podman-pause.1.md
+++ b/docs/source/markdown/podman-pause.1.md
@@ -17,21 +17,65 @@ Pauses all the processes in one or more containers. You may use container IDs o
Pause all running containers.
+#### **--cidfile**
+
+Read container ID from the specified file and pause the container. Can be specified multiple times.
+
+#### **--filter**, **-f**=*filter*
+
+Filter what containers pause.
+Multiple filters can be given with multiple uses of the --filter flag.
+Filters with the same key work inclusive with the only exception being
+`label` which is exclusive. Filters with different keys always work exclusive.
+
+Valid filters are listed below:
+
+| **Filter** | **Description** |
+| --------------- | -------------------------------------------------------------------------------- |
+| id | [ID] Container's ID (accepts regex) |
+| name | [Name] Container's name (accepts regex) |
+| label | [Key] or [Key=Value] Label assigned to a container |
+| exited | [Int] Container's exit code |
+| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' |
+| ancestor | [ImageName] Image or descendant used to create container |
+| before | [ID] or [Name] Containers created before this container |
+| since | [ID] or [Name] Containers created since this container |
+| volume | [VolumeName] or [MountpointDestination] Volume mounted in container |
+| health | [Status] healthy or unhealthy |
+| pod | [Pod] name or full or partial ID of pod |
+| network | [Network] name or full ID of network |
+
+#### **--latest**, **-l**
+
+Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
+to run containers such as CRI-O, the last started container could be from either of those methods. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
+
## EXAMPLE
-Pause a container named 'mywebserver'
+Pause container named 'mywebserver'
```
podman pause mywebserver
```
-Pause a container by partial container ID.
+Pause container by partial container ID.
```
podman pause 860a4b23
```
Pause all **running** containers.
```
-podman pause -a
+podman pause --all
+```
+
+Pause container using ID specified in a given files.
+```
+podman pause --cidfile /home/user/cidfile-1
+podman pause --cidfile /home/user/cidfile-1 --cidfile ./cidfile-2
+```
+
+Pause the latest container created by Podman.
+```
+podman pause --latest
```
## SEE ALSO
diff --git a/docs/source/markdown/podman-pod-create.1.md b/docs/source/markdown/podman-pod-create.1.md
index 660112865..7b63ac51d 100644
--- a/docs/source/markdown/podman-pod-create.1.md
+++ b/docs/source/markdown/podman-pod-create.1.md
@@ -284,9 +284,12 @@ Valid _mode_ values are:
#### **--network-alias**=*alias*
-Add a network-scoped alias for the pod, setting the alias for all networks that the pod joins. To set a name only for a specific network, use the alias option as described under the **--network** option.
-Network aliases work only with the bridge networking mode. This option can be specified multiple times.
-NOTE: A container will only have access to aliases on the first network that it joins. This is a limitation that will be removed in a later release.
+Add a network-scoped alias for the pod, setting the alias for all networks that the container joins. To set a
+name only for a specific network, use the alias option as described under the **--network** option.
+If the network has DNS enabled (`podman network inspect -f {{.DNSEnabled}} <name>`),
+these aliases can be used for name resolution on the given network. This option can be specified multiple times.
+NOTE: When using CNI a pod will only have access to aliases on the first network that it joins. This limitation does
+not exist with netavark/aardvark-dns.
#### **--no-hosts**
@@ -370,7 +373,7 @@ Note: Labeling can be disabled for all containers by setting label=false in the
#### **--share**=*namespace*
-A comma-separated list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared. The namespaces to choose from are cgroup, ipc, net, pid, uts. If the option is prefixed with a "+" then the namespace is appended to the default list, otherwise it replaces the default list. Defaults matches Kubernetes default (ipc, net, uts)
+A comma-separated list of kernel namespaces to share. If none or "" is specified, no namespaces will be shared and the infra container will not be created unless expiclity specified via **--infra=true**. The namespaces to choose from are cgroup, ipc, net, pid, uts. If the option is prefixed with a "+" then the namespace is appended to the default list, otherwise it replaces the default list. Defaults matches Kubernetes default (ipc, net, uts)
#### **--share-parent**
diff --git a/docs/source/markdown/podman-run.1.md b/docs/source/markdown/podman-run.1.md
index 4566a73d0..cb19e929e 100644
--- a/docs/source/markdown/podman-run.1.md
+++ b/docs/source/markdown/podman-run.1.md
@@ -755,9 +755,12 @@ Valid _mode_ values are:
#### **--network-alias**=*alias*
-Add a network-scoped alias for the container, setting the alias for all networks that the container joins. To set a name only for a specific network, use the alias option as described under the **--network** option.
-Network aliases work only with the bridge networking mode. This option can be specified multiple times.
-NOTE: A container will only have access to aliases on the first network that it joins. This is a limitation that will be removed in a later release.
+Add a network-scoped alias for the container, setting the alias for all networks that the container joins. To set a
+name only for a specific network, use the alias option as described under the **--network** option.
+If the network has DNS enabled (`podman network inspect -f {{.DNSEnabled}} <name>`),
+these aliases can be used for name resolution on the given network. This option can be specified multiple times.
+NOTE: When using CNI a container will only have access to aliases on the first network that it joins. This limitation does
+not exist with netavark/aardvark-dns.
#### **--no-healthcheck**
diff --git a/docs/source/markdown/podman-unpause.1.md b/docs/source/markdown/podman-unpause.1.md
index 4f66bf393..b94ace89e 100644
--- a/docs/source/markdown/podman-unpause.1.md
+++ b/docs/source/markdown/podman-unpause.1.md
@@ -17,21 +17,65 @@ Unpauses the processes in one or more containers. You may use container IDs or
Unpause all paused containers.
+#### **--cidfile**
+
+Read container ID from the specified file and unpause the container. Can be specified multiple times.
+
+#### **--filter**, **-f**=*filter*
+
+Filter what containers unpause.
+Multiple filters can be given with multiple uses of the --filter flag.
+Filters with the same key work inclusive with the only exception being
+`label` which is exclusive. Filters with different keys always work exclusive.
+
+Valid filters are listed below:
+
+| **Filter** | **Description** |
+| --------------- | -------------------------------------------------------------------------------- |
+| id | [ID] Container's ID (accepts regex) |
+| name | [Name] Container's name (accepts regex) |
+| label | [Key] or [Key=Value] Label assigned to a container |
+| exited | [Int] Container's exit code |
+| status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' |
+| ancestor | [ImageName] Image or descendant used to create container |
+| before | [ID] or [Name] Containers created before this container |
+| since | [ID] or [Name] Containers created since this container |
+| volume | [VolumeName] or [MountpointDestination] Volume mounted in container |
+| health | [Status] healthy or unhealthy |
+| pod | [Pod] name or full or partial ID of pod |
+| network | [Network] name or full ID of network |
+
+#### **--latest**, **-l**
+
+Instead of providing the container name or ID, use the last created container. If you use methods other than Podman
+to run containers such as CRI-O, the last started container could be from either of those methods. (This option is not available with the remote Podman client, including Mac and Windows (excluding WSL2) machines)
+
## EXAMPLE
-Unpause a container called 'mywebserver'
+Unpause container called 'mywebserver'
```
podman unpause mywebserver
```
-Unpause a container by a partial container ID.
+Unpause container by a partial container ID.
```
podman unpause 860a4b23
```
Unpause all **paused** containers.
```
-podman unpause -a
+podman unpause --all
+```
+
+Unpause container using ID specified in a given files.
+```
+podman unpause --cidfile /home/user/cidfile-1
+podman unpause --cidfile /home/user/cidfile-1 --cidfile ./cidfile-2
+```
+
+Unpause the latest container created by Podman.
+```
+podman unpause --latest
```
## SEE ALSO
diff --git a/docs/tutorials/basic_networking.md b/docs/tutorials/basic_networking.md
index 0a6034e7a..05c3a731e 100644
--- a/docs/tutorials/basic_networking.md
+++ b/docs/tutorials/basic_networking.md
@@ -32,7 +32,7 @@ port mapping. Depending on the firewall implementation, we have observed firewa
ports being opened automatically due to running a container with a port mapping (for
example). If container traffic does not seem to work properly, check the firewall
and allow traffic on ports the container is using. A common problem is that
-reloading the firewall deletes the cni iptables rules resulting in a loss of
+reloading the firewall deletes the cni/netavark iptables rules resulting in a loss of
network connectivity for rootful containers. Podman v3 provides the podman
network reload command to restore this without having to restart the container.
@@ -83,7 +83,7 @@ users. But as of Podman version 4.0, rootless users can also use netavark.
The user experience of rootless netavark is very akin to a rootful netavark, except that
there is no default network configuration provided. You simply need to create a
network, and the one will be created as a bridge network. If you would like to switch from
-CNI networking to netvaark, you must issue the `podman system reset --force` command.
+CNI networking to netavark, you must issue the `podman system reset --force` command.
This will delete all of your images, containers, and custom networks.
```
@@ -177,7 +177,7 @@ address, you should continue to use CNI instead of netavark.
```
$ sudo podman network create -d macvlan -o parent=eth0 webnetwork
-/etc/cni/net.d/webnetwork.conflist
+webnetwork
```
The next step is to ensure that the DHCP CNI plugin is running. This plugin facilitates
the DHCP lease from the network.
diff --git a/go.mod b/go.mod
index c09c1222b..978e475a8 100644
--- a/go.mod
+++ b/go.mod
@@ -12,12 +12,12 @@ require (
github.com/containernetworking/cni v1.1.1
github.com/containernetworking/plugins v1.1.1
github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab
- github.com/containers/common v0.48.1-0.20220718075257-ecddf87b3840
+ github.com/containers/common v0.48.1-0.20220720145307-26032247af78
github.com/containers/conmon v2.0.20+incompatible
github.com/containers/image/v5 v5.21.2-0.20220721072459-bf19265865b7
github.com/containers/ocicrypt v1.1.5
github.com/containers/psgo v1.7.2
- github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a
+ github.com/containers/storage v1.41.1-0.20220718173332-b10c469fda0a
github.com/coreos/go-systemd/v22 v22.3.2
github.com/coreos/stream-metadata-go v0.0.0-20210225230131-70edb9eb47b3
github.com/cyphar/filepath-securejoin v0.2.3
diff --git a/go.sum b/go.sum
index 9f7cb9273..7d28490f2 100644
--- a/go.sum
+++ b/go.sum
@@ -393,8 +393,8 @@ github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19
github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab h1:NeI0DOkTf3Tn4OpdjMhMubAfTPs2oCO5jUY5wnpv4qk=
github.com/containers/buildah v1.26.1-0.20220716095526-d31d27c357ab/go.mod h1:iVtQtU6a+pbETBqIzg0oAWW3gTR1ItrAihJpLFFppmA=
github.com/containers/common v0.48.1-0.20220715075726-2ac10faca05a/go.mod h1:1dA7JPGoSi83kjf5H4NIrGANyLOULyvFqV1bwvYFEek=
-github.com/containers/common v0.48.1-0.20220718075257-ecddf87b3840 h1:+5C5tnWO2a6M9QqKNUibMIn56LAuIDtuyb/xT6ZGU/4=
-github.com/containers/common v0.48.1-0.20220718075257-ecddf87b3840/go.mod h1:1dA7JPGoSi83kjf5H4NIrGANyLOULyvFqV1bwvYFEek=
+github.com/containers/common v0.48.1-0.20220720145307-26032247af78 h1:Z25E8uA264l7dgk0h+1pfV5Y3ZhrFY/0eR6BUQ5BwkY=
+github.com/containers/common v0.48.1-0.20220720145307-26032247af78/go.mod h1:w9q2iCLu6pIB9qu0S9oZWM2Qo4lOWrIdDB+2SjLljqA=
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.21.2-0.20220712113758-29aec5f7bbbf/go.mod h1:0+N0ZM9mgMmoZZc6uNcgnEsbX85Ne7b29cIW5lqWwVU=
@@ -416,8 +416,9 @@ github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c
github.com/containers/storage v1.38.0/go.mod h1:lBzt28gAk5ADZuRtwdndRJyqX22vnRaXmlF+7ktfMYc=
github.com/containers/storage v1.41.0/go.mod h1:Pb0l5Sm/89kolX3o2KolKQ5cCHk5vPNpJrhNaLcdS5s=
github.com/containers/storage v1.41.1-0.20220712184034-d26be7b27860/go.mod h1:uu6HCcijN30xRxW1ZuZRngwFGOlH5NpBWYiNBnDQNRw=
-github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a h1:+arJAP0v8kEy5fKRPIELjarjpwUHhB7SyRE0uFXlyKY=
github.com/containers/storage v1.41.1-0.20220714115232-fc9b0ff5272a/go.mod h1:4DfR+cPpkXKhJnnyydD3z82DXrnTBT63y1k0QWtM2i4=
+github.com/containers/storage v1.41.1-0.20220718173332-b10c469fda0a h1:+2n/MLjSlLQwxcROpJLAOvN86SvOMB5IxOahq4iitok=
+github.com/containers/storage v1.41.1-0.20220718173332-b10c469fda0a/go.mod h1:jfYNR16uI3eCaWU2Bdn9sHgET7W8JB0OPiswQamG1Cs=
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=
diff --git a/hack/golangci-lint.sh b/hack/golangci-lint.sh
index 2eaf206d7..dd06004ac 100755
--- a/hack/golangci-lint.sh
+++ b/hack/golangci-lint.sh
@@ -9,9 +9,9 @@ BUILD_TAGS[abi]="${BUILD_TAGS[default]},systemd"
BUILD_TAGS[tunnel]="${BUILD_TAGS[default]},remote"
declare -A SKIP_DIRS
-SKIP_DIRS[abi]="pkg/machine/e2e"
+SKIP_DIRS[abi]=""
# TODO: add "remote" build tag to pkg/api
-SKIP_DIRS[tunnel]="pkg/api,pkg/machine/e2e"
+SKIP_DIRS[tunnel]="pkg/api"
[[ $1 == run ]] && shift
diff --git a/libpod/container_api.go b/libpod/container_api.go
index 742eb6d3e..2ff4bfe08 100644
--- a/libpod/container_api.go
+++ b/libpod/container_api.go
@@ -555,7 +555,7 @@ func (c *Container) WaitForExit(ctx context.Context, pollInterval time.Duration)
// The container never ran.
return true, 0, nil
}
- return true, -1, err
+ return true, -1, fmt.Errorf("%w (container in state %s)", err, c.state.State)
}
return true, exitCode, nil
diff --git a/libpod/runtime_pod_linux.go b/libpod/runtime_pod_linux.go
index 3bb22ec26..57c0b5c48 100644
--- a/libpod/runtime_pod_linux.go
+++ b/libpod/runtime_pod_linux.go
@@ -7,7 +7,6 @@ import (
"context"
"errors"
"fmt"
- "os"
"path"
"path/filepath"
"strings"
@@ -18,7 +17,6 @@ import (
"github.com/containers/podman/v4/libpod/events"
"github.com/containers/podman/v4/pkg/rootless"
"github.com/containers/podman/v4/pkg/specgen"
- runcconfig "github.com/opencontainers/runc/libcontainer/configs"
"github.com/sirupsen/logrus"
)
@@ -214,83 +212,37 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
return fmt.Errorf("pod %s contains containers and cannot be removed: %w", p.ID(), define.ErrCtrExists)
}
- // Go through and lock all containers so we can operate on them all at
- // once.
- // First loop also checks that we are ready to go ahead and remove.
- containersLocked := true
+ ctrNamedVolumes := make(map[string]*ContainerNamedVolume)
+
+ var removalErr error
for _, ctr := range ctrs {
- ctrLock := ctr.lock
- ctrLock.Lock()
- defer func() {
- if containersLocked {
+ err := func() error {
+ ctrLock := ctr.lock
+ ctrLock.Lock()
+ defer func() {
ctrLock.Unlock()
- }
- }()
+ }()
- // If we're force-removing, no need to check status.
- if force {
- continue
- }
-
- // Sync all containers
- if err := ctr.syncContainer(); err != nil {
- return err
- }
-
- // Ensure state appropriate for removal
- if err := ctr.checkReadyForRemoval(); err != nil {
- return fmt.Errorf("pod %s has containers that are not ready to be removed: %w", p.ID(), err)
- }
- }
-
- // We're going to be removing containers.
- // If we are Cgroupfs cgroup driver, to avoid races, we need to hit
- // the pod and conmon Cgroups with a PID limit to prevent them from
- // spawning any further processes (particularly cleanup processes) which
- // would prevent removing the Cgroups.
- if p.runtime.config.Engine.CgroupManager == config.CgroupfsCgroupsManager {
- // Get the conmon Cgroup
- conmonCgroupPath := filepath.Join(p.state.CgroupPath, "conmon")
- conmonCgroup, err := cgroups.Load(conmonCgroupPath)
- if err != nil && err != cgroups.ErrCgroupDeleted && err != cgroups.ErrCgroupV1Rootless {
- logrus.Errorf("Retrieving pod %s conmon cgroup %s: %v", p.ID(), conmonCgroupPath, err)
- }
-
- // New resource limits
- resLimits := new(runcconfig.Resources)
- resLimits.PidsLimit = 1 // Inhibit forks with very low pids limit
-
- // Don't try if we failed to retrieve the cgroup
- if err == nil {
- if err := conmonCgroup.Update(resLimits); err != nil && !os.IsNotExist(err) {
- logrus.Warnf("Error updating pod %s conmon cgroup PID limit: %v", p.ID(), err)
+ if err := ctr.syncContainer(); err != nil {
+ return err
}
- }
- }
-
- var removalErr error
- ctrNamedVolumes := make(map[string]*ContainerNamedVolume)
+ for _, vol := range ctr.config.NamedVolumes {
+ ctrNamedVolumes[vol.Name] = vol
+ }
- // Second loop - all containers are good, so we should be clear to
- // remove.
- for _, ctr := range ctrs {
- // Remove the container.
- // Do NOT remove named volumes. Instead, we're going to build a
- // list of them to be removed at the end, once the containers
- // have been removed by RemovePodContainers.
- for _, vol := range ctr.config.NamedVolumes {
- ctrNamedVolumes[vol.Name] = vol
- }
+ return r.removeContainer(ctx, ctr, force, false, true, timeout)
+ }()
- if err := r.removeContainer(ctx, ctr, force, false, true, timeout); err != nil {
- if removalErr == nil {
- removalErr = err
- } else {
- logrus.Errorf("Removing container %s from pod %s: %v", ctr.ID(), p.ID(), err)
- }
+ if removalErr == nil {
+ removalErr = err
+ } else {
+ logrus.Errorf("Removing container %s from pod %s: %v", ctr.ID(), p.ID(), err)
}
}
+ if removalErr != nil {
+ return removalErr
+ }
// Clear infra container ID before we remove the infra container.
// There is a potential issue if we don't do that, and removal is
@@ -326,12 +278,6 @@ func (r *Runtime) removePod(ctx context.Context, p *Pod, removeCtrs, force bool,
}
}
- // let's unlock the containers so if there is any cleanup process, it can terminate its execution
- for _, ctr := range ctrs {
- ctr.lock.Unlock()
- }
- containersLocked = false
-
// Remove pod cgroup, if present
if p.state.CgroupPath != "" {
logrus.Debugf("Removing pod cgroup %s", p.state.CgroupPath)
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index 2f8d151d8..39bd165d6 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -23,6 +23,7 @@ import (
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/infra/abi"
"github.com/containers/storage"
+ "github.com/docker/docker/pkg/jsonmessage"
"github.com/gorilla/schema"
"github.com/opencontainers/go-digest"
"github.com/sirupsen/logrus"
@@ -325,16 +326,8 @@ func CreateImageFromImage(w http.ResponseWriter, r *http.Request) {
loop: // break out of for/select infinite loop
for {
- var report struct {
- Stream string `json:"stream,omitempty"`
- Status string `json:"status,omitempty"`
- Progress struct {
- Current uint64 `json:"current,omitempty"`
- Total int64 `json:"total,omitempty"`
- } `json:"progressDetail,omitempty"`
- Error string `json:"error,omitempty"`
- Id string `json:"id,omitempty"` //nolint:revive,stylecheck
- }
+ report := jsonmessage.JSONMessage{}
+ report.Progress = &jsonmessage.JSONProgress{}
select {
case e := <-progress:
switch e.Event {
@@ -342,14 +335,15 @@ loop: // break out of for/select infinite loop
report.Status = "Pulling fs layer"
case types.ProgressEventRead:
report.Status = "Downloading"
- report.Progress.Current = e.Offset
+ report.Progress.Current = int64(e.Offset)
report.Progress.Total = e.Artifact.Size
+ report.ProgressMessage = report.Progress.String()
case types.ProgressEventSkipped:
report.Status = "Already exists"
case types.ProgressEventDone:
report.Status = "Download complete"
}
- report.Id = e.Artifact.Digest.Encoded()[0:12]
+ report.ID = e.Artifact.Digest.Encoded()[0:12]
if err := enc.Encode(report); err != nil {
logrus.Warnf("Failed to json encode error %q", err.Error())
}
@@ -358,7 +352,11 @@ loop: // break out of for/select infinite loop
err := pullRes.err
pulledImages := pullRes.images
if err != nil {
- report.Error = err.Error()
+ msg := err.Error()
+ report.Error = &jsonmessage.JSONError{
+ Message: msg,
+ }
+ report.ErrorMessage = msg
} else {
if len(pulledImages) > 0 {
img := pulledImages[0].ID()
@@ -367,9 +365,13 @@ loop: // break out of for/select infinite loop
} else {
report.Status = "Download complete"
}
- report.Id = img[0:12]
+ report.ID = img[0:12]
} else {
- report.Error = "internal error: no images pulled"
+ msg := "internal error: no images pulled"
+ report.Error = &jsonmessage.JSONError{
+ Message: msg,
+ }
+ report.ErrorMessage = msg
}
}
if err := enc.Encode(report); err != nil {
diff --git a/pkg/api/handlers/compat/images_build.go b/pkg/api/handlers/compat/images_build.go
index a9185c3d3..15cfc824e 100644
--- a/pkg/api/handlers/compat/images_build.go
+++ b/pkg/api/handlers/compat/images_build.go
@@ -140,6 +140,7 @@ func BuildImage(w http.ResponseWriter, r *http.Request) {
Registry: "docker.io",
Rm: true,
ShmSize: 64 * 1024 * 1024,
+ TLSVerify: true,
}
decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
diff --git a/pkg/api/handlers/compat/images_push.go b/pkg/api/handlers/compat/images_push.go
index bb82ef10d..f29808124 100644
--- a/pkg/api/handlers/compat/images_push.go
+++ b/pkg/api/handlers/compat/images_push.go
@@ -156,6 +156,7 @@ loop: // break out of for/select infinite loop
Current: int64(e.Offset),
Total: e.Artifact.Size,
}
+ report.ProgressMessage = report.Progress.String()
case types.ProgressEventSkipped:
report.Status = "Layer already exists"
case types.ProgressEventDone:
diff --git a/pkg/api/handlers/compat/images_search.go b/pkg/api/handlers/compat/images_search.go
index a6fd3a3a1..2fc95e84e 100644
--- a/pkg/api/handlers/compat/images_search.go
+++ b/pkg/api/handlers/compat/images_search.go
@@ -26,6 +26,7 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
ListTags bool `json:"listTags"`
}{
// This is where you can override the golang default value for one of fields
+ TLSVerify: true,
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index 65177218a..29d1398cf 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -23,6 +23,13 @@ import (
"github.com/sirupsen/logrus"
)
+func normalizeNetworkName(rt *libpod.Runtime, name string) (string, bool) {
+ if name == nettypes.BridgeNetworkDriver {
+ return rt.Network().DefaultNetworkName(), true
+ }
+ return name, false
+}
+
func InspectNetwork(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
@@ -44,13 +51,13 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
utils.Error(w, http.StatusBadRequest, define.ErrInvalidArg)
return
}
- name := utils.GetName(r)
+ name, changed := normalizeNetworkName(runtime, utils.GetName(r))
net, err := runtime.Network().NetworkInspect(name)
if err != nil {
utils.NetworkNotFound(w, name, err)
return
}
- report, err := convertLibpodNetworktoDockerNetwork(runtime, net)
+ report, err := convertLibpodNetworktoDockerNetwork(runtime, &net, changed)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -58,7 +65,7 @@ func InspectNetwork(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, report)
}
-func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, network nettypes.Network) (*types.NetworkResource, error) {
+func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, network *nettypes.Network, changeDefaultName bool) (*types.NetworkResource, error) {
cons, err := runtime.GetAllContainers()
if err != nil {
return nil, err
@@ -107,11 +114,15 @@ func convertLibpodNetworktoDockerNetwork(runtime *libpod.Runtime, network nettyp
Config: ipamConfigs,
}
+ name := network.Name
+ if changeDefaultName && name == runtime.Network().DefaultNetworkName() {
+ name = nettypes.BridgeNetworkDriver
+ }
report := types.NetworkResource{
- Name: network.Name,
- ID: network.ID,
- Driver: network.Driver,
- // TODO add Created: ,
+ Name: name,
+ ID: network.ID,
+ Driver: network.Driver,
+ Created: network.Created,
Internal: network.Internal,
EnableIPv6: network.IPv6Enabled,
Labels: network.Labels,
@@ -149,7 +160,7 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
}
reports := make([]*types.NetworkResource, 0, len(nets))
for _, net := range nets {
- report, err := convertLibpodNetworktoDockerNetwork(runtime, net)
+ report, err := convertLibpodNetworktoDockerNetwork(runtime, &net, true)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -182,27 +193,22 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
network.Options = make(map[string]string)
- // TODO: we should consider making this constants in c/common/libnetwork/types
+ // dockers bridge networks are always isolated from each other
+ if network.Driver == nettypes.BridgeNetworkDriver {
+ network.Options[nettypes.IsolateOption] = "true"
+ }
+
for opt, optVal := range networkCreate.Options {
switch opt {
- case "mtu":
+ case nettypes.MTUOption:
fallthrough
case "com.docker.network.driver.mtu":
- if network.Driver == nettypes.BridgeNetworkDriver {
- network.Options["mtu"] = optVal
- }
- case "icc":
- fallthrough
- case "com.docker.network.bridge.enable_icc":
- // TODO: needs to be implemented
- if network.Driver == nettypes.BridgeNetworkDriver {
- responseWarning = "com.docker.network.bridge.enable_icc is not currently implemented"
- }
+ network.Options[nettypes.MTUOption] = optVal
case "com.docker.network.bridge.name":
if network.Driver == nettypes.BridgeNetworkDriver {
network.NetworkInterface = optVal
}
- case "mode":
+ case nettypes.ModeOption:
if network.Driver == nettypes.MacVLANNetworkDriver || network.Driver == nettypes.IPVLANNetworkDriver {
network.Options[opt] = optVal
}
@@ -305,7 +311,7 @@ func RemoveNetwork(w http.ResponseWriter, r *http.Request) {
Timeout: query.Timeout,
}
- name := utils.GetName(r)
+ name, _ := normalizeNetworkName(runtime, utils.GetName(r))
reports, err := ic.NetworkRm(r.Context(), []string{name}, options)
if err != nil {
utils.Error(w, http.StatusInternalServerError, err)
@@ -340,7 +346,7 @@ func Connect(w http.ResponseWriter, r *http.Request) {
netOpts := nettypes.PerNetworkOptions{}
- name := utils.GetName(r)
+ name, _ := normalizeNetworkName(runtime, utils.GetName(r))
if netConnect.EndpointConfig != nil {
if netConnect.EndpointConfig.Aliases != nil {
netOpts.Aliases = netConnect.EndpointConfig.Aliases
@@ -416,7 +422,7 @@ func Disconnect(w http.ResponseWriter, r *http.Request) {
return
}
- name := utils.GetName(r)
+ name, _ := normalizeNetworkName(runtime, utils.GetName(r))
err := runtime.DisconnectContainerFromNetwork(netDisconnect.Container, name, netDisconnect.Force)
if err != nil {
if errors.Is(err, define.ErrNoSuchCtr) {
diff --git a/pkg/api/handlers/libpod/containers_create.go b/pkg/api/handlers/libpod/containers_create.go
index e4964d602..1307c267a 100644
--- a/pkg/api/handlers/libpod/containers_create.go
+++ b/pkg/api/handlers/libpod/containers_create.go
@@ -31,6 +31,9 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
ContainerNetworkConfig: specgen.ContainerNetworkConfig{
UseImageHosts: conf.Containers.NoHosts,
},
+ ContainerSecurityConfig: specgen.ContainerSecurityConfig{
+ Umask: conf.Containers.Umask,
+ },
}
if err := json.NewDecoder(r.Body).Decode(&sg); err != nil {
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go
index ed1c65f8e..67943ecf1 100644
--- a/pkg/api/handlers/libpod/images.go
+++ b/pkg/api/handlers/libpod/images.go
@@ -1,7 +1,6 @@
package libpod
import (
- "context"
"errors"
"fmt"
"io"
@@ -14,13 +13,11 @@ import (
"github.com/containers/buildah"
"github.com/containers/common/libimage"
"github.com/containers/image/v5/manifest"
- "github.com/containers/image/v5/types"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/api/handlers"
"github.com/containers/podman/v4/pkg/api/handlers/utils"
api "github.com/containers/podman/v4/pkg/api/types"
- "github.com/containers/podman/v4/pkg/auth"
"github.com/containers/podman/v4/pkg/domain/entities"
"github.com/containers/podman/v4/pkg/domain/entities/reports"
"github.com/containers/podman/v4/pkg/domain/infra/abi"
@@ -416,74 +413,6 @@ func ImagesImport(w http.ResponseWriter, r *http.Request) {
utils.WriteResponse(w, http.StatusOK, report)
}
-// PushImage is the handler for the compat http endpoint for pushing images.
-func PushImage(w http.ResponseWriter, r *http.Request) {
- decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
- runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
-
- query := struct {
- All bool `schema:"all"`
- Destination string `schema:"destination"`
- Format string `schema:"format"`
- RemoveSignatures bool `schema:"removeSignatures"`
- TLSVerify bool `schema:"tlsVerify"`
- }{
- // This is where you can override the golang default value for one of fields
- }
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
- return
- }
-
- source := strings.TrimSuffix(utils.GetName(r), "/push") // GetName returns the entire path
- if _, err := utils.ParseStorageReference(source); err != nil {
- utils.Error(w, http.StatusBadRequest, err)
- return
- }
-
- destination := query.Destination
- if destination == "" {
- destination = source
- }
-
- if err := utils.IsRegistryReference(destination); err != nil {
- utils.Error(w, http.StatusBadRequest, err)
- return
- }
-
- authconf, authfile, err := auth.GetCredentials(r)
- if err != nil {
- utils.Error(w, http.StatusBadRequest, err)
- return
- }
- defer auth.RemoveAuthfile(authfile)
- var username, password string
- if authconf != nil {
- username = authconf.Username
- password = authconf.Password
- }
- options := entities.ImagePushOptions{
- All: query.All,
- Authfile: authfile,
- Format: query.Format,
- Password: password,
- Quiet: true,
- RemoveSignatures: query.RemoveSignatures,
- Username: username,
- }
- if _, found := r.URL.Query()["tlsVerify"]; found {
- options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
- }
-
- imageEngine := abi.ImageEngine{Libpod: runtime}
- if err := imageEngine.Push(context.Background(), source, destination, options); err != nil {
- utils.Error(w, http.StatusBadRequest, fmt.Errorf("error pushing image %q: %w", destination, err))
- return
- }
-
- utils.WriteResponse(w, http.StatusOK, "")
-}
-
func CommitContainer(w http.ResponseWriter, r *http.Request) {
var (
destImage string
diff --git a/pkg/api/handlers/libpod/images_push.go b/pkg/api/handlers/libpod/images_push.go
new file mode 100644
index 000000000..9ee651f5b
--- /dev/null
+++ b/pkg/api/handlers/libpod/images_push.go
@@ -0,0 +1,145 @@
+package libpod
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "net/http"
+ "strings"
+
+ "github.com/containers/image/v5/types"
+ "github.com/containers/podman/v4/libpod"
+ "github.com/containers/podman/v4/pkg/api/handlers/utils"
+ api "github.com/containers/podman/v4/pkg/api/types"
+ "github.com/containers/podman/v4/pkg/auth"
+ "github.com/containers/podman/v4/pkg/channel"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+ "github.com/containers/podman/v4/pkg/domain/infra/abi"
+ "github.com/gorilla/schema"
+ "github.com/sirupsen/logrus"
+)
+
+// PushImage is the handler for the compat http endpoint for pushing images.
+func PushImage(w http.ResponseWriter, r *http.Request) {
+ decoder := r.Context().Value(api.DecoderKey).(*schema.Decoder)
+ runtime := r.Context().Value(api.RuntimeKey).(*libpod.Runtime)
+
+ query := struct {
+ All bool `schema:"all"`
+ Destination string `schema:"destination"`
+ Format string `schema:"format"`
+ RemoveSignatures bool `schema:"removeSignatures"`
+ TLSVerify bool `schema:"tlsVerify"`
+ Quiet bool `schema:"quiet"`
+ }{
+ TLSVerify: true,
+ // #14971: older versions did not sent *any* data, so we need
+ // to be quiet by default to remain backwards compatible
+ Quiet: true,
+ }
+ if err := decoder.Decode(&query, r.URL.Query()); err != nil {
+ utils.Error(w, http.StatusBadRequest, fmt.Errorf("failed to parse parameters for %s: %w", r.URL.String(), err))
+ return
+ }
+
+ source := strings.TrimSuffix(utils.GetName(r), "/push") // GetName returns the entire path
+ if _, err := utils.ParseStorageReference(source); err != nil {
+ utils.Error(w, http.StatusBadRequest, err)
+ return
+ }
+
+ destination := query.Destination
+ if destination == "" {
+ destination = source
+ }
+
+ if err := utils.IsRegistryReference(destination); err != nil {
+ utils.Error(w, http.StatusBadRequest, err)
+ return
+ }
+
+ authconf, authfile, err := auth.GetCredentials(r)
+ if err != nil {
+ utils.Error(w, http.StatusBadRequest, err)
+ return
+ }
+ defer auth.RemoveAuthfile(authfile)
+
+ var username, password string
+ if authconf != nil {
+ username = authconf.Username
+ password = authconf.Password
+ }
+ options := entities.ImagePushOptions{
+ All: query.All,
+ Authfile: authfile,
+ Format: query.Format,
+ Password: password,
+ Quiet: true,
+ RemoveSignatures: query.RemoveSignatures,
+ Username: username,
+ }
+
+ if _, found := r.URL.Query()["tlsVerify"]; found {
+ options.SkipTLSVerify = types.NewOptionalBool(!query.TLSVerify)
+ }
+
+ imageEngine := abi.ImageEngine{Libpod: runtime}
+
+ // Let's keep thing simple when running in quiet mode and push directly.
+ if query.Quiet {
+ if err := imageEngine.Push(context.Background(), source, destination, options); err != nil {
+ utils.Error(w, http.StatusBadRequest, fmt.Errorf("error pushing image %q: %w", destination, err))
+ return
+ }
+ utils.WriteResponse(w, http.StatusOK, "")
+ return
+ }
+
+ writer := channel.NewWriter(make(chan []byte))
+ defer writer.Close()
+ options.Writer = writer
+
+ pushCtx, pushCancel := context.WithCancel(r.Context())
+ var pushError error
+ go func() {
+ defer pushCancel()
+ pushError = imageEngine.Push(pushCtx, source, destination, options)
+ }()
+
+ flush := func() {
+ if flusher, ok := w.(http.Flusher); ok {
+ flusher.Flush()
+ }
+ }
+
+ w.WriteHeader(http.StatusOK)
+ w.Header().Set("Content-Type", "application/json")
+ flush()
+
+ enc := json.NewEncoder(w)
+ enc.SetEscapeHTML(true)
+ for {
+ var report entities.ImagePushReport
+ select {
+ case s := <-writer.Chan():
+ report.Stream = string(s)
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to encode json: %v", err)
+ }
+ flush()
+ case <-pushCtx.Done():
+ if pushError != nil {
+ report.Error = pushError.Error()
+ if err := enc.Encode(report); err != nil {
+ logrus.Warnf("Failed to encode json: %v", err)
+ }
+ }
+ flush()
+ return
+ case <-r.Context().Done():
+ // Client has closed connection
+ return
+ }
+ }
+}
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go
index 3235a2972..43c7139d3 100644
--- a/pkg/api/handlers/libpod/manifests.go
+++ b/pkg/api/handlers/libpod/manifests.go
@@ -310,6 +310,7 @@ func ManifestPush(w http.ResponseWriter, r *http.Request) {
TLSVerify bool `schema:"tlsVerify"`
}{
// Add defaults here once needed.
+ TLSVerify: true,
}
if err := decoder.Decode(&query, r.URL.Query()); err != nil {
utils.Error(w, http.StatusBadRequest,
diff --git a/pkg/api/server/register_images.go b/pkg/api/server/register_images.go
index a2f46cb35..1bfedd77e 100644
--- a/pkg/api/server/register_images.go
+++ b/pkg/api/server/register_images.go
@@ -192,8 +192,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - in: query
// name: tlsVerify
// type: boolean
- // default: false
- // description: skip TLS verification for registries
+ // default: true
+ // description: Require HTTPS and verify signatures when contacting registries.
// - in: query
// name: listTags
// type: boolean
@@ -730,6 +730,11 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// description: Require TLS verification.
// type: boolean
// default: true
+ // - in: query
+ // name: quiet
+ // description: "silences extra stream data on push"
+ // type: boolean
+ // default: true
// - in: header
// name: X-Registry-Auth
// type: string
@@ -1115,8 +1120,8 @@ func (s *APIServer) registerImagesHandlers(r *mux.Router) error {
// - in: query
// name: tlsVerify
// type: boolean
- // default: false
- // description: skip TLS verification for registries
+ // default: true
+ // description: Require HTTPS and verify signatures when contacting registries.
// - in: query
// name: listTags
// type: boolean
diff --git a/pkg/api/server/register_manifest.go b/pkg/api/server/register_manifest.go
index 4fadb92fd..19b507047 100644
--- a/pkg/api/server/register_manifest.go
+++ b/pkg/api/server/register_manifest.go
@@ -69,12 +69,12 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// name: all
// description: push all images
// type: boolean
- // default: false
+ // default: true
// - in: query
// name: tlsVerify
// type: boolean
- // default: false
- // description: skip TLS verification for registries
+ // default: true
+ // description: Require HTTPS and verify signatures when contacting registries.
// responses:
// 200:
// schema:
@@ -195,8 +195,8 @@ func (s *APIServer) registerManifestHandlers(r *mux.Router) error {
// - in: query
// name: tlsVerify
// type: boolean
- // default: false
- // description: skip TLS verification for registries
+ // default: true
+ // description: Require HTTPS and verify signatures when contacting registries.
// - in: body
// name: options
// description: options for mutating a manifest
diff --git a/pkg/bindings/images/images.go b/pkg/bindings/images/images.go
index cd5147629..bb7867c4e 100644
--- a/pkg/bindings/images/images.go
+++ b/pkg/bindings/images/images.go
@@ -267,46 +267,6 @@ func Import(ctx context.Context, r io.Reader, options *ImportOptions) (*entities
return &report, response.Process(&report)
}
-// Push is the binding for libpod's v2 endpoints for push images. Note that
-// `source` must be a referring to an image in the remote's container storage.
-// The destination must be a reference to a registry (i.e., of docker transport
-// or be normalized to one). Other transports are rejected as they do not make
-// sense in a remote context.
-func Push(ctx context.Context, source string, destination string, options *PushOptions) error {
- if options == nil {
- options = new(PushOptions)
- }
- conn, err := bindings.GetClient(ctx)
- if err != nil {
- return err
- }
- header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword())
- if err != nil {
- return err
- }
-
- params, err := options.ToParams()
- if err != nil {
- return err
- }
- // SkipTLSVerify is special. We need to delete the param added by
- // toparams and change the key and flip the bool
- if options.SkipTLSVerify != nil {
- params.Del("SkipTLSVerify")
- params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
- }
- params.Set("destination", destination)
-
- path := fmt.Sprintf("/images/%s/push", source)
- response, err := conn.DoRequest(ctx, nil, http.MethodPost, path, params, header)
- if err != nil {
- return err
- }
- defer response.Body.Close()
-
- return response.Process(err)
-}
-
// Search is the binding for libpod's v2 endpoints for Search images.
func Search(ctx context.Context, term string, options *SearchOptions) ([]entities.ImageSearchReport, error) {
if options == nil {
diff --git a/pkg/bindings/images/push.go b/pkg/bindings/images/push.go
new file mode 100644
index 000000000..8db3726e6
--- /dev/null
+++ b/pkg/bindings/images/push.go
@@ -0,0 +1,96 @@
+package images
+
+import (
+ "context"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "os"
+ "strconv"
+
+ imageTypes "github.com/containers/image/v5/types"
+ "github.com/containers/podman/v4/pkg/auth"
+ "github.com/containers/podman/v4/pkg/bindings"
+ "github.com/containers/podman/v4/pkg/domain/entities"
+)
+
+// Push is the binding for libpod's endpoints for push images. Note that
+// `source` must be a referring to an image in the remote's container storage.
+// The destination must be a reference to a registry (i.e., of docker transport
+// or be normalized to one). Other transports are rejected as they do not make
+// sense in a remote context.
+func Push(ctx context.Context, source string, destination string, options *PushOptions) error {
+ if options == nil {
+ options = new(PushOptions)
+ }
+ conn, err := bindings.GetClient(ctx)
+ if err != nil {
+ return err
+ }
+ header, err := auth.MakeXRegistryAuthHeader(&imageTypes.SystemContext{AuthFilePath: options.GetAuthfile()}, options.GetUsername(), options.GetPassword())
+ if err != nil {
+ return err
+ }
+
+ params, err := options.ToParams()
+ if err != nil {
+ return err
+ }
+ // SkipTLSVerify is special. We need to delete the param added by
+ // toparams and change the key and flip the bool
+ if options.SkipTLSVerify != nil {
+ params.Del("SkipTLSVerify")
+ params.Set("tlsVerify", strconv.FormatBool(!options.GetSkipTLSVerify()))
+ }
+ params.Set("destination", destination)
+
+ path := fmt.Sprintf("/images/%s/push", source)
+ response, err := conn.DoRequest(ctx, nil, http.MethodPost, path, params, header)
+ if err != nil {
+ return err
+ }
+ defer response.Body.Close()
+
+ if !response.IsSuccess() {
+ return response.Process(err)
+ }
+
+ // Historically push writes status to stderr
+ writer := io.Writer(os.Stderr)
+ if options.GetQuiet() {
+ writer = ioutil.Discard
+ }
+
+ dec := json.NewDecoder(response.Body)
+ for {
+ var report entities.ImagePushReport
+ if err := dec.Decode(&report); err != nil {
+ if errors.Is(err, io.EOF) {
+ break
+ }
+ return err
+ }
+
+ select {
+ case <-response.Request.Context().Done():
+ break
+ default:
+ // non-blocking select
+ }
+
+ switch {
+ case report.Stream != "":
+ fmt.Fprint(writer, report.Stream)
+ case report.Error != "":
+ // There can only be one error.
+ return errors.New(report.Error)
+ default:
+ return fmt.Errorf("failed to parse push results stream, unexpected input: %v", report)
+ }
+ }
+
+ return nil
+}
diff --git a/pkg/bindings/images/types.go b/pkg/bindings/images/types.go
index 3728ae5c0..0e672cdea 100644
--- a/pkg/bindings/images/types.go
+++ b/pkg/bindings/images/types.go
@@ -133,6 +133,8 @@ type PushOptions struct {
RemoveSignatures *bool
// Username for authenticating against the registry.
Username *string
+ // Quiet can be specified to suppress progress when pushing.
+ Quiet *bool
}
//go:generate go run ../generator/generator.go SearchOptions
diff --git a/pkg/bindings/images/types_push_options.go b/pkg/bindings/images/types_push_options.go
index 25f6c5546..63a19fb81 100644
--- a/pkg/bindings/images/types_push_options.go
+++ b/pkg/bindings/images/types_push_options.go
@@ -136,3 +136,18 @@ func (o *PushOptions) GetUsername() string {
}
return *o.Username
}
+
+// WithQuiet set field Quiet to given value
+func (o *PushOptions) WithQuiet(value bool) *PushOptions {
+ o.Quiet = &value
+ return o
+}
+
+// GetQuiet returns value of field Quiet
+func (o *PushOptions) GetQuiet() bool {
+ if o.Quiet == nil {
+ var z bool
+ return z
+ }
+ return *o.Quiet
+}
diff --git a/pkg/bindings/test/images_test.go b/pkg/bindings/test/images_test.go
index a005be6ac..8f76ce456 100644
--- a/pkg/bindings/test/images_test.go
+++ b/pkg/bindings/test/images_test.go
@@ -120,8 +120,6 @@ var _ = Describe("Podman images", func() {
// deleting hence image cannot be deleted until the container is deleted.
_, errs = images.Remove(bt.conn, []string{alpine.shortName}, nil)
code, _ = bindings.CheckResponseCode(errs[0])
- // FIXME FIXME FIXME: #12441: another invalid error
- // FIXME FIXME FIXME: this time msg="Image used by SHA: ..."
Expect(code).To(BeNumerically("==", -1))
// Removing the image "alpine" where force = true
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 934a7cbdc..df793034b 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -71,12 +71,15 @@ type StringSliceReport struct {
}
type PauseUnPauseOptions struct {
- All bool
+ Filters map[string][]string
+ All bool
+ Latest bool
}
type PauseUnpauseReport struct {
- Err error
- Id string //nolint:revive,stylecheck
+ Err error
+ Id string //nolint:revive,stylecheck
+ RawInput string
}
type StopOptions struct {
diff --git a/pkg/domain/entities/images.go b/pkg/domain/entities/images.go
index da317cfad..b8b346005 100644
--- a/pkg/domain/entities/images.go
+++ b/pkg/domain/entities/images.go
@@ -1,6 +1,7 @@
package entities
import (
+ "io"
"net/url"
"time"
@@ -192,8 +193,7 @@ type ImagePushOptions struct {
// image. Default is manifest type of source, with fallbacks.
// Ignored for remote calls.
Format string
- // Quiet can be specified to suppress pull progress when pulling. Ignored
- // for remote calls.
+ // Quiet can be specified to suppress push progress when pushing.
Quiet bool
// Rm indicates whether to remove the manifest list if push succeeds
Rm bool
@@ -211,6 +211,17 @@ type ImagePushOptions struct {
Progress chan types.ProgressProperties
// CompressionFormat is the format to use for the compression of the blobs
CompressionFormat string
+ // Writer is used to display copy information including progress bars.
+ Writer io.Writer
+}
+
+// ImagePushReport is the response from pushing an image.
+// Currently only used in the remote API.
+type ImagePushReport struct {
+ // Stream used to provide push progress
+ Stream string `json:"stream,omitempty"`
+ // Error contains text of errors from pushing
+ Error string `json:"error,omitempty"`
}
// ImageSearchOptions are the arguments for searching images.
diff --git a/pkg/domain/entities/machine.go b/pkg/domain/entities/machine.go
index 6ba53dbd1..4fd0413c9 100644
--- a/pkg/domain/entities/machine.go
+++ b/pkg/domain/entities/machine.go
@@ -1,5 +1,7 @@
package entities
+import "github.com/containers/podman/v4/libpod/define"
+
type ListReporter struct {
Name string
Default bool
@@ -16,3 +18,23 @@ type ListReporter struct {
RemoteUsername string
IdentityPath string
}
+
+// MachineInfo contains info on the machine host and version info
+type MachineInfo struct {
+ Host *MachineHostInfo `json:"Host"`
+ Version define.Version `json:"Version"`
+}
+
+// MachineHostInfo contains info on the machine host
+type MachineHostInfo struct {
+ Arch string `json:"Arch"`
+ CurrentMachine string `json:"CurrentMachine"`
+ DefaultMachine string `json:"DefaultMachine"`
+ EventsDir string `json:"EventsDir"`
+ MachineConfigDir string `json:"MachineConfigDir"`
+ MachineImageDir string `json:"MachineImageDir"`
+ MachineState string `json:"MachineState"`
+ NumberOfMachines int `json:"NumberOfMachines"`
+ OS string `json:"OS"`
+ VMType string `json:"VMType"`
+}
diff --git a/pkg/domain/entities/play.go b/pkg/domain/entities/play.go
index 35a5d8a4a..5bb438d7d 100644
--- a/pkg/domain/entities/play.go
+++ b/pkg/domain/entities/play.go
@@ -88,6 +88,7 @@ type PlayKubeReport struct {
// Volumes - volumes created by play kube.
Volumes []PlayKubeVolume
PlayKubeTeardown
+ Secrets []PlaySecret
}
type KubePlayReport = PlayKubeReport
@@ -100,3 +101,7 @@ type PlayKubeTeardown struct {
StopReport []*PodStopReport
RmReport []*PodRmReport
}
+
+type PlaySecret struct {
+ CreateReport *SecretCreateReport
+}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 04eb85504..dd7053a23 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -62,6 +62,11 @@ func getContainersAndInputByContext(all, latest bool, names []string, filters ma
}
case all:
ctrs, err = runtime.GetAllContainers()
+ if err == nil {
+ for _, ctr := range ctrs {
+ rawInput = append(rawInput, ctr.ID())
+ }
+ }
case latest:
ctr, err = runtime.GetLatestContainer()
if err == nil {
@@ -133,37 +138,57 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod)
+ ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, options.Filters, ic.Libpod)
if err != nil {
return nil, err
}
- report := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
+ ctrMap := map[string]string{}
+ if len(rawInputs) == len(ctrs) {
+ for i := range ctrs {
+ ctrMap[ctrs[i].ID()] = rawInputs[i]
+ }
+ }
+ reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs {
err := c.Pause()
if err != nil && options.All && errors.Is(err, define.ErrCtrStateInvalid) {
logrus.Debugf("Container %s is not running", c.ID())
continue
}
- report = append(report, &entities.PauseUnpauseReport{Id: c.ID(), Err: err})
+ reports = append(reports, &entities.PauseUnpauseReport{
+ Id: c.ID(),
+ Err: err,
+ RawInput: ctrMap[c.ID()],
+ })
}
- return report, nil
+ return reports, nil
}
func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- ctrs, err := getContainersByContext(options.All, false, namesOrIds, ic.Libpod)
+ ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, namesOrIds, options.Filters, ic.Libpod)
if err != nil {
return nil, err
}
- report := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
+ ctrMap := map[string]string{}
+ if len(rawInputs) == len(ctrs) {
+ for i := range ctrs {
+ ctrMap[ctrs[i].ID()] = rawInputs[i]
+ }
+ }
+ reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs {
err := c.Unpause()
if err != nil && options.All && errors.Is(err, define.ErrCtrStateInvalid) {
logrus.Debugf("Container %s is not paused", c.ID())
continue
}
- report = append(report, &entities.PauseUnpauseReport{Id: c.ID(), Err: err})
+ reports = append(reports, &entities.PauseUnpauseReport{
+ Id: c.ID(),
+ Err: err,
+ RawInput: ctrMap[c.ID()],
+ })
}
- return report, nil
+ return reports, nil
}
func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []string, options entities.StopOptions) ([]*entities.StopReport, error) {
names := namesOrIds
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 38008c7b9..ff42b0367 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -305,6 +305,7 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
pushOptions.RemoveSignatures = options.RemoveSignatures
pushOptions.SignBy = options.SignBy
pushOptions.InsecureSkipTLSVerify = options.SkipTLSVerify
+ pushOptions.Writer = options.Writer
compressionFormat := options.CompressionFormat
if compressionFormat == "" {
@@ -322,7 +323,7 @@ func (ir *ImageEngine) Push(ctx context.Context, source string, destination stri
pushOptions.CompressionFormat = &algo
}
- if !options.Quiet {
+ if !options.Quiet && pushOptions.Writer == nil {
pushOptions.Writer = os.Stderr
}
diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go
index 8b47eff53..3f2fd5f92 100644
--- a/pkg/domain/infra/abi/play.go
+++ b/pkg/domain/infra/abi/play.go
@@ -84,15 +84,15 @@ func (ic *ContainerEngine) createServiceContainer(ctx context.Context, name stri
return ctr, nil
}
-// Creates the name for a service container based on the provided content of a
-// K8s yaml file.
-func serviceContainerName(content []byte) string {
+// Creates the name for a k8s entity based on the provided content of a
+// K8s yaml file and a given suffix.
+func k8sName(content []byte, suffix string) string {
// The name of the service container is the first 12
// characters of the yaml file's hash followed by the
// '-service' suffix to guarantee a predictable and
// discoverable name.
hash := digest.FromBytes(content).Encoded()
- return hash[0:12] + "-service"
+ return hash[0:12] + "-" + suffix
}
func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options entities.PlayKubeOptions) (_ *entities.PlayKubeReport, finalErr error) {
@@ -132,7 +132,7 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
// TODO: create constants for the various "kinds" of yaml files.
var serviceContainer *libpod.Container
if options.ServiceContainer && (kind == "Pod" || kind == "Deployment") {
- ctr, err := ic.createServiceContainer(ctx, serviceContainerName(content), options)
+ ctr, err := ic.createServiceContainer(ctx, k8sName(content, "service"), options)
if err != nil {
return nil, err
}
@@ -213,6 +213,19 @@ func (ic *ContainerEngine) PlayKube(ctx context.Context, body io.Reader, options
return nil, fmt.Errorf("unable to read YAML as Kube ConfigMap: %w", err)
}
configMaps = append(configMaps, configMap)
+ case "Secret":
+ var secret v1.Secret
+
+ if err := yaml.Unmarshal(document, &secret); err != nil {
+ return nil, fmt.Errorf("unable to read YAML as kube secret: %w", err)
+ }
+
+ r, err := ic.playKubeSecret(&secret)
+ if err != nil {
+ return nil, err
+ }
+ report.Secrets = append(report.Secrets, entities.PlaySecret{CreateReport: r})
+ validKinds++
default:
logrus.Infof("Kube kind %s not supported", kind)
continue
@@ -380,7 +393,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
configMaps = append(configMaps, cm)
}
- volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes, configMaps)
+ volumes, err := kube.InitializeVolumes(podYAML.Spec.Volumes, configMaps, secretsManager)
if err != nil {
return nil, err
}
@@ -388,7 +401,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
// Go through the volumes and create a podman volume for all volumes that have been
// defined by a configmap
for _, v := range volumes {
- if v.Type == kube.KubeVolumeTypeConfigMap && !v.Optional {
+ if (v.Type == kube.KubeVolumeTypeConfigMap || v.Type == kube.KubeVolumeTypeSecret) && !v.Optional {
vol, err := ic.Libpod.NewVolume(ctx, libpod.WithVolumeName(v.Source))
if err != nil {
if errors.Is(err, define.ErrVolumeExists) {
@@ -583,6 +596,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY
UserNSIsHost: p.Userns.IsHost(),
Volumes: volumes,
}
+
specGen, err := kube.ToSpecGen(ctx, &specgenOpts)
if err != nil {
return nil, err
@@ -968,3 +982,55 @@ func (ic *ContainerEngine) PlayKubeDown(ctx context.Context, body io.Reader, _ e
return reports, nil
}
+
+// playKubeSecret allows users to create and store a kubernetes secret as a podman secret
+func (ic *ContainerEngine) playKubeSecret(secret *v1.Secret) (*entities.SecretCreateReport, error) {
+ r := &entities.SecretCreateReport{}
+
+ // Create the secret manager before hand
+ secretsManager, err := ic.Libpod.SecretsManager()
+ if err != nil {
+ return nil, err
+ }
+
+ data, err := yaml.Marshal(secret)
+ if err != nil {
+ return nil, err
+ }
+
+ secretsPath := ic.Libpod.GetSecretsStorageDir()
+ opts := make(map[string]string)
+ opts["path"] = filepath.Join(secretsPath, "filedriver")
+ // maybe k8sName(data)...
+ // using this does not allow the user to use the name given to the secret
+ // but keeping secret.Name as the ID can lead to a collision.
+
+ s, err := secretsManager.Lookup(secret.Name)
+ if err == nil {
+ if val, ok := s.Metadata["immutable"]; ok {
+ if val == "true" {
+ return nil, fmt.Errorf("cannot remove colliding secret as it is set to immutable")
+ }
+ }
+ _, err = secretsManager.Delete(s.Name)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ // now we have either removed the old secret w/ the same name or
+ // the name was not taken. Either way, we can now store.
+
+ meta := make(map[string]string)
+ if secret.Immutable != nil && *secret.Immutable {
+ meta["immutable"] = "true"
+ }
+ secretID, err := secretsManager.Store(secret.Name, data, "file", opts, meta)
+ if err != nil {
+ return nil, err
+ }
+
+ r.ID = secretID
+
+ return r, nil
+}
diff --git a/pkg/domain/infra/abi/secrets.go b/pkg/domain/infra/abi/secrets.go
index 7321ef715..e82fa4fdd 100644
--- a/pkg/domain/infra/abi/secrets.go
+++ b/pkg/domain/infra/abi/secrets.go
@@ -42,7 +42,7 @@ func (ic *ContainerEngine) SecretCreate(ctx context.Context, name string, reader
}
}
- secretID, err := manager.Store(name, data, options.Driver, options.DriverOpts)
+ secretID, err := manager.Store(name, data, options.Driver, options.DriverOpts, nil)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index fcabff7c4..272c23268 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -57,10 +57,14 @@ func (ic *ContainerEngine) ContainerWait(ctx context.Context, namesOrIds []strin
}
func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- ctrs, err := getContainersByContext(ic.ClientCtx, options.All, false, namesOrIds)
+ ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, options.All, false, namesOrIds, options.Filters)
if err != nil {
return nil, err
}
+ ctrMap := map[string]string{}
+ for i := range ctrs {
+ ctrMap[ctrs[i].ID] = rawInputs[i]
+ }
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs {
err := containers.Pause(ic.ClientCtx, c.ID, nil)
@@ -68,24 +72,36 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
logrus.Debugf("Container %s is not running", c.ID)
continue
}
- reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err})
+ reports = append(reports, &entities.PauseUnpauseReport{
+ Id: c.ID,
+ Err: err,
+ RawInput: ctrMap[c.ID],
+ })
}
return reports, nil
}
func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []string, options entities.PauseUnPauseOptions) ([]*entities.PauseUnpauseReport, error) {
- reports := []*entities.PauseUnpauseReport{}
- ctrs, err := getContainersByContext(ic.ClientCtx, options.All, false, namesOrIds)
+ ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, options.All, false, namesOrIds, options.Filters)
if err != nil {
return nil, err
}
+ ctrMap := map[string]string{}
+ for i := range ctrs {
+ ctrMap[ctrs[i].ID] = rawInputs[i]
+ }
+ reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs {
err := containers.Unpause(ic.ClientCtx, c.ID, nil)
if err != nil && options.All && strings.Contains(err.Error(), define.ErrCtrStateInvalid.Error()) {
logrus.Debugf("Container %s is not paused", c.ID)
continue
}
- reports = append(reports, &entities.PauseUnpauseReport{Id: c.ID, Err: err})
+ reports = append(reports, &entities.PauseUnpauseReport{
+ Id: c.ID,
+ Err: err,
+ RawInput: ctrMap[c.ID],
+ })
}
return reports, nil
}
diff --git a/pkg/domain/infra/tunnel/images.go b/pkg/domain/infra/tunnel/images.go
index 18f750dcc..9ad408850 100644
--- a/pkg/domain/infra/tunnel/images.go
+++ b/pkg/domain/infra/tunnel/images.go
@@ -240,7 +240,7 @@ func (ir *ImageEngine) Import(ctx context.Context, opts entities.ImageImportOpti
func (ir *ImageEngine) Push(ctx context.Context, source string, destination string, opts entities.ImagePushOptions) error {
options := new(images.PushOptions)
- options.WithAll(opts.All).WithCompress(opts.Compress).WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithFormat(opts.Format).WithRemoveSignatures(opts.RemoveSignatures)
+ options.WithAll(opts.All).WithCompress(opts.Compress).WithUsername(opts.Username).WithPassword(opts.Password).WithAuthfile(opts.Authfile).WithFormat(opts.Format).WithRemoveSignatures(opts.RemoveSignatures).WithQuiet(opts.Quiet)
if s := opts.SkipTLSVerify; s != types.OptionalBoolUndefined {
if s == types.OptionalBoolTrue {
diff --git a/pkg/k8s.io/api/core/v1/types.go b/pkg/k8s.io/api/core/v1/types.go
index 48f353cc6..39a675dae 100644
--- a/pkg/k8s.io/api/core/v1/types.go
+++ b/pkg/k8s.io/api/core/v1/types.go
@@ -56,6 +56,7 @@ type VolumeSource struct {
// ConfigMap represents a configMap that should populate this volume
// +optional
ConfigMap *ConfigMapVolumeSource `json:"configMap,omitempty"`
+ Secret *SecretVolumeSource
}
// PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace.
diff --git a/pkg/machine/e2e/basic_test.go b/pkg/machine/e2e/basic_test.go
index f67fb4c67..da0310485 100644
--- a/pkg/machine/e2e/basic_test.go
+++ b/pkg/machine/e2e/basic_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
. "github.com/onsi/ginkgo"
@@ -20,7 +20,7 @@ var _ = Describe("run basic podman commands", func() {
})
It("Basic ops", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withNow()).run()
Expect(err).To(BeNil())
diff --git a/pkg/machine/e2e/config_basic.go b/pkg/machine/e2e/config_basic_test.go
index be0896156..d1cb24174 100644
--- a/pkg/machine/e2e/config_basic.go
+++ b/pkg/machine/e2e/config_basic_test.go
@@ -1,8 +1,7 @@
-package e2e
+package e2e_test
type basicMachine struct {
args []string
- cmd []string
}
func (s basicMachine) buildCmd(m *machineTestBuilder) []string {
diff --git a/pkg/machine/e2e/config_info.go b/pkg/machine/e2e/config_info_test.go
index 410c7e518..4da40ab99 100644
--- a/pkg/machine/e2e/config_info.go
+++ b/pkg/machine/e2e/config_info_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
type infoMachine struct {
format string
diff --git a/pkg/machine/e2e/config_init.go b/pkg/machine/e2e/config_init_test.go
index 7f18cce7d..d6c7990b0 100644
--- a/pkg/machine/e2e/config_init.go
+++ b/pkg/machine/e2e/config_init_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"strconv"
@@ -25,7 +25,7 @@ type initMachine struct {
memory *uint
now bool
timezone string
- rootful bool
+ rootful bool //nolint:unused,structcheck
volumes []string
cmd []string
@@ -71,7 +71,7 @@ func (i *initMachine) withDiskSize(size uint) *initMachine {
return i
}
-func (i *initMachine) withIgnitionPath(path string) *initMachine {
+func (i *initMachine) withIgnitionPath(path string) *initMachine { //nolint:unused
i.ignitionPath = path
return i
}
diff --git a/pkg/machine/e2e/config_inspect.go b/pkg/machine/e2e/config_inspect_test.go
index 74c9a5d9c..ffd74220f 100644
--- a/pkg/machine/e2e/config_inspect.go
+++ b/pkg/machine/e2e/config_inspect_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
type inspectMachine struct {
/*
diff --git a/pkg/machine/e2e/config_list.go b/pkg/machine/e2e/config_list_test.go
index 150f984bc..78f9edc62 100644
--- a/pkg/machine/e2e/config_list.go
+++ b/pkg/machine/e2e/config_list_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
type listMachine struct {
/*
diff --git a/pkg/machine/e2e/config_rm.go b/pkg/machine/e2e/config_rm_test.go
index 6cf262a22..1f9c9b4ec 100644
--- a/pkg/machine/e2e/config_rm.go
+++ b/pkg/machine/e2e/config_rm_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
type rmMachine struct {
/*
@@ -40,17 +40,17 @@ func (i *rmMachine) withForce() *rmMachine {
return i
}
-func (i *rmMachine) withSaveIgnition() *rmMachine {
+func (i *rmMachine) withSaveIgnition() *rmMachine { //nolint:unused
i.saveIgnition = true
return i
}
-func (i *rmMachine) withSaveImage() *rmMachine {
+func (i *rmMachine) withSaveImage() *rmMachine { //nolint:unused
i.saveImage = true
return i
}
-func (i *rmMachine) withSaveKeys() *rmMachine {
+func (i *rmMachine) withSaveKeys() *rmMachine { //nolint:unused
i.saveKeys = true
return i
}
diff --git a/pkg/machine/e2e/config_set.go b/pkg/machine/e2e/config_set_test.go
index b310ab1b9..3c773b970 100644
--- a/pkg/machine/e2e/config_set.go
+++ b/pkg/machine/e2e/config_set_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"strconv"
diff --git a/pkg/machine/e2e/config_ssh.go b/pkg/machine/e2e/config_ssh_test.go
index b09eed47d..f062625fa 100644
--- a/pkg/machine/e2e/config_ssh.go
+++ b/pkg/machine/e2e/config_ssh_test.go
@@ -1,14 +1,12 @@
-package e2e
+package e2e_test
type sshMachine struct {
/*
--username string Username to use when ssh-ing into the VM.
*/
- username string
+ username string //nolint:unused
sshCommand []string
-
- cmd []string
}
func (s sshMachine) buildCmd(m *machineTestBuilder) []string {
@@ -22,7 +20,7 @@ func (s sshMachine) buildCmd(m *machineTestBuilder) []string {
return cmd
}
-func (s *sshMachine) withUsername(name string) *sshMachine {
+func (s *sshMachine) withUsername(name string) *sshMachine { //nolint:unused
s.username = name
return s
}
diff --git a/pkg/machine/e2e/config_start.go b/pkg/machine/e2e/config_start_test.go
index 86b1721f8..d9efbf489 100644
--- a/pkg/machine/e2e/config_start.go
+++ b/pkg/machine/e2e/config_start_test.go
@@ -1,10 +1,9 @@
-package e2e
+package e2e_test
type startMachine struct {
/*
No command line args other than a machine vm name (also not required)
*/
- cmd []string
}
func (s startMachine) buildCmd(m *machineTestBuilder) []string {
diff --git a/pkg/machine/e2e/config_stop.go b/pkg/machine/e2e/config_stop_test.go
index 04dcfb524..41142ec7e 100644
--- a/pkg/machine/e2e/config_stop.go
+++ b/pkg/machine/e2e/config_stop_test.go
@@ -1,10 +1,9 @@
-package e2e
+package e2e_test
type stopMachine struct {
/*
No command line args other than a machine vm name (also not required)
*/
- cmd []string
}
func (s stopMachine) buildCmd(m *machineTestBuilder) []string {
diff --git a/pkg/machine/e2e/config.go b/pkg/machine/e2e/config_test.go
index b3fe74b0c..9940e711b 100644
--- a/pkg/machine/e2e/config.go
+++ b/pkg/machine/e2e/config_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"encoding/json"
@@ -10,13 +10,11 @@ import (
"time"
"github.com/containers/podman/v4/pkg/machine"
- "github.com/containers/podman/v4/pkg/machine/qemu"
"github.com/containers/podman/v4/pkg/util"
"github.com/containers/storage/pkg/stringid"
- . "github.com/onsi/ginkgo" //nolint:golint,stylecheck
+ . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
- "github.com/onsi/gomega/gexec"
- . "github.com/onsi/gomega/gexec" //nolint:golint,stylecheck
+ . "github.com/onsi/gomega/gexec"
)
var originalHomeDir = os.Getenv("HOME")
@@ -36,7 +34,7 @@ type MachineTestBuilder interface {
run() (*machineSession, error)
}
type machineSession struct {
- *gexec.Session
+ *Session
}
type machineTestBuilder struct {
@@ -47,10 +45,6 @@ type machineTestBuilder struct {
podmanBinary string
timeout time.Duration
}
-type qemuMachineInspectInfo struct {
- State machine.Status
- VM qemu.MachineVM
-}
// waitWithTimeout waits for a command to complete for a given
// number of seconds
@@ -121,7 +115,7 @@ func (m *machineTestBuilder) setCmd(mc machineCommand) *machineTestBuilder {
// If no name for the machine exists, we set a random name.
if !util.StringInSlice(m.name, m.names) {
if len(m.name) < 1 {
- m.name = randomString(12)
+ m.name = randomString()
}
m.names = append(m.names, m.name)
}
@@ -136,10 +130,10 @@ func (m *machineTestBuilder) setTimeout(timeout time.Duration) *machineTestBuild
// toQemuInspectInfo is only for inspecting qemu machines. Other providers will need
// to make their own.
-func (mb *machineTestBuilder) toQemuInspectInfo() ([]machine.InspectInfo, int, error) {
+func (m *machineTestBuilder) toQemuInspectInfo() ([]machine.InspectInfo, int, error) {
args := []string{"machine", "inspect"}
- args = append(args, mb.names...)
- session, err := runWrapper(mb.podmanBinary, args, defaultTimeout, true)
+ args = append(args, m.names...)
+ session, err := runWrapper(m.podmanBinary, args, defaultTimeout, true)
if err != nil {
return nil, -1, err
}
@@ -175,9 +169,7 @@ func runWrapper(podmanBinary string, cmdArgs []string, timeout time.Duration, wa
return &ms, nil
}
-func (m *machineTestBuilder) init() {}
-
// randomString returns a string of given length composed of random characters
-func randomString(n int) string {
+func randomString() string {
return stringid.GenerateRandomID()[0:12]
}
diff --git a/pkg/machine/e2e/info_test.go b/pkg/machine/e2e/info_test.go
index eeabb78af..fe0cfba32 100644
--- a/pkg/machine/e2e/info_test.go
+++ b/pkg/machine/e2e/info_test.go
@@ -1,7 +1,7 @@
-package e2e
+package e2e_test
import (
- "github.com/containers/podman/v4/cmd/podman/machine"
+ "github.com/containers/podman/v4/pkg/domain/entities"
jsoniter "github.com/json-iterator/go"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -51,7 +51,7 @@ var _ = Describe("podman machine info", func() {
Expect(err).NotTo(HaveOccurred())
Expect(infoSession).Should(Exit(0))
- infoReport := &machine.Info{}
+ infoReport := &entities.MachineInfo{}
err = jsoniter.Unmarshal(infoSession.Bytes(), infoReport)
Expect(err).To(BeNil())
})
diff --git a/pkg/machine/e2e/init_test.go b/pkg/machine/e2e/init_test.go
index 40f140cae..b246dc4da 100644
--- a/pkg/machine/e2e/init_test.go
+++ b/pkg/machine/e2e/init_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"io/ioutil"
@@ -78,7 +78,7 @@ var _ = Describe("podman machine init", func() {
})
It("machine init with cpus, disk size, memory, timezone", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withCPUs(2).withDiskSize(102).withMemory(4000).withTimezone("Pacific/Honolulu")).run()
Expect(err).To(BeNil())
@@ -108,7 +108,7 @@ var _ = Describe("podman machine init", func() {
switch runtime.GOOS {
// os's handle memory differently
case "linux":
- Expect(memorySession.outputToString()).To(ContainSubstring("3821"))
+ Expect(memorySession.outputToString()).To(ContainSubstring("3822"))
case "darwin":
Expect(memorySession.outputToString()).To(ContainSubstring("3824"))
default:
@@ -130,7 +130,7 @@ var _ = Describe("podman machine init", func() {
mount := tmpDir + ":/testmountdir"
defer os.RemoveAll(tmpDir)
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withVolume(mount)).run()
Expect(err).To(BeNil())
diff --git a/pkg/machine/e2e/inspect_test.go b/pkg/machine/e2e/inspect_test.go
index 93fb8cc2b..0ab928205 100644
--- a/pkg/machine/e2e/inspect_test.go
+++ b/pkg/machine/e2e/inspect_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"strings"
@@ -52,15 +52,15 @@ var _ = Describe("podman machine stop", func() {
})
It("inspect with go format", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
Expect(session).To(Exit(0))
// regular inspect should
- inspectJson := new(inspectMachine)
- inspectSession, err := mb.setName(name).setCmd(inspectJson).run()
+ inspectJSON := new(inspectMachine)
+ inspectSession, err := mb.setName(name).setCmd(inspectJSON).run()
Expect(err).To(BeNil())
Expect(inspectSession).To(Exit(0))
diff --git a/pkg/machine/e2e/list_test.go b/pkg/machine/e2e/list_test.go
index 8b7443d47..5c7ae6c5e 100644
--- a/pkg/machine/e2e/list_test.go
+++ b/pkg/machine/e2e/list_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"strings"
@@ -45,8 +45,8 @@ var _ = Describe("podman machine list", func() {
It("list machines with quiet or noheading", func() {
// Random names for machines to test list
- name1 := randomString(12)
- name2 := randomString(12)
+ name1 := randomString()
+ name2 := randomString()
list := new(listMachine)
firstList, err := mb.setCmd(list.withQuiet()).run()
@@ -109,7 +109,7 @@ var _ = Describe("podman machine list", func() {
It("list with --format", func() {
// Random names for machines to test list
- name1 := randomString(12)
+ name1 := randomString()
i := new(initMachine)
session, err := mb.setName(name1).setCmd(i.withImagePath(mb.imagePath)).run()
diff --git a/pkg/machine/e2e/machine_test.go b/pkg/machine/e2e/machine_test.go
index 93eabdad3..5de04b9f7 100644
--- a/pkg/machine/e2e/machine_test.go
+++ b/pkg/machine/e2e/machine_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"fmt"
diff --git a/pkg/machine/e2e/rm_test.go b/pkg/machine/e2e/rm_test.go
index 43b8c594c..e33eaf702 100644
--- a/pkg/machine/e2e/rm_test.go
+++ b/pkg/machine/e2e/rm_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
. "github.com/onsi/ginkgo"
diff --git a/pkg/machine/e2e/set_test.go b/pkg/machine/e2e/set_test.go
index 80cb89488..4839e33da 100644
--- a/pkg/machine/e2e/set_test.go
+++ b/pkg/machine/e2e/set_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"runtime"
@@ -22,7 +22,7 @@ var _ = Describe("podman machine set", func() {
})
It("set machine cpus, disk, memory", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
@@ -62,7 +62,7 @@ var _ = Describe("podman machine set", func() {
switch runtime.GOOS {
// it seems macos and linux handle memory differently
case "linux":
- Expect(memorySession.outputToString()).To(ContainSubstring("3821"))
+ Expect(memorySession.outputToString()).To(ContainSubstring("3822"))
case "darwin":
Expect(memorySession.outputToString()).To(ContainSubstring("3824"))
default:
@@ -75,7 +75,7 @@ var _ = Describe("podman machine set", func() {
})
It("no settings should change if no flags", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
diff --git a/pkg/machine/e2e/ssh_test.go b/pkg/machine/e2e/ssh_test.go
index 9ee31ac26..52d714c91 100644
--- a/pkg/machine/e2e/ssh_test.go
+++ b/pkg/machine/e2e/ssh_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
. "github.com/onsi/ginkgo"
@@ -20,17 +20,16 @@ var _ = Describe("podman machine ssh", func() {
})
It("bad machine name", func() {
- name := randomString(12)
+ name := randomString()
ssh := sshMachine{}
session, err := mb.setName(name).setCmd(ssh).run()
Expect(err).To(BeNil())
Expect(session).To(Exit(125))
- // TODO seems like stderr is not being returned; re-enabled when fixed
- //Expect(session.outputToString()).To(ContainSubstring("not exist"))
+ Expect(session.errorToString()).To(ContainSubstring("not exist"))
})
It("ssh to non-running machine", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath)).run()
Expect(err).To(BeNil())
@@ -39,13 +38,12 @@ var _ = Describe("podman machine ssh", func() {
ssh := sshMachine{}
sshSession, err := mb.setName(name).setCmd(ssh).run()
Expect(err).To(BeNil())
- // TODO seems like stderr is not being returned; re-enabled when fixed
- //Expect(sshSession.outputToString()).To(ContainSubstring("is not running"))
+ Expect(sshSession.errorToString()).To(ContainSubstring("is not running"))
Expect(sshSession).To(Exit(125))
})
It("ssh to running machine and check os-type", func() {
- name := randomString(12)
+ name := randomString()
i := new(initMachine)
session, err := mb.setName(name).setCmd(i.withImagePath(mb.imagePath).withNow()).run()
Expect(err).To(BeNil())
diff --git a/pkg/machine/e2e/start_test.go b/pkg/machine/e2e/start_test.go
index 1de66eb9a..1f9405569 100644
--- a/pkg/machine/e2e/start_test.go
+++ b/pkg/machine/e2e/start_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
"github.com/containers/podman/v4/pkg/machine"
diff --git a/pkg/machine/e2e/stop_test.go b/pkg/machine/e2e/stop_test.go
index 0c27045a6..621bbdb16 100644
--- a/pkg/machine/e2e/stop_test.go
+++ b/pkg/machine/e2e/stop_test.go
@@ -1,4 +1,4 @@
-package e2e
+package e2e_test
import (
. "github.com/onsi/ginkgo"
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index 3b57455c4..7974c261e 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -670,11 +670,11 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
// because / is immutable, we have to monkey around with permissions
// if we dont mount in /home or /mnt
args := []string{"-q", "--"}
- if !strings.HasPrefix(mount.Target, "/home") || !strings.HasPrefix(mount.Target, "/mnt") {
+ if !strings.HasPrefix(mount.Target, "/home") && !strings.HasPrefix(mount.Target, "/mnt") {
args = append(args, "sudo", "chattr", "-i", "/", ";")
}
args = append(args, "sudo", "mkdir", "-p", mount.Target)
- if !strings.HasPrefix(mount.Target, "/home") || !strings.HasPrefix(mount.Target, "/mnt") {
+ if !strings.HasPrefix(mount.Target, "/home") && !strings.HasPrefix(mount.Target, "/mnt") {
args = append(args, ";", "sudo", "chattr", "+i", "/", ";")
}
err = v.SSH(name, machine.SSHOptions{Args: args})
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 9bb7caace..8cfac924b 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -494,10 +494,10 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
if s.ResourceLimits == nil {
s.ResourceLimits = &spec.LinuxResources{}
}
- if s.ResourceLimits.BlockIO == nil {
- s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
- }
if bps := s.ThrottleReadBpsDevice; len(bps) > 0 {
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
+ }
for k, v := range bps {
statT := unix.Stat_t{}
if err := unix.Stat(k, &statT); err != nil {
@@ -512,6 +512,9 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
}
}
if bps := s.ThrottleWriteBpsDevice; len(bps) > 0 {
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
+ }
for k, v := range bps {
statT := unix.Stat_t{}
if err := unix.Stat(k, &statT); err != nil {
@@ -523,6 +526,9 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
}
}
if iops := s.ThrottleReadIOPSDevice; len(iops) > 0 {
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
+ }
for k, v := range iops {
statT := unix.Stat_t{}
if err := unix.Stat(k, &statT); err != nil {
@@ -534,6 +540,9 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
}
}
if iops := s.ThrottleWriteIOPSDevice; len(iops) > 0 {
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = &spec.LinuxBlockIO{}
+ }
for k, v := range iops {
statT := unix.Stat_t{}
if err := unix.Stat(k, &statT); err != nil {
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 389900820..8334d386f 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -55,6 +55,10 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
}
}
+ if err := FinishThrottleDevices(s); err != nil {
+ return nil, nil, nil, err
+ }
+
// Set defaults for unset namespaces
if s.PidNS.IsDefault() {
defaultNS, err := GetDefaultNamespaceMode("pid", rtc, pod)
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 454a1e1d0..e9abf419b 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -398,6 +398,16 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
Type: "b",
}
s.Devices = append(s.Devices, device)
+ case KubeVolumeTypeSecret:
+ // in podman play kube we need to add these secrets as volumes rather than as
+ // specgen.Secrets. Adding them as volumes allows for all key: value pairs to be mounted
+ secretVolume := specgen.NamedVolume{
+ Dest: volume.MountPath,
+ Name: volumeSource.Source,
+ Options: options,
+ }
+
+ s.Volumes = append(s.Volumes, &secretVolume)
default:
return nil, errors.New("unsupported volume source type")
}
diff --git a/pkg/specgen/generate/kube/play_test.go b/pkg/specgen/generate/kube/play_test.go
index 466dab610..470c0c39c 100644
--- a/pkg/specgen/generate/kube/play_test.go
+++ b/pkg/specgen/generate/kube/play_test.go
@@ -28,7 +28,7 @@ func createSecrets(t *testing.T, d string) *secrets.SecretsManager {
data, err := json.Marshal(s.Data)
assert.NoError(t, err)
- _, err = secretsManager.Store(s.ObjectMeta.Name, data, driver, driverOpts)
+ _, err = secretsManager.Store(s.ObjectMeta.Name, data, driver, driverOpts, nil)
assert.NoError(t, err)
}
diff --git a/pkg/specgen/generate/kube/volume.go b/pkg/specgen/generate/kube/volume.go
index f5c0c241d..c12adadd8 100644
--- a/pkg/specgen/generate/kube/volume.go
+++ b/pkg/specgen/generate/kube/volume.go
@@ -6,9 +6,13 @@ import (
"os"
"github.com/containers/common/pkg/parse"
+ "github.com/containers/common/pkg/secrets"
"github.com/containers/podman/v4/libpod"
v1 "github.com/containers/podman/v4/pkg/k8s.io/api/core/v1"
+ metav1 "github.com/containers/podman/v4/pkg/k8s.io/apimachinery/pkg/apis/meta/v1"
+
"github.com/sirupsen/logrus"
+ "gopkg.in/yaml.v3"
)
const (
@@ -27,6 +31,7 @@ const (
KubeVolumeTypeConfigMap
KubeVolumeTypeBlockDevice
KubeVolumeTypeCharDevice
+ KubeVolumeTypeSecret
)
//nolint:revive
@@ -125,6 +130,49 @@ func VolumeFromHostPath(hostPath *v1.HostPathVolumeSource) (*KubeVolume, error)
}, nil
}
+// VolumeFromSecret creates a new kube volume from a kube secret.
+func VolumeFromSecret(secretSource *v1.SecretVolumeSource, secretsManager *secrets.SecretsManager) (*KubeVolume, error) {
+ // returns a byte array of a kube secret data, meaning this needs to go into a string map
+ _, secretByte, err := secretsManager.LookupSecretData(secretSource.SecretName)
+ if err != nil {
+ return nil, err
+ }
+
+ // unmarshaling directly into a v1.secret creates type mismatch errors
+ // use a more friendly, string only secret struct.
+ type KubeSecret struct {
+ metav1.TypeMeta `json:",inline"`
+ // +optional
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+ // +optional
+ Immutable *bool `json:"immutable,omitempty"`
+ Data map[string]string `json:"data,omitempty"`
+ // +optional
+ StringData map[string]string `json:"stringData,omitempty"`
+ // +optional
+ Type string `json:"type,omitempty"`
+ }
+
+ data := &KubeSecret{}
+
+ err = yaml.Unmarshal(secretByte, data)
+ if err != nil {
+ return nil, err
+ }
+
+ kv := &KubeVolume{}
+ kv.Type = KubeVolumeTypeSecret
+ kv.Source = secretSource.SecretName
+ kv.Optional = *secretSource.Optional
+ kv.Items = make(map[string]string)
+
+ // add key: value pairs to the items array
+ for key, entry := range data.Data {
+ kv.Items[key] = entry
+ }
+ return kv, nil
+}
+
// Create a KubeVolume from a PersistentVolumeClaimVolumeSource
func VolumeFromPersistentVolumeClaim(claim *v1.PersistentVolumeClaimVolumeSource) (*KubeVolume, error) {
return &KubeVolume{
@@ -172,7 +220,7 @@ func VolumeFromConfigMap(configMapVolumeSource *v1.ConfigMapVolumeSource, config
}
// Create a KubeVolume from one of the supported VolumeSource
-func VolumeFromSource(volumeSource v1.VolumeSource, configMaps []v1.ConfigMap) (*KubeVolume, error) {
+func VolumeFromSource(volumeSource v1.VolumeSource, configMaps []v1.ConfigMap, secretsManager *secrets.SecretsManager) (*KubeVolume, error) {
switch {
case volumeSource.HostPath != nil:
return VolumeFromHostPath(volumeSource.HostPath)
@@ -180,17 +228,19 @@ func VolumeFromSource(volumeSource v1.VolumeSource, configMaps []v1.ConfigMap) (
return VolumeFromPersistentVolumeClaim(volumeSource.PersistentVolumeClaim)
case volumeSource.ConfigMap != nil:
return VolumeFromConfigMap(volumeSource.ConfigMap, configMaps)
+ case volumeSource.Secret != nil:
+ return VolumeFromSecret(volumeSource.Secret, secretsManager)
default:
return nil, errors.New("HostPath, ConfigMap, and PersistentVolumeClaim are currently the only supported VolumeSource")
}
}
// Create a map of volume name to KubeVolume
-func InitializeVolumes(specVolumes []v1.Volume, configMaps []v1.ConfigMap) (map[string]*KubeVolume, error) {
+func InitializeVolumes(specVolumes []v1.Volume, configMaps []v1.ConfigMap, secretsManager *secrets.SecretsManager) (map[string]*KubeVolume, error) {
volumes := make(map[string]*KubeVolume)
for _, specVolume := range specVolumes {
- volume, err := VolumeFromSource(specVolume.VolumeSource, configMaps)
+ volume, err := VolumeFromSource(specVolume.VolumeSource, configMaps, secretsManager)
if err != nil {
return nil, fmt.Errorf("failed to create volume %q: %w", specVolume.Name, err)
}
diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go
index 4ab019b5b..7392e7b44 100644
--- a/pkg/specgenutil/specgen.go
+++ b/pkg/specgenutil/specgen.go
@@ -77,11 +77,11 @@ func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (
if s.ResourceLimits == nil {
s.ResourceLimits = &specs.LinuxResources{}
}
- if s.ResourceLimits.BlockIO == nil {
- s.ResourceLimits.BlockIO = &specs.LinuxBlockIO{}
- }
hasLimits := false
if b := c.BlkIOWeight; len(b) > 0 {
+ if s.ResourceLimits.BlockIO == nil {
+ s.ResourceLimits.BlockIO = &specs.LinuxBlockIO{}
+ }
u, err := strconv.ParseUint(b, 10, 16)
if err != nil {
return nil, fmt.Errorf("invalid value for blkio-weight: %w", err)
@@ -103,7 +103,6 @@ func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (
if s.ThrottleReadBpsDevice, err = parseThrottleBPSDevices(bps); err != nil {
return nil, err
}
-
hasLimits = true
}
@@ -131,8 +130,6 @@ func getIOLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (
if !hasLimits {
return nil, nil
}
- io = s.ResourceLimits.BlockIO
-
return io, nil
}
diff --git a/test/apiv2/12-imagesMore.at b/test/apiv2/12-imagesMore.at
index d4b09174f..498d67569 100644
--- a/test/apiv2/12-imagesMore.at
+++ b/test/apiv2/12-imagesMore.at
@@ -28,7 +28,10 @@ t GET libpod/images/$IMAGE/json 200 \
.RepoTags[1]=localhost:$REGISTRY_PORT/myrepo:mytag
# Push to local registry...
-t POST "images/localhost:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" 200
+t POST "images/localhost:$REGISTRY_PORT/myrepo/push?tag=mytag" 200 \
+ .error~".*x509: certificate signed by unknown authority"
+t POST "images/localhost:$REGISTRY_PORT/myrepo/push?tlsVerify=false&tag=mytag" 200 \
+ .error~null
# ...and check output. We can't use our built-in checks because this output
# is a sequence of JSON objects, i.e., individual ones, not in a JSON array.
diff --git a/test/apiv2/15-manifest.at b/test/apiv2/15-manifest.at
index 970bed5a8..6584ea8e4 100644
--- a/test/apiv2/15-manifest.at
+++ b/test/apiv2/15-manifest.at
@@ -31,6 +31,8 @@ t POST /v3.4.0/libpod/manifests/$id_abc/add images="[\"containers-storage:$id_ab
t PUT /v4.0.0/libpod/manifests/$id_xyz operation='update' images="[\"containers-storage:$id_xyz_image\"]" 200
t POST "/v3.4.0/libpod/manifests/abc:latest/push?destination=localhost:$REGISTRY_PORT%2Fabc:latest&tlsVerify=false&all=true" 200
+t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2Fxyz:latest?all=true" 400 \
+ .cause='x509: certificate signed by unknown authority'
t POST "/v4.0.0/libpod/manifests/xyz:latest/registry/localhost:$REGISTRY_PORT%2Fxyz:latest?tlsVerify=false&all=true" 200
# /v3.x cannot delete a manifest list
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 6ef4ef917..a8d9baef3 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -123,7 +123,8 @@ t GET libpod/containers/${cid}/json 200 \
.Id=$cid \
.State.Status~\\\(exited\\\|stopped\\\) \
.State.Running=false \
- .State.ExitCode=0
+ .State.ExitCode=0 \
+ .Config.Umask=0022 # regression check for #15036
t DELETE libpod/containers/$cid 200 .[0].Id=$cid
CNAME=myfoo
diff --git a/test/apiv2/35-networks.at b/test/apiv2/35-networks.at
index fcff26521..07ba45efb 100644
--- a/test/apiv2/35-networks.at
+++ b/test/apiv2/35-networks.at
@@ -84,12 +84,24 @@ t GET networks?filters='{"dangling":["true","0"]}' 500 \
t GET networks?filters='{"name":["doesnotexists"]}' 200 \
"[]"
+# check default name in list endpoint
+t GET networks 200 \
+ .[].Name~.*bridge.*
+
# network inspect docker
t GET networks/$network1_id 200 \
.Name=network1 \
.Id=$network1_id \
.Scope=local
+# inspect default bridge network
+t GET networks/bridge 200 \
+ .Name=bridge
+
+# inspect default bridge network with real podman name should return real name
+t GET networks/podman 200 \
+ .Name=podman
+
# network create docker
t POST networks/create Name=net3\ IPAM='{"Config":[]}' 201
# network delete docker
diff --git a/test/buildah-bud/apply-podman-deltas b/test/buildah-bud/apply-podman-deltas
index d6d539fa4..6578afc93 100755
--- a/test/buildah-bud/apply-podman-deltas
+++ b/test/buildah-bud/apply-podman-deltas
@@ -163,7 +163,7 @@ skip "does not work under podman" \
# which we could and perhaps should fix in the buildah repo via:
# - ... ${TESTSDIR}/bud/layers-squash/Dockerfile.hardlinks
# + ... -f Dockerfile.hardlinks ${TESTSDIR}/bud/layers-squash
-skip "FIXME FIXME FIXME: argument-order incompatible with podman" \
+skip "argument-order incompatible with podman" \
"bud-squash-hardlinks"
# Fails with "Error: context must be a directory: /path/to/Dockerfile"
@@ -231,7 +231,7 @@ skip_if_remote "FIXME FIXME FIXME: does this test make sense in remote?" \
###############################################################################
# BEGIN tests which are skipped due to actual podman or podman-remote bugs.
-skip_if_remote "Podman #12838: different error messages" \
+skip_if_remote "different error messages between podman & podman-remote" \
"bud with .dockerignore #2"
# These two tests, new in 2022-01, invoke podman (create, export) in ways
diff --git a/test/compose/test-compose b/test/compose/test-compose
index 7c4bf2e91..99d063c25 100755
--- a/test/compose/test-compose
+++ b/test/compose/test-compose
@@ -212,7 +212,6 @@ function start_service() {
rm -f $DOCKER_SOCK
mkdir --mode 0755 $WORKDIR/{root,runroot,cni}
chcon --reference=/var/lib/containers $WORKDIR/root
- cp /etc/cni/net.d/*podman*conflist $WORKDIR/cni/
$PODMAN_BIN \
--log-level debug \
diff --git a/test/e2e/benchmarks_test.go b/test/e2e/benchmarks_test.go
index fe045b97a..4be048de2 100644
--- a/test/e2e/benchmarks_test.go
+++ b/test/e2e/benchmarks_test.go
@@ -240,7 +240,7 @@ var _ = Describe("Podman Benchmark Suite", func() {
// --------------------------------------------------------------------------
newBenchmark("podman create", func() {
- session := podmanTest.Podman([]string{"run", ALPINE, "true"})
+ session := podmanTest.Podman([]string{"create", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
}, nil)
@@ -262,5 +262,11 @@ var _ = Describe("Podman Benchmark Suite", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
}, nil)
+
+ newBenchmark("podman run --detach", func() {
+ session := podmanTest.Podman([]string{"run", "--detach", ALPINE, "true"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ }, nil)
})
})
diff --git a/test/e2e/build_test.go b/test/e2e/build_test.go
index 9ecc2f8c6..424c7244e 100644
--- a/test/e2e/build_test.go
+++ b/test/e2e/build_test.go
@@ -524,6 +524,8 @@ subdir**`
// See https://github.com/containers/podman/issues/13535
It("Remote build .containerignore filtering embedded directory (#13535)", func() {
SkipIfNotRemote("Testing remote .containerignore file filtering")
+ Skip("FIXME: #15014: test times out in 'dd' on f36.")
+
podmanTest.RestartRemoteService()
// Switch to temp dir and restore it afterwards
@@ -552,7 +554,7 @@ subdir**`
Expect(ioutil.WriteFile(filepath.Join(subdirPath, "extra"), contents.Bytes(), 0644)).
ToNot(HaveOccurred())
randomFile := filepath.Join(subdirPath, "randomFile")
- dd := exec.Command("dd", "if=/dev/random", "of="+randomFile, "bs=1G", "count=1")
+ dd := exec.Command("dd", "if=/dev/urandom", "of="+randomFile, "bs=1G", "count=1")
ddSession, err := Start(dd, GinkgoWriter, GinkgoWriter)
Expect(err).ToNot(HaveOccurred())
Eventually(ddSession, "10s", "1s").Should(Exit(0))
diff --git a/test/e2e/checkpoint_image_test.go b/test/e2e/checkpoint_image_test.go
index 94320a70e..5700802e8 100644
--- a/test/e2e/checkpoint_image_test.go
+++ b/test/e2e/checkpoint_image_test.go
@@ -58,6 +58,7 @@ var _ = Describe("Podman checkpoint", func() {
})
It("podman checkpoint --create-image with running container", func() {
+ SkipIfContainerized("FIXME: #15015. All checkpoint tests hang when containerized.")
// Container image must be lowercase
checkpointImage := "alpine-checkpoint-" + strings.ToLower(RandomString(6))
containerName := "alpine-container-" + RandomString(6)
@@ -163,7 +164,8 @@ var _ = Describe("Podman checkpoint", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
- It("podman restore multiple containers from single checkpint image", func() {
+ It("podman restore multiple containers from single checkpoint image", func() {
+ SkipIfContainerized("FIXME: #15015. All checkpoint tests hang when containerized.")
// Container image must be lowercase
checkpointImage := "alpine-checkpoint-" + strings.ToLower(RandomString(6))
containerName := "alpine-container-" + RandomString(6)
@@ -225,7 +227,8 @@ var _ = Describe("Podman checkpoint", func() {
Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
})
- It("podman restore multiple containers from multiple checkpint images", func() {
+ It("podman restore multiple containers from multiple checkpoint images", func() {
+ SkipIfContainerized("FIXME: #15015. All checkpoint tests hang when containerized.")
// Container image must be lowercase
checkpointImage1 := "alpine-checkpoint-" + strings.ToLower(RandomString(6))
checkpointImage2 := "alpine-checkpoint-" + strings.ToLower(RandomString(6))
diff --git a/test/e2e/checkpoint_test.go b/test/e2e/checkpoint_test.go
index 5ccafeb37..d1771f336 100644
--- a/test/e2e/checkpoint_test.go
+++ b/test/e2e/checkpoint_test.go
@@ -57,6 +57,7 @@ var _ = Describe("Podman checkpoint", func() {
BeforeEach(func() {
SkipIfRootless("checkpoint not supported in rootless mode")
+ SkipIfContainerized("FIXME: #15015. All checkpoint tests hang when containerized.")
tempdir, err = CreateTempDirInTempDir()
Expect(err).To(BeNil())
@@ -1128,6 +1129,10 @@ var _ = Describe("Podman checkpoint", func() {
share := share // copy into local scope, for use inside function
It(testName, func() {
+ if podmanTest.Host.Distribution == "ubuntu" && IsRemote() {
+ Skip("FIXME: #15018. Cannot restore --pod under cgroupsV1 and remote")
+ }
+
if !criu.CheckForCriu(criu.PodCriuVersion) {
Skip("CRIU is missing or too old.")
}
@@ -1452,11 +1457,6 @@ var _ = Describe("Podman checkpoint", func() {
})
It("podman checkpoint and restore container with --file-locks", func() {
- if !strings.Contains(podmanTest.OCIRuntime, "runc") {
- // TODO: Enable test for crun when this feature has been released
- // https://github.com/containers/crun/pull/783
- Skip("FIXME: requires crun >= 1.4")
- }
localRunString := getRunString([]string{"--name", "test_name", ALPINE, "flock", "test.lock", "sleep", "100"})
session := podmanTest.Podman(localRunString)
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go
index 43367cf63..2d7c47a7f 100644
--- a/test/e2e/common_test.go
+++ b/test/e2e/common_test.go
@@ -856,12 +856,8 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
eventsType = "none"
}
- podmanOptions := strings.Split(fmt.Sprintf("%s--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --cgroup-manager %s --tmpdir %s --events-backend %s",
- debug, p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.NetworkConfigDir, p.CgroupManager, p.TmpDir, eventsType), " ")
-
- if !p.RemoteTest {
- podmanOptions = append(podmanOptions, "--network-backend", p.NetworkBackend.ToString())
- }
+ podmanOptions := strings.Split(fmt.Sprintf("%s--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --network-backend %s --cgroup-manager %s --tmpdir %s --events-backend %s",
+ debug, p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.NetworkConfigDir, p.NetworkBackend.ToString(), p.CgroupManager, p.TmpDir, eventsType), " ")
podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
if !noCache {
diff --git a/test/e2e/containers_conf_test.go b/test/e2e/containers_conf_test.go
index 819efa628..41e78ce0e 100644
--- a/test/e2e/containers_conf_test.go
+++ b/test/e2e/containers_conf_test.go
@@ -535,7 +535,8 @@ var _ = Describe("Verify podman containers.conf usage", func() {
It("podman containers.conf cgroups=disabled", func() {
if !strings.Contains(podmanTest.OCIRuntime, "crun") {
- Skip("FIXME: requires crun")
+ // Assume this will never be fixed in runc
+ Skip("NoCgroups requires crun")
}
conffile := filepath.Join(podmanTest.TempDir, "container.conf")
diff --git a/test/e2e/info_test.go b/test/e2e/info_test.go
index 2c2c82cb6..9d31deb55 100644
--- a/test/e2e/info_test.go
+++ b/test/e2e/info_test.go
@@ -152,4 +152,19 @@ var _ = Describe("Podman Info", func() {
Expect(session.OutputToString()).To(ContainSubstring("memory"))
Expect(session.OutputToString()).To(ContainSubstring("pids"))
})
+
+ It("Podman info: check desired runtime", func() {
+ // defined in .cirrus.yml
+ want := os.Getenv("CI_DESIRED_RUNTIME")
+ if want == "" {
+ if os.Getenv("CIRRUS_CI") == "" {
+ Skip("CI_DESIRED_RUNTIME is not set--this is OK because we're not running under Cirrus")
+ }
+ Fail("CIRRUS_CI is set, but CI_DESIRED_RUNTIME is not! See #14912")
+ }
+ session := podmanTest.Podman([]string{"info", "--format", "{{.Host.OCIRuntime.Name}}"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).To(Exit(0))
+ Expect(session.OutputToString()).To(Equal(want))
+ })
})
diff --git a/test/e2e/kill_test.go b/test/e2e/kill_test.go
index 2a9a86729..9b33e2f0d 100644
--- a/test/e2e/kill_test.go
+++ b/test/e2e/kill_test.go
@@ -129,6 +129,7 @@ var _ = Describe("Podman kill", func() {
})
It("podman kill paused container", func() {
+ SkipIfRootlessCgroupsV1("pause is not supported for cgroupv1 rootless")
ctrName := "testctr"
session := podmanTest.RunTopContainer(ctrName)
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/libpod_suite_remote_test.go b/test/e2e/libpod_suite_remote_test.go
index 19affbc6d..86be17eb3 100644
--- a/test/e2e/libpod_suite_remote_test.go
+++ b/test/e2e/libpod_suite_remote_test.go
@@ -136,11 +136,8 @@ func (p *PodmanTestIntegration) StopRemoteService() {
// MakeOptions assembles all the podman main options
func getRemoteOptions(p *PodmanTestIntegration, args []string) []string {
networkDir := p.NetworkConfigDir
- podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --cgroup-manager %s",
- p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, networkDir, p.CgroupManager), " ")
- if p.NetworkBackend.ToString() == "netavark" {
- podmanOptions = append(podmanOptions, "--network-backend", "netavark")
- }
+ podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --network-backend %s --cgroup-manager %s",
+ p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, networkDir, p.NetworkBackend.ToString(), p.CgroupManager), " ")
podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
podmanOptions = append(podmanOptions, args...)
return podmanOptions
diff --git a/test/e2e/network_connect_disconnect_test.go b/test/e2e/network_connect_disconnect_test.go
index c9ffe6a8d..ece1b519d 100644
--- a/test/e2e/network_connect_disconnect_test.go
+++ b/test/e2e/network_connect_disconnect_test.go
@@ -71,6 +71,7 @@ var _ = Describe("Podman network connect and disconnect", func() {
})
It("podman network disconnect", func() {
+ SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
@@ -180,6 +181,7 @@ var _ = Describe("Podman network connect and disconnect", func() {
})
It("podman network connect", func() {
+ SkipIfRootlessCgroupsV1("stats not supported under rootless CgroupsV1")
netName := "aliasTest" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
diff --git a/test/e2e/pause_test.go b/test/e2e/pause_test.go
index d677eddb0..363df2624 100644
--- a/test/e2e/pause_test.go
+++ b/test/e2e/pause_test.go
@@ -319,4 +319,181 @@ var _ = Describe("Podman pause", func() {
Expect(running.OutputToStringArray()).To(HaveLen(3))
})
+ It("podman pause --latest", func() {
+ SkipIfRemote("--latest flag n/a")
+ session := podmanTest.RunTopContainer("")
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ result := podmanTest.Podman([]string{"pause", "-l"})
+ result.WaitWithDefaultTimeout()
+
+ Expect(session).Should(Exit(0))
+ Expect(podmanTest.NumberOfContainersRunning()).To(Equal(0))
+ Expect(strings.ToLower(podmanTest.GetContainerStatus())).To(ContainSubstring(pausedState))
+
+ result = podmanTest.Podman([]string{"unpause", "-l"})
+ result.WaitWithDefaultTimeout()
+ })
+
+ It("podman pause --cidfile", func() {
+ tmpDir, err := ioutil.TempDir("", "")
+ Expect(err).To(BeNil())
+ tmpFile := tmpDir + "cid"
+
+ defer os.RemoveAll(tmpDir)
+
+ session := podmanTest.Podman([]string{"create", "--cidfile", tmpFile, ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ cid := session.OutputToStringArray()[0]
+
+ session = podmanTest.Podman([]string{"start", cid})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ result := podmanTest.Podman([]string{"pause", "--cidfile", tmpFile})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ output := result.OutputToString()
+ Expect(output).To(ContainSubstring(cid))
+
+ result = podmanTest.Podman([]string{"unpause", "--cidfile", tmpFile})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ output = result.OutputToString()
+ Expect(output).To(ContainSubstring(cid))
+ })
+
+ It("podman pause multiple --cidfile", func() {
+ tmpDir, err := ioutil.TempDir("", "")
+ Expect(err).To(BeNil())
+ tmpFile1 := tmpDir + "cid-1"
+ tmpFile2 := tmpDir + "cid-2"
+
+ defer os.RemoveAll(tmpDir)
+
+ session := podmanTest.Podman([]string{"run", "--cidfile", tmpFile1, "-d", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ cid1 := session.OutputToStringArray()[0]
+ Expect(podmanTest.NumberOfContainers()).To(Equal(1))
+
+ session = podmanTest.Podman([]string{"run", "--cidfile", tmpFile2, "-d", ALPINE, "top"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ cid2 := session.OutputToStringArray()[0]
+ Expect(podmanTest.NumberOfContainers()).To(Equal(2))
+
+ result := podmanTest.Podman([]string{"pause", "--cidfile", tmpFile1, "--cidfile", tmpFile2})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ output := result.OutputToString()
+ Expect(output).To(ContainSubstring(cid1))
+ Expect(output).To(ContainSubstring(cid2))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(2))
+
+ result = podmanTest.Podman([]string{"unpause", "--cidfile", tmpFile1, "--cidfile", tmpFile2})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(0))
+ output = result.OutputToString()
+ Expect(output).To(ContainSubstring(cid1))
+ Expect(output).To(ContainSubstring(cid2))
+ Expect(podmanTest.NumberOfContainers()).To(Equal(2))
+ })
+
+ It("podman pause invalid --latest and --cidfile and --all", func() {
+ SkipIfRemote("--latest flag n/a")
+ result := podmanTest.Podman([]string{"pause", "--cidfile", "foobar", "--latest"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ result = podmanTest.Podman([]string{"pause", "--cidfile", "foobar", "--all"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ result = podmanTest.Podman([]string{"pause", "--cidfile", "foobar", "--all", "--latest"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ result = podmanTest.Podman([]string{"pause", "--latest", "--all"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ })
+
+ It("podman unpause invalid --latest and --cidfile and --all", func() {
+ SkipIfRemote("--latest flag n/a")
+ result := podmanTest.Podman([]string{"unpause", "--cidfile", "foobar", "--latest"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ result = podmanTest.Podman([]string{"unpause", "--cidfile", "foobar", "--all"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ result = podmanTest.Podman([]string{"unpause", "--cidfile", "foobar", "--all", "--latest"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ result = podmanTest.Podman([]string{"unpause", "--latest", "--all"})
+ result.WaitWithDefaultTimeout()
+ Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("cannot be used together"))
+ })
+
+ It("podman pause --filter", func() {
+ session1 := podmanTest.RunTopContainer("")
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid1 := session1.OutputToString()
+
+ session1 = podmanTest.RunTopContainer("")
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid2 := session1.OutputToString()
+
+ session1 = podmanTest.RunTopContainer("")
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid3 := session1.OutputToString()
+ shortCid3 := cid3[0:5]
+
+ session1 = podmanTest.Podman([]string{"pause", cid1, "-f", "status=test"})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(125))
+
+ session1 = podmanTest.Podman([]string{"unpause", cid1, "-f", "status=paused"})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(125))
+
+ session1 = podmanTest.Podman([]string{"pause", "-a", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(HaveLen(0))
+
+ session1 = podmanTest.Podman([]string{"pause", "-a", "--filter", fmt.Sprintf("id=%s", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid3))
+
+ session1 = podmanTest.Podman([]string{"unpause", "-a", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(HaveLen(0))
+
+ session1 = podmanTest.Podman([]string{"unpause", "-a", "--filter", fmt.Sprintf("id=%s", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid3))
+
+ session1 = podmanTest.Podman([]string{"pause", "-f", fmt.Sprintf("id=%s", cid2)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid2))
+
+ session1 = podmanTest.Podman([]string{"unpause", "-f", fmt.Sprintf("id=%s", cid2)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid2))
+ })
})
diff --git a/test/e2e/play_kube_test.go b/test/e2e/play_kube_test.go
index 9e2d4de19..1b4eefd45 100644
--- a/test/e2e/play_kube_test.go
+++ b/test/e2e/play_kube_test.go
@@ -29,6 +29,76 @@ import (
"github.com/opencontainers/selinux/go-selinux"
)
+var secretYaml = `
+apiVersion: v1
+kind: Secret
+metadata:
+ name: newsecret
+type: Opaque
+data:
+ username: dXNlcg==
+ password: NTRmNDFkMTJlOGZh
+`
+
+var complexSecretYaml = `
+apiVersion: v1
+kind: Secret
+metadata:
+ name: newsecrettwo
+type: Opaque
+data:
+ username: Y2RvZXJuCg==
+ password: dGVzdGluZ3Rlc3RpbmcK
+ note: a3ViZSBzZWNyZXRzIGFyZSBjb29sIQo=
+`
+
+var secretPodYaml = `
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod
+spec:
+ containers:
+ - name: myctr
+ image: quay.io/libpod/alpine_nginx:latest
+ volumeMounts:
+ - name: foo
+ mountPath: /etc/foo
+ readOnly: true
+ volumes:
+ - name: foo
+ secret:
+ secretName: newsecret
+ optional: false
+`
+
+var secretPodYamlTwo = `
+apiVersion: v1
+kind: Pod
+metadata:
+ name: mypod2
+spec:
+ containers:
+ - name: myctr
+ image: quay.io/libpod/alpine_nginx:latest
+ volumeMounts:
+ - name: foo
+ mountPath: /etc/foo
+ readOnly: true
+ - name: bar
+ mountPath: /etc/bar
+ readOnly: true
+ volumes:
+ - name: foo
+ secret:
+ secretName: newsecret
+ optional: false
+ - name: bar
+ secret:
+ secretName: newsecrettwo
+ optional: false
+`
+
var unknownKindYaml = `
apiVersion: v1
kind: UnknownKind
@@ -3493,7 +3563,7 @@ ENV OPENJ9_JAVA_OPTIONS=%q
SkipIfRemote("cannot run in a remote setup")
address := url.URL{
Scheme: "tcp",
- Host: net.JoinHostPort("localhost", randomPort()),
+ Host: net.JoinHostPort("localhost", "8080"),
}
session := podmanTest.Podman([]string{
@@ -3857,4 +3927,74 @@ ENV OPENJ9_JAVA_OPTIONS=%q
Expect(kube).Should(Exit(125))
})
+ It("podman play kube secret as volume support", func() {
+ err := writeYaml(secretYaml, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube := podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ secretList := podmanTest.Podman([]string{"secret", "list"})
+ secretList.WaitWithDefaultTimeout()
+ Expect(secretList).Should(Exit(0))
+ Expect(secretList.OutputToString()).Should(ContainSubstring("newsecret"))
+
+ err = writeYaml(secretPodYaml, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube = podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ exec := podmanTest.Podman([]string{"exec", "-it", "mypod-myctr", "cat", "/etc/foo/username"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec).Should(Exit(0))
+ Expect(exec.OutputToString()).Should(ContainSubstring("dXNlcg=="))
+
+ secretRm := podmanTest.Podman([]string{"secret", "rm", "newsecret"})
+ secretRm.WaitWithDefaultTimeout()
+ Expect(secretRm).Should(Exit(0))
+
+ podRm := podmanTest.Podman([]string{"pod", "rm", "-f", "mypod"})
+ podRm.WaitWithDefaultTimeout()
+ Expect(podRm).Should(Exit(0))
+
+ yamls := []string{secretYaml, secretPodYaml}
+ err = generateMultiDocKubeYaml(yamls, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube = podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ // do not remove newsecret to test that we auto remove on collision
+
+ yamls = []string{secretYaml, complexSecretYaml}
+ err = generateMultiDocKubeYaml(yamls, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube = podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ err = writeYaml(secretPodYamlTwo, kubeYaml)
+ Expect(err).To(BeNil())
+
+ kube = podmanTest.Podman([]string{"play", "kube", kubeYaml})
+ kube.WaitWithDefaultTimeout()
+ Expect(kube).Should(Exit(0))
+
+ exec = podmanTest.Podman([]string{"exec", "-it", "mypod2-myctr", "cat", "/etc/foo/username"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec).Should(Exit(0))
+ Expect(exec.OutputToString()).Should(ContainSubstring("dXNlcg=="))
+
+ exec = podmanTest.Podman([]string{"exec", "-it", "mypod2-myctr", "cat", "/etc/bar/username"})
+ exec.WaitWithDefaultTimeout()
+ Expect(exec).Should(Exit(0))
+ Expect(exec.OutputToString()).Should(ContainSubstring("Y2RvZXJuCg=="))
+
+ })
+
})
diff --git a/test/e2e/pod_create_test.go b/test/e2e/pod_create_test.go
index 3caae2bd5..24d9d6854 100644
--- a/test/e2e/pod_create_test.go
+++ b/test/e2e/pod_create_test.go
@@ -1051,6 +1051,7 @@ ENTRYPOINT ["sleep","99999"]
It("podman pod create --share-parent test", func() {
SkipIfRootlessCgroupsV1("rootless cannot use cgroups with cgroupsv1")
+ SkipIfCgroupV1("FIXME: #15013: CgroupMode shows 'host' instead of CID under Cgroups V1.")
podCreate := podmanTest.Podman([]string{"pod", "create", "--share-parent=false"})
podCreate.WaitWithDefaultTimeout()
Expect(podCreate).Should(Exit(0))
diff --git a/test/e2e/pod_infra_container_test.go b/test/e2e/pod_infra_container_test.go
index a2e090524..b53630156 100644
--- a/test/e2e/pod_infra_container_test.go
+++ b/test/e2e/pod_infra_container_test.go
@@ -435,4 +435,20 @@ var _ = Describe("Podman pod create", func() {
Expect(session).Should(Exit(0))
Expect(session.OutputToString()).To(ContainSubstring(hostname))
})
+
+ tests := []string{"", "none"}
+ for _, test := range tests {
+ test := test
+ It("podman pod create --share="+test+" should not create an infra ctr", func() {
+ session := podmanTest.Podman([]string{"pod", "create", "--share", test})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ session = podmanTest.Podman([]string{"pod", "inspect", "--format", "{{.NumContainers}}", session.OutputToString()})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).Should((Equal("0")))
+ })
+ }
+
})
diff --git a/test/e2e/push_test.go b/test/e2e/push_test.go
index 97567e40d..f2a103f6b 100644
--- a/test/e2e/push_test.go
+++ b/test/e2e/push_test.go
@@ -116,15 +116,26 @@ var _ = Describe("Podman push", func() {
push := podmanTest.Podman([]string{"push", "-q", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"})
push.WaitWithDefaultTimeout()
Expect(push).Should(Exit(0))
+ Expect(len(push.ErrorToString())).To(Equal(0))
- SkipIfRemote("Remote does not support --digestfile")
- // Test --digestfile option
- push2 := podmanTest.Podman([]string{"push", "--tls-verify=false", "--digestfile=/tmp/digestfile.txt", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"})
- push2.WaitWithDefaultTimeout()
- fi, err := os.Lstat("/tmp/digestfile.txt")
- Expect(err).To(BeNil())
- Expect(fi.Name()).To(Equal("digestfile.txt"))
- Expect(push2).Should(Exit(0))
+ push = podmanTest.Podman([]string{"push", "--tls-verify=false", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"})
+ push.WaitWithDefaultTimeout()
+ Expect(push).Should(Exit(0))
+ output := push.ErrorToString()
+ Expect(output).To(ContainSubstring("Copying blob "))
+ Expect(output).To(ContainSubstring("Copying config "))
+ Expect(output).To(ContainSubstring("Writing manifest to image destination"))
+ Expect(output).To(ContainSubstring("Storing signatures"))
+
+ if !IsRemote() { // Remote does not support --digestfile
+ // Test --digestfile option
+ push2 := podmanTest.Podman([]string{"push", "--tls-verify=false", "--digestfile=/tmp/digestfile.txt", "--remove-signatures", ALPINE, "localhost:5000/my-alpine"})
+ push2.WaitWithDefaultTimeout()
+ fi, err := os.Lstat("/tmp/digestfile.txt")
+ Expect(err).To(BeNil())
+ Expect(fi.Name()).To(Equal("digestfile.txt"))
+ Expect(push2).Should(Exit(0))
+ }
})
It("podman push to local registry with authorization", func() {
diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go
index 6edb705a1..c7a0b3f2b 100644
--- a/test/e2e/run_test.go
+++ b/test/e2e/run_test.go
@@ -91,7 +91,8 @@ var _ = Describe("Podman run", func() {
if exitCode == 0 {
Expect(session.OutputToString()).To(ContainSubstring("aarch64"))
} else {
- Expect(session.ErrorToString()).To(ContainSubstring("Exec format error"))
+ // crun says 'Exec', runc says 'exec'. Handle either.
+ Expect(session.ErrorToString()).To(ContainSubstring("xec format error"))
}
})
@@ -714,8 +715,7 @@ USER bin`, BB)
})
It("podman run device-read-bps test", func() {
- SkipIfRootless("FIXME: requested cgroup controller `io` is not available")
- SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users")
+ SkipIfRootless("Setting device-read-bps not supported for rootless users")
var session *PodmanSessionIntegration
@@ -733,8 +733,7 @@ USER bin`, BB)
})
It("podman run device-write-bps test", func() {
- SkipIfRootless("FIXME: requested cgroup controller `io` is not available")
- SkipIfRootlessCgroupsV1("Setting device-write-bps not supported on cgroupv1 for rootless users")
+ SkipIfRootless("Setting device-write-bps not supported for rootless users")
var session *PodmanSessionIntegration
@@ -751,8 +750,7 @@ USER bin`, BB)
})
It("podman run device-read-iops test", func() {
- SkipIfRootless("FIXME: requested cgroup controller `io` is not available")
- SkipIfRootlessCgroupsV1("Setting device-read-iops not supported on cgroupv1 for rootless users")
+ SkipIfRootless("Setting device-read-iops not supported for rootless users")
var session *PodmanSessionIntegration
if CGROUPSV2 {
@@ -769,8 +767,7 @@ USER bin`, BB)
})
It("podman run device-write-iops test", func() {
- SkipIfRootless("FIXME: requested cgroup controller `io` is not available")
- SkipIfRootlessCgroupsV1("Setting device-write-iops not supported on cgroupv1 for rootless users")
+ SkipIfRootless("Setting device-write-iops not supported for rootless users")
var session *PodmanSessionIntegration
if CGROUPSV2 {
@@ -1238,6 +1235,7 @@ USER mail`, BB)
})
It("podman run --mount type=bind,bind-nonrecursive", func() {
+ // crun: mount `/` to `/host`: Invalid argument
SkipIfRootless("FIXME: rootless users are not allowed to mount bind-nonrecursive (Could this be a Kernel bug?")
session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"})
session.WaitWithDefaultTimeout()
diff --git a/test/system/005-info.bats b/test/system/005-info.bats
index 333553b07..43a345f11 100644
--- a/test/system/005-info.bats
+++ b/test/system/005-info.bats
@@ -55,7 +55,24 @@ host.slirp4netns.executable | $expr_path
dprint "# actual=<$actual> expect=<$expect>"
is "$actual" "$expect" "jq .$field"
done
+}
+
+@test "podman info - confirm desired runtime" {
+ if [[ -z "$CI_DESIRED_RUNTIME" ]]; then
+ # When running in Cirrus, CI_DESIRED_RUNTIME *must* be defined
+ # in .cirrus.yml so we can double-check that all CI VMs are
+ # using crun/runc as desired.
+ if [[ -n "$CIRRUS_CI" ]]; then
+ die "CIRRUS_CI is set, but CI_DESIRED_RUNTIME is not! See #14912"
+ fi
+
+ # Not running under Cirrus (e.g., gating tests, or dev laptop).
+ # Totally OK to skip this test.
+ skip "CI_DESIRED_RUNTIME is unset--OK, because we're not in Cirrus"
+ fi
+ run_podman info --format '{{.Host.OCIRuntime.Name}}'
+ is "$output" "$CI_DESIRED_RUNTIME" "CI_DESIRED_RUNTIME (from .cirrus.yml)"
}
# 2021-04-06 discussed in watercooler: RHEL must never use crun, even if
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index b3e3cef00..5014ef47b 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -70,6 +70,7 @@ echo $rand | 0 | $rand
}
@test "podman run - uidmapping has no /sys/kernel mounts" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
skip_if_rootless "cannot umount as rootless"
skip_if_remote "TODO Fix this for remote case"
@@ -805,6 +806,7 @@ EOF
# rhbz#1902979 : podman run fails to update /etc/hosts when --uidmap is provided
@test "podman run update /etc/hosts" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
HOST=$(random_string 25)
run_podman run --uidmap 0:10001:10002 --rm --hostname ${HOST} $IMAGE grep ${HOST} /etc/hosts
is "${lines[0]}" ".*${HOST}.*"
@@ -853,4 +855,19 @@ EOF
run_podman rm $output
}
+@test "podman run --device-read-bps" {
+ skip_if_rootless "cannot use this flag in rootless mode"
+ # this test is a triple check on blkio flags since they seem to sneak by the tests
+ if is_cgroupsv2; then
+ run_podman run -dt --device-read-bps=/dev/zero:1M $IMAGE top
+ run_podman exec -it $output cat /sys/fs/cgroup/io.max
+ is "$output" ".*1:5 rbps=1048576 wbps=max riops=max wiops=max" "throttle devices passed successfully.*"
+ else
+ run_podman run -dt --device-read-bps=/dev/zero:1M $IMAGE top
+ run_podman exec -it $output cat /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device
+ is "$output" ".*1:5 1048576" "throttle devices passed successfully.*"
+ fi
+ run_podman container rm -fa
+}
+
# vim: filetype=sh
diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats
index da60112a0..18e806699 100644
--- a/test/system/160-volumes.bats
+++ b/test/system/160-volumes.bats
@@ -149,16 +149,16 @@ EOF
# By default, volumes are mounted exec, but we have manually added the
# noexec option. This should fail.
- # ARGH. Unfortunately, runc (used for cgroups v1) produces a different error
+ # ARGH. Unfortunately, runc (used for cgroups v1) has different exit status
local expect_rc=126
- local expect_msg='.* OCI permission denied.*'
if [[ $(podman_runtime) = "runc" ]]; then
expect_rc=1
- expect_msg='.* exec user process caused.*permission denied'
fi
run_podman ${expect_rc} run --rm --volume $myvolume:/vol:noexec,z $IMAGE /vol/myscript
- is "$output" "$expect_msg" "run on volume, noexec"
+ # crun and runc emit different messages, and even runc is inconsistent
+ # with itself (output changed some time in 2022?). Deal with all.
+ assert "$output" =~ 'exec.* permission denied' "run on volume, noexec"
# With the default, it should pass
run_podman run --rm -v $myvolume:/vol:z $IMAGE /vol/myscript
diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats
index 2ad9eb0b8..5ad7473da 100644
--- a/test/system/170-run-userns.bats
+++ b/test/system/170-run-userns.bats
@@ -30,6 +30,7 @@ function _require_crun() {
}
@test "podman --group-add without keep-groups while in a userns" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
skip_if_rootless "chroot is not allowed in rootless mode"
skip_if_remote "--group-add keep-groups not supported in remote mode"
run chroot --groups 1234,5678 / ${PODMAN} run --rm --uidmap 0:200000:5000 --group-add 457 $IMAGE id
@@ -37,6 +38,7 @@ function _require_crun() {
}
@test "rootful pod with custom ID mapping" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
skip_if_rootless "does not work rootless - rootful feature"
random_pod_name=$(random_string 30)
run_podman pod create --uidmap 0:200000:5000 --name=$random_pod_name
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index b9c668993..667e2baef 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -479,9 +479,8 @@ spec:
@test "pod resource limits" {
skip_if_remote "resource limits only implemented on non-remote"
- if is_rootless || ! is_cgroupsv2; then
- skip "only meaningful for rootful"
- fi
+ skip_if_rootless "resource limits only work with root"
+ skip_if_cgroupsv1 "resource limits only meaningful on cgroups V2"
# create loopback device
lofile=${PODMAN_TMPDIR}/disk.img
diff --git a/test/system/251-system-service.bats b/test/system/251-system-service.bats
index edee4a28c..197d1cb18 100644
--- a/test/system/251-system-service.bats
+++ b/test/system/251-system-service.bats
@@ -17,6 +17,10 @@ function teardown() {
@test "podman-system-service containers survive service stop" {
skip_if_remote "podman system service unavailable over remote"
+ local runtime=$(podman_runtime)
+ if [[ "$runtime" != "crun" ]]; then
+ skip "survival code only implemented in crun; you're using $runtime"
+ fi
port=$(random_free_port)
URL=tcp://127.0.0.1:$port
diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats
index 710ff066c..0d6be2d60 100644
--- a/test/system/400-unprivileged-access.bats
+++ b/test/system/400-unprivileged-access.bats
@@ -7,6 +7,7 @@
load helpers
@test "podman container storage is not accessible by unprivileged users" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
skip_if_rootless "test meaningless without suid"
skip_if_remote
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 50eb15216..f45540f5f 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -84,6 +84,7 @@ load helpers
# Issue #5466 - port-forwarding doesn't work with this option and -d
@test "podman networking: port with --userns=keep-id for rootless or --uidmap=* for rootful" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
for cidr in "" "$(random_rfc1918_subnet).0/24"; do
myport=$(random_free_port 52000-52999)
if [[ -z $cidr ]]; then
@@ -744,6 +745,7 @@ EOF
}
@test "podman run /etc/* permissions" {
+ skip_if_cgroupsv1 "FIXME: #15025: run --uidmap fails on cgroups v1"
userns="--userns=keep-id"
if ! is_rootless; then
userns="--uidmap=0:1111111:65536 --gidmap=0:1111111:65536"
diff --git a/test/system/520-checkpoint.bats b/test/system/520-checkpoint.bats
index 7f60f01b3..7c8fc143a 100644
--- a/test/system/520-checkpoint.bats
+++ b/test/system/520-checkpoint.bats
@@ -12,7 +12,7 @@ function setup() {
# could run to see if it's fixed, but it's way too complicated. Since
# integration tests also skip checkpoint tests on Ubuntu, do the same here.
if is_ubuntu; then
- skip "FIXME: checkpointing broken in Ubuntu 2004, 2104, 2110, ..."
+ skip "FIXME: checkpointing broken in Ubuntu 2004, 2104, 2110, 2204, ..."
fi
# None of these tests work rootless....
diff --git a/test/utils/utils.go b/test/utils/utils.go
index 924f66ec8..9c2a63c81 100644
--- a/test/utils/utils.go
+++ b/test/utils/utils.go
@@ -110,9 +110,6 @@ func (p *PodmanTest) PodmanAsUserBase(args []string, uid, gid uint32, cwd string
}
runCmd := wrapper
runCmd = append(runCmd, podmanBinary)
- if !p.RemoteTest && p.NetworkBackend == Netavark {
- runCmd = append(runCmd, []string{"--network-backend", "netavark"}...)
- }
if env == nil {
fmt.Printf("Running: %s %s\n", strings.Join(runCmd, " "), strings.Join(podmanOptions, " "))
@@ -367,8 +364,8 @@ func (s *PodmanSession) WaitWithDefaultTimeout() {
func (s *PodmanSession) WaitWithTimeout(timeout int) {
Eventually(s, timeout).Should(Exit(), func() string {
// in case of timeouts show output
- return fmt.Sprintf("command %v timed out\nSTDOUT: %s\nSTDERR: %s",
- s.Command.Args, string(s.Out.Contents()), string(s.Err.Contents()))
+ return fmt.Sprintf("command timed out after %ds: %v\nSTDOUT: %s\nSTDERR: %s",
+ timeout, s.Command.Args, string(s.Out.Contents()), string(s.Err.Contents()))
})
os.Stdout.Sync()
os.Stderr.Sync()
diff --git a/vendor/github.com/containers/common/pkg/secrets/secrets.go b/vendor/github.com/containers/common/pkg/secrets/secrets.go
index e23db1152..ba0aa3776 100644
--- a/vendor/github.com/containers/common/pkg/secrets/secrets.go
+++ b/vendor/github.com/containers/common/pkg/secrets/secrets.go
@@ -129,7 +129,7 @@ func NewManager(rootPath string) (*SecretsManager, error) {
// Store takes a name, creates a secret and stores the secret metadata and the secret payload.
// It returns a generated ID that is associated with the secret.
// The max size for secret data is 512kB.
-func (s *SecretsManager) Store(name string, data []byte, driverType string, driverOpts map[string]string) (string, error) {
+func (s *SecretsManager) Store(name string, data []byte, driverType string, driverOpts map[string]string, metadata map[string]string) (string, error) {
err := validateSecretName(name)
if err != nil {
return "", err
@@ -168,8 +168,12 @@ func (s *SecretsManager) Store(name string, data []byte, driverType string, driv
}
}
+ if metadata == nil {
+ metadata = make(map[string]string)
+ }
+
secr.Driver = driverType
- secr.Metadata = make(map[string]string)
+ secr.Metadata = metadata
secr.CreatedAt = time.Now()
secr.DriverOptions = driverOpts
diff --git a/vendor/github.com/containers/storage/go.mod b/vendor/github.com/containers/storage/go.mod
index 02df413c0..1b455a0c8 100644
--- a/vendor/github.com/containers/storage/go.mod
+++ b/vendor/github.com/containers/storage/go.mod
@@ -18,7 +18,7 @@ require (
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
github.com/moby/sys/mountinfo v0.6.2
github.com/opencontainers/go-digest v1.0.0
- github.com/opencontainers/runc v1.1.1-0.20220607072441-a7a45d7d2721
+ github.com/opencontainers/runc v1.1.3
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
github.com/opencontainers/selinux v1.10.1
github.com/sirupsen/logrus v1.8.1
diff --git a/vendor/github.com/containers/storage/go.sum b/vendor/github.com/containers/storage/go.sum
index 083f899f7..42e88f347 100644
--- a/vendor/github.com/containers/storage/go.sum
+++ b/vendor/github.com/containers/storage/go.sum
@@ -107,7 +107,7 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
-github.com/cilium/ebpf v0.9.0/go.mod h1:+OhNOIXx/Fnu1IE8bJz2dzOA+VSfyTfdNUVdlQnxUFY=
+github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -266,7 +266,6 @@ github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
-github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
@@ -300,7 +299,7 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -437,7 +436,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -469,6 +467,7 @@ github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQ
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
+github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
@@ -522,8 +521,8 @@ github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
-github.com/opencontainers/runc v1.1.1-0.20220607072441-a7a45d7d2721 h1:geG4wjkUPHyg+Ya/BBb8YlX1z4INWpVMdoUnmBxttqc=
-github.com/opencontainers/runc v1.1.1-0.20220607072441-a7a45d7d2721/go.mod h1:QvA0UNe48mC1JxcXq0sENIR38+/LdJMLNxuAvtFBhxA=
+github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
+github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
@@ -535,6 +534,7 @@ 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.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.10.1 h1:09LIPVRP3uuZGQvgR+SgMSNBd1Eb3vlRbGqQpoHsF8w=
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -580,7 +580,6 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
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/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
@@ -646,7 +645,6 @@ github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijb
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
-github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME=
github.com/vbatts/tar-split v0.11.2/go.mod h1:vV3ZuO2yWSVsz+pfFzDG/upWH1JhjOiEaWq6kXyQ3VI=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
@@ -852,6 +850,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -993,7 +993,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/vendor/modules.txt b/vendor/modules.txt
index faf71ed37..d7edfabe7 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -114,7 +114,7 @@ github.com/containers/buildah/pkg/rusage
github.com/containers/buildah/pkg/sshagent
github.com/containers/buildah/pkg/util
github.com/containers/buildah/util
-# github.com/containers/common v0.48.1-0.20220718075257-ecddf87b3840
+# github.com/containers/common v0.48.1-0.20220720145307-26032247af78
## explicit
github.com/containers/common/libimage
github.com/containers/common/libimage/define
@@ -257,7 +257,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.41.1-0.20220714115232-fc9b0ff5272a
+# github.com/containers/storage v1.41.1-0.20220718173332-b10c469fda0a
## explicit
github.com/containers/storage
github.com/containers/storage/drivers