diff options
53 files changed, 946 insertions, 269 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index b585c41f8..c629bcf70 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: @@ -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/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-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-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-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 @@ -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 @@ -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/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/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/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/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/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/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/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/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/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/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..a4646b6d1 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.") } 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/manifest_test.go b/test/e2e/manifest_test.go index 1f58419a1..ecddf2935 100644 --- a/test/e2e/manifest_test.go +++ b/test/e2e/manifest_test.go @@ -293,6 +293,9 @@ var _ = Describe("Podman manifest", func() { }) It("authenticated push", func() { + if podmanTest.Host.Distribution == "ubuntu" && IsRemote() { + Skip("FIXME: #15017. Registry times out.") + } registryOptions := &podmanRegistry.Options{ Image: "docker-archive:" + imageTarPath(REGISTRY_IMAGE), } 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/run_test.go b/test/e2e/run_test.go index 6edb705a1..64b70f1ee 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,6 +715,7 @@ USER bin`, BB) }) It("podman run device-read-bps test", func() { + SkipIfCgroupV1("FIXME: #15035 - bps broken") SkipIfRootless("FIXME: requested cgroup controller `io` is not available") SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users") @@ -733,6 +735,7 @@ USER bin`, BB) }) It("podman run device-write-bps test", func() { + SkipIfCgroupV1("FIXME: #15035 - bps broken") SkipIfRootless("FIXME: requested cgroup controller `io` is not available") SkipIfRootlessCgroupsV1("Setting device-write-bps not supported on cgroupv1 for rootless users") @@ -751,6 +754,7 @@ USER bin`, BB) }) It("podman run device-read-iops test", func() { + SkipIfCgroupV1("FIXME: #15035 - bps broken") SkipIfRootless("FIXME: requested cgroup controller `io` is not available") SkipIfRootlessCgroupsV1("Setting device-read-iops not supported on cgroupv1 for rootless users") var session *PodmanSessionIntegration @@ -769,6 +773,7 @@ USER bin`, BB) }) It("podman run device-write-iops test", func() { + SkipIfCgroupV1("FIXME: #15035 - bps broken") SkipIfRootless("FIXME: requested cgroup controller `io` is not available") SkipIfRootlessCgroupsV1("Setting device-write-iops not supported on cgroupv1 for rootless users") var session *PodmanSessionIntegration 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..e62e7679f 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}.*" 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/utils/utils.go b/test/utils/utils.go index 924f66ec8..e84b57cc6 100644 --- a/test/utils/utils.go +++ b/test/utils/utils.go @@ -367,8 +367,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 |