summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml2
-rw-r--r--contrib/pkginstaller/.gitignore6
-rw-r--r--contrib/pkginstaller/Distribution.in17
-rw-r--r--contrib/pkginstaller/Makefile50
-rw-r--r--contrib/pkginstaller/README.md22
-rw-r--r--contrib/pkginstaller/Resources/banner.pngbin0 -> 50381 bytes
-rw-r--r--contrib/pkginstaller/Resources/conclusion.html13
-rwxr-xr-xcontrib/pkginstaller/package.sh60
-rwxr-xr-xcontrib/pkginstaller/scripts/postinstall27
-rwxr-xr-xcontrib/pkginstaller/scripts/preinstall5
-rw-r--r--contrib/pkginstaller/welcome.html.in16
-rw-r--r--docs/tutorials/socket_activation.md23
-rw-r--r--pkg/domain/filters/containers.go9
-rw-r--r--pkg/domain/filters/pods.go3
-rw-r--r--pkg/domain/filters/volumes.go5
-rw-r--r--pkg/domain/infra/abi/containers.go1
-rw-r--r--pkg/util/filters.go33
-rw-r--r--pkg/util/filters_test.go4
-rw-r--r--test/e2e/prune_test.go18
19 files changed, 270 insertions, 44 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index c629bcf70..7a488216e 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -843,7 +843,7 @@ meta_task:
container:
cpu: 2
memory: 2
- image: quay.io/libpod/imgts:$IMAGE_SUFFIX
+ image: quay.io/libpod/imgts:latest
env:
# Space-separated list of images used by this repository state
# Disabled ${PRIOR_FEDORA_CACHE_IMAGE_NAME} for Fedora 35
diff --git a/contrib/pkginstaller/.gitignore b/contrib/pkginstaller/.gitignore
new file mode 100644
index 000000000..5e597ab07
--- /dev/null
+++ b/contrib/pkginstaller/.gitignore
@@ -0,0 +1,6 @@
+out
+Distribution
+welcome.html
+tmp-download
+.vscode
+root
diff --git a/contrib/pkginstaller/Distribution.in b/contrib/pkginstaller/Distribution.in
new file mode 100644
index 000000000..0e0d3843a
--- /dev/null
+++ b/contrib/pkginstaller/Distribution.in
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<installer-script minSpecVersion="1.000000">
+ <title>Podman __VERSION__</title>
+ <background mime-type="image/png" file="banner.png" scaling="proportional"/>
+ <welcome file="welcome.html" mime-type="text/html" />
+ <conclusion file="conclusion.html" mime-type="text/html" />
+ <license file="LICENSE.txt"/>
+ <options customize="never" hostArchitectures="x86_64,arm64" />
+ <domains enable_localSystem="true" />
+ <choices-outline>
+ <line choice="podman"/>
+ </choices-outline>
+ <choice id="podman" title="podman">
+ <pkg-ref id="podman.pkg"/>
+ </choice>
+ <pkg-ref id="podman.pkg">podman.pkg</pkg-ref>
+</installer-script>
diff --git a/contrib/pkginstaller/Makefile b/contrib/pkginstaller/Makefile
new file mode 100644
index 000000000..19c9b51aa
--- /dev/null
+++ b/contrib/pkginstaller/Makefile
@@ -0,0 +1,50 @@
+SHELL := bash
+
+ARCH ?= aarch64
+PODMAN_VERSION ?= 4.1.0
+GVPROXY_VERSION ?= 0.4.0
+QEMU_VERSION ?= 7.0.0-2
+GVPROXY_RELEASE_URL ?= https://github.com/containers/gvisor-tap-vsock/releases/download/v$(GVPROXY_VERSION)/gvproxy-darwin
+QEMU_RELEASE_URL ?= https://github.com/containers/podman-machine-qemu/releases/download/v$(QEMU_VERSION)/podman-machine-qemu-$(ARCH)-$(QEMU_VERSION).tar.xz
+PACKAGE_DIR ?= out/packaging
+TMP_DOWNLOAD ?= tmp-download
+PACKAGE_ROOT ?= root
+
+default: pkginstaller
+
+get_gvproxy:
+ mkdir -p $(TMP_DOWNLOAD)
+ cd $(TMP_DOWNLOAD) && curl -sLo gvproxy $(GVPROXY_RELEASE_URL)
+
+get_qemu:
+ mkdir -p $(TMP_DOWNLOAD)
+ cd $(TMP_DOWNLOAD) && curl -sLO $(QEMU_RELEASE_URL)
+
+packagedir: package_root Distribution welcome.html
+ mkdir -p $(PACKAGE_DIR)
+ cp -r Resources $(PACKAGE_DIR)/
+ cp welcome.html $(PACKAGE_DIR)/Resources/
+ cp Distribution $(PACKAGE_DIR)/
+ cp -r scripts $(PACKAGE_DIR)/
+ cp -r $(PACKAGE_ROOT) $(PACKAGE_DIR)/
+ cp package.sh $(PACKAGE_DIR)/
+ cd $(PACKAGE_DIR) && pkgbuild --analyze --root ./root component.plist
+ echo -n $(PODMAN_VERSION) > $(PACKAGE_DIR)/VERSION
+ echo -n $(ARCH) > $(PACKAGE_DIR)/ARCH
+ cp ../../LICENSE $(PACKAGE_DIR)/Resources/LICENSE.txt
+
+package_root: get_gvproxy get_qemu
+ 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/
+ chmod a+x $(PACKAGE_ROOT)/podman/bin/*
+
+%: %.in
+ @sed -e 's/__VERSION__/'$(PODMAN_VERSION)'/g' $< >$@
+
+pkginstaller: packagedir
+ cd $(PACKAGE_DIR) && ./package.sh ..
+
+.PHONY: clean
+clean:
+ rm -rf $(TMP_DOWNLOAD) $(PACKAGE_ROOT) $(PACKAGE_DIR) Distribution welcome.html
diff --git a/contrib/pkginstaller/README.md b/contrib/pkginstaller/README.md
new file mode 100644
index 000000000..37c59ce04
--- /dev/null
+++ b/contrib/pkginstaller/README.md
@@ -0,0 +1,22 @@
+## How to build
+
+```sh
+$ make ARCH=<amd64 | aarch64> NO_CODESIGN=1 pkginstaller
+
+# or to create signed pkg
+$ make ARCH=<amd64 | aarch64> CODESIGN_IDENTITY=<ID> PRODUCTSIGN_IDENTITY=<ID> pkginstaller
+```
+
+The generated pkg will be written to `out/podman-macos-installer-*.pkg`.
+Currently the pkg installs `podman`, `qemu`, `gvproxy` and `podman-mac-helper` to `/Applications/podman`
+
+The `qemu` build it uses is from [containers/podman-machine-qemu](https://github.com/containers/podman-machine-qemu)
+
+## Uninstalling
+
+```sh
+$ sudo rm -rf /opt/podman
+```
+
+### Screenshot
+<img width="626" alt="screenshot-macOS-pkg-podman" src="https://user-images.githubusercontent.com/8885742/157380992-2e3b1573-34a0-4aa0-bdc1-a85f4792a1d2.png">
diff --git a/contrib/pkginstaller/Resources/banner.png b/contrib/pkginstaller/Resources/banner.png
new file mode 100644
index 000000000..7db751341
--- /dev/null
+++ b/contrib/pkginstaller/Resources/banner.png
Binary files differ
diff --git a/contrib/pkginstaller/Resources/conclusion.html b/contrib/pkginstaller/Resources/conclusion.html
new file mode 100644
index 000000000..c442e4ebf
--- /dev/null
+++ b/contrib/pkginstaller/Resources/conclusion.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8"/>
+</head>
+<body>
+<div align="left" style="font-family: Helvetica; padding-left: 10px;">
+ <br/>
+ <p style="color: #020202; font-size: 12px;">Thanks for installing Podman!</p>
+ <p style="color: #020202; font-size: 12px;">You can now start using the 'podman' command. First run 'podman machine init'</b>.</p>
+</div>
+</body>
+</html>
diff --git a/contrib/pkginstaller/package.sh b/contrib/pkginstaller/package.sh
new file mode 100755
index 000000000..b7b33954d
--- /dev/null
+++ b/contrib/pkginstaller/package.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+set -euxo pipefail
+
+BASEDIR=$(dirname "$0")
+OUTPUT=$1
+CODESIGN_IDENTITY=${CODESIGN_IDENTITY:-mock}
+PRODUCTSIGN_IDENTITY=${PRODUCTSIGN_IDENTITY:-mock}
+NO_CODESIGN=${NO_CODESIGN:-0}
+HELPER_BINARIES_DIR="/opt/podman/qemu/bin"
+
+binDir="${BASEDIR}/root/podman/bin"
+
+function build_podman() {
+ pushd "$1"
+ make podman-remote HELPER_BINARIES_DIR="${HELPER_BINARIES_DIR}"
+ make podman-mac-helper
+ cp bin/darwin/podman "contrib/pkginstaller/out/packaging/${binDir}/podman"
+ cp bin/darwin/podman-mac-helper "contrib/pkginstaller/out/packaging/${binDir}/podman-mac-helper"
+ popd
+}
+
+function sign() {
+ if [ "${NO_CODESIGN}" -eq "1" ]; then
+ return
+ fi
+ local opts=""
+ entitlements="${BASEDIR}/$(basename "$1").entitlements"
+ if [ -f "${entitlements}" ]; then
+ opts="--entitlements ${entitlements}"
+ fi
+ codesign --deep --sign "${CODESIGN_IDENTITY}" --options runtime --force --timestamp "${opts}" "$1"
+}
+
+version=$(cat "${BASEDIR}/VERSION")
+arch=$(cat "${BASEDIR}/ARCH")
+
+build_podman "../../../../"
+sign "${binDir}/podman"
+sign "${binDir}/gvproxy"
+sign "${binDir}/podman-mac-helper"
+
+pkgbuild --identifier com.redhat.podman --version "${version}" \
+ --scripts "${BASEDIR}/scripts" \
+ --root "${BASEDIR}/root" \
+ --install-location /opt \
+ --component-plist "${BASEDIR}/component.plist" \
+ "${OUTPUT}/podman.pkg"
+
+productbuild --distribution "${BASEDIR}/Distribution" \
+ --resources "${BASEDIR}/Resources" \
+ --package-path "${OUTPUT}" \
+ "${OUTPUT}/podman-unsigned.pkg"
+rm "${OUTPUT}/podman.pkg"
+
+if [ ! "${NO_CODESIGN}" -eq "1" ]; then
+ productsign --timestamp --sign "${PRODUCTSIGN_IDENTITY}" "${OUTPUT}/podman-unsigned.pkg" "${OUTPUT}/podman-installer-macos-${arch}.pkg"
+else
+ mv "${OUTPUT}/podman-unsigned.pkg" "${OUTPUT}/podman-installer-macos-${arch}.pkg"
+fi
diff --git a/contrib/pkginstaller/scripts/postinstall b/contrib/pkginstaller/scripts/postinstall
new file mode 100755
index 000000000..db17eede8
--- /dev/null
+++ b/contrib/pkginstaller/scripts/postinstall
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+set -e
+
+BZSH_PODMAN_PATH_EXP='PATH="/opt/podman/bin:$PATH"'
+FISH_PODMAN_PATH_EXP='set PATH "/opt/podman/bin $PATH"'
+BASHRC_PATH="$HOME/.bash_profile"
+ZSHENV_PATH="$HOME/.zshenv"
+ZSHRC_PATH="$HOME/.zshrc"
+FSHCFG_PATH="$HOME/.config/fish/config.fish"
+
+# append /Applications/podman/bin to $PATH
+if [ -f "$BASHRC_PATH" ]; then
+ grep -Fxq "$BZSH_PODMAN_PATH_EXP" "$BASHRC_PATH" || echo "$BZSH_PODMAN_PATH_EXP" >> "$BASHRC_PATH"
+fi
+if [ -f "$ZSHENV_PATH" ]; then
+ grep -Fxq "$BZSH_PODMAN_PATH_EXP" "$ZSHENV_PATH" || echo "$BZSH_PODMAN_PATH_EXP" >> "$ZSHENV_PATH"
+fi
+if [ -f "$ZSHRC_PATH" ]; then
+ grep -Fxq "$BZSH_PODMAN_PATH_EXP" "$ZSHRC_PATH" || echo "$BZSH_PODMAN_PATH_EXP" >> "$ZSHRC_PATH"
+fi
+if [ -f "$FSHCFG_PATH" ]; then
+ grep -Fxq "$FISH_PODMAN_PATH_EXP" "$FSHCFG_PATH" || echo "$FISH_PODMAN_PATH_EXP" >> "$FSHCFG_PATH"
+fi
+
+ln -s /opt/podman/bin/podman-mac-helper /opt/podman/qemu/bin/podman-mac-helper
+ln -s /opt/podman/bin/gvproxy /opt/podman/qemu/bin/gvproxy
diff --git a/contrib/pkginstaller/scripts/preinstall b/contrib/pkginstaller/scripts/preinstall
new file mode 100755
index 000000000..a381868fc
--- /dev/null
+++ b/contrib/pkginstaller/scripts/preinstall
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+set -e
+
+rm -rf /opt/podman
diff --git a/contrib/pkginstaller/welcome.html.in b/contrib/pkginstaller/welcome.html.in
new file mode 100644
index 000000000..b06198716
--- /dev/null
+++ b/contrib/pkginstaller/welcome.html.in
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8"/>
+</head>
+<body>
+<div align="left" style="font-family: Helvetica; padding-left: 10px;">
+ <br/>
+ <p style="color: #020202; font-size: 12px;">This will install <span style="color: #46b9d6; font-size: 12px;">Podman __VERSION__</span>
+ on your computer. You will be guided through the steps necessary to install this software.</p>
+ <br/>
+ <p style="color: #abb0b0; font-size: 12px;">Click <span style="color: #626666">“Continue"</span> to continue the
+ setup</p>
+</div>
+</body>
+</html>
diff --git a/docs/tutorials/socket_activation.md b/docs/tutorials/socket_activation.md
index 9b4b02b81..f4ad5aefd 100644
--- a/docs/tutorials/socket_activation.md
+++ b/docs/tutorials/socket_activation.md
@@ -19,7 +19,7 @@ The architecture looks like this
``` mermaid
stateDiagram-v2
- [*] --> systemd: client connects
+ [*] --> systemd: first client connects
systemd --> podman: socket inherited via fork/exec
```
@@ -55,6 +55,9 @@ $ export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock
$ docker-compose up
```
+When __docker-compose__ or any other client connects to the UNIX socket `$XDG_RUNTIME_DIR/podman/podman.sock`,
+the service _podman.service_ is started. See its definition in the file _/usr/lib/systemd/user/podman.service_.
+
## Socket activation of containers
Since version 3.4.0 Podman supports socket activation of containers, i.e., passing
@@ -65,7 +68,7 @@ as can be seen in the following diagram:
``` mermaid
stateDiagram-v2
- [*] --> systemd: client connects
+ [*] --> systemd: first client connects
systemd --> podman: socket inherited via fork/exec
state "OCI runtime" as s2
podman --> conmon: socket inherited via double fork/exec
@@ -207,6 +210,18 @@ container then runs with less privileges.
When using rootless Podman, network traffic is normally passed through slirp4netns. This comes with
a performance penalty. Fortunately, communication over the socket-activated socket does not pass through
slirp4netns so it has the same performance characteristics as the normal network on the host.
-Note, there is a delay when the first connection is made because the container needs to
+
+### Starting a socket-activated service
+
+There is a delay when the first connection is made because the container needs to
start up. To minimize this delay, consider passing __--pull=never__ to `podman run` and instead
-pull the container image beforehand.
+pull the container image beforehand. Instead of waiting for the start of the service to be triggered by the
+first client connecting to it, the service can also be explicitly started (`systemctl --user start echo.service`).
+
+### Stopping a socket-activated service
+
+Some services run a command (configured by the systemd directive __ExecStart__) that exits after some time of inactivity.
+Depending on the restart configuration for the service
+(systemd directive [__Restart__](https://www.freedesktop.org/software/systemd/man/systemd.service.html#Restart=)),
+it may then be stopped. An example of this is _podman.service_ that stops after some time of inactivity.
+The service will be started again when the next client connects to the socket.
diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go
index f88a165e7..de62b6582 100644
--- a/pkg/domain/filters/containers.go
+++ b/pkg/domain/filters/containers.go
@@ -7,6 +7,7 @@ import (
"strings"
"time"
+ "github.com/containers/common/pkg/filters"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
@@ -24,7 +25,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
case "label":
// we have to match that all given labels exits on that container
return func(c *libpod.Container) bool {
- return util.MatchLabelFilters(filterValues, c.Labels())
+ return filters.MatchLabelFilters(filterValues, c.Labels())
}, nil
case "name":
// we only have to match one name
@@ -299,7 +300,11 @@ func GeneratePruneContainerFilterFuncs(filter string, filterValues []string, r *
switch filter {
case "label":
return func(c *libpod.Container) bool {
- return util.MatchLabelFilters(filterValues, c.Labels())
+ return filters.MatchLabelFilters(filterValues, c.Labels())
+ }, nil
+ case "label!":
+ return func(c *libpod.Container) bool {
+ return !filters.MatchLabelFilters(filterValues, c.Labels())
}, nil
case "until":
return prepareUntilFilterFunc(filterValues)
diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go
index 78b97db64..7b0944292 100644
--- a/pkg/domain/filters/pods.go
+++ b/pkg/domain/filters/pods.go
@@ -6,6 +6,7 @@ import (
"strconv"
"strings"
+ "github.com/containers/common/pkg/filters"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
@@ -115,7 +116,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
case "label":
return func(p *libpod.Pod) bool {
labels := p.Labels()
- return util.MatchLabelFilters(filterValues, labels)
+ return filters.MatchLabelFilters(filterValues, labels)
}, nil
case "until":
return func(p *libpod.Pod) bool {
diff --git a/pkg/domain/filters/volumes.go b/pkg/domain/filters/volumes.go
index 7c5047225..9cec39fbb 100644
--- a/pkg/domain/filters/volumes.go
+++ b/pkg/domain/filters/volumes.go
@@ -6,6 +6,7 @@ import (
"regexp"
"strings"
+ pruneFilters "github.com/containers/common/pkg/filters"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/pkg/util"
)
@@ -36,7 +37,7 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
case "label":
filter := val
vf = append(vf, func(v *libpod.Volume) bool {
- return util.MatchLabelFilters([]string{filter}, v.Labels())
+ return pruneFilters.MatchLabelFilters([]string{filter}, v.Labels())
})
case "opt":
filterArray := strings.SplitN(val, "=", 2)
@@ -100,7 +101,7 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro
switch filter {
case "label":
vf = append(vf, func(v *libpod.Volume) bool {
- return util.MatchLabelFilters([]string{filterVal}, v.Labels())
+ return pruneFilters.MatchLabelFilters([]string{filterVal}, v.Labels())
})
case "until":
f, err := createUntilFilterVolumeFunction(filterVal)
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index dd7053a23..ab742fb35 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -260,6 +260,7 @@ func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities.
if err != nil {
return nil, err
}
+
filterFuncs = append(filterFuncs, generatedFunc)
}
return ic.Libpod.PruneContainers(filterFuncs)
diff --git a/pkg/util/filters.go b/pkg/util/filters.go
index 08148806f..104b9c3c2 100644
--- a/pkg/util/filters.go
+++ b/pkg/util/filters.go
@@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"net/http"
- "path/filepath"
"strings"
"time"
@@ -94,35 +93,3 @@ func PrepareFilters(r *http.Request) (*map[string][]string, error) {
}
return &filterMap, nil
}
-
-func matchPattern(pattern string, value string) bool {
- if strings.Contains(pattern, "*") {
- filter := fmt.Sprintf("*%s*", pattern)
- filter = strings.ReplaceAll(filter, string(filepath.Separator), "|")
- newName := strings.ReplaceAll(value, string(filepath.Separator), "|")
- match, _ := filepath.Match(filter, newName)
- return match
- }
- return false
-}
-
-// MatchLabelFilters matches labels and returns true if they are valid
-func MatchLabelFilters(filterValues []string, labels map[string]string) bool {
-outer:
- for _, filterValue := range filterValues {
- filterArray := strings.SplitN(filterValue, "=", 2)
- filterKey := filterArray[0]
- if len(filterArray) > 1 {
- filterValue = filterArray[1]
- } else {
- filterValue = ""
- }
- for labelKey, labelValue := range labels {
- if ((labelKey == filterKey) || matchPattern(filterKey, labelKey)) && (filterValue == "" || labelValue == filterValue) {
- continue outer
- }
- }
- return false
- }
- return true
-}
diff --git a/pkg/util/filters_test.go b/pkg/util/filters_test.go
index 47259013e..8e45ea61c 100644
--- a/pkg/util/filters_test.go
+++ b/pkg/util/filters_test.go
@@ -2,6 +2,8 @@ package util
import (
"testing"
+
+ "github.com/containers/common/pkg/filters"
)
func TestMatchLabelFilters(t *testing.T) {
@@ -71,7 +73,7 @@ func TestMatchLabelFilters(t *testing.T) {
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
- if got := MatchLabelFilters(tt.args.filterValues, tt.args.labels); got != tt.want {
+ if got := filters.MatchLabelFilters(tt.args.filterValues, tt.args.labels); got != tt.want {
t.Errorf("MatchLabelFilters() = %v, want %v", got, tt.want)
}
})
diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go
index 89cc65540..0b1d68aea 100644
--- a/test/e2e/prune_test.go
+++ b/test/e2e/prune_test.go
@@ -280,6 +280,24 @@ var _ = Describe("Podman prune", func() {
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
Expect(session.OutputToStringArray()).To(HaveLen(0))
+
+ // Create new network.
+ session = podmanTest.Podman([]string{"network", "create", "test1", "--label", "foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
+ // Remove all unused networks.
+ session = podmanTest.Podman([]string{"system", "prune", "-f", "--filter", "label!=foo"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ Expect(session.OutputToString()).Should(Equal("Total reclaimed space: 0B"))
+
+ // Unused networks removed.
+ session = podmanTest.Podman([]string{"network", "ls", "-q", "--filter", "name=^test1$"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+ // label should make sure we do not remove this network
+ Expect(session.OutputToStringArray()).To(HaveLen(1))
})
It("podman system prune - pod,container stopped", func() {