aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/podman/containers/kill.go7
-rw-r--r--cmd/podman/containers/rm.go24
-rw-r--r--cmd/podman/containers/stop.go7
-rwxr-xr-xcontrib/cirrus/setup_environment.sh4
-rw-r--r--contrib/pkginstaller/Makefile19
-rw-r--r--contrib/pkginstaller/README.md3
-rw-r--r--contrib/pkginstaller/hvf.entitlements8
-rwxr-xr-xcontrib/pkginstaller/package.sh34
-rw-r--r--docs/source/markdown/podman-rm.1.md24
-rw-r--r--libpod/runtime_ctr.go4
-rw-r--r--pkg/domain/entities/containers.go1
-rw-r--r--pkg/domain/entities/reports/containers.go5
-rw-r--r--pkg/domain/infra/abi/containers.go43
-rw-r--r--pkg/domain/infra/tunnel/containers.go57
-rw-r--r--pkg/domain/infra/tunnel/helpers.go2
-rw-r--r--test/e2e/mount_rootless_test.go22
-rw-r--r--test/e2e/rm_test.go65
-rw-r--r--test/system/055-rm.bats1
-rw-r--r--test/system/200-pod.bats1
-rw-r--r--test/upgrade/test-upgrade.bats4
20 files changed, 264 insertions, 71 deletions
diff --git a/cmd/podman/containers/kill.go b/cmd/podman/containers/kill.go
index 5a5379389..c08b3abb6 100644
--- a/cmd/podman/containers/kill.go
+++ b/cmd/podman/containers/kill.go
@@ -49,7 +49,8 @@ var (
)
var (
- killOptions = entities.KillOptions{}
+ killOptions = entities.KillOptions{}
+ killCidFiles = []string{}
)
func killFlags(cmd *cobra.Command) {
@@ -61,7 +62,7 @@ func killFlags(cmd *cobra.Command) {
flags.StringVarP(&killOptions.Signal, signalFlagName, "s", "KILL", "Signal to send to the container")
_ = cmd.RegisterFlagCompletionFunc(signalFlagName, common.AutocompleteStopSignal)
cidfileFlagName := "cidfile"
- flags.StringArrayVar(&cidFiles, cidfileFlagName, []string{}, "Read the container ID from the file")
+ flags.StringArrayVar(&killCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
}
@@ -94,7 +95,7 @@ func kill(_ *cobra.Command, args []string) error {
if sig < 1 || sig > 64 {
return errors.New("valid signals are 1 through 64")
}
- for _, cidFile := range cidFiles {
+ for _, cidFile := range killCidFiles {
content, err := ioutil.ReadFile(cidFile)
if err != nil {
return fmt.Errorf("error reading CIDFile: %w", err)
diff --git a/cmd/podman/containers/rm.go b/cmd/podman/containers/rm.go
index 056e32651..1e3976389 100644
--- a/cmd/podman/containers/rm.go
+++ b/cmd/podman/containers/rm.go
@@ -52,8 +52,10 @@ var (
)
var (
- rmOptions = entities.RmOptions{}
- cidFiles = []string{}
+ rmOptions = entities.RmOptions{
+ Filters: make(map[string][]string),
+ }
+ rmCidFiles = []string{}
)
func rmFlags(cmd *cobra.Command) {
@@ -69,9 +71,13 @@ func rmFlags(cmd *cobra.Command) {
flags.BoolVarP(&rmOptions.Volumes, "volumes", "v", false, "Remove anonymous volumes associated with the container")
cidfileFlagName := "cidfile"
- flags.StringArrayVar(&cidFiles, cidfileFlagName, nil, "Read the container ID from the file")
+ flags.StringArrayVar(&rmCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
+ filterFlagName := "filter"
+ flags.StringSliceVar(&filters, filterFlagName, []string{}, "Filter output based on conditions given")
+ _ = cmd.RegisterFlagCompletionFunc(filterFlagName, common.AutocompletePsFilters)
+
if !registry.IsRemote() {
// This option is deprecated, but needs to still exists for backwards compatibility
flags.Bool("storage", false, "Remove container from storage library")
@@ -101,7 +107,7 @@ func rm(cmd *cobra.Command, args []string) error {
}
rmOptions.Timeout = &stopTimeout
}
- for _, cidFile := range cidFiles {
+ for _, cidFile := range rmCidFiles {
content, err := ioutil.ReadFile(cidFile)
if err != nil {
return fmt.Errorf("error reading CIDFile: %w", err)
@@ -110,6 +116,14 @@ func rm(cmd *cobra.Command, args []string) error {
args = append(args, id)
}
+ for _, f := range filters {
+ split := strings.SplitN(f, "=", 2)
+ if len(split) < 2 {
+ return fmt.Errorf("invalid filter %q", f)
+ }
+ rmOptions.Filters[split[0]] = append(rmOptions.Filters[split[0]], split[1])
+ }
+
if rmOptions.All {
logrus.Debug("--all is set: enforcing --depend=true")
rmOptions.Depend = true
@@ -147,7 +161,7 @@ func removeContainers(namesOrIDs []string, rmOptions entities.RmOptions, setExit
}
errs = append(errs, r.Err)
} else {
- fmt.Println(r.Id)
+ fmt.Println(r.RawInput)
}
}
return errs.PrintErrors()
diff --git a/cmd/podman/containers/stop.go b/cmd/podman/containers/stop.go
index 261f441c3..b0f449266 100644
--- a/cmd/podman/containers/stop.go
+++ b/cmd/podman/containers/stop.go
@@ -52,7 +52,8 @@ var (
stopOptions = entities.StopOptions{
Filters: make(map[string][]string),
}
- stopTimeout uint
+ stopCidFiles = []string{}
+ stopTimeout uint
)
func stopFlags(cmd *cobra.Command) {
@@ -62,7 +63,7 @@ func stopFlags(cmd *cobra.Command) {
flags.BoolVarP(&stopOptions.Ignore, "ignore", "i", false, "Ignore errors when a specified container is missing")
cidfileFlagName := "cidfile"
- flags.StringArrayVar(&cidFiles, cidfileFlagName, nil, "Read the container ID from the file")
+ flags.StringArrayVar(&stopCidFiles, cidfileFlagName, nil, "Read the container ID from the file")
_ = cmd.RegisterFlagCompletionFunc(cidfileFlagName, completion.AutocompleteDefault)
timeFlagName := "time"
@@ -103,7 +104,7 @@ func stop(cmd *cobra.Command, args []string) error {
if cmd.Flag("time").Changed {
stopOptions.Timeout = &stopTimeout
}
- for _, cidFile := range cidFiles {
+ for _, cidFile := range stopCidFiles {
content, err := ioutil.ReadFile(cidFile)
if err != nil {
return fmt.Errorf("error reading CIDFile: %w", err)
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index c3b7811bc..f84f78ee9 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -277,7 +277,7 @@ case "$TEST_FLAVOR" in
;& # continue with next item
compose)
make install.tools
- rpm -ivh $PACKAGE_DOWNLOAD_DIR/podman-docker*
+ dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-docker*
;& # continue with next item
int) ;&
sys) ;&
@@ -307,7 +307,7 @@ case "$TEST_FLAVOR" in
install_test_configs
;;
machine)
- rpm -ivh $PACKAGE_DOWNLOAD_DIR/podman-gvproxy*
+ dnf install -y $PACKAGE_DOWNLOAD_DIR/podman-gvproxy*
remove_packaged_podman_files
make install.tools
make install PREFIX=/usr ETCDIR=/etc
diff --git a/contrib/pkginstaller/Makefile b/contrib/pkginstaller/Makefile
index 19c9b51aa..c84a08482 100644
--- a/contrib/pkginstaller/Makefile
+++ b/contrib/pkginstaller/Makefile
@@ -9,14 +9,15 @@ QEMU_RELEASE_URL ?= https://github.com/containers/podman-machine-qemu/releases/d
PACKAGE_DIR ?= out/packaging
TMP_DOWNLOAD ?= tmp-download
PACKAGE_ROOT ?= root
+PKG_NAME := podman-installer-macos-$(ARCH).pkg
default: pkginstaller
-get_gvproxy:
+$(TMP_DOWNLOAD)/gvproxy:
mkdir -p $(TMP_DOWNLOAD)
cd $(TMP_DOWNLOAD) && curl -sLo gvproxy $(GVPROXY_RELEASE_URL)
-get_qemu:
+$(TMP_DOWNLOAD)/podman-machine-qemu-$(ARCH)-$(QEMU_VERSION).tar.xz:
mkdir -p $(TMP_DOWNLOAD)
cd $(TMP_DOWNLOAD) && curl -sLO $(QEMU_RELEASE_URL)
@@ -32,8 +33,9 @@ packagedir: package_root Distribution welcome.html
echo -n $(PODMAN_VERSION) > $(PACKAGE_DIR)/VERSION
echo -n $(ARCH) > $(PACKAGE_DIR)/ARCH
cp ../../LICENSE $(PACKAGE_DIR)/Resources/LICENSE.txt
+ cp hvf.entitlements $(PACKAGE_DIR)/
-package_root: get_gvproxy get_qemu
+package_root: clean-pkgroot $(TMP_DOWNLOAD)/podman-machine-qemu-$(ARCH)-$(QEMU_VERSION).tar.xz $(TMP_DOWNLOAD)/gvproxy
mkdir -p $(PACKAGE_ROOT)/podman/bin $(PACKAGE_ROOT)/podman/qemu
tar -C $(PACKAGE_ROOT)/podman/qemu -xf $(TMP_DOWNLOAD)/podman-machine-qemu-$(ARCH)-$(QEMU_VERSION).tar.xz
cp $(TMP_DOWNLOAD)/gvproxy $(PACKAGE_ROOT)/podman/bin/
@@ -45,6 +47,15 @@ package_root: get_gvproxy get_qemu
pkginstaller: packagedir
cd $(PACKAGE_DIR) && ./package.sh ..
-.PHONY: clean
+_notarize: pkginstaller
+ xcrun notarytool submit --apple-id $(NOTARIZE_USERNAME) --password $(NOTARIZE_PASSWORD) --team-id=$(NOTARIZE_TEAM) -f json --wait out/$(PKG_NAME)
+
+notarize: _notarize
+ xcrun stapler staple out/$(PKG_NAME)
+
+.PHONY: clean clean-pkgroot
clean:
rm -rf $(TMP_DOWNLOAD) $(PACKAGE_ROOT) $(PACKAGE_DIR) Distribution welcome.html
+
+clean-pkgroot:
+ rm -rf $(PACKAGE_ROOT) $(PACKAGE_DIR) Distribution welcome.html
diff --git a/contrib/pkginstaller/README.md b/contrib/pkginstaller/README.md
index 37c59ce04..1951d4eab 100644
--- a/contrib/pkginstaller/README.md
+++ b/contrib/pkginstaller/README.md
@@ -5,6 +5,9 @@ $ make ARCH=<amd64 | aarch64> NO_CODESIGN=1 pkginstaller
# or to create signed pkg
$ make ARCH=<amd64 | aarch64> CODESIGN_IDENTITY=<ID> PRODUCTSIGN_IDENTITY=<ID> pkginstaller
+
+# or to prepare a signed and notarized pkg for release
+$ make ARCH=<amd64 | aarch64> CODESIGN_IDENTITY=<ID> PRODUCTSIGN_IDENTITY=<ID> NOTARIZE_USERNAME=<appleID> NOTARIZE_PASSWORD=<appleID-password> NOTARIZE_TEAM=<team-id> notarize
```
The generated pkg will be written to `out/podman-macos-installer-*.pkg`.
diff --git a/contrib/pkginstaller/hvf.entitlements b/contrib/pkginstaller/hvf.entitlements
new file mode 100644
index 000000000..154f3308e
--- /dev/null
+++ b/contrib/pkginstaller/hvf.entitlements
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.security.hypervisor</key>
+ <true/>
+</dict>
+</plist>
diff --git a/contrib/pkginstaller/package.sh b/contrib/pkginstaller/package.sh
index b7b33954d..ca8d54f7f 100755
--- a/contrib/pkginstaller/package.sh
+++ b/contrib/pkginstaller/package.sh
@@ -10,6 +10,10 @@ NO_CODESIGN=${NO_CODESIGN:-0}
HELPER_BINARIES_DIR="/opt/podman/qemu/bin"
binDir="${BASEDIR}/root/podman/bin"
+qemuBinDir="${BASEDIR}/root/podman/qemu/bin"
+
+version=$(cat "${BASEDIR}/VERSION")
+arch=$(cat "${BASEDIR}/ARCH")
function build_podman() {
pushd "$1"
@@ -29,16 +33,40 @@ function sign() {
if [ -f "${entitlements}" ]; then
opts="--entitlements ${entitlements}"
fi
- codesign --deep --sign "${CODESIGN_IDENTITY}" --options runtime --force --timestamp "${opts}" "$1"
+ codesign --deep --sign "${CODESIGN_IDENTITY}" --options runtime --timestamp --force ${opts} "$1"
}
-version=$(cat "${BASEDIR}/VERSION")
-arch=$(cat "${BASEDIR}/ARCH")
+function signQemu() {
+ if [ "${NO_CODESIGN}" -eq "1" ]; then
+ return
+ fi
+
+ local qemuArch="${arch}"
+ if [ "${qemuArch}" = amd64 ]; then
+ qemuArch=x86_64
+ fi
+
+ # sign the files inside /opt/podman/qemu/lib
+ libs=$(find "${BASEDIR}"/root/podman/qemu/lib -depth -name "*.dylib" -or -type f -perm +111)
+ echo "${libs}" | xargs -t -I % codesign --deep --sign "${CODESIGN_IDENTITY}" --options runtime --timestamp --force % || true
+
+ # sign the files inside /opt/podman/qemu/bin except qemu-system-*
+ bins=$(find "${BASEDIR}"/root/podman/qemu/bin -depth -type f -perm +111 ! -name "qemu-system-${qemuArch}")
+ echo "${bins}" | xargs -t -I % codesign --deep --sign "${CODESIGN_IDENTITY}" --options runtime --timestamp --force % || true
+
+ # sign the qemu-system-* binary
+ # need to remove any extended attributes, otherwise codesign complains:
+ # qemu-system-aarch64: resource fork, Finder information, or similar detritus not allowed
+ xattr -cr "${qemuBinDir}/qemu-system-${qemuArch}"
+ codesign --deep --sign "${CODESIGN_IDENTITY}" --options runtime --timestamp --force \
+ --entitlements "${BASEDIR}/hvf.entitlements" "${qemuBinDir}/qemu-system-${qemuArch}"
+}
build_podman "../../../../"
sign "${binDir}/podman"
sign "${binDir}/gvproxy"
sign "${binDir}/podman-mac-helper"
+signQemu
pkgbuild --identifier com.redhat.podman --version "${version}" \
--scripts "${BASEDIR}/scripts" \
diff --git a/docs/source/markdown/podman-rm.1.md b/docs/source/markdown/podman-rm.1.md
index 1fac3aa34..1dbd1d0c3 100644
--- a/docs/source/markdown/podman-rm.1.md
+++ b/docs/source/markdown/podman-rm.1.md
@@ -26,6 +26,30 @@ Read container ID from the specified file and remove the container. Can be spec
Remove selected container and recursively remove all containers that depend on it.
+#### **--filter**=*filter*
+
+Filter what containers remove.
+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 |
+
#### **--force**, **-f**
Force the removal of running and paused containers. Forcing a container removal also
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index ce0fd869d..703ae5cbe 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -995,7 +995,7 @@ func (r *Runtime) RemoveDepend(ctx context.Context, rmCtr *Container, force bool
return nil, err
}
for _, cID := range podContainerIDS {
- rmReports = append(rmReports, &reports.RmReport{Id: cID})
+ rmReports = append(rmReports, &reports.RmReport{Id: cID, RawInput: cID})
}
return rmReports, nil
}
@@ -1023,7 +1023,7 @@ func (r *Runtime) RemoveDepend(ctx context.Context, rmCtr *Container, force bool
rmReports = append(rmReports, reports...)
}
- report := reports.RmReport{Id: rmCtr.ID()}
+ report := reports.RmReport{Id: rmCtr.ID(), RawInput: rmCtr.ID()}
report.Err = r.removeContainer(ctx, rmCtr, force, removeVolume, false, timeout)
return append(rmReports, &report), nil
}
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index df793034b..7048cd1d2 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -131,6 +131,7 @@ type RestartReport struct {
}
type RmOptions struct {
+ Filters map[string][]string
All bool
Depend bool
Force bool
diff --git a/pkg/domain/entities/reports/containers.go b/pkg/domain/entities/reports/containers.go
index db9a66012..6759fc402 100644
--- a/pkg/domain/entities/reports/containers.go
+++ b/pkg/domain/entities/reports/containers.go
@@ -1,8 +1,9 @@
package reports
type RmReport struct {
- Id string `json:"Id"` //nolint:revive,stylecheck
- Err error `json:"Err,omitempty"`
+ Id string `json:"Id"` //nolint:revive,stylecheck
+ Err error `json:"Err,omitempty"`
+ RawInput string
}
func RmReportsIds(r []*RmReport) []string {
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 783224e9c..ed149a869 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -142,10 +142,10 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
if len(rawInputs) == len(ctrs) {
for i := range ctrs {
- ctrMap[ctrs[i].ID()] = rawInputs[i]
+ idToRawInput[ctrs[i].ID()] = rawInputs[i]
}
}
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
@@ -158,7 +158,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
reports = append(reports, &entities.PauseUnpauseReport{
Id: c.ID(),
Err: err,
- RawInput: ctrMap[c.ID()],
+ RawInput: idToRawInput[c.ID()],
})
}
return reports, nil
@@ -169,10 +169,10 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
if len(rawInputs) == len(ctrs) {
for i := range ctrs {
- ctrMap[ctrs[i].ID()] = rawInputs[i]
+ idToRawInput[ctrs[i].ID()] = rawInputs[i]
}
}
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
@@ -185,7 +185,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
reports = append(reports, &entities.PauseUnpauseReport{
Id: c.ID(),
Err: err,
- RawInput: ctrMap[c.ID()],
+ RawInput: idToRawInput[c.ID()],
})
}
return reports, nil
@@ -196,10 +196,10 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
if len(rawInputs) == len(ctrs) {
for i := range ctrs {
- ctrMap[ctrs[i].ID()] = rawInputs[i]
+ idToRawInput[ctrs[i].ID()] = rawInputs[i]
}
}
errMap, err := parallelctr.ContainerOp(ctx, ctrs, func(c *libpod.Container) error {
@@ -245,7 +245,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
if options.All {
report.RawInput = ctr.ID()
} else {
- report.RawInput = ctrMap[ctr.ID()]
+ report.RawInput = idToRawInput[ctr.ID()]
}
report.Err = err
reports = append(reports, report)
@@ -275,10 +275,10 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
if len(rawInputs) == len(ctrs) {
for i := range ctrs {
- ctrMap[ctrs[i].ID()] = rawInputs[i]
+ idToRawInput[ctrs[i].ID()] = rawInputs[i]
}
}
reports := make([]*entities.KillReport, 0, len(ctrs))
@@ -291,7 +291,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
reports = append(reports, &entities.KillReport{
Id: con.ID(),
Err: err,
- RawInput: ctrMap[con.ID()],
+ RawInput: idToRawInput[con.ID()],
})
}
return reports, nil
@@ -360,7 +360,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
// this will fail and code will fall through to removing the container from libpod.`
tmpNames := []string{}
for _, ctr := range names {
- report := reports.RmReport{Id: ctr}
+ report := reports.RmReport{Id: ctr, RawInput: ctr}
report.Err = ic.Libpod.RemoveStorageContainer(ctr, options.Force)
//nolint:gocritic
if report.Err == nil {
@@ -381,7 +381,16 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
}
names = tmpNames
- ctrs, err := getContainersByContext(options.All, options.Latest, names, ic.Libpod)
+ ctrs, rawInputs, err := getContainersAndInputByContext(options.All, options.Latest, names, options.Filters, ic.Libpod)
+ if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
+ return nil, err
+ }
+ idToRawInput := map[string]string{}
+ if len(rawInputs) == len(ctrs) {
+ for i := range ctrs {
+ idToRawInput[ctrs[i].ID()] = rawInputs[i]
+ }
+ }
if err != nil && !(options.Ignore && errors.Is(err, define.ErrNoSuchCtr)) {
// Failed to get containers. If force is specified, get the containers ID
// and evict them
@@ -391,7 +400,10 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
for _, ctr := range names {
logrus.Debugf("Evicting container %q", ctr)
- report := reports.RmReport{Id: ctr}
+ report := reports.RmReport{
+ Id: ctr,
+ RawInput: idToRawInput[ctr],
+ }
_, err := ic.Libpod.EvictContainer(ctx, ctr, options.Volumes)
if err != nil {
if options.Ignore && errors.Is(err, define.ErrNoSuchCtr) {
@@ -461,6 +473,7 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
report := new(reports.RmReport)
report.Id = ctr.ID()
report.Err = err
+ report.RawInput = idToRawInput[ctr.ID()]
rmReports = append(rmReports, report)
}
return rmReports, nil
diff --git a/pkg/domain/infra/tunnel/containers.go b/pkg/domain/infra/tunnel/containers.go
index 98c73c51a..225aee017 100644
--- a/pkg/domain/infra/tunnel/containers.go
+++ b/pkg/domain/infra/tunnel/containers.go
@@ -61,9 +61,9 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
for i := range ctrs {
- ctrMap[ctrs[i].ID] = rawInputs[i]
+ idToRawInput[ctrs[i].ID] = rawInputs[i]
}
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs {
@@ -75,7 +75,7 @@ func (ic *ContainerEngine) ContainerPause(ctx context.Context, namesOrIds []stri
reports = append(reports, &entities.PauseUnpauseReport{
Id: c.ID,
Err: err,
- RawInput: ctrMap[c.ID],
+ RawInput: idToRawInput[c.ID],
})
}
return reports, nil
@@ -86,9 +86,9 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
for i := range ctrs {
- ctrMap[ctrs[i].ID] = rawInputs[i]
+ idToRawInput[ctrs[i].ID] = rawInputs[i]
}
reports := make([]*entities.PauseUnpauseReport, 0, len(ctrs))
for _, c := range ctrs {
@@ -100,7 +100,7 @@ func (ic *ContainerEngine) ContainerUnpause(ctx context.Context, namesOrIds []st
reports = append(reports, &entities.PauseUnpauseReport{
Id: c.ID,
Err: err,
- RawInput: ctrMap[c.ID],
+ RawInput: idToRawInput[c.ID],
})
}
return reports, nil
@@ -111,9 +111,9 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
for i := range ctrs {
- ctrMap[ctrs[i].ID] = rawInputs[i]
+ idToRawInput[ctrs[i].ID] = rawInputs[i]
}
options := new(containers.StopOptions).WithIgnore(opts.Ignore)
if to := opts.Timeout; to != nil {
@@ -123,7 +123,7 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
for _, c := range ctrs {
report := entities.StopReport{
Id: c.ID,
- RawInput: ctrMap[c.ID],
+ RawInput: idToRawInput[c.ID],
}
if err = containers.Stop(ic.ClientCtx, c.ID, options); err != nil {
// These first two are considered non-fatal under the right conditions
@@ -154,9 +154,9 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
if err != nil {
return nil, err
}
- ctrMap := map[string]string{}
+ idToRawInput := map[string]string{}
for i := range ctrs {
- ctrMap[ctrs[i].ID] = rawInputs[i]
+ idToRawInput[ctrs[i].ID] = rawInputs[i]
}
options := new(containers.KillOptions).WithSignal(opts.Signal)
reports := make([]*entities.KillReport, 0, len(ctrs))
@@ -169,7 +169,7 @@ func (ic *ContainerEngine) ContainerKill(ctx context.Context, namesOrIds []strin
reports = append(reports, &entities.KillReport{
Id: c.ID,
Err: err,
- RawInput: ctrMap[c.ID],
+ RawInput: idToRawInput[c.ID],
})
}
return reports, nil
@@ -208,11 +208,18 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
toRemove := []string{}
alreadyRemoved := make(map[string]bool) // Avoids trying to remove already removed containers
- if opts.All {
- ctrs, err := getContainersByContext(ic.ClientCtx, opts.All, opts.Ignore, nil)
+ idToRawInput := map[string]string{}
+
+ if opts.All || len(opts.Filters) > 0 {
+ ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, opts.All, opts.Ignore, nil, opts.Filters)
if err != nil {
return nil, err
}
+ if len(rawInputs) == len(ctrs) {
+ for i := range ctrs {
+ idToRawInput[ctrs[i].ID] = rawInputs[i]
+ }
+ }
for _, c := range ctrs {
toRemove = append(toRemove, c.ID)
}
@@ -225,10 +232,15 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
// instead of the ID. Since this can only happen
// with external containers, it poses no threat
// to the `alreadyRemoved` checks below.
- ctrs, err := getContainersByContext(ic.ClientCtx, false, true, []string{ctr})
+ ctrs, rawInputs, err := getContainersAndInputByContext(ic.ClientCtx, false, true, []string{ctr}, opts.Filters)
if err != nil {
return nil, err
}
+ if len(rawInputs) == len(ctrs) {
+ for i := range ctrs {
+ idToRawInput[ctrs[i].ID] = rawInputs[i]
+ }
+ }
id := ctr
if len(ctrs) == 1 {
id = ctrs[0].ID
@@ -238,13 +250,20 @@ func (ic *ContainerEngine) ContainerRm(ctx context.Context, namesOrIds []string,
}
rmReports := make([]*reports.RmReport, 0, len(toRemove))
- for _, nameOrID := range toRemove {
- if alreadyRemoved[nameOrID] {
+ for _, rmCtr := range toRemove {
+ if alreadyRemoved[rmCtr] {
continue
}
- newReports, err := containers.Remove(ic.ClientCtx, nameOrID, options)
+ if ctr, exist := idToRawInput[rmCtr]; exist {
+ rmCtr = ctr
+ }
+ newReports, err := containers.Remove(ic.ClientCtx, rmCtr, options)
if err != nil {
- rmReports = append(rmReports, &reports.RmReport{Id: nameOrID, Err: err})
+ rmReports = append(rmReports, &reports.RmReport{
+ Id: rmCtr,
+ Err: err,
+ RawInput: idToRawInput[rmCtr],
+ })
continue
}
for i := range newReports {
diff --git a/pkg/domain/infra/tunnel/helpers.go b/pkg/domain/infra/tunnel/helpers.go
index 9ff1641f0..a0b01dd71 100644
--- a/pkg/domain/infra/tunnel/helpers.go
+++ b/pkg/domain/infra/tunnel/helpers.go
@@ -14,7 +14,7 @@ import (
// FIXME: the `ignore` parameter is very likely wrong here as it should rather
// be used on *errors* from operations such as remove.
-func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) {
+func getContainersByContext(contextWithConnection context.Context, all, ignore bool, namesOrIDs []string) ([]entities.ListContainer, error) { //nolint:unparam
ctrs, _, err := getContainersAndInputByContext(contextWithConnection, all, ignore, namesOrIDs, nil)
return ctrs, err
}
diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go
index 994a5899b..b0452deda 100644
--- a/test/e2e/mount_rootless_test.go
+++ b/test/e2e/mount_rootless_test.go
@@ -52,9 +52,16 @@ var _ = Describe("Podman mount", func() {
Expect(setup).Should(Exit(0))
cid := setup.OutputToString()
- session := podmanTest.Podman([]string{"unshare", PODMAN_BINARY, "mount", cid})
+ // command: podman <options> unshare podman <options> mount cid
+ args := []string{"unshare", podmanTest.PodmanBinary}
+ opts := podmanTest.PodmanMakeOptions([]string{"mount", cid}, false, false)
+ args = append(args, opts...)
+
+ // container root file system location is /tmp/... because "--root /tmp/..."
+ session := podmanTest.Podman(args)
session.WaitWithDefaultTimeout()
- Expect(setup).Should(Exit(0))
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("/tmp"))
})
It("podman image mount", func() {
@@ -71,8 +78,15 @@ var _ = Describe("Podman mount", func() {
setup.WaitWithDefaultTimeout()
Expect(setup).Should(Exit(0))
- session := podmanTest.Podman([]string{"unshare", PODMAN_BINARY, "image", "mount", ALPINE})
+ // command: podman <options> unshare podman <options> image mount ALPINE
+ args := []string{"unshare", podmanTest.PodmanBinary}
+ opts := podmanTest.PodmanMakeOptions([]string{"image", "mount", ALPINE}, false, false)
+ args = append(args, opts...)
+
+ // image location is /tmp/... because "--root /tmp/..."
+ session := podmanTest.Podman(args)
session.WaitWithDefaultTimeout()
- Expect(setup).Should(Exit(0))
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(ContainSubstring("/tmp"))
})
})
diff --git a/test/e2e/rm_test.go b/test/e2e/rm_test.go
index 7dbe5fed8..e76451824 100644
--- a/test/e2e/rm_test.go
+++ b/test/e2e/rm_test.go
@@ -1,6 +1,7 @@
package integration
import (
+ "fmt"
"io/ioutil"
"os"
@@ -51,6 +52,7 @@ var _ = Describe("Podman rm", func() {
result := podmanTest.Podman([]string{"rm", cid})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(2))
+ Expect(result.ErrorToString()).To(ContainSubstring("containers cannot be removed without force"))
})
It("podman rm created container", func() {
@@ -140,11 +142,9 @@ var _ = Describe("Podman rm", func() {
output := result.OutputToString()
Expect(output).To(ContainSubstring(cid))
Expect(podmanTest.NumberOfContainers()).To(Equal(1))
-
})
It("podman rm --cidfile", func() {
-
tmpDir, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())
tmpFile := tmpDir + "cid"
@@ -166,7 +166,6 @@ var _ = Describe("Podman rm", func() {
})
It("podman rm multiple --cidfile", func() {
-
tmpDir, err := ioutil.TempDir("", "")
Expect(err).To(BeNil())
tmpFile1 := tmpDir + "cid-1"
@@ -201,18 +200,22 @@ var _ = Describe("Podman rm", func() {
result := podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--latest"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("--all, --latest, and --cidfile cannot be used together"))
result = podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--all"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("--all, --latest, and --cidfile cannot be used together"))
result = podmanTest.Podman([]string{"rm", "--cidfile", "foobar", "--all", "--latest"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("--all, --latest, and --cidfile cannot be used together"))
result = podmanTest.Podman([]string{"rm", "--latest", "--all"})
result.WaitWithDefaultTimeout()
Expect(result).Should(Exit(125))
+ Expect(result.ErrorToString()).To(ContainSubstring("--all and --latest cannot be used together"))
})
It("podman rm --all", func() {
@@ -242,10 +245,17 @@ var _ = Describe("Podman rm", func() {
session = podmanTest.Podman([]string{"rm", "bogus", cid})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(1))
+ Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
+ if IsRemote() {
+ Expect(session.OutputToString()).To(BeEquivalentTo(cid))
+ }
session = podmanTest.Podman([]string{"rm", "--ignore", "bogus", cid})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
+ if !IsRemote() {
+ Expect(session.OutputToString()).To(BeEquivalentTo(cid))
+ }
Expect(podmanTest.NumberOfContainers()).To(Equal(0))
})
@@ -253,6 +263,7 @@ var _ = Describe("Podman rm", func() {
session := podmanTest.Podman([]string{"rm", "bogus"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(1))
+ Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
})
It("podman rm bogus container and a running container", func() {
@@ -263,10 +274,12 @@ var _ = Describe("Podman rm", func() {
session = podmanTest.Podman([]string{"rm", "bogus", "test1"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(1))
+ Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
session = podmanTest.Podman([]string{"rm", "test1", "bogus"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(1))
+ Expect(session.ErrorToString()).To(ContainSubstring("\"bogus\" found: no such container"))
})
It("podman rm --ignore bogus container and a running container", func() {
@@ -274,12 +287,52 @@ var _ = Describe("Podman rm", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
- session = podmanTest.Podman([]string{"rm", "-t", "0", "--force", "--ignore", "bogus", "test1"})
+ session = podmanTest.Podman([]string{"rm", "--ignore", "test1", "bogus"})
session.WaitWithDefaultTimeout()
- Expect(session).Should(Exit(0))
+ Expect(session).Should(Exit(2))
+ Expect(session.ErrorToString()).To(ContainSubstring("containers cannot be removed without force"))
- session = podmanTest.Podman([]string{"rm", "--ignore", "test1", "bogus"})
+ session = podmanTest.Podman([]string{"rm", "-t", "0", "--force", "--ignore", "bogus", "test1"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).To(BeEquivalentTo("test1"))
+ })
+
+ It("podman rm --filter", func() {
+ session1 := podmanTest.RunTopContainer("test1")
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid1 := session1.OutputToString()
+
+ session1 = podmanTest.RunTopContainer("test2")
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid2 := session1.OutputToString()
+
+ session1 = podmanTest.RunTopContainer("test3")
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ cid3 := session1.OutputToString()
+ shortCid3 := cid3[0:5]
+
+ session1 = podmanTest.Podman([]string{"rm", cid1, "-f", "--filter", "status=running"})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(125))
+ Expect(session1.ErrorToString()).To(ContainSubstring("--filter takes no arguments"))
+
+ session1 = podmanTest.Podman([]string{"rm", "-a", "-f", "--filter", fmt.Sprintf("id=%swrongid", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(HaveLen(0))
+
+ session1 = podmanTest.Podman([]string{"rm", "-a", "-f", "--filter", fmt.Sprintf("id=%s", shortCid3)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid3))
+
+ session1 = podmanTest.Podman([]string{"rm", "-f", "--filter", fmt.Sprintf("id=%s", cid2)})
+ session1.WaitWithDefaultTimeout()
+ Expect(session1).Should(Exit(0))
+ Expect(session1.OutputToString()).To(BeEquivalentTo(cid2))
})
})
diff --git a/test/system/055-rm.bats b/test/system/055-rm.bats
index dcd679a1f..613c60c96 100644
--- a/test/system/055-rm.bats
+++ b/test/system/055-rm.bats
@@ -18,6 +18,7 @@ load helpers
# Remove container; now 'inspect' should fail
run_podman rm $rand
+ is "$output" "$rand" "display raw input"
run_podman 125 inspect $rand
}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index cbbd62ffb..b1b9ee5e1 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -482,6 +482,7 @@ spec:
skip_if_remote "resource limits only implemented on non-remote"
skip_if_rootless "resource limits only work with root"
skip_if_cgroupsv1 "resource limits only meaningful on cgroups V2"
+ skip_if_aarch64 "FIXME: #15074 - flakes often on aarch64"
# create loopback device
lofile=${PODMAN_TMPDIR}/disk.img
diff --git a/test/upgrade/test-upgrade.bats b/test/upgrade/test-upgrade.bats
index 5efe05d49..dca97e324 100644
--- a/test/upgrade/test-upgrade.bats
+++ b/test/upgrade/test-upgrade.bats
@@ -345,10 +345,10 @@ failed | exited | 17
@test "rm a stopped container" {
run_podman rm myfailedcontainer
- is "$output" "[0-9a-f]\\{64\\}" "podman rm myfailedcontainer"
+ is "$output" "myfailedcontainer" "podman rm myfailedcontainer"
run_podman rm mydonecontainer
- is "$output" "[0-9a-f]\\{64\\}" "podman rm mydonecontainer"
+ is "$output" "mydonecontainer" "podman rm mydonecontainer"
}