summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cirrus.yml4
-rw-r--r--cmd/podman/containers/clone.go9
-rw-r--r--cmd/podman/machine/init.go15
-rw-r--r--cmd/podman/machine/set.go7
-rwxr-xr-xcontrib/cirrus/logformatter2
-rwxr-xr-xcontrib/cirrus/setup_environment.sh5
-rw-r--r--contrib/podmanimage/README.md2
-rw-r--r--contrib/remote/containers.conf2
-rw-r--r--docs/source/markdown/podman-build.1.md2
-rw-r--r--docs/source/markdown/podman-container-clone.1.md4
-rw-r--r--docs/source/markdown/podman-image-scp.1.md2
-rw-r--r--docs/source/markdown/podman-image-unmount.1.md2
-rw-r--r--docs/source/markdown/podman-machine-init.1.md6
-rw-r--r--docs/source/markdown/podman-machine-set.1.md20
-rw-r--r--libpod/networking_slirp4netns.go2
-rw-r--r--pkg/bindings/README.md8
-rw-r--r--pkg/domain/entities/containers.go1
-rw-r--r--pkg/domain/infra/abi/containers.go2
-rw-r--r--pkg/domain/infra/abi/images.go6
-rw-r--r--pkg/machine/config.go4
-rw-r--r--pkg/machine/qemu/config.go8
-rw-r--r--pkg/machine/qemu/machine.go20
-rw-r--r--pkg/machine/wsl/machine.go22
-rw-r--r--pkg/specgen/generate/container.go2
-rw-r--r--pkg/specgen/generate/container_create.go2
-rw-r--r--pkg/specgenutil/volumes.go11
-rw-r--r--rootless.md2
-rw-r--r--test/e2e/container_clone_test.go32
-rw-r--r--test/e2e/exec_test.go2
-rw-r--r--test/e2e/mount_rootless_test.go2
-rw-r--r--test/e2e/network_test.go2
-rw-r--r--test/e2e/run_volume_test.go5
-rw-r--r--test/system/000-TEMPLATE10
-rw-r--r--test/system/001-basic.bats26
-rw-r--r--test/system/015-help.bats21
-rw-r--r--test/system/030-run.bats53
-rw-r--r--test/system/035-logs.bats5
-rw-r--r--test/system/040-ps.bats5
-rw-r--r--test/system/045-start.bats5
-rw-r--r--test/system/050-stop.bats17
-rw-r--r--test/system/065-cp.bats28
-rw-r--r--test/system/070-build.bats56
-rw-r--r--test/system/090-events.bats5
-rw-r--r--test/system/120-load.bats10
-rw-r--r--test/system/160-volumes.bats4
-rw-r--r--test/system/180-blkio.bats3
-rw-r--r--test/system/190-run-ipcns.bats42
-rw-r--r--test/system/200-pod.bats15
-rw-r--r--test/system/250-systemd.bats60
-rw-r--r--test/system/255-auto-update.bats11
-rw-r--r--test/system/270-socket-activation.bats2
-rw-r--r--test/system/400-unprivileged-access.bats4
-rw-r--r--test/system/410-selinux.bats10
-rw-r--r--test/system/450-interactive.bats4
-rw-r--r--test/system/500-networking.bats65
-rw-r--r--test/system/520-checkpoint.bats15
-rw-r--r--test/system/600-completion.bats11
-rw-r--r--test/system/750-trust.bats3
-rw-r--r--test/system/helpers.bash113
59 files changed, 439 insertions, 379 deletions
diff --git a/.cirrus.yml b/.cirrus.yml
index c984c8859..cf97f4467 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -101,6 +101,10 @@ ext_svc_check_task:
else
git reset --hard $CIRRUS_CHANGE_IN_REPO
fi
+ # Some test operations & checks require a git "identity"
+ _gc='git config --file /root/.gitconfig'
+ $_gc user.email "TMcTestFace@example.com"
+ $_gc user.name "Testy McTestface"
make install.tools
setup_script: &setup '$GOSRC/$SCRIPT_BASE/setup_environment.sh'
diff --git a/cmd/podman/containers/clone.go b/cmd/podman/containers/clone.go
index 8a1473608..6912da1fc 100644
--- a/cmd/podman/containers/clone.go
+++ b/cmd/podman/containers/clone.go
@@ -38,6 +38,9 @@ func cloneFlags(cmd *cobra.Command) {
runFlagName := "run"
flags.BoolVar(&ctrClone.Run, runFlagName, false, "run the new container")
+ forceFlagName := "force"
+ flags.BoolVarP(&ctrClone.Force, forceFlagName, "f", false, "force the existing container to be destroyed")
+
common.DefineCreateFlags(cmd, &ctrClone.CreateOpts, false, true)
}
func init() {
@@ -52,7 +55,7 @@ func init() {
func clone(cmd *cobra.Command, args []string) error {
switch len(args) {
case 0:
- return errors.Wrapf(define.ErrInvalidArg, "Must Specify at least 1 argument")
+ return errors.Wrapf(define.ErrInvalidArg, "must specify at least 1 argument")
case 2:
ctrClone.CreateOpts.Name = args[1]
case 3:
@@ -68,6 +71,10 @@ func clone(cmd *cobra.Command, args []string) error {
ctrClone.RawImageName = rawImageName
}
}
+ if ctrClone.Force && !ctrClone.Destroy {
+ return errors.Wrapf(define.ErrInvalidArg, "cannot set --force without --destroy")
+ }
+
ctrClone.ID = args[0]
ctrClone.CreateOpts.IsClone = true
rep, err := registry.ContainerEngine().ContainerClone(registry.GetContext(), ctrClone)
diff --git a/cmd/podman/machine/init.go b/cmd/podman/machine/init.go
index 2d0afbf05..06c1f7248 100644
--- a/cmd/podman/machine/init.go
+++ b/cmd/podman/machine/init.go
@@ -12,6 +12,7 @@ import (
"github.com/containers/podman/v4/pkg/machine"
"github.com/pkg/errors"
"github.com/spf13/cobra"
+ "github.com/spf13/pflag"
)
var (
@@ -106,8 +107,18 @@ func init() {
flags.StringVar(&initOpts.IgnitionPath, IgnitionPathFlagName, "", "Path to ignition file")
_ = initCmd.RegisterFlagCompletionFunc(IgnitionPathFlagName, completion.AutocompleteDefault)
- rootfulFlagName := "rootful"
- flags.BoolVar(&initOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ rootfullFlagName := "rootfull"
+ flags.BoolVar(&initOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
+ flags.SetNormalizeFunc(aliasFlags)
+}
+
+// aliasFlags is a function to handle backwards compatibility with old flags
+func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName {
+ switch name {
+ case "rootful":
+ name = "rootfull"
+ }
+ return pflag.NormalizedName(name)
}
// TODO should we allow for a users to append to the qemu cmdline?
diff --git a/cmd/podman/machine/set.go b/cmd/podman/machine/set.go
index 4c15f1de1..b1dfb51da 100644
--- a/cmd/podman/machine/set.go
+++ b/cmd/podman/machine/set.go
@@ -17,7 +17,7 @@ var (
Long: "Sets an updatable virtual machine setting",
RunE: setMachine,
Args: cobra.MaximumNArgs(1),
- Example: `podman machine set --rootful=false`,
+ Example: `podman machine set --rootfull=false`,
ValidArgsFunction: completion.AutocompleteNone,
}
)
@@ -33,8 +33,9 @@ func init() {
})
flags := setCmd.Flags()
- rootfulFlagName := "rootful"
- flags.BoolVar(&setOpts.Rootful, rootfulFlagName, false, "Whether this machine should prefer rootful container execution")
+ rootfullFlagName := "rootfull"
+ flags.BoolVar(&setOpts.Rootfull, rootfullFlagName, false, "Whether this machine should prefer rootfull container execution")
+ flags.SetNormalizeFunc(aliasFlags)
}
func setMachine(cmd *cobra.Command, args []string) error {
diff --git a/contrib/cirrus/logformatter b/contrib/cirrus/logformatter
index 3ec839aa8..3c52e612b 100755
--- a/contrib/cirrus/logformatter
+++ b/contrib/cirrus/logformatter
@@ -204,7 +204,7 @@ END_HTML
print { $out_fh } "<pre> <!-- begin processed output -->\n";
- # Assume rootful prompt, check for rootless (here and in log itself, below)
+ # Assume rootfull prompt, check for rootless (here and in log itself, below)
my $Prompt = '#';
$Prompt = '$' if $test_name =~ /rootless/;
diff --git a/contrib/cirrus/setup_environment.sh b/contrib/cirrus/setup_environment.sh
index 906a898b2..a7d0f7fa1 100755
--- a/contrib/cirrus/setup_environment.sh
+++ b/contrib/cirrus/setup_environment.sh
@@ -41,6 +41,11 @@ cp hack/podman-registry /bin
# Make sure cni network plugins directory exists
mkdir -p /etc/cni/net.d
+# Some test operations & checks require a git "identity"
+_gc='git config --file /root/.gitconfig'
+$_gc user.email "TMcTestFace@example.com"
+$_gc user.name "Testy McTestface"
+
# Ensure that all lower-level contexts and child-processes have
# ready access to higher level orchestration (e.g Cirrus-CI)
# variables.
diff --git a/contrib/podmanimage/README.md b/contrib/podmanimage/README.md
index 4f184ca28..58c14be72 100644
--- a/contrib/podmanimage/README.md
+++ b/contrib/podmanimage/README.md
@@ -70,4 +70,4 @@ file to `/etc/modules.load.d`. See `man modules-load.d` for more details.
### Blog Post with Details
-Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootful and as a rootless user. Please refer to this blog for more detailed information.
+Dan Walsh wrote a blog post on the [Enable Sysadmin](https://www.redhat.com/sysadmin/) site titled [How to use Podman inside of a container](https://www.redhat.com/sysadmin/podman-inside-container). In it, he details how to use these images as a rootfull and as a rootless user. Please refer to this blog for more detailed information.
diff --git a/contrib/remote/containers.conf b/contrib/remote/containers.conf
index 9b0b62c42..45f58171a 100644
--- a/contrib/remote/containers.conf
+++ b/contrib/remote/containers.conf
@@ -7,5 +7,5 @@
# Default Remote URI to access the Podman service.
# Examples:
# remote rootless ssh://engineering.lab.company.com/run/user/1000/podman/podman.sock
-# remote rootful ssh://root@10.10.1.136:22/run/podman/podman.sock
+# remote rootfull ssh://root@10.10.1.136:22/run/podman/podman.sock
# remote_uri= ""
diff --git a/docs/source/markdown/podman-build.1.md b/docs/source/markdown/podman-build.1.md
index 1080581d7..5793ecae5 100644
--- a/docs/source/markdown/podman-build.1.md
+++ b/docs/source/markdown/podman-build.1.md
@@ -429,7 +429,7 @@ container full access to local system services such as D-bus and is therefore
considered insecure.
- **ns:**_path_: path to a network namespace to join.
- **private**: create a new namespace for the container (default)
-- **\<network name|ID\>**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootful users.
+- **\<network name|ID\>**: Join the network with the given name or ID, e.g. use `--network mynet` to join the network with the name mynet. Only supported for rootfull users.
#### **--no-cache**
diff --git a/docs/source/markdown/podman-container-clone.1.md b/docs/source/markdown/podman-container-clone.1.md
index 7d5e1c262..69423113d 100644
--- a/docs/source/markdown/podman-container-clone.1.md
+++ b/docs/source/markdown/podman-container-clone.1.md
@@ -125,6 +125,10 @@ If none are specified, the original container's CPU memory nodes are used.
Remove the original container that we are cloning once used to mimic the configuration.
+#### **--force**, **-f**
+
+Force removal of the original container that we are cloning. Can only be used in conjunction with **--destroy**.
+
#### **--memory**, **-m**=*limit*
Memory limit (format: `<number>[<unit>]`, where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes))
diff --git a/docs/source/markdown/podman-image-scp.1.md b/docs/source/markdown/podman-image-scp.1.md
index 1d902da91..6d5a51298 100644
--- a/docs/source/markdown/podman-image-scp.1.md
+++ b/docs/source/markdown/podman-image-scp.1.md
@@ -8,7 +8,7 @@ podman-image-scp - Securely copy an image from one host to another
## DESCRIPTION
**podman image scp** copies container images between hosts on a network. You can load to the remote host or from the remote host as well as in between two remote hosts.
-Note: `::` is used to specify the image name depending on if you are saving or loading. Images can also be transferred from rootful to rootless storage on the same machine without using sshd. This feature is not supported on the remote client, including Mac and Windows (excluding WSL2) machines.
+Note: `::` is used to specify the image name depending on if you are saving or loading. Images can also be transferred from rootfull to rootless storage on the same machine without using sshd. This feature is not supported on the remote client, including Mac and Windows (excluding WSL2) machines.
**podman image scp [GLOBAL OPTIONS]**
diff --git a/docs/source/markdown/podman-image-unmount.1.md b/docs/source/markdown/podman-image-unmount.1.md
index f2d75f15f..394811bd4 100644
--- a/docs/source/markdown/podman-image-unmount.1.md
+++ b/docs/source/markdown/podman-image-unmount.1.md
@@ -38,7 +38,7 @@ Unmount image with a given ID
podman image unmount imageID
```
-Unmount multiple images wit given IDs
+Unmount multiple images with given IDs
```
podman image unmount imageID1 imageID2 imageID3
```
diff --git a/docs/source/markdown/podman-machine-init.1.md b/docs/source/markdown/podman-machine-init.1.md
index 33947bbba..e42c5025b 100644
--- a/docs/source/markdown/podman-machine-init.1.md
+++ b/docs/source/markdown/podman-machine-init.1.md
@@ -59,9 +59,9 @@ Memory (in MB).
Start the virtual machine immediately after it has been initialized.
-#### **--rootful**=*true|false*
+#### **--rootfull**=*true|false*
-Whether this machine should prefer rootful (`true`) or rootless (`false`)
+Whether this machine should prefer rootfull (`true`) or rootless (`false`)
container execution. This option will also determine the remote connection default
if there is no existing remote connection configurations.
@@ -95,7 +95,7 @@ Driver to use for mounting volumes from the host, such as `virtfs`.
```
$ podman machine init
$ podman machine init myvm
-$ podman machine init --rootful
+$ podman machine init --rootfull
$ podman machine init --disk-size 50
$ podman machine init --memory=1024 myvm
$ podman machine init -v /Users:/mnt/Users
diff --git a/docs/source/markdown/podman-machine-set.1.md b/docs/source/markdown/podman-machine-set.1.md
index a4918eacf..e69a7dc14 100644
--- a/docs/source/markdown/podman-machine-set.1.md
+++ b/docs/source/markdown/podman-machine-set.1.md
@@ -19,39 +19,39 @@ subset can be changed after machine initialization.
Print usage statement.
-#### **--rootful**=*true|false*
+#### **--rootfull**=*true|false*
-Whether this machine should prefer rootful (`true`) or rootless (`false`)
+Whether this machine should prefer rootfull (`true`) or rootless (`false`)
container execution. This option will also update the current podman
remote connection default if it is currently pointing at the specified
machine name (or `podman-machine-default` if no name is specified).
Unlike [**podman system connection default**](podman-system-connection-default.1.md)
-this option will also make the API socket, if available, forward to the rootful/rootless
+this option will also make the API socket, if available, forward to the rootfull/rootless
socket in the VM.
## EXAMPLES
-To switch the default VM `podman-machine-default` from rootless to rootful:
+To switch the default VM `podman-machine-default` from rootless to rootfull:
```
-$ podman machine set --rootful
+$ podman machine set --rootfull
```
or more explicitly:
```
-$ podman machine set --rootful=true
+$ podman machine set --rootfull=true
```
-To switch the default VM `podman-machine-default` from rootful to rootless:
+To switch the default VM `podman-machine-default` from rootfull to rootless:
```
-$ podman machine set --rootful=false
+$ podman machine set --rootfull=false
```
-To switch the VM `myvm` from rootless to rootful:
+To switch the VM `myvm` from rootless to rootfull:
```
-$ podman machine set --rootful myvm
+$ podman machine set --rootfull myvm
```
## SEE ALSO
diff --git a/libpod/networking_slirp4netns.go b/libpod/networking_slirp4netns.go
index 4a0ef0b3a..4b1203dc3 100644
--- a/libpod/networking_slirp4netns.go
+++ b/libpod/networking_slirp4netns.go
@@ -210,7 +210,7 @@ func createBasicSlirp4netnsCmdArgs(options *slirp4netnsNetworkOptions, features
return cmdArgs, nil
}
-// setupSlirp4netns can be called in rootful as well as in rootless
+// setupSlirp4netns can be called in rootfull as well as in rootless
func (r *Runtime) setupSlirp4netns(ctr *Container, netns ns.NetNS) error {
path := r.config.Engine.NetworkCmdPath
if path == "" {
diff --git a/pkg/bindings/README.md b/pkg/bindings/README.md
index ebc8a13d1..713adb104 100644
--- a/pkg/bindings/README.md
+++ b/pkg/bindings/README.md
@@ -9,7 +9,7 @@ The bindings require that the Podman system service is running for the specified
by calling the service directly.
### Starting the service with system
-The command to start the Podman service differs slightly depending on the user that is running the service. For a rootful service,
+The command to start the Podman service differs slightly depending on the user that is running the service. For a rootfull service,
start the service like this:
```
# systemctl start podman.socket
@@ -26,7 +26,7 @@ It can be handy to run the system service manually. Doing so allows you to enab
$ podman --log-level=debug system service -t0
```
If you do not provide a specific path for the socket, a default is provided. The location of that socket for
-rootful connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
+rootfull connections is `/run/podman/podman.sock` and for rootless it is `/run/USERID#/podman/podman.sock`. For more
information about the Podman system service, see `man podman-system-service`.
### Creating a connection
@@ -35,7 +35,7 @@ as they will be required to compile a Go program making use of the bindings.
The first step for using the bindings is to create a connection to the socket. As mentioned earlier, the destination
-of the socket depends on the user who owns it. In this case, a rootful connection is made.
+of the socket depends on the user who owns it. In this case, a rootfull connection is made.
```
import (
@@ -59,7 +59,7 @@ The `conn` variable returned from the `bindings.NewConnection` function can then
to interact with containers.
### Examples
-The following examples build upon the connection example from above. They are all rootful connections as well.
+The following examples build upon the connection example from above. They are all rootfull connections as well.
Note: Optional arguments to the bindings methods are set using With*() methods on *Option structures.
Composite types are not duplicated rather the address is used. As such, you should not change an underlying
diff --git a/pkg/domain/entities/containers.go b/pkg/domain/entities/containers.go
index 3d1d7a6d2..ae60e5b96 100644
--- a/pkg/domain/entities/containers.go
+++ b/pkg/domain/entities/containers.go
@@ -477,4 +477,5 @@ type ContainerCloneOptions struct {
Image string
RawImageName string
Run bool
+ Force bool
}
diff --git a/pkg/domain/infra/abi/containers.go b/pkg/domain/infra/abi/containers.go
index 46ef01b80..b56c36015 100644
--- a/pkg/domain/infra/abi/containers.go
+++ b/pkg/domain/infra/abi/containers.go
@@ -1630,7 +1630,7 @@ func (ic *ContainerEngine) ContainerClone(ctx context.Context, ctrCloneOpts enti
if ctrCloneOpts.Destroy {
var time *uint
- err := ic.Libpod.RemoveContainer(context.Background(), c, false, false, time)
+ err = ic.Libpod.RemoveContainer(context.Background(), c, ctrCloneOpts.Force, false, time)
if err != nil {
return nil, err
}
diff --git a/pkg/domain/infra/abi/images.go b/pkg/domain/infra/abi/images.go
index 74478b26d..43440b594 100644
--- a/pkg/domain/infra/abi/images.go
+++ b/pkg/domain/infra/abi/images.go
@@ -367,7 +367,7 @@ func (ir *ImageEngine) Transfer(ctx context.Context, source entities.ImageScpOpt
if rootless.IsRootless() && (len(dest.User) == 0 || dest.User == "root") { // if we are rootless and do not have a destination user we can just use sudo
return transferRootless(source, dest, podman, parentFlags)
}
- return transferRootful(source, dest, podman, parentFlags)
+ return transferRootfull(source, dest, podman, parentFlags)
}
func (ir *ImageEngine) Tag(ctx context.Context, nameOrID string, tags []string, options entities.ImageTagOptions) error {
@@ -785,8 +785,8 @@ func transferRootless(source entities.ImageScpOptions, dest entities.ImageScpOpt
return cmdLoad.Run()
}
-// TransferRootful creates new podman processes using exec.Command and a new uid/gid alongside a cleared environment
-func transferRootful(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
+// transferRootfull creates new podman processes using exec.Command and a new uid/gid alongside a cleared environment
+func transferRootfull(source entities.ImageScpOptions, dest entities.ImageScpOptions, podman string, parentFlags []string) error {
basicCommand := []string{podman}
basicCommand = append(basicCommand, parentFlags...)
saveCommand := append(basicCommand, "save")
diff --git a/pkg/machine/config.go b/pkg/machine/config.go
index 6c2fab0e5..5dc5f6105 100644
--- a/pkg/machine/config.go
+++ b/pkg/machine/config.go
@@ -28,7 +28,7 @@ type InitOptions struct {
URI url.URL
Username string
ReExec bool
- Rootful bool
+ Rootfull bool
// The numerical userid of the user that called machine
UID string
}
@@ -95,7 +95,7 @@ type ListResponse struct {
}
type SetOptions struct {
- Rootful bool
+ Rootfull bool
}
type SSHOptions struct {
diff --git a/pkg/machine/qemu/config.go b/pkg/machine/qemu/config.go
index 4d4e3a6c1..6ab25b951 100644
--- a/pkg/machine/qemu/config.go
+++ b/pkg/machine/qemu/config.go
@@ -57,8 +57,8 @@ type MachineVMV1 struct {
QMPMonitor Monitorv1
// RemoteUsername of the vm user
RemoteUsername string
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
// UID is the numerical id of the user that called machine
UID int
}
@@ -99,8 +99,8 @@ type ImageConfig struct {
// HostUser describes the host user
type HostUser struct {
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
// UID is the numerical id of the user that called machine
UID int
}
diff --git a/pkg/machine/qemu/machine.go b/pkg/machine/qemu/machine.go
index a3dedeedb..4cfd4e8b0 100644
--- a/pkg/machine/qemu/machine.go
+++ b/pkg/machine/qemu/machine.go
@@ -204,7 +204,7 @@ func migrateVM(configPath string, config []byte, vm *MachineVM) error {
vm.QMPMonitor = qmpMonitor
vm.ReadySocket = readySocket
vm.RemoteUsername = old.RemoteUsername
- vm.Rootful = old.Rootful
+ vm.Rootfull = old.Rootfull
vm.UID = old.UID
// Backup the original config file
@@ -258,7 +258,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
)
sshDir := filepath.Join(homedir.Get(), ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
switch opts.ImagePath {
case Testing, Next, Stable, "":
@@ -356,8 +356,8 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
names := []string{v.Name, v.Name + "-root"}
// The first connection defined when connections is empty will become the default
- // regardless of IsDefault, so order according to rootful
- if opts.Rootful {
+ // regardless of IsDefault, so order according to rootfull
+ if opts.Rootfull {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -435,7 +435,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
}
func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
+ if v.Rootfull == opts.Rootfull {
return nil
}
@@ -459,7 +459,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootful {
+ if opts.Rootfull {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -467,7 +467,7 @@ func (v *MachineVM) Set(_ string, opts machine.SetOptions) error {
}
}
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
return v.writeConfig()
}
@@ -1117,7 +1117,7 @@ func (v *MachineVM) setupAPIForwarding(cmd []string) ([]string, string, apiForwa
destSock := fmt.Sprintf("/run/user/%d/podman/podman.sock", v.UID)
forwardUser := "core"
- if v.Rootful {
+ if v.Rootfull {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
@@ -1323,11 +1323,11 @@ func (v *MachineVM) waitAPIAndPrintInfo(forwardState apiForwardingState, forward
}
waitAndPingAPI(forwardSock)
- if !v.Rootful {
+ if !v.Rootfull {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
}
fmt.Printf("API forwarding listening on: %s\n", forwardSock)
diff --git a/pkg/machine/wsl/machine.go b/pkg/machine/wsl/machine.go
index dff7bfef9..dc3f33fa7 100644
--- a/pkg/machine/wsl/machine.go
+++ b/pkg/machine/wsl/machine.go
@@ -165,8 +165,8 @@ type MachineVM struct {
Port int
// RemoteUsername of the vm user
RemoteUsername string
- // Whether this machine should run in a rootful or rootless manner
- Rootful bool
+ // Whether this machine should run in a rootfull or rootless manner
+ Rootfull bool
}
type ExitCodeError struct {
@@ -232,7 +232,7 @@ func (v *MachineVM) Init(opts machine.InitOptions) (bool, error) {
homeDir := homedir.Get()
sshDir := filepath.Join(homeDir, ".ssh")
v.IdentityPath = filepath.Join(sshDir, v.Name)
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
if err := downloadDistro(v, opts); err != nil {
return false, err
@@ -316,8 +316,8 @@ func setupConnections(v *MachineVM, opts machine.InitOptions, sshDir string) err
names := []string{v.Name, v.Name + "-root"}
// The first connection defined when connections is empty will become the default
- // regardless of IsDefault, so order according to rootful
- if opts.Rootful {
+ // regardless of IsDefault, so order according to rootfull
+ if opts.Rootfull {
uris[0], names[0], uris[1], names[1] = uris[1], names[1], uris[0], names[0]
}
@@ -733,7 +733,7 @@ func pipeCmdPassThrough(name string, input string, arg ...string) error {
}
func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
- if v.Rootful == opts.Rootful {
+ if v.Rootfull == opts.Rootfull {
return nil
}
@@ -744,7 +744,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
if changeCon {
newDefault := v.Name
- if opts.Rootful {
+ if opts.Rootfull {
newDefault += "-root"
}
if err := machine.ChangeDefault(newDefault); err != nil {
@@ -752,7 +752,7 @@ func (v *MachineVM) Set(name string, opts machine.SetOptions) error {
}
}
- v.Rootful = opts.Rootful
+ v.Rootfull = opts.Rootfull
return v.writeConfig()
}
@@ -768,7 +768,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
return errors.Wrap(err, "WSL bootstrap script failed")
}
- if !v.Rootful {
+ if !v.Rootfull {
fmt.Printf("\nThis machine is currently configured in rootless mode. If your containers\n")
fmt.Printf("require root permissions (e.g. ports < 1024), or if you run into compatibility\n")
fmt.Printf("issues with non-podman clients, you can switch using the following command: \n")
@@ -777,7 +777,7 @@ func (v *MachineVM) Start(name string, _ machine.StartOptions) error {
if name != machine.DefaultMachineName {
suffix = " " + name
}
- fmt.Printf("\n\tpodman machine set --rootful%s\n\n", suffix)
+ fmt.Printf("\n\tpodman machine set --rootfull%s\n\n", suffix)
}
globalName, pipeName, err := launchWinProxy(v)
@@ -833,7 +833,7 @@ func launchWinProxy(v *MachineVM) (bool, string, error) {
destSock := "/run/user/1000/podman/podman.sock"
forwardUser := v.RemoteUsername
- if v.Rootful {
+ if v.Rootfull {
destSock = "/run/podman/podman.sock"
forwardUser = "root"
}
diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go
index 5f4218899..81286b962 100644
--- a/pkg/specgen/generate/container.go
+++ b/pkg/specgen/generate/container.go
@@ -346,7 +346,7 @@ func FinishThrottleDevices(s *specgen.SpecGenerator) error {
return nil
}
-// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an exisiting container
+// ConfigToSpec takes a completed container config and converts it back into a specgenerator for purposes of cloning an existing container
func ConfigToSpec(rt *libpod.Runtime, specg *specgen.SpecGenerator, contaierID string) (*libpod.Container, *libpod.InfraInherit, error) {
c, err := rt.LookupContainer(contaierID)
if err != nil {
diff --git a/pkg/specgen/generate/container_create.go b/pkg/specgen/generate/container_create.go
index 5667a02e8..021b88280 100644
--- a/pkg/specgen/generate/container_create.go
+++ b/pkg/specgen/generate/container_create.go
@@ -293,7 +293,7 @@ func createContainerOptions(ctx context.Context, rt *libpod.Runtime, s *specgen.
"/usr/sbin/init": true,
"/usr/local/sbin/init": true,
}
- // Grab last command incase this is launched from a shell
+ // Grab last command in case this is launched from a shell
cmd := command
if len(command) > 2 {
// Podman build will add "/bin/sh" "-c" to
diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go
index aa07de0af..95ce420f8 100644
--- a/pkg/specgenutil/volumes.go
+++ b/pkg/specgenutil/volumes.go
@@ -1,6 +1,7 @@
package specgenutil
import (
+ "encoding/csv"
"fmt"
"path/filepath"
"strings"
@@ -152,7 +153,15 @@ func findMountType(input string) (mountType string, tokens []string, err error)
// Split by comma, iterate over the slice and look for
// "type=$mountType". Everything else is appended to tokens.
found := false
- for _, s := range strings.Split(input, ",") {
+ csvReader := csv.NewReader(strings.NewReader(input))
+ records, err := csvReader.ReadAll()
+ if err != nil {
+ return "", nil, err
+ }
+ if len(records) != 1 {
+ return "", nil, errInvalidSyntax
+ }
+ for _, s := range records[0] {
kv := strings.Split(s, "=")
if found || !(len(kv) == 2 && kv[0] == "type") {
tokens = append(tokens, s)
diff --git a/rootless.md b/rootless.md
index 39c961d2a..d485290f2 100644
--- a/rootless.md
+++ b/rootless.md
@@ -18,7 +18,7 @@ can easily fail
* Some system unit configuration options do not work in the rootless container
* systemd fails to apply several options and failures are silently ignored (e.g. CPUShares, MemoryLimit). Should work on cgroup V2.
* Use of certain options will cause service startup failures (e.g. PrivateNetwork). The systemd services requiring `PrivateNetwork` can be made to work by passing `--cap-add SYS_ADMIN`, but the security implications should be carefully evaluated. In most cases, it's better to create an override.conf drop-in that sets `PrivateNetwork=no`. This also applies to containers run by root.
-* Can not share container images with CRI-O or other rootful users
+* Can not share container images with CRI-O or other rootfull users
* Difficult to use additional stores for sharing content
* Does not work on NFS or parallel filesystem homedirs (e.g. [GPFS](https://www.ibm.com/support/knowledgecenter/en/SSFKCN/gpfs_welcome.html))
* NFS and parallel filesystems enforce file creation on different UIDs on the server side and does not understand User Namespace.
diff --git a/test/e2e/container_clone_test.go b/test/e2e/container_clone_test.go
index 1d5944d1a..1ff4b3b5f 100644
--- a/test/e2e/container_clone_test.go
+++ b/test/e2e/container_clone_test.go
@@ -235,4 +235,36 @@ var _ = Describe("Podman container clone", func() {
Expect(ctrInspect.InspectContainerToJSON()[0].HostConfig.NetworkMode).Should(ContainSubstring("container:"))
})
+
+ It("podman container clone --destroy --force test", func() {
+ create := podmanTest.Podman([]string{"create", ALPINE})
+ create.WaitWithDefaultTimeout()
+ Expect(create).To(Exit(0))
+ clone := podmanTest.Podman([]string{"container", "clone", "--destroy", create.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ inspect := podmanTest.Podman([]string{"inspect", create.OutputToString()})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).ToNot(Exit(0))
+
+ run := podmanTest.Podman([]string{"run", "-dt", ALPINE})
+ run.WaitWithDefaultTimeout()
+ Expect(run).To(Exit(0))
+ clone = podmanTest.Podman([]string{"container", "clone", "--destroy", "-f", run.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).To(Exit(0))
+
+ inspect = podmanTest.Podman([]string{"inspect", run.OutputToString()})
+ inspect.WaitWithDefaultTimeout()
+ Expect(inspect).ToNot(Exit(0))
+
+ run = podmanTest.Podman([]string{"run", "-dt", ALPINE})
+ run.WaitWithDefaultTimeout()
+ Expect(run).To(Exit(0))
+ clone = podmanTest.Podman([]string{"container", "clone", "-f", run.OutputToString()})
+ clone.WaitWithDefaultTimeout()
+ Expect(clone).ToNot(Exit(0))
+
+ })
})
diff --git a/test/e2e/exec_test.go b/test/e2e/exec_test.go
index 3987746d0..4cfaa9a2e 100644
--- a/test/e2e/exec_test.go
+++ b/test/e2e/exec_test.go
@@ -123,7 +123,7 @@ var _ = Describe("Podman exec", func() {
})
It("podman exec in keep-id container drops privileges", func() {
- SkipIfNotRootless("This function is not enabled for rootful podman")
+ SkipIfNotRootless("This function is not enabled for rootfull podman")
ctrName := "testctr1"
testCtr := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--userns=keep-id", ALPINE, "top"})
testCtr.WaitWithDefaultTimeout()
diff --git a/test/e2e/mount_rootless_test.go b/test/e2e/mount_rootless_test.go
index 30d7ce8a9..830c2dcda 100644
--- a/test/e2e/mount_rootless_test.go
+++ b/test/e2e/mount_rootless_test.go
@@ -17,7 +17,7 @@ var _ = Describe("Podman mount", func() {
)
BeforeEach(func() {
- SkipIfNotRootless("This function is not enabled for rootful podman")
+ SkipIfNotRootless("This function is not enabled for rootfull podman")
SkipIfRemote("Podman mount not supported for remote connections")
tempdir, err = CreateTempDirInTempDir()
if err != nil {
diff --git a/test/e2e/network_test.go b/test/e2e/network_test.go
index 89a9005f5..a7981a4d8 100644
--- a/test/e2e/network_test.go
+++ b/test/e2e/network_test.go
@@ -254,7 +254,7 @@ var _ = Describe("Podman network", func() {
expectedNetworks := []string{name}
if !rootless.IsRootless() {
- // rootful image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
+ // rootfull image contains "podman/cni/87-podman-bridge.conflist" for "podman" network
expectedNetworks = append(expectedNetworks, "podman")
}
session := podmanTest.Podman(append([]string{"network", "inspect"}, expectedNetworks...))
diff --git a/test/e2e/run_volume_test.go b/test/e2e/run_volume_test.go
index 4887197f6..0be84e11b 100644
--- a/test/e2e/run_volume_test.go
+++ b/test/e2e/run_volume_test.go
@@ -120,6 +120,11 @@ var _ = Describe("Podman run with volumes", func() {
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
+ // test csv escaping
+ session = podmanTest.Podman([]string{"run", "--rm", "--mount=type=tmpfs,tmpfs-size=512M,\"destination=/test,\"", ALPINE, "ls", "/test,"})
+ session.WaitWithDefaultTimeout()
+ Expect(session).Should(Exit(0))
+
session = podmanTest.Podman([]string{"run", "--rm", "--mount", "type=bind,src=/tmp,target=/tmp,tmpcopyup", ALPINE, "true"})
session.WaitWithDefaultTimeout()
Expect(session).To(ExitWithError())
diff --git a/test/system/000-TEMPLATE b/test/system/000-TEMPLATE
index 85e25e921..a6a9ca141 100644
--- a/test/system/000-TEMPLATE
+++ b/test/system/000-TEMPLATE
@@ -10,7 +10,7 @@ load helpers
@test "podman subcmd - description of this particular test" {
args="some sort of argument list"
run_podman subcmd $args
- is "$output" "what we expect" "output from 'podman subcmd $args'"
+ assert "$output" == "what we expect" "output from 'podman subcmd $args'"
}
# vim: filetype=sh
@@ -66,7 +66,7 @@ function teardown() {
# FIXME: example of dprint. This will trigger if PODMAN_TEST_DEBUG=FOO
# FIXME: ...or anything that matches the name assigned in the @test line.
dprint "podman logs $cid -> '$output'"
- is "$output" "what are we expecting?" "description of this check"
+ assert "$output" == "what are we expecting?" "description of this check"
# Clean up
run_podman rm $cid
@@ -90,7 +90,7 @@ size | -\\\?[0-9]\\\+
run_podman history --format json $IMAGE
# FIXME: parse_table is what does all the work, giving us test cases.
- parse_table "$tests" | while read field expect; do
+ while read field expect; do
# FIXME: this shows a drawback of BATS and bash: we can't include '|'
# FIXME: in the table, but we need to because some images don't
# FIXME: have a CID. So, yeah, this is ugly -- but rare.
@@ -104,10 +104,10 @@ size | -\\\?[0-9]\\\+
# FIXME: please be sure to note the third field!
# FIXME: that's the test name. Make it something useful! Include
# FIXME: loop variables whenever possible. Don't just say "my test"
- is "$actual" "$expect\$" "jq .[$i].$field"
+ assert "$actual" =~ "$expect\$" "jq .[$i].$field"
i=$(expr $i + 1)
done
- done
+ done < <(parse_table "$tests")
}
diff --git a/test/system/001-basic.bats b/test/system/001-basic.bats
index 582efa058..0d2a99d4b 100644
--- a/test/system/001-basic.bats
+++ b/test/system/001-basic.bats
@@ -28,9 +28,7 @@ function setup() {
# Test that build date is reasonable, e.g. after 2019-01-01
local built=$(expr "$output" : ".*Built: \+\(.*\)" | head -n1)
local built_t=$(date --date="$built" +%s)
- if [ $built_t -lt 1546300800 ]; then
- die "Preposterous 'Built' time in podman version: '$built'"
- fi
+ assert "$built_t" -gt 1546300800 "Preposterous 'Built' time in podman version"
}
@test "podman info" {
@@ -114,29 +112,25 @@ See 'podman version --help'" "podman version --remote"
# By default, podman should include '--remote' in its help output
run_podman --help
- is "$output" ".* --remote " "podman --help includes the --remote option"
+ assert "$output" =~ " --remote " "podman --help includes the --remote option"
# When it detects CONTAINER_HOST or _CONNECTION, --remote is not an option
CONTAINER_HOST=foobar run_podman --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with CONTAINER_HOST set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with CONTAINER_HOST set, should not show --remote"
CONTAINER_CONNECTION=foobar run_podman --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with CONTAINER_CONNECTION set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with CONTAINER_CONNECTION set, should not show --remote"
# When it detects --url or --connection, --remote is not an option
run_podman --url foobar --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with --url set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with --url set, should not show --remote"
run_podman --connection foobar --help
- if grep -- " --remote " <<<"$output"; then
- die "podman --help, with --connection set, is showing --remote"
- fi
+ assert "$output" !~ " --remote " \
+ "podman --help, with --connection set, should not show --remote"
}
# Check that just calling "podman-remote" prints the usage message even
diff --git a/test/system/015-help.bats b/test/system/015-help.bats
index 4eeea85bf..5757d51dc 100644
--- a/test/system/015-help.bats
+++ b/test/system/015-help.bats
@@ -27,7 +27,7 @@ function check_help() {
# The line immediately after 'Usage:' gives us a 1-line synopsis
usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
- [ -n "$usage" ] || die "podman $cmd: no Usage message found"
+ assert "$usage" != "" "podman $cmd: no Usage message found"
# e.g. 'podman ps' should not show 'podman container ps' in usage
# Trailing space in usage handles 'podman system renumber' which
@@ -42,14 +42,12 @@ function check_help() {
fi
# We had someone write upper-case '[OPTIONS]' once. Prevent it.
- if expr "$usage" : '.*\[OPTION' >/dev/null; then
- die "'options' string must be lower-case in usage: $usage"
- fi
+ assert "$usage" !~ '\[OPTION' \
+ "'options' string must be lower-case in usage"
# We had someone do 'podman foo ARG [options]' one time. Yeah, no.
- if expr "$usage" : '.*[A-Z].*\[option' >/dev/null; then
- die "'options' must precede arguments in usage: $usage"
- fi
+ assert "$usage" !~ '[A-Z].*\[option' \
+ "'options' must precede arguments in usage"
# Cross-check: if usage includes '[options]', there must be a
# longer 'Options:' section in the full --help output; vice-versa,
@@ -169,16 +167,15 @@ function check_help() {
# This can happen if the output of --help changes, such as between
# the old command parser and cobra.
- [ $count -gt 0 ] || \
- die "Internal error: no commands found in 'podman help $@' list"
+ assert "$count" -gt 0 \
+ "Internal error: no commands found in 'podman help $*' list"
# Sanity check: make sure the special loops above triggered at least once.
# (We've had situations where a typo makes the conditional never run)
if [ -z "$*" ]; then
for i in subcommands required_args takes_no_args fixed_args; do
- if [[ -z ${found[$i]} ]]; then
- die "Internal error: '$i' subtest did not trigger"
- fi
+ assert "${found[$i]}" != "" \
+ "Internal error: '$i' subtest did not trigger"
done
fi
}
diff --git a/test/system/030-run.bats b/test/system/030-run.bats
index aba18badb..526003c2d 100644
--- a/test/system/030-run.bats
+++ b/test/system/030-run.bats
@@ -78,12 +78,11 @@ echo $rand | 0 | $rand
skip_if_remote "TODO Fix this for remote case"
run_podman run --rm --uidmap 0:100:10000 $IMAGE mount
- run grep /sys/kernel <(echo "$output")
- is "$output" "" "unwanted /sys/kernel in 'mount' output"
+ assert "$output" !~ /sys/kernel "unwanted /sys/kernel in 'mount' output"
run_podman run --rm --net host --uidmap 0:100:10000 $IMAGE mount
- run grep /sys/kernel <(echo "$output")
- is "$output" "" "unwanted /sys/kernel in 'mount' output (with --net=host)"
+ assert "$output" !~ /sys/kernel \
+ "unwanted /sys/kernel in 'mount' output (with --net=host)"
}
# 'run --rm' goes through different code paths and may lose exit status.
@@ -692,10 +691,8 @@ json-file | f
# This operation should take
# exactly 10 seconds. Give it some leeway.
delta_t=$(( $t1 - $t0 ))
- [ $delta_t -gt 8 ] ||\
- die "podman stop: ran too quickly! ($delta_t seconds; expected >= 10)"
- [ $delta_t -le 14 ] ||\
- die "podman stop: took too long ($delta_t seconds; expected ~10)"
+ assert "$delta_t" -gt 8 "podman stop: ran too quickly!"
+ assert "$delta_t" -le 14 "podman stop: took too long"
run_podman rm $cid
}
@@ -753,34 +750,40 @@ EOF
@test "podman run defaultenv" {
run_podman run --rm $IMAGE printenv
- is "$output" ".*TERM=xterm" "output matches TERM"
- is "$output" ".*container=podman" "output matches container=podman"
+ assert "$output" =~ "TERM=xterm" "env includes TERM"
+ assert "$output" =~ "container=podman" "env includes container=podman"
run_podman run --unsetenv=TERM --rm $IMAGE printenv
- is "$output" ".*container=podman" "output matches container=podman"
- run grep TERM <<<$output
- is "$output" "" "unwanted TERM environment variable despite --unsetenv=TERM"
+ assert "$output" =~ "container=podman" "env includes container=podman"
+ assert "$output" != "TERM" "unwanted TERM environment variable despite --unsetenv=TERM"
run_podman run --unsetenv-all --rm $IMAGE /bin/printenv
- run grep TERM <<<$output
- is "$output" "" "unwanted TERM environment variable despite --unsetenv-all"
- run grep container <<<$output
- is "$output" "" "unwanted container environment variable despite --unsetenv-all"
- run grep PATH <<<$output
- is "$output" "" "unwanted PATH environment variable despite --unsetenv-all"
+ for v in TERM container PATH; do
+ assert "$output" !~ "$v" "variable present despite --unsetenv-all"
+ done
run_podman run --unsetenv-all --env TERM=abc --rm $IMAGE /bin/printenv
- is "$output" ".*TERM=abc" "missing TERM environment variable despite TERM being set on commandline"
+ assert "$output" =~ "TERM=abc" \
+ "missing TERM environment variable despite TERM being set on commandline"
}
@test "podman run - no /etc/hosts" {
+ if [[ -z "$container" ]]; then
+ skip "Test is too dangerous to run in a non-container environment"
+ fi
skip_if_rootless "cannot move /etc/hosts file as a rootless user"
- tmpfile=$PODMAN_TMPDIR/hosts
- mv /etc/hosts $tmpfile
+
+ local hosts_tmp=/etc/hosts.RENAME-ME-BACK-TO-JUST-HOSTS
+ if [[ -e $hosts_tmp ]]; then
+ die "Internal error: leftover backup hosts file: $hosts_tmp"
+ fi
+ mv /etc/hosts $hosts_tmp
run_podman '?' run --rm --add-host "foo.com:1.2.3.4" $IMAGE cat "/etc/hosts"
- mv $tmpfile /etc/hosts
- is "$status" 0 "podman run without /etc/hosts file should work"
- is "$output" "1.2.3.4 foo.com.*" "users can add hosts even without /etc/hosts"
+ mv $hosts_tmp /etc/hosts
+ assert "$status" = 0 \
+ "podman run without /etc/hosts file should work"
+ assert "$output" =~ "^1\.2\.3\.4 foo.com.*" \
+ "users can add hosts even without /etc/hosts"
}
# rhbz#1854566 : $IMAGE has incorrect permission 555 on the root '/' filesystem
diff --git a/test/system/035-logs.bats b/test/system/035-logs.bats
index e38cdb383..97d984ef1 100644
--- a/test/system/035-logs.bats
+++ b/test/system/035-logs.bats
@@ -224,9 +224,8 @@ $s_after"
retries=$((retries - 1))
sleep 0.1
done
- if [[ $retries -eq 0 ]]; then
- die "Timed out waiting for before&after in podman logs: $output"
- fi
+ assert $retries -gt 0 \
+ "Timed out waiting for before&after in podman logs: $output"
run_podman logs --until $before test
is "$output" "" "podman logs --until before"
diff --git a/test/system/040-ps.bats b/test/system/040-ps.bats
index 6fc0b9b6e..f450caf7c 100644
--- a/test/system/040-ps.bats
+++ b/test/system/040-ps.bats
@@ -98,9 +98,8 @@ RUN sleep 30
EOF
local t1=$SECONDS
local delta_t=$((t1 - t0))
- if [[ $delta_t -gt 10 ]]; then
- die "podman build did not get killed within 10 seconds (actual time: $delta_t seconds)"
- fi
+ assert $delta_t -le 10 \
+ "podman build did not get killed within 10 seconds"
run_podman ps -a
is "${#lines[@]}" "1" "podman ps -a does not see buildah containers"
diff --git a/test/system/045-start.bats b/test/system/045-start.bats
index 31e924ca5..ad8483bba 100644
--- a/test/system/045-start.bats
+++ b/test/system/045-start.bats
@@ -21,9 +21,8 @@ load helpers
is "$output" ".*$cid_none_implicit" "started: container with no --restart"
is "$output" ".*$cid_none_explicit" "started: container with --restart=no"
is "$output" ".*$cid_on_failure" "started: container with --restart=on-failure"
- if [[ $output =~ $cid_always ]]; then
- die "podman start --all restarted a running container"
- fi
+ assert "$output" !~ "$cid_always" \
+ "podman start --all should not restart a running container"
run_podman wait $cid_none_implicit $cid_none_explicit $cid_on_failure
diff --git a/test/system/050-stop.bats b/test/system/050-stop.bats
index 7dd8f98e8..c2dfba84d 100644
--- a/test/system/050-stop.bats
+++ b/test/system/050-stop.bats
@@ -22,10 +22,8 @@ load helpers
# The initial SIGTERM is ignored, so this operation should take
# exactly 10 seconds. Give it some leeway.
delta_t=$(( $t1 - $t0 ))
- [ $delta_t -gt 8 ] ||\
- die "podman stop: ran too quickly! ($delta_t seconds; expected >= 10)"
- [ $delta_t -le 14 ] ||\
- die "podman stop: took too long ($delta_t seconds; expected ~10)"
+ assert $delta_t -gt 8 "podman stop: ran too quickly!"
+ assert $delta_t -le 14 "podman stop: took too long"
run_podman rm $cid
}
@@ -103,8 +101,7 @@ load helpers
# The 'stop' command should return almost instantaneously
delta_t=$(( $t1 - $t0 ))
- [ $delta_t -le 2 ] ||\
- die "podman stop: took too long ($delta_t seconds; expected <= 2)"
+ assert $delta_t -le 2 "podman stop: took too long"
run_podman rm $cid
done
@@ -138,9 +135,7 @@ load helpers
break
fi
timeout=$((timeout - 1))
- if [[ $timeout -eq 0 ]]; then
- die "Timed out waiting for container to receive SIGERM"
- fi
+ assert $timeout -gt 0 "Timed out waiting for container to receive SIGTERM"
sleep 0.5
done
@@ -154,9 +149,7 @@ load helpers
# Time check: make sure we were able to run 'ps' before the container
# exited. If this takes too long, it means ps had to wait for lock.
local delta_t=$(( $SECONDS - t0 ))
- if [[ $delta_t -gt 5 ]]; then
- die "Operations took too long ($delta_t seconds)"
- fi
+ assert $delta_t -le 5 "Operations took too long"
run_podman kill stopme
run_podman wait stopme
diff --git a/test/system/065-cp.bats b/test/system/065-cp.bats
index 780fc6737..fe9292fd0 100644
--- a/test/system/065-cp.bats
+++ b/test/system/065-cp.bats
@@ -589,20 +589,22 @@ ${randomcontent[1]}" "$description"
# RUNNING container
# NOTE: /dest does not exist yet but is expected to be created during copy
run_podman cp cpcontainer:/tmp/sub/weirdlink $destdir/dest
- run cat $destdir/dest/containerfile0 $destdir/dest/containerfile1
- is "${lines[0]}" "${randomcontent[0]}" "eval symlink - running container"
- is "${lines[1]}" "${randomcontent[1]}" "eval symlink - running container"
+ for i in 0 1; do
+ assert "$(< $destdir/dest/containerfile$i)" = "${randomcontent[$i]}" \
+ "eval symlink - running container - file $i/1"
+ done
run_podman kill cpcontainer
run_podman rm -t 0 -f cpcontainer
- run rm -rf $srcdir/dest
+ rm -rf $srcdir/dest
# CREATED container
run_podman create --name cpcontainer $cpimage
run_podman cp cpcontainer:/tmp/sub/weirdlink $destdir/dest
- run cat $destdir/dest/containerfile0 $destdir/dest/containerfile1
- is "${lines[0]}" "${randomcontent[0]}" "eval symlink - created container"
- is "${lines[1]}" "${randomcontent[1]}" "eval symlink - created container"
+ for i in 0 1; do
+ assert "$(< $destdir/dest/containerfile$i)" = "${randomcontent[$i]}" \
+ "eval symlink - created container - file $i/1"
+ done
run_podman rm -t 0 -f cpcontainer
run_podman rmi $cpimage
}
@@ -924,20 +926,16 @@ ${randomcontent[1]}" "$description"
# Copy file.
$PODMAN cp cpcontainer:/tmp/file.txt - > $srcdir/stdout.tar
- if [ $? -ne 0 ]; then
- die "Command failed: podman cp ... - | cat"
- fi
tar xvf $srcdir/stdout.tar -C $srcdir
- is "$(< $srcdir/file.txt)" "$rand_content"
- run 1 ls $srcdir/empty.txt
+ is "$(< $srcdir/file.txt)" "$rand_content" "File contents: file.txt"
+ if [[ -e "$srcdir/empty.txt" ]]; then
+ die "File should not exist, but does: empty.txt"
+ fi
rm -f $srcdir/*
# Copy directory.
$PODMAN cp cpcontainer:/tmp - > $srcdir/stdout.tar
- if [ $? -ne 0 ]; then
- die "Command failed: podman cp ... - | cat : $output"
- fi
tar xvf $srcdir/stdout.tar -C $srcdir
is "$(< $srcdir/tmp/file.txt)" "$rand_content"
diff --git a/test/system/070-build.bats b/test/system/070-build.bats
index 7466c3b74..b7e0ab447 100644
--- a/test/system/070-build.bats
+++ b/test/system/070-build.bats
@@ -60,21 +60,18 @@ EOF
# Now confirm that each volume got a unique device ID
run_podman run --rm build_test stat -c '%D' / /a /a/b /a/b/c /\[ /\[/etc /\[/etc/foo, /etc /etc/bar\]
# First, the non-volumes should all be the same...
- is "${lines[0]}" "${lines[1]}" "devnum( / ) = devnum( /a )"
- is "${lines[0]}" "${lines[2]}" "devnum( / ) = devnum( /a/b )"
- is "${lines[0]}" "${lines[4]}" "devnum( / ) = devnum( /[ )"
- is "${lines[0]}" "${lines[5]}" "devnum( / ) = devnum( /[etc )"
- is "${lines[0]}" "${lines[7]}" "devnum( / ) = devnum( /etc )"
- is "${lines[6]}" "${lines[8]}" "devnum( /[etc/foo, ) = devnum( /etc/bar] )"
+ assert "${lines[0]}" = "${lines[1]}" "devnum( / ) = devnum( /a )"
+ assert "${lines[0]}" = "${lines[2]}" "devnum( / ) = devnum( /a/b )"
+ assert "${lines[0]}" = "${lines[4]}" "devnum( / ) = devnum( /[ )"
+ assert "${lines[0]}" = "${lines[5]}" "devnum( / ) = devnum( /[etc )"
+ assert "${lines[0]}" = "${lines[7]}" "devnum( / ) = devnum( /etc )"
+ assert "${lines[6]}" = "${lines[8]}" "devnum( /[etc/foo, ) = devnum( /etc/bar] )"
# ...then, each volume should be different
- if [[ "${lines[0]}" = "${lines[3]}" ]]; then
- die "devnum( / ) (${lines[0]}) = devnum( volume0 ) (${lines[3]}) -- they should differ"
- fi
- if [[ "${lines[0]}" = "${lines[6]}" ]]; then
- die "devnum( / ) (${lines[0]}) = devnum( volume1 ) (${lines[6]}) -- they should differ"
- fi
+ assert "${lines[0]}" != "${lines[3]}" "devnum( / ) != devnum( volume0 )"
+ assert "${lines[0]}" != "${lines[6]}" "devnum( / ) != devnum( volume1 )"
+
# FIXME: is this expected? I thought /a/b/c and /[etc/foo, would differ
- is "${lines[3]}" "${lines[6]}" "devnum( volume0 ) = devnum( volume1 )"
+ assert "${lines[3]}" = "${lines[6]}" "devnum( volume0 ) = devnum( volume1 )"
run_podman rmi -f build_test
}
@@ -106,7 +103,7 @@ EOF
rand_content=$(random_string 50)
tmpdir=$PODMAN_TMPDIR/build-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containerfile=$tmpdir/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
@@ -122,7 +119,7 @@ EOF
# Test on the CLI and via containers.conf
tmpdir=$PODMAN_TMPDIR/build-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containerfile=$tmpdir/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
@@ -146,10 +143,10 @@ EOF
@test "podman build - cache (#3920)" {
# Make an empty test directory, with a subdirectory used for tar
tmpdir=$PODMAN_TMPDIR/build-test
- mkdir -p $tmpdir/subtest || die "Could not mkdir $tmpdir/subtest"
+ mkdir -p $tmpdir/subtest
echo "This is the ORIGINAL file" > $tmpdir/subtest/myfile1
- run tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
+ tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
cat >$tmpdir/Dockerfile <<EOF
FROM $IMAGE
@@ -169,7 +166,7 @@ EOF
# Step 2: Recreate the tarfile, with new content. Rerun podman build.
echo "This is a NEW file" >| $tmpdir/subtest/myfile2
- run tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
+ tar -C $tmpdir -cJf $tmpdir/myfile.tar.xz subtest
run_podman build -t build_test -f $tmpdir/Dockerfile $tmpdir
is "$output" ".*COMMIT" "COMMIT seen in log"
@@ -371,9 +368,8 @@ EOF
-t build_test -f build-test/Containerfile build-test
local iid="${lines[-1]}"
- if [[ $output =~ missing.*build.argument ]]; then
- die "podman did not see the given --build-arg(s)"
- fi
+ assert "$output" !~ "missing.*build.argument" \
+ "podman did not see the given --build-arg(s)"
# Make sure 'podman build' had the secret mounted
is "$output" ".*$secret_contents.*" "podman build has /run/secrets mounted"
@@ -449,9 +445,7 @@ EOF
run_podman image inspect build_test
# (Assert that output is formatted, not a one-line blob: #8011)
- if [[ "${#lines[*]}" -lt 10 ]]; then
- die "Output from 'image inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 10 "Output from 'image inspect'; see #8011"
tests="
Env[1] | MYENV1=$s_env1
@@ -591,12 +585,11 @@ EOF
for f in ${files[@]}; do
if [[ $f =~ ^- ]]; then
f=${f##-}
- if [[ $output =~ $f ]]; then
- die "File '$f' found in image; it should have been ignored via $ignorefile"
- fi
+ assert "$output" !~ "$f" \
+ "File '$f' should have been ignored via $ignorefile"
else
- is "$output" ".*$newdir/$f" \
- "File '$f' should exist in container (no match in $ignorefile)"
+ assert "$output" =~ "$newdir/$f" \
+ "File '$f' should exist in container (no match in $ignorefile)"
fi
done
@@ -727,7 +720,7 @@ a${random3}z"
@test "podman build --layers test" {
rand_content=$(random_string 50)
tmpdir=$PODMAN_TMPDIR/build-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containerfile=$tmpdir/Containerfile
cat >$containerfile <<EOF
FROM $IMAGE
@@ -870,8 +863,7 @@ FROM $IMAGE
EOF
run_podman build -t build_test --format=docker --logfile=$tmpdir/logfile $tmpbuilddir
- run cat $tmpdir/logfile
- is "$output" ".*COMMIT" "COMMIT seen in log"
+ assert "$(< $tmpdir/logfile)" =~ "COMMIT" "COMMIT seen in log"
run_podman rmi -f build_test
}
diff --git a/test/system/090-events.bats b/test/system/090-events.bats
index cac0a177c..128802360 100644
--- a/test/system/090-events.bats
+++ b/test/system/090-events.bats
@@ -126,8 +126,7 @@ function _events_disjunctive_filters() {
events_logfile_path="$events_file"
EOF
CONTAINERS_CONF="$containersconf" run_podman --events-backend=file pull $IMAGE
- run cat $events_file
- is "$output" ".*\"Name\":\"$IMAGE" "test"
+ assert "$(< $events_file)" =~ "\"Name\":\"$IMAGE\"" "Image found in events"
}
function _populate_events_file() {
@@ -172,7 +171,7 @@ EOF
[engine]
events_logger="file"
events_logfile_path="$eventsFile"
-# The limit of 4750 is the *exact* half of the inital events file.
+# The limit of 4750 is the *exact* half of the initial events file.
events_logfile_max_size=4750
EOF
diff --git a/test/system/120-load.bats b/test/system/120-load.bats
index 8bf785081..45e0b3362 100644
--- a/test/system/120-load.bats
+++ b/test/system/120-load.bats
@@ -52,9 +52,7 @@ verify_iid_and_name() {
# which redirects stdout and stderr. Here we need to guarantee
# that podman's stdout is a pipe, not any other form of redirection
$PODMAN save --format oci-archive $fqin | cat >$archive
- if [ "$status" -ne 0 ]; then
- die "Command failed: podman save ... | cat"
- fi
+ assert "$?" -eq 0 "Command failed: podman save ... | cat"
# Make sure we can reload it
run_podman rmi $fqin
@@ -265,9 +263,7 @@ verify_iid_and_name() {
# which redirects stdout and stderr. Here we need to guarantee
# that podman's stdout is a pipe, not any other form of redirection
$PODMAN save -m $img1 $img2 | cat >$archive
- if [ "$status" -ne 0 ]; then
- die "Command failed: podman save ... | cat"
- fi
+ assert "$?" -eq 0 "Command failed: podman save ... | cat"
run_podman rmi -f $img1 $img2
run_podman load -i $archive
@@ -284,7 +280,7 @@ verify_iid_and_name() {
# Create a tarball, unpack it and make sure the layers are uncompressed.
run_podman save -o $archive --format oci-archive --uncompressed $IMAGE
- run tar -C $untar -xvf $archive
+ tar -C $untar -xvf $archive
run file $untar/blobs/sha256/*
is "$output" ".*POSIX tar archive" "layers are uncompressed"
}
diff --git a/test/system/160-volumes.bats b/test/system/160-volumes.bats
index d0088b994..571d8767e 100644
--- a/test/system/160-volumes.bats
+++ b/test/system/160-volumes.bats
@@ -282,9 +282,7 @@ EOF
# (Assert that output is formatted, not a one-line blob: #8011)
run_podman volume inspect ${v[1]}
- if [[ "${#lines[*]}" -lt 10 ]]; then
- die "Output from 'volume inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 10 "Output from 'volume inspect'; see #8011"
# Run two containers: one mounting v1, one mounting v2 & v3
run_podman run --name c1 --volume ${v[1]}:/vol1 $IMAGE date
diff --git a/test/system/180-blkio.bats b/test/system/180-blkio.bats
index 7999c9ec5..7b7fb0201 100644
--- a/test/system/180-blkio.bats
+++ b/test/system/180-blkio.bats
@@ -31,7 +31,8 @@ function teardown() {
losetup -f ${lofile}
run losetup -l --noheadings --output BACK-FILE,NAME,MAJ:MIN
- is "$output" ".\+" "Empty output from losetup"
+ assert "$status" -eq 0 "losetup: status"
+ assert "$output" != "" "losetup: output"
lodevice=$(awk "\$1 == \"$lofile\" { print \$2 }" <<<"$output")
lomajmin=$(awk "\$1 == \"$lofile\" { print \$3 }" <<<"$output")
diff --git a/test/system/190-run-ipcns.bats b/test/system/190-run-ipcns.bats
index 9327d8ec7..db1d716d7 100644
--- a/test/system/190-run-ipcns.bats
+++ b/test/system/190-run-ipcns.bats
@@ -7,30 +7,25 @@
load helpers
@test "podman --ipc=host" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run --rm --ipc=host $IMAGE readlink /proc/self/ns/ipc
is "$output" "$hostipc" "HostIPC and container IPC should be same"
}
@test "podman --ipc=none" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run --rm --ipc=none $IMAGE readlink /proc/self/ns/ipc
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc should != hostipc"
+
run_podman 1 run --rm --ipc=none $IMAGE ls /dev/shm
is "$output" "ls: /dev/shm: No such file or directory" "Should fail with missing /dev/shm"
}
@test "podman --ipc=private" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run -d --ipc=private --name test $IMAGE sleep 100
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc should != hostipc"
+
run_podman 125 run --ipc=container:test --rm $IMAGE readlink /proc/self/ns/ipc
is "$output" ".*is not allowed: non-shareable IPC (hint: use IpcMode:shareable for the donor container)" "Containers should not share private ipc namespace"
run_podman stop -t 0 test
@@ -38,31 +33,26 @@ load helpers
}
@test "podman --ipc=shareable" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run -d --ipc=shareable --name test $IMAGE sleep 100
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc(shareable) should != hostipc"
+
run_podman run --ipc=container:test --rm $IMAGE readlink /proc/self/ns/ipc
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc(:test) should != hostipc"
+
run_podman stop -t 0 test
run_podman rm test
}
@test "podman --ipc=container@test" {
- run readlink /proc/self/ns/ipc
- hostipc=$output
+ hostipc="$(readlink /proc/self/ns/ipc)"
run_podman run -d --name test $IMAGE sleep 100
run_podman exec test readlink /proc/self/ns/ipc
- if [[ $output == "$hostipc" ]]; then
- die "hostipc and containeripc should be different"
- fi
+ assert "$output" != "$hostipc" "containeripc(exec) should != hostipc"
+
testipc=$output
run_podman run --ipc=container:test --rm $IMAGE readlink /proc/self/ns/ipc
- is "$output" "$testipc" "Containers should share ipc namespace"
+ assert "$output" = "$testipc" "Containers should share ipc namespace"
run_podman stop -t 0 test
run_podman rm test
}
diff --git a/test/system/200-pod.bats b/test/system/200-pod.bats
index f5fe41924..56449dcad 100644
--- a/test/system/200-pod.bats
+++ b/test/system/200-pod.bats
@@ -59,7 +59,7 @@ function teardown() {
skip_if_remote "CONTAINERS_CONF only effects server side"
image="i.do/not/exist:image"
tmpdir=$PODMAN_TMPDIR/pod-test
- run mkdir -p $tmpdir
+ mkdir -p $tmpdir
containersconf=$tmpdir/containers.conf
cat >$containersconf <<EOF
[engine]
@@ -86,9 +86,7 @@ EOF
# (Assert that output is formatted, not a one-line blob: #8021)
run_podman pod inspect $podname
- if [[ "${#lines[*]}" -lt 10 ]]; then
- die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 10 "Output from 'pod inspect'; see #8011"
# Randomly-assigned port in the 5xxx range
port=$(random_free_port)
@@ -322,10 +320,11 @@ EOF
run_podman --noout pod create --name $pod_name --infra-name "$infra_name" --infra-image "$infra_image"
is "$output" "" "output from pod create should be empty"
- run_podman '?' pod create --infra-name "$infra_name"
- if [ $status -eq 0 ]; then
- die "Podman should fail when user try to create two pods with the same infra-name value"
- fi
+
+ run_podman 125 pod create --infra-name "$infra_name"
+ assert "$output" =~ "^Error: .*: the container name \"$infra_name\" is already in use by .* You have to remove that container to be able to reuse that name.: that name is already in use" \
+ "Trying to create two pods with same infra-name"
+
run_podman pod rm -f $pod_name
run_podman rmi $infra_image
}
diff --git a/test/system/250-systemd.bats b/test/system/250-systemd.bats
index 6c72e14e8..d0da654ad 100644
--- a/test/system/250-systemd.bats
+++ b/test/system/250-systemd.bats
@@ -18,9 +18,15 @@ function setup() {
}
function teardown() {
- run '?' systemctl stop "$SERVICE_NAME"
- rm -f "$UNIT_FILE"
- systemctl daemon-reload
+ if [[ -e "$UNIT_FILE" ]]; then
+ run systemctl stop "$SERVICE_NAME"
+ if [ $status -ne 0 ]; then
+ echo "# WARNING: systemctl stop failed in teardown: $output" >&3
+ fi
+
+ rm -f "$UNIT_FILE"
+ systemctl daemon-reload
+ fi
run_podman rmi -a
basic_teardown
@@ -36,41 +42,23 @@ function service_setup() {
# Also test enabling services (see #12438).
run systemctl enable "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error enabling systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "Error enabling systemd unit $SERVICE_NAME: $output"
run systemctl start "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error starting systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "Error starting systemd unit $SERVICE_NAME: $output"
run systemctl status "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Non-zero status of systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "systemctl status $SERVICE_NAME: $output"
}
# Helper to stop a systemd service running a container
function service_cleanup() {
local status=$1
run systemctl stop "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error stopping systemd unit $SERVICE_NAME, output: $output"
- fi
+ assert $status -eq 0 "Error stopping systemd unit $SERVICE_NAME: $output"
run systemctl disable "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error disbling systemd unit $SERVICE_NAME, output: $output"
- fi
-
- if [[ -z "$status" ]]; then
- run systemctl is-active "$SERVICE_NAME"
- if [ $status -ne 0 ]; then
- die "Error checking stauts of systemd unit $SERVICE_NAME, output: $output"
- fi
- is "$output" "$status" "$SERVICE_NAME not in expected state"
- fi
+ assert $status -eq 0 "Error disabling systemd unit $SERVICE_NAME: $output"
rm -f "$UNIT_FILE"
systemctl daemon-reload
@@ -230,27 +218,13 @@ LISTEN_FDNAMES=listen_fdnames" | sort)
INSTANCE="$SERVICE_NAME@1.service"
run systemctl start "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Error starting systemd unit $INSTANCE, output: $output"
- fi
+ assert $status -eq 0 "Error starting systemd unit $INSTANCE: $output"
run systemctl status "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Non-zero status of systemd unit $INSTANCE, output: $output"
- fi
+ assert $status -eq 0 "systemctl status $INSTANCE: $output"
run systemctl stop "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Error stopping systemd unit $INSTANCE, output: $output"
- fi
-
- if [[ -z "$status" ]]; then
- run systemctl is-active "$INSTANCE"
- if [ $status -ne 0 ]; then
- die "Error checking stauts of systemd unit $INSTANCE, output: $output"
- fi
- is "$output" "$status" "$INSTANCE not in expected state"
- fi
+ assert $status -eq 0 "Error stopping systemd unit $INSTANCE: $output"
rm -f "$TEMPLATE_FILE_PREFIX@.service"
systemctl daemon-reload
diff --git a/test/system/255-auto-update.bats b/test/system/255-auto-update.bats
index 5a8bf4218..6cdae2ada 100644
--- a/test/system/255-auto-update.bats
+++ b/test/system/255-auto-update.bats
@@ -178,9 +178,8 @@ function _confirm_update() {
is "$output" "$oldID" "container rolled back to previous image"
run_podman container inspect --format "{{.ID}}" $cname
- if [[ $output == $containerID ]]; then
- die "container has not been restarted during rollback (previous id: $containerID, current id: $output)"
- fi
+ assert "$output" != "$containerID" \
+ "container has not been restarted during rollback"
}
@test "podman auto-update - label io.containers.autoupdate=disabled" {
@@ -329,11 +328,9 @@ EOF
for cname in "${cnames[@]}"; do
run_podman inspect --format "{{.Image}}" $cname
if [[ -n "${expect_update[$cname]}" ]]; then
- if [[ "$output" == "$img_id" ]]; then
- die "$cname: image ID ($output) did not change"
- fi
+ assert "$output" != "$img_id" "$cname: image ID did not change"
else
- is "$output" "$img_id" "Image should not be changed."
+ assert "$output" = "$img_id" "Image ID should not be changed."
fi
done
}
diff --git a/test/system/270-socket-activation.bats b/test/system/270-socket-activation.bats
index 6d582be18..19f68abdd 100644
--- a/test/system/270-socket-activation.bats
+++ b/test/system/270-socket-activation.bats
@@ -90,7 +90,7 @@ function teardown() {
@test "podman system service - socket activation - kill rootless pause" {
if ! is_rootless; then
- skip "there is no pause process when running rootful"
+ skip "there is no pause process when running rootfull"
fi
run_podman run -d $IMAGE sleep 90
cid="$output"
diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats
index cf0d0e6bf..710ff066c 100644
--- a/test/system/400-unprivileged-access.bats
+++ b/test/system/400-unprivileged-access.bats
@@ -128,9 +128,7 @@ EOF
# number of links, major, and minor (see below for why). Do it all
# in one go, to avoid multiple podman-runs
run_podman '?' run --rm $IMAGE stat -c'%n:%F:%h:%T:%t' /dev/null ${subset[@]}
- if [[ $status -gt 1 ]]; then
- die "Unexpected exit status $status: expected 0 or 1"
- fi
+ assert $status -le 1 "stat exit status: expected 0 or 1"
local devnull=
for result in "${lines[@]}"; do
diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats
index 056a056f6..21ac4cb8f 100644
--- a/test/system/410-selinux.bats
+++ b/test/system/410-selinux.bats
@@ -135,9 +135,8 @@ function check_label() {
# net NS: do not share context
run_podman run --rm --net container:myctr $IMAGE cat -v /proc/self/attr/current
- if [[ "$output" = "$context_c1" ]]; then
- die "run --net : context ($output) is same as running container (it should not be)"
- fi
+ assert "$output" != "$context_c1" \
+ "run --net : context should != context of running container"
# The 'myctr2' above was not run with --rm, so it still exists, and
# we can't remove the original container until this one is gone.
@@ -189,9 +188,8 @@ function check_label() {
# Even after #7902, labels (':c123,c456') should be different
run_podman run --rm --pod myselinuxpod $IMAGE cat -v /proc/self/attr/current
- if [[ "$output" = "$context_c1" ]]; then
- die "context ($output) is the same on two separate containers, it should have been different"
- fi
+ assert "$output" != "$context_c1" \
+ "context of two separate containers should be different"
run_podman pod rm myselinuxpod
}
diff --git a/test/system/450-interactive.bats b/test/system/450-interactive.bats
index b817fe1a7..a642a2e95 100644
--- a/test/system/450-interactive.bats
+++ b/test/system/450-interactive.bats
@@ -27,9 +27,7 @@ function setup() {
retries=5
while [[ ! -e $PODMAN_TEST_PTY ]]; do
retries=$(( retries - 1 ))
- if [[ $retries -eq 0 ]]; then
- die "Timed out waiting for $PODMAN_TEST_PTY"
- fi
+ assert $retries -gt 0 "Timed out waiting for $PODMAN_TEST_PTY"
sleep 0.5
done
}
diff --git a/test/system/500-networking.bats b/test/system/500-networking.bats
index 78ad3fe04..3bfc58a07 100644
--- a/test/system/500-networking.bats
+++ b/test/system/500-networking.bats
@@ -6,16 +6,12 @@
load helpers
@test "podman network - basic tests" {
- heading="*NETWORK*ID*NAME*DRIVER*"
+ heading="NETWORK *ID *NAME *DRIVER"
run_podman network ls
- if [[ ${output} != ${heading} ]]; then
- die "network ls expected heading is not available"
- fi
+ assert "${lines[0]}" =~ "^$heading\$" "network ls header missing"
run_podman network ls --noheading
- if [[ ${output} = ${heading} ]]; then
- die "network ls --noheading did not remove heading: $output"
- fi
+ assert "$output" !~ "$heading" "network ls --noheading shows header anyway"
# check deterministic list order
local net1=a-$(random_string 10)
@@ -174,9 +170,7 @@ load helpers
# (Assert that output is formatted, not a one-line blob: #8011)
run_podman network inspect $mynetname
- if [[ "${#lines[*]}" -lt 5 ]]; then
- die "Output from 'pod inspect' is only ${#lines[*]} lines; see #8011"
- fi
+ assert "${#lines[*]}" -ge 5 "Output from 'pod inspect'; see #8011"
run_podman run --rm --network $mynetname $IMAGE ip a
is "$output" ".* inet ${mysubnet}\.2/24 brd ${mysubnet}\.255 " \
@@ -265,9 +259,7 @@ load helpers
# check that we cannot curl (timeout after 5 sec)
run timeout 5 curl -s $SERVER/index.txt
- if [ "$status" -ne 124 ]; then
- die "curl did not timeout, status code: $status"
- fi
+ assert $status -eq 124 "curl did not time out"
fi
# reload the network to recreate the iptables rules
@@ -366,16 +358,11 @@ load helpers
# ipv4 slirp
run_podman run --rm --network slirp4netns:enable_ipv6=false $IMAGE cat /etc/resolv.conf
- if grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf contains a ipv6 nameserver"
- fi
+ assert "$output" !~ "$ipv6_regex" "resolv.conf should not contain ipv6 nameserver"
# ipv6 slirp
run_podman run --rm --network slirp4netns:enable_ipv6=true $IMAGE cat /etc/resolv.conf
- # "is" does not like the ipv6 regex
- if ! grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf does not contain a ipv6 nameserver"
- fi
+ assert "$output" =~ "$ipv6_regex" "resolv.conf should contain ipv6 nameserver"
# ipv4 cni
local mysubnet=$(random_rfc1918_subnet)
@@ -385,9 +372,7 @@ load helpers
is "$output" "$netname" "output of 'network create'"
run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf
- if grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf contains a ipv6 nameserver"
- fi
+ assert "$output" !~ "$ipv6_regex" "resolv.conf should not contain ipv6 nameserver"
run_podman network rm -t 0 -f $netname
@@ -399,10 +384,7 @@ load helpers
is "$output" "$netname" "output of 'network create'"
run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf
- # "is" does not like the ipv6 regex
- if ! grep -E "$ipv6_regex" <<< $output; then
- die "resolv.conf does not contain a ipv6 nameserver"
- fi
+ assert "$output" =~ "$ipv6_regex" "resolv.conf should contain ipv6 nameserver"
run_podman network rm -t 0 -f $netname
}
@@ -456,9 +438,8 @@ load helpers
# check that we cannot curl (timeout after 3 sec)
run curl --max-time 3 -s $SERVER/index.txt
- if [ "$status" -eq 0 ]; then
- die "curl did not fail, it should have timed out or failed with non zero exit code"
- fi
+ assert $status -ne 0 \
+ "curl did not fail, it should have timed out or failed with non zero exit code"
run_podman network connect $netname $cid
is "$output" "" "Output should be empty (no errors)"
@@ -470,13 +451,12 @@ load helpers
# check that we have a new ip and mac
# if the ip is still the same this whole test turns into a nop
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").IPAddress}}"
- if [[ "$output" == "$ip" ]]; then
- die "IP address did not change after podman network disconnect/connect"
- fi
+ assert "$output" != "$ip" \
+ "IP address did not change after podman network disconnect/connect"
+
run_podman inspect $cid --format "{{(index .NetworkSettings.Networks \"$netname\").MacAddress}}"
- if [[ "$output" == "$mac" ]]; then
- die "MAC address did not change after podman network disconnect/connect"
- fi
+ assert "$output" != "$mac" \
+ "MAC address did not change after podman network disconnect/connect"
# Disconnect/reconnect of a container *with no ports* should succeed quietly
run_podman network disconnect $netname $background_cid
@@ -552,9 +532,7 @@ load helpers
while kill -0 $pid; do
sleep 0.5
retries=$((retries - 1))
- if [[ $retries -eq 0 ]]; then
- die "Process $pid (container $cid) refused to die"
- fi
+ assert $retries -gt 0 "Process $pid (container $cid) refused to die"
done
# Wait for container to restart
@@ -563,16 +541,13 @@ load helpers
run_podman container inspect --format "{{.State.Pid}}" $cid
# pid is 0 as long as the container is not running
if [[ $output -ne 0 ]]; then
- if [[ $output == $pid ]]; then
- die "This should never happen! Restarted container has same PID ($output) as killed one!"
- fi
+ assert "$output" != "$pid" \
+ "This should never happen! Restarted container has same PID as killed one!"
break
fi
sleep 0.5
retries=$((retries - 1))
- if [[ $retries -eq 0 ]]; then
- die "Timed out waiting for container to restart"
- fi
+ assert $retries -gt 0 "Timed out waiting for container to restart"
done
# Verify http contents again: curl from localhost
diff --git a/test/system/520-checkpoint.bats b/test/system/520-checkpoint.bats
index b41d460a4..c16a8c35d 100644
--- a/test/system/520-checkpoint.bats
+++ b/test/system/520-checkpoint.bats
@@ -80,9 +80,8 @@ function teardown() {
# Get full logs, and make sure something changed
run_podman logs $cid
local nlines_after="${#lines[*]}"
- if [[ $nlines_after -eq $nlines_before ]]; then
- die "Container failed to output new lines after first restore"
- fi
+ assert $nlines_after -gt $nlines_before \
+ "Container failed to output new lines after first restore"
# Same thing again: test for https://github.com/containers/crun/issues/756
# in which, after second checkpoint/restore, we lose logs
@@ -96,9 +95,8 @@ function teardown() {
sleep 0.3
run_podman container logs $cid
nlines_after="${#lines[*]}"
- if [[ $nlines_after -eq $nlines_before ]]; then
- die "stdout went away after second restore (crun issue 756)"
- fi
+ assert $nlines_after -gt $nlines_before \
+ "stdout went away after second restore (crun issue 756)"
run_podman rm -t 0 -f $cid
}
@@ -160,9 +158,8 @@ function teardown() {
sleep .3
run curl --max-time 3 -s $server/mydate
local date_newroot="$output"
- if [[ $date_newroot = $date_oldroot ]]; then
- die "Restored container did not update the timestamp file"
- fi
+ assert "$date_newroot" != "$date_oldroot" \
+ "Restored container did not update the timestamp file"
run_podman exec $cid cat /myvol/cname
is "$output" "$cname" "volume transferred fine"
diff --git a/test/system/600-completion.bats b/test/system/600-completion.bats
index 9fdd42332..018e95e78 100644
--- a/test/system/600-completion.bats
+++ b/test/system/600-completion.bats
@@ -40,7 +40,7 @@ function check_shell_completion() {
# The line immediately after 'Usage:' gives us a 1-line synopsis
usage=$(echo "$full_help" | grep -A1 '^Usage:' | tail -1)
- [ -n "$usage" ] || die "podman $cmd: no Usage message found"
+ assert "$usage" != "" "podman $cmd: no Usage message found"
# If usage ends in '[command]', recurse into subcommands
if expr "$usage" : '.*\[command\]$' >/dev/null; then
@@ -74,7 +74,8 @@ function check_shell_completion() {
# If this fails there is most likely a problem with the cobra library
is "${lines[0]}" "--.*" \
"$* $cmd: flag(s) listed in suggestions"
- [ ${#lines[@]} -gt 2 ] || die "$* $cmd: No flag suggestions"
+ assert "${#lines[@]}" -gt 2 \
+ "$* $cmd: No flag suggestions"
_check_completion_end NoFileComp
fi
# continue the outer for args loop
@@ -149,7 +150,7 @@ function check_shell_completion() {
### FIXME how can we get the configured registries?
_check_completion_end NoFileComp
### FIXME this fails if no registries are configured
- [[ ${#lines[@]} -gt 2 ]] || die "$* $cmd: No REGISTRIES found in suggestions"
+ assert "${#lines[@]}" -gt 2 "$* $cmd: No REGISTRIES found in suggestions"
match=true
# resume
@@ -174,7 +175,7 @@ function check_shell_completion() {
_check_completion_end NoSpace
else
_check_completion_end Default
- [[ ${#lines[@]} -eq 2 ]] || die "$* $cmd: Suggestions are in the output"
+ assert "${#lines[@]}" -eq 2 "$* $cmd: Suggestions are in the output"
fi
;;
@@ -210,7 +211,7 @@ function check_shell_completion() {
i=0
length=$(( ${#lines[@]} - 2 ))
while [[ i -lt length ]]; do
- [[ "${lines[$i]:0:7}" == "[Debug]" ]] || die "Suggestions are in the output"
+ assert "${lines[$i]:0:7}" == "[Debug]" "Suggestions are in the output"
i=$(( i + 1 ))
done
fi
diff --git a/test/system/750-trust.bats b/test/system/750-trust.bats
index f06df35e7..0d04c33dc 100644
--- a/test/system/750-trust.bats
+++ b/test/system/750-trust.bats
@@ -37,8 +37,7 @@ load helpers
subset=$(jq -r '.[1] | .repo_name, .type' <<<"$output" | fmt)
is "$subset" "docker.io accept" "--json, docker.io should now be accept"
- run cat $policypath
- policy=$output
+ policy="$(< $policypath)"
run_podman image trust show --policypath=$policypath --raw
is "$output" "$policy" "output should show match content of policy.json"
}
diff --git a/test/system/helpers.bash b/test/system/helpers.bash
index 0d336592f..1a1dc0df9 100644
--- a/test/system/helpers.bash
+++ b/test/system/helpers.bash
@@ -483,7 +483,7 @@ function skip_if_root_ubuntu {
if is_ubuntu; then
if ! is_remote; then
if ! is_rootless; then
- skip "Cannot run this test on rootful ubuntu, usually due to user errors"
+ skip "Cannot run this test on rootfull ubuntu, usually due to user errors"
fi
fi
fi
@@ -500,19 +500,107 @@ function die() {
false
}
-
-########
-# is # Compare actual vs expected string; fail w/diagnostic if mismatch
-########
+############
+# assert # Compare actual vs expected string; fail if mismatch
+############
#
-# Compares given string against expectations, using 'expr' to allow patterns.
+# Compares string (default: $output) against the given string argument.
+# By default we do an exact-match comparison against $output, but there
+# are two different ways to invoke us, each with an optional description:
+#
+# assert "EXPECT" [DESCRIPTION]
+# assert "RESULT" "OP" "EXPECT" [DESCRIPTION]
+#
+# The first form (one or two arguments) does an exact-match comparison
+# of "$output" against "EXPECT". The second (three or four args) compares
+# the first parameter against EXPECT, using the given OPerator. If present,
+# DESCRIPTION will be displayed on test failure.
#
# Examples:
#
-# is "$actual" "$expected" "descriptive test name"
-# is "apple" "orange" "name of a test that will fail in most universes"
-# is "apple" "[a-z]\+" "this time it should pass"
+# assert "this is exactly what we expect"
+# assert "${lines[0]}" =~ "^abc" "first line begins with abc"
#
+function assert() {
+ local actual_string="$output"
+ local operator='=='
+ local expect_string="$1"
+ local testname="$2"
+
+ case "${#*}" in
+ 0) die "Internal error: 'assert' requires one or more arguments" ;;
+ 1|2) ;;
+ 3|4) actual_string="$1"
+ operator="$2"
+ expect_string="$3"
+ testname="$4"
+ ;;
+ *) die "Internal error: too many arguments to 'assert'" ;;
+ esac
+
+ # Comparisons.
+ # Special case: there is no !~ operator, so fake it via '! x =~ y'
+ local not=
+ local actual_op="$operator"
+ if [[ $operator == '!~' ]]; then
+ not='!'
+ actual_op='=~'
+ fi
+ if [[ $operator == '=' || $operator == '==' ]]; then
+ # Special case: we can't use '=' or '==' inside [[ ... ]] because
+ # the right-hand side is treated as a pattern... and '[xy]' will
+ # not compare literally. There seems to be no way to turn that off.
+ if [ "$actual_string" = "$expect_string" ]; then
+ return
+ fi
+ elif [[ $operator == '!=' ]]; then
+ # Same special case as above
+ if [ "$actual_string" != "$expect_string" ]; then
+ return
+ fi
+ else
+ if eval "[[ $not \$actual_string $actual_op \$expect_string ]]"; then
+ return
+ elif [ $? -gt 1 ]; then
+ die "Internal error: could not process 'actual' $operator 'expect'"
+ fi
+ fi
+
+ # Test has failed. Get a descriptive test name.
+ if [ -z "$testname" ]; then
+ testname="${MOST_RECENT_PODMAN_COMMAND:-[no test name given]}"
+ fi
+
+ # Display optimization: the typical case for 'expect' is an
+ # exact match ('='), but there are also '=~' or '!~' or '-ge'
+ # and the like. Omit the '=' but show the others; and always
+ # align subsequent output lines for ease of comparison.
+ local op=''
+ local ws=''
+ if [ "$operator" != '==' ]; then
+ op="$operator "
+ ws=$(printf "%*s" ${#op} "")
+ fi
+
+ # This is a multi-line message, which may in turn contain multi-line
+ # output, so let's format it ourself, readably
+ local actual_split
+ IFS=$'\n' read -rd '' -a actual_split <<<"$actual_string" || true
+ printf "#/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n" >&2
+ printf "#| FAIL: %s\n" "$testname" >&2
+ printf "#| expected: %s'%s'\n" "$op" "$expect_string" >&2
+ printf "#| actual: %s'%s'\n" "$ws" "${actual_split[0]}" >&2
+ local line
+ for line in "${actual_split[@]:1}"; do
+ printf "#| > %s'%s'\n" "$ws" "$line" >&2
+ done
+ printf "#\\^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n" >&2
+ false
+}
+
+########
+# is # **DEPRECATED**; see assert() above
+########
function is() {
local actual="$1"
local expect="$2"
@@ -716,10 +804,9 @@ function remove_same_dev_warning() {
# return that list.
function _podman_commands() {
dprint "$@"
- run_podman help "$@" |
- awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' |
- grep .
- "$output"
+ # &>/dev/null prevents duplicate output
+ run_podman help "$@" &>/dev/null
+ awk '/^Available Commands:/{ok=1;next}/^Options:/{ok=0}ok { print $1 }' <<<"$output" | grep .
}
# END miscellaneous tools