github.com/AbhinandanKurakure/podman/v3@v3.4.10/test/e2e/run_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net"
     7  	"os"
     8  	"path/filepath"
     9  	"strconv"
    10  	"strings"
    11  	"syscall"
    12  	"time"
    13  
    14  	"github.com/containers/podman/v3/pkg/cgroups"
    15  	. "github.com/containers/podman/v3/test/utils"
    16  	"github.com/containers/storage/pkg/stringid"
    17  	"github.com/mrunalp/fileutils"
    18  	. "github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  	. "github.com/onsi/gomega/gexec"
    21  )
    22  
    23  var _ = Describe("Podman run", func() {
    24  	var (
    25  		tempdir    string
    26  		err        error
    27  		podmanTest *PodmanTestIntegration
    28  	)
    29  
    30  	BeforeEach(func() {
    31  		tempdir, err = CreateTempDirInTempDir()
    32  		if err != nil {
    33  			os.Exit(1)
    34  		}
    35  		podmanTest = PodmanTestCreate(tempdir)
    36  		podmanTest.Setup()
    37  		podmanTest.SeedImages()
    38  	})
    39  
    40  	AfterEach(func() {
    41  		podmanTest.Cleanup()
    42  		f := CurrentGinkgoTestDescription()
    43  		processTestResult(f)
    44  	})
    45  
    46  	It("podman run a container based on local image", func() {
    47  		session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
    48  		session.WaitWithDefaultTimeout()
    49  		Expect(session).Should(Exit(0))
    50  	})
    51  
    52  	It("podman run check /run/.containerenv", func() {
    53  		session := podmanTest.Podman([]string{"run", ALPINE, "cat", "/run/.containerenv"})
    54  		session.WaitWithDefaultTimeout()
    55  		Expect(session).Should(Exit(0))
    56  		Expect(session.OutputToString()).To(Equal(""))
    57  
    58  		session = podmanTest.Podman([]string{"run", "--privileged", "--name=test1", ALPINE, "cat", "/run/.containerenv"})
    59  		session.WaitWithDefaultTimeout()
    60  		Expect(session).Should(Exit(0))
    61  		Expect(session.OutputToString()).To(ContainSubstring("name=\"test1\""))
    62  		Expect(session.OutputToString()).To(ContainSubstring("image=\"" + ALPINE + "\""))
    63  
    64  		session = podmanTest.Podman([]string{"run", "-v", "/:/host", ALPINE, "cat", "/run/.containerenv"})
    65  		session.WaitWithDefaultTimeout()
    66  		Expect(session).Should(Exit(0))
    67  		Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1"))
    68  
    69  		session = podmanTest.Podman([]string{"run", "-v", "/:/host", "--privileged", ALPINE, "cat", "/run/.containerenv"})
    70  		session.WaitWithDefaultTimeout()
    71  		Expect(session).Should(Exit(0))
    72  		Expect(session.OutputToString()).To(ContainSubstring("graphRootMounted=1"))
    73  	})
    74  
    75  	It("podman run a container based on a complex local image name", func() {
    76  		imageName := strings.TrimPrefix(nginx, "quay.io/")
    77  		session := podmanTest.Podman([]string{"run", imageName, "ls"})
    78  		session.WaitWithDefaultTimeout()
    79  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
    80  		Expect(session).Should(Exit(0))
    81  	})
    82  
    83  	It("podman run --signature-policy", func() {
    84  		SkipIfRemote("SigPolicy not handled by remote")
    85  		session := podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/no/such/file", ALPINE})
    86  		session.WaitWithDefaultTimeout()
    87  		Expect(session).To(ExitWithError())
    88  
    89  		session = podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE})
    90  		session.WaitWithDefaultTimeout()
    91  		Expect(session).Should(Exit(0))
    92  	})
    93  
    94  	It("podman run --rm with --restart", func() {
    95  		session := podmanTest.Podman([]string{"run", "--rm", "--restart", "", ALPINE})
    96  		session.WaitWithDefaultTimeout()
    97  		Expect(session).Should(Exit(0))
    98  
    99  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "no", ALPINE})
   100  		session.WaitWithDefaultTimeout()
   101  		Expect(session).Should(Exit(0))
   102  
   103  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "on-failure", ALPINE})
   104  		session.WaitWithDefaultTimeout()
   105  		Expect(session).Should(Exit(0))
   106  
   107  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "always", ALPINE})
   108  		session.WaitWithDefaultTimeout()
   109  		Expect(session).To(ExitWithError())
   110  
   111  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "unless-stopped", ALPINE})
   112  		session.WaitWithDefaultTimeout()
   113  		Expect(session).To(ExitWithError())
   114  	})
   115  
   116  	It("podman run a container based on on a short name with localhost", func() {
   117  		tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"})
   118  		tag.WaitWithDefaultTimeout()
   119  
   120  		rmi := podmanTest.Podman([]string{"rmi", nginx})
   121  		rmi.WaitWithDefaultTimeout()
   122  
   123  		session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"})
   124  		session.WaitWithDefaultTimeout()
   125  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
   126  		Expect(session).Should(Exit(0))
   127  	})
   128  
   129  	It("podman container run a container based on on a short name with localhost", func() {
   130  		tag := podmanTest.Podman([]string{"image", "tag", nginx, "localhost/libpod/alpine_nginx:latest"})
   131  		tag.WaitWithDefaultTimeout()
   132  
   133  		rmi := podmanTest.Podman([]string{"image", "rm", nginx})
   134  		rmi.WaitWithDefaultTimeout()
   135  
   136  		session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"})
   137  		session.WaitWithDefaultTimeout()
   138  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
   139  		Expect(session).Should(Exit(0))
   140  	})
   141  
   142  	It("podman run a container based on local image with short options", func() {
   143  		session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"})
   144  		session.WaitWithDefaultTimeout()
   145  		Expect(session).Should(Exit(0))
   146  	})
   147  
   148  	It("podman run a container based on local image with short options and args", func() {
   149  		// regression test for #714
   150  		session := podmanTest.Podman([]string{"run", ALPINE, "find", "/etc", "-name", "hosts"})
   151  		session.WaitWithDefaultTimeout()
   152  		Expect(session).Should(Exit(0))
   153  		match, _ := session.GrepString("/etc/hosts")
   154  		Expect(match).Should(BeTrue())
   155  	})
   156  
   157  	It("podman create pod with name in /etc/hosts", func() {
   158  		name := "test_container"
   159  		hostname := "test_hostname"
   160  		session := podmanTest.Podman([]string{"run", "-ti", "--rm", "--name", name, "--hostname", hostname, ALPINE, "cat", "/etc/hosts"})
   161  		session.WaitWithDefaultTimeout()
   162  		Expect(session).Should(Exit(0))
   163  		match, _ := session.GrepString(name)
   164  		Expect(match).Should(BeTrue())
   165  		match, _ = session.GrepString(hostname)
   166  		Expect(match).Should(BeTrue())
   167  	})
   168  
   169  	It("podman run a container based on remote image", func() {
   170  		// Changing session to rsession
   171  		rsession := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"})
   172  		rsession.WaitWithDefaultTimeout()
   173  		Expect(rsession).Should(Exit(0))
   174  
   175  		lock := GetPortLock("5000")
   176  		defer lock.Unlock()
   177  		session := podmanTest.Podman([]string{"run", "-d", "--name", "registry", "-p", "5000:5000", registry, "/entrypoint.sh", "/etc/docker/registry/config.yml"})
   178  		session.WaitWithDefaultTimeout()
   179  		Expect(session).Should(Exit(0))
   180  
   181  		if !WaitContainerReady(podmanTest, "registry", "listening on", 20, 1) {
   182  			Skip("Cannot start docker registry.")
   183  		}
   184  
   185  		run := podmanTest.Podman([]string{"run", "--tls-verify=false", ALPINE})
   186  		run.WaitWithDefaultTimeout()
   187  		Expect(run).Should(Exit(0))
   188  		Expect(podmanTest.NumberOfContainers()).To(Equal(3))
   189  
   190  		// Now registries.conf will be consulted where localhost:5000
   191  		// is set to be insecure.
   192  		run = podmanTest.Podman([]string{"run", ALPINE})
   193  		run.WaitWithDefaultTimeout()
   194  		Expect(run).Should(Exit(0))
   195  	})
   196  
   197  	It("podman run a container with a --rootfs", func() {
   198  		rootfs := filepath.Join(tempdir, "rootfs")
   199  		uls := filepath.Join("/", "usr", "local", "share")
   200  		uniqueString := stringid.GenerateNonCryptoID()
   201  		testFilePath := filepath.Join(uls, uniqueString)
   202  		tarball := filepath.Join(tempdir, "rootfs.tar")
   203  
   204  		err := os.Mkdir(rootfs, 0770)
   205  		Expect(err).Should(BeNil())
   206  
   207  		// Change image in predictable way to validate export
   208  		csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE,
   209  			"/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)})
   210  		csession.WaitWithDefaultTimeout()
   211  		Expect(csession).Should(Exit(0))
   212  
   213  		// Export from working container image guarantees working root
   214  		esession := podmanTest.Podman([]string{"export", "--output", tarball, uniqueString})
   215  		esession.WaitWithDefaultTimeout()
   216  		Expect(esession).Should(Exit(0))
   217  		Expect(tarball).Should(BeARegularFile())
   218  
   219  		// N/B: This will loose any extended attributes like SELinux types
   220  		fmt.Fprintf(os.Stderr, "Extracting container root tarball\n")
   221  		tarsession := SystemExec("tar", []string{"xf", tarball, "-C", rootfs})
   222  		Expect(tarsession).Should(Exit(0))
   223  		Expect(filepath.Join(rootfs, uls)).Should(BeADirectory())
   224  
   225  		// Other tests confirm SELinux types, just confirm --rootfs is working.
   226  		session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable",
   227  			"--rootfs", rootfs, "cat", testFilePath})
   228  		session.WaitWithDefaultTimeout()
   229  		Expect(session).Should(Exit(0))
   230  
   231  		// Validate changes made in original container and export
   232  		stdoutLines := session.OutputToStringArray()
   233  		Expect(stdoutLines).Should(HaveLen(1))
   234  		Expect(stdoutLines[0]).Should(Equal(uniqueString))
   235  	})
   236  
   237  	It("podman run a container with --init", func() {
   238  		session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"})
   239  		session.WaitWithDefaultTimeout()
   240  		Expect(session).Should(Exit(0))
   241  		result := podmanTest.Podman([]string{"inspect", "test"})
   242  		result.WaitWithDefaultTimeout()
   243  		Expect(result).Should(Exit(0))
   244  		conData := result.InspectContainerToJSON()
   245  		Expect(conData[0].Path).To(Equal("/dev/init"))
   246  		Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE"))
   247  	})
   248  
   249  	It("podman run a container with --init and --init-path", func() {
   250  		session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
   251  		session.WaitWithDefaultTimeout()
   252  		Expect(session).Should(Exit(0))
   253  		result := podmanTest.Podman([]string{"inspect", "test"})
   254  		result.WaitWithDefaultTimeout()
   255  		Expect(result).Should(Exit(0))
   256  		conData := result.InspectContainerToJSON()
   257  		Expect(conData[0].Path).To(Equal("/dev/init"))
   258  		Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE"))
   259  	})
   260  
   261  	It("podman run a container without --init", func() {
   262  		session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
   263  		session.WaitWithDefaultTimeout()
   264  		Expect(session).Should(Exit(0))
   265  		result := podmanTest.Podman([]string{"inspect", "test"})
   266  		result.WaitWithDefaultTimeout()
   267  		Expect(result).Should(Exit(0))
   268  		conData := result.InspectContainerToJSON()
   269  		Expect(conData[0].Path).To(Equal("ls"))
   270  		Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("FALSE"))
   271  	})
   272  
   273  	forbidGetCWDSeccompProfile := func() string {
   274  		in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
   275  		jsonFile, err := podmanTest.CreateSeccompJson(in)
   276  		if err != nil {
   277  			fmt.Println(err)
   278  			Skip("Failed to prepare seccomp.json for test.")
   279  		}
   280  		return jsonFile
   281  	}
   282  
   283  	It("podman run mask and unmask path test", func() {
   284  		session := podmanTest.Podman([]string{"run", "-d", "--name=maskCtr1", "--security-opt", "unmask=ALL", "--security-opt", "mask=/proc/acpi", ALPINE, "sleep", "200"})
   285  		session.WaitWithDefaultTimeout()
   286  		Expect(session).Should(Exit(0))
   287  		session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/sys/firmware"})
   288  		session.WaitWithDefaultTimeout()
   289  		Expect(session.OutputToString()).To(Not(BeEmpty()))
   290  		Expect(session).Should(Exit(0))
   291  		session = podmanTest.Podman([]string{"exec", "maskCtr1", "ls", "/proc/acpi"})
   292  		session.WaitWithDefaultTimeout()
   293  		Expect(session.OutputToString()).To(BeEmpty())
   294  
   295  		session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr2", "--security-opt", "unmask=/proc/acpi:/sys/firmware", ALPINE, "sleep", "200"})
   296  		session.WaitWithDefaultTimeout()
   297  		Expect(session).Should(Exit(0))
   298  		session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/sys/firmware"})
   299  		session.WaitWithDefaultTimeout()
   300  		Expect(session.OutputToString()).To(Not(BeEmpty()))
   301  		Expect(session).Should(Exit(0))
   302  		session = podmanTest.Podman([]string{"exec", "maskCtr2", "ls", "/proc/acpi"})
   303  		session.WaitWithDefaultTimeout()
   304  		Expect(session.OutputToString()).To(Not(BeEmpty()))
   305  		Expect(session).Should(Exit(0))
   306  
   307  		session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr3", "--security-opt", "mask=/sys/power/disk", ALPINE, "sleep", "200"})
   308  		session.WaitWithDefaultTimeout()
   309  		Expect(session).Should(Exit(0))
   310  		session = podmanTest.Podman([]string{"exec", "maskCtr3", "cat", "/sys/power/disk"})
   311  		session.WaitWithDefaultTimeout()
   312  		Expect(session.OutputToString()).To(BeEmpty())
   313  		Expect(session).Should(Exit(0))
   314  
   315  		session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr4", "--security-opt", "systempaths=unconfined", ALPINE, "sleep", "200"})
   316  		session.WaitWithDefaultTimeout()
   317  		Expect(session).Should(Exit(0))
   318  		session = podmanTest.Podman([]string{"exec", "maskCtr4", "ls", "/sys/firmware"})
   319  		session.WaitWithDefaultTimeout()
   320  		Expect(session.OutputToString()).To(Not(BeEmpty()))
   321  		Expect(session).Should(Exit(0))
   322  
   323  		session = podmanTest.Podman([]string{"run", "-d", "--name=maskCtr5", "--security-opt", "systempaths=unconfined", ALPINE, "grep", "/proc", "/proc/self/mounts"})
   324  		session.WaitWithDefaultTimeout()
   325  		Expect(session).Should(Exit(0))
   326  		Expect(session.OutputToStringArray()).Should(HaveLen(1))
   327  
   328  		session = podmanTest.Podman([]string{"run", "-d", "--security-opt", "unmask=/proc/*", ALPINE, "grep", "/proc", "/proc/self/mounts"})
   329  		session.WaitWithDefaultTimeout()
   330  		Expect(session).Should(Exit(0))
   331  		Expect(session.OutputToStringArray()).Should(HaveLen(1))
   332  
   333  		session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/proc/a*", ALPINE, "ls", "/proc/acpi"})
   334  		session.WaitWithDefaultTimeout()
   335  		Expect(session).Should(Exit(0))
   336  		Expect(session.OutputToString()).To(Not(BeEmpty()))
   337  	})
   338  
   339  	It("podman run security-opt unmask on /sys/fs/cgroup", func() {
   340  
   341  		SkipIfCgroupV1("podman umask on /sys/fs/cgroup will fail with cgroups V1")
   342  		SkipIfRootless("/sys/fs/cgroup rw access is needed")
   343  		rwOnCGroups := "/sys/fs/cgroup cgroup2 rw"
   344  		session := podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
   345  		session.WaitWithDefaultTimeout()
   346  		Expect(session).Should(Exit(0))
   347  		Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups))
   348  
   349  		session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
   350  		session.WaitWithDefaultTimeout()
   351  		Expect(session).Should(Exit(0))
   352  		Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups))
   353  
   354  		session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup///", ALPINE, "cat", "/proc/mounts"})
   355  		session.WaitWithDefaultTimeout()
   356  		Expect(session).Should(Exit(0))
   357  		Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups))
   358  
   359  		session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=ALL", ALPINE, "cat", "/proc/mounts"})
   360  		session.WaitWithDefaultTimeout()
   361  		Expect(session).Should(Exit(0))
   362  		Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups))
   363  
   364  		session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", "--security-opt", "mask=/sys/fs/cgroup", ALPINE, "cat", "/proc/mounts"})
   365  		session.WaitWithDefaultTimeout()
   366  		Expect(session).Should(Exit(0))
   367  		Expect(session.OutputToString()).To(ContainSubstring(rwOnCGroups))
   368  
   369  		session = podmanTest.Podman([]string{"run", "--security-opt", "unmask=/sys/fs/cgroup", ALPINE, "ls", "/sys/fs/cgroup"})
   370  		session.WaitWithDefaultTimeout()
   371  		Expect(session).Should(Exit(0))
   372  		Expect(session.OutputToString()).ToNot(BeEmpty())
   373  	})
   374  
   375  	It("podman run seccomp test", func() {
   376  		session := podmanTest.Podman([]string{"run", "-it", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"})
   377  		session.WaitWithDefaultTimeout()
   378  		Expect(session).To(ExitWithError())
   379  		match, _ := session.GrepString("Operation not permitted")
   380  		Expect(match).Should(BeTrue())
   381  	})
   382  
   383  	It("podman run seccomp test --privileged", func() {
   384  		session := podmanTest.Podman([]string{"run", "-it", "--privileged", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"})
   385  		session.WaitWithDefaultTimeout()
   386  		Expect(session).To(ExitWithError())
   387  		match, _ := session.GrepString("Operation not permitted")
   388  		Expect(match).Should(BeTrue())
   389  	})
   390  
   391  	It("podman run seccomp test --privileged no profile should be unconfined", func() {
   392  		session := podmanTest.Podman([]string{"run", "-it", "--privileged", ALPINE, "grep", "Seccomp", "/proc/self/status"})
   393  		session.WaitWithDefaultTimeout()
   394  		Expect(session.OutputToString()).To(ContainSubstring("0"))
   395  		Expect(session).Should(Exit(0))
   396  	})
   397  
   398  	It("podman run seccomp test no profile should be default", func() {
   399  		session := podmanTest.Podman([]string{"run", "-it", ALPINE, "grep", "Seccomp", "/proc/self/status"})
   400  		session.WaitWithDefaultTimeout()
   401  		Expect(session.OutputToString()).To(ContainSubstring("2"))
   402  		Expect(session).Should(Exit(0))
   403  	})
   404  
   405  	It("podman run capabilities test", func() {
   406  		session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"})
   407  		session.WaitWithDefaultTimeout()
   408  		Expect(session).Should(Exit(0))
   409  
   410  		session = podmanTest.Podman([]string{"run", "--rm", "--cap-add", "sys_admin", ALPINE, "cat", "/proc/self/status"})
   411  		session.WaitWithDefaultTimeout()
   412  		Expect(session).Should(Exit(0))
   413  
   414  		session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "all", ALPINE, "cat", "/proc/self/status"})
   415  		session.WaitWithDefaultTimeout()
   416  		Expect(session).Should(Exit(0))
   417  
   418  		session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "setuid", ALPINE, "cat", "/proc/self/status"})
   419  		session.WaitWithDefaultTimeout()
   420  		Expect(session).Should(Exit(0))
   421  	})
   422  
   423  	It("podman run user capabilities test", func() {
   424  		// We need to ignore the containers.conf on the test distribution for this test
   425  		os.Setenv("CONTAINERS_CONF", "/dev/null")
   426  		if IsRemote() {
   427  			podmanTest.RestartRemoteService()
   428  		}
   429  		session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapBnd", "/proc/self/status"})
   430  		session.WaitWithDefaultTimeout()
   431  		Expect(session).Should(Exit(0))
   432  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   433  
   434  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapEff", "/proc/self/status"})
   435  		session.WaitWithDefaultTimeout()
   436  		Expect(session).Should(Exit(0))
   437  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   438  
   439  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapInh", "/proc/self/status"})
   440  		session.WaitWithDefaultTimeout()
   441  		Expect(session).Should(Exit(0))
   442  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   443  
   444  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"})
   445  		session.WaitWithDefaultTimeout()
   446  		Expect(session).Should(Exit(0))
   447  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   448  
   449  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapEff", "/proc/self/status"})
   450  		session.WaitWithDefaultTimeout()
   451  		Expect(session).Should(Exit(0))
   452  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   453  
   454  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapInh", "/proc/self/status"})
   455  		session.WaitWithDefaultTimeout()
   456  		Expect(session).Should(Exit(0))
   457  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   458  
   459  		session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"})
   460  		session.WaitWithDefaultTimeout()
   461  		Expect(session).Should(Exit(0))
   462  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   463  
   464  		session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"})
   465  		session.WaitWithDefaultTimeout()
   466  		Expect(session).Should(Exit(0))
   467  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   468  
   469  		session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   470  		session.WaitWithDefaultTimeout()
   471  		Expect(session).Should(Exit(0))
   472  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
   473  
   474  		session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
   475  		session.WaitWithDefaultTimeout()
   476  		Expect(session).Should(Exit(0))
   477  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
   478  
   479  		session = podmanTest.Podman([]string{"run", "--user=0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   480  		session.WaitWithDefaultTimeout()
   481  		Expect(session).Should(Exit(0))
   482  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   483  
   484  		session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   485  		session.WaitWithDefaultTimeout()
   486  		Expect(session).Should(Exit(0))
   487  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   488  
   489  		session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
   490  		session.WaitWithDefaultTimeout()
   491  		Expect(session).Should(Exit(0))
   492  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   493  
   494  		if os.Geteuid() > 0 {
   495  			if os.Getenv("SKIP_USERNS") != "" {
   496  				Skip("Skip userns tests.")
   497  			}
   498  			if _, err := os.Stat("/proc/self/uid_map"); err != nil {
   499  				Skip("User namespaces not supported.")
   500  			}
   501  			session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   502  			session.WaitWithDefaultTimeout()
   503  			Expect(session).Should(Exit(0))
   504  			Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
   505  
   506  			session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--privileged", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
   507  			session.WaitWithDefaultTimeout()
   508  			Expect(session).Should(Exit(0))
   509  			Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   510  
   511  			session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapInh", "/proc/self/status"})
   512  			session.WaitWithDefaultTimeout()
   513  			Expect(session).Should(Exit(0))
   514  			Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
   515  		}
   516  	})
   517  
   518  	It("podman run user capabilities test with image", func() {
   519  		// We need to ignore the containers.conf on the test distribution for this test
   520  		os.Setenv("CONTAINERS_CONF", "/dev/null")
   521  		if IsRemote() {
   522  			podmanTest.RestartRemoteService()
   523  		}
   524  		dockerfile := fmt.Sprintf(`FROM %s
   525  USER bin`, BB)
   526  		podmanTest.BuildImage(dockerfile, "test", "false")
   527  		session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"})
   528  		session.WaitWithDefaultTimeout()
   529  		Expect(session).Should(Exit(0))
   530  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   531  
   532  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapEff", "/proc/self/status"})
   533  		session.WaitWithDefaultTimeout()
   534  		Expect(session).Should(Exit(0))
   535  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   536  	})
   537  
   538  	It("podman run limits test", func() {
   539  		SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users")
   540  
   541  		if !isRootless() {
   542  			session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"})
   543  			session.WaitWithDefaultTimeout()
   544  			Expect(session).Should(Exit(0))
   545  		}
   546  
   547  		session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"})
   548  		session.WaitWithDefaultTimeout()
   549  		Expect(session).Should(Exit(0))
   550  		Expect(session.OutputToString()).To(ContainSubstring("2048"))
   551  
   552  		session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=1024:1028", fedoraMinimal, "ulimit", "-n"})
   553  		session.WaitWithDefaultTimeout()
   554  		Expect(session).Should(Exit(0))
   555  		Expect(session.OutputToString()).To(ContainSubstring("1024"))
   556  
   557  		if !CGROUPSV2 {
   558  			// --oom-kill-disable not supported on cgroups v2.
   559  			session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
   560  			session.WaitWithDefaultTimeout()
   561  			Expect(session).Should(Exit(0))
   562  		}
   563  
   564  		session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=111", fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
   565  		session.WaitWithDefaultTimeout()
   566  		Expect(session).Should(Exit(0))
   567  		Expect(session.OutputToString()).To(Equal("111"))
   568  	})
   569  
   570  	It("podman run limits host test", func() {
   571  		SkipIfRemote("This can only be used for local tests")
   572  
   573  		var l syscall.Rlimit
   574  
   575  		err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
   576  		Expect(err).To(BeNil())
   577  
   578  		session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"})
   579  		session.WaitWithDefaultTimeout()
   580  		Expect(session).Should(Exit(0))
   581  
   582  		ulimitCtrStr := strings.TrimSpace(session.OutputToString())
   583  		ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0)
   584  		Expect(err).To(BeNil())
   585  
   586  		Expect(ulimitCtr).Should(BeNumerically(">=", l.Max))
   587  	})
   588  
   589  	It("podman run with cidfile", func() {
   590  		session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
   591  		session.WaitWithDefaultTimeout()
   592  		Expect(session).Should(Exit(0))
   593  		err := os.Remove(tempdir + "cidfile")
   594  		Expect(err).To(BeNil())
   595  	})
   596  
   597  	It("podman run sysctl test", func() {
   598  		SkipIfRootless("Network sysctls are not available root rootless")
   599  		session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
   600  		session.WaitWithDefaultTimeout()
   601  		Expect(session).Should(Exit(0))
   602  		Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535"))
   603  
   604  		// network sysctls should fail if --net=host is set
   605  		session = podmanTest.Podman([]string{"run", "--net", "host", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
   606  		session.WaitWithDefaultTimeout()
   607  		Expect(session).Should(Exit(125))
   608  	})
   609  
   610  	It("podman run blkio-weight test", func() {
   611  		SkipIfRootlessCgroupsV1("Setting blkio-weight not supported on cgroupv1 for rootless users")
   612  		SkipIfRootless("By default systemd doesn't delegate io to rootless users")
   613  		if CGROUPSV2 {
   614  			if _, err := os.Stat("/sys/fs/cgroup/io.stat"); os.IsNotExist(err) {
   615  				Skip("Kernel does not have io.stat")
   616  			}
   617  			if _, err := os.Stat("/sys/fs/cgroup/system.slice/io.bfq.weight"); os.IsNotExist(err) {
   618  				Skip("Kernel does not support BFQ IO scheduler")
   619  			}
   620  			session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/io.bfq.weight"})
   621  			session.WaitWithDefaultTimeout()
   622  			Expect(session).Should(Exit(0))
   623  			// there was a documentation issue in the kernel that reported a different range [1-10000] for the io controller.
   624  			// older versions of crun/runc used it.  For the time being allow both versions to pass the test.
   625  			// FIXME: drop "|51" once all the runtimes we test have the fix in place.
   626  			Expect(strings.Replace(session.OutputToString(), "default ", "", 1)).To(MatchRegexp("15|51"))
   627  		} else {
   628  			if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
   629  				Skip("Kernel does not support blkio.weight")
   630  			}
   631  			session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
   632  			session.WaitWithDefaultTimeout()
   633  			Expect(session).Should(Exit(0))
   634  			Expect(session.OutputToString()).To(ContainSubstring("15"))
   635  		}
   636  	})
   637  
   638  	It("podman run device-read-bps test", func() {
   639  		SkipIfRootless("FIXME: Missing /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control")
   640  		SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users")
   641  
   642  		var session *PodmanSessionIntegration
   643  
   644  		if CGROUPSV2 {
   645  			session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
   646  		} else {
   647  			session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
   648  		}
   649  
   650  		session.WaitWithDefaultTimeout()
   651  		Expect(session).Should(Exit(0))
   652  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   653  			Expect(session.OutputToString()).To(ContainSubstring("1048576"))
   654  		}
   655  	})
   656  
   657  	It("podman run device-write-bps test", func() {
   658  		SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist")
   659  		SkipIfRootlessCgroupsV1("Setting device-write-bps not supported on cgroupv1 for rootless users")
   660  
   661  		var session *PodmanSessionIntegration
   662  
   663  		if CGROUPSV2 {
   664  			session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
   665  		} else {
   666  			session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
   667  		}
   668  		session.WaitWithDefaultTimeout()
   669  		Expect(session).Should(Exit(0))
   670  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   671  			Expect(session.OutputToString()).To(ContainSubstring("1048576"))
   672  		}
   673  	})
   674  
   675  	It("podman run device-read-iops test", func() {
   676  		SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist")
   677  		SkipIfRootlessCgroupsV1("Setting device-read-iops not supported on cgroupv1 for rootless users")
   678  		var session *PodmanSessionIntegration
   679  
   680  		if CGROUPSV2 {
   681  			session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
   682  		} else {
   683  			session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
   684  		}
   685  
   686  		session.WaitWithDefaultTimeout()
   687  		Expect(session).Should(Exit(0))
   688  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   689  			Expect(session.OutputToString()).To(ContainSubstring("100"))
   690  		}
   691  	})
   692  
   693  	It("podman run device-write-iops test", func() {
   694  		SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist")
   695  		SkipIfRootlessCgroupsV1("Setting device-write-iops not supported on cgroupv1 for rootless users")
   696  		var session *PodmanSessionIntegration
   697  
   698  		if CGROUPSV2 {
   699  			session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.max"})
   700  		} else {
   701  			session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
   702  		}
   703  
   704  		session.WaitWithDefaultTimeout()
   705  		Expect(session).Should(Exit(0))
   706  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   707  			Expect(session.OutputToString()).To(ContainSubstring("100"))
   708  		}
   709  	})
   710  
   711  	It("podman run notify_socket", func() {
   712  		SkipIfRemote("This can only be used for local tests")
   713  
   714  		host := GetHostDistributionInfo()
   715  		if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" {
   716  			Skip("this test requires a working runc")
   717  		}
   718  		sock := filepath.Join(podmanTest.TempDir, "notify")
   719  		addr := net.UnixAddr{
   720  			Name: sock,
   721  			Net:  "unixgram",
   722  		}
   723  		socket, err := net.ListenUnixgram("unixgram", &addr)
   724  		Expect(err).To(BeNil())
   725  		defer os.Remove(sock)
   726  		defer socket.Close()
   727  
   728  		os.Setenv("NOTIFY_SOCKET", sock)
   729  		defer os.Unsetenv("NOTIFY_SOCKET")
   730  
   731  		session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "NOTIFY_SOCKET"})
   732  		session.WaitWithDefaultTimeout()
   733  		Expect(session).Should(Exit(0))
   734  		Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0))
   735  	})
   736  
   737  	It("podman run log-opt", func() {
   738  		log := filepath.Join(podmanTest.TempDir, "/container.log")
   739  		session := podmanTest.Podman([]string{"run", "--rm", "--log-driver", "k8s-file", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"})
   740  		session.WaitWithDefaultTimeout()
   741  		Expect(session).Should(Exit(0))
   742  		_, err := os.Stat(log)
   743  		Expect(err).To(BeNil())
   744  		_ = os.Remove(log)
   745  	})
   746  
   747  	It("podman run tagged image", func() {
   748  		podmanTest.AddImageToRWStore(BB)
   749  		tag := podmanTest.Podman([]string{"tag", BB, "bb"})
   750  		tag.WaitWithDefaultTimeout()
   751  		Expect(tag).Should(Exit(0))
   752  
   753  		session := podmanTest.Podman([]string{"run", "--rm", "bb", "ls"})
   754  		session.WaitWithDefaultTimeout()
   755  		Expect(session).Should(Exit(0))
   756  	})
   757  
   758  	It("podman test hooks", func() {
   759  		hcheck := "/run/hookscheck"
   760  		hooksDir := tempdir + "/hooks"
   761  		os.Mkdir(hooksDir, 0755)
   762  		fileutils.CopyFile("hooks/hooks.json", hooksDir)
   763  		os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir=%s", hooksDir))
   764  		os.Remove(hcheck)
   765  		session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
   766  		session.Wait(10)
   767  		os.Unsetenv("HOOK_OPTION")
   768  		Expect(session).Should(Exit(0))
   769  	})
   770  
   771  	It("podman run with subscription secrets", func() {
   772  		SkipIfRemote("--default-mount-file option is not supported in podman-remote")
   773  		containersDir := filepath.Join(podmanTest.TempDir, "containers")
   774  		err := os.MkdirAll(containersDir, 0755)
   775  		Expect(err).To(BeNil())
   776  
   777  		secretsDir := filepath.Join(podmanTest.TempDir, "rhel", "secrets")
   778  		err = os.MkdirAll(secretsDir, 0755)
   779  		Expect(err).To(BeNil())
   780  
   781  		mountsFile := filepath.Join(containersDir, "mounts.conf")
   782  		mountString := secretsDir + ":/run/secrets"
   783  		err = ioutil.WriteFile(mountsFile, []byte(mountString), 0755)
   784  		Expect(err).To(BeNil())
   785  
   786  		secretsFile := filepath.Join(secretsDir, "test.txt")
   787  		secretsString := "Testing secrets mount. I am mounted!"
   788  		err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755)
   789  		Expect(err).To(BeNil())
   790  
   791  		targetDir := tempdir + "/symlink/target"
   792  		err = os.MkdirAll(targetDir, 0755)
   793  		Expect(err).To(BeNil())
   794  		keyFile := filepath.Join(targetDir, "key.pem")
   795  		err = ioutil.WriteFile(keyFile, []byte(mountString), 0755)
   796  		Expect(err).To(BeNil())
   797  		execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")})
   798  		Expect(execSession).Should(Exit(0))
   799  
   800  		session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"})
   801  		session.WaitWithDefaultTimeout()
   802  		Expect(session).Should(Exit(0))
   803  		Expect(session.OutputToString()).To(Equal(secretsString))
   804  
   805  		session = podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"})
   806  		session.WaitWithDefaultTimeout()
   807  		Expect(session).Should(Exit(0))
   808  		Expect(session.OutputToString()).To(ContainSubstring("key.pem"))
   809  	})
   810  
   811  	It("podman run with FIPS mode secrets", func() {
   812  		SkipIfRootless("rootless can not manipulate system-fips file")
   813  		fipsFile := "/etc/system-fips"
   814  		err = ioutil.WriteFile(fipsFile, []byte{}, 0755)
   815  		Expect(err).To(BeNil())
   816  
   817  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"})
   818  		session.WaitWithDefaultTimeout()
   819  		Expect(session).Should(Exit(0))
   820  		Expect(session.OutputToString()).To(ContainSubstring("system-fips"))
   821  
   822  		err = os.Remove(fipsFile)
   823  		Expect(err).To(BeNil())
   824  	})
   825  
   826  	It("podman run without group-add", func() {
   827  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
   828  		session.WaitWithDefaultTimeout()
   829  		Expect(session).Should(Exit(0))
   830  		Expect(session.LineInOutputContains("27(video),777,65533(nogroup)")).To(BeFalse())
   831  	})
   832  
   833  	It("podman run with group-add", func() {
   834  		session := podmanTest.Podman([]string{"run", "--rm", "--group-add=audio", "--group-add=nogroup", "--group-add=777", ALPINE, "id"})
   835  		session.WaitWithDefaultTimeout()
   836  		Expect(session).Should(Exit(0))
   837  		Expect(session.LineInOutputContains("777,65533(nogroup)")).To(BeTrue())
   838  	})
   839  
   840  	It("podman run with user (default)", func() {
   841  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
   842  		session.WaitWithDefaultTimeout()
   843  		Expect(session).Should(Exit(0))
   844  		Expect(session.LineInOutputContains("uid=0(root) gid=0(root)")).To(BeTrue())
   845  	})
   846  
   847  	It("podman run with user (integer, not in /etc/passwd)", func() {
   848  		session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "id"})
   849  		session.WaitWithDefaultTimeout()
   850  		Expect(session).Should(Exit(0))
   851  		Expect(session.OutputToString()).To(Equal("uid=1234(1234) gid=0(root)"))
   852  	})
   853  
   854  	It("podman run with user (integer, in /etc/passwd)", func() {
   855  		session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"})
   856  		session.WaitWithDefaultTimeout()
   857  		Expect(session).Should(Exit(0))
   858  		Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue())
   859  	})
   860  
   861  	It("podman run with user (username)", func() {
   862  		session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"})
   863  		session.WaitWithDefaultTimeout()
   864  		Expect(session).Should(Exit(0))
   865  		Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue())
   866  	})
   867  
   868  	It("podman run with user:group (username:integer)", func() {
   869  		session := podmanTest.Podman([]string{"run", "--rm", "--user=mail:21", ALPINE, "id"})
   870  		session.WaitWithDefaultTimeout()
   871  		Expect(session).Should(Exit(0))
   872  		Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)"))
   873  	})
   874  
   875  	It("podman run with user:group (integer:groupname)", func() {
   876  		session := podmanTest.Podman([]string{"run", "--rm", "--user=8:ftp", ALPINE, "id"})
   877  		session.WaitWithDefaultTimeout()
   878  		Expect(session).Should(Exit(0))
   879  		Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)"))
   880  	})
   881  
   882  	It("podman run with user, verify caps dropped", func() {
   883  		session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "grep", "CapEff", "/proc/self/status"})
   884  		session.WaitWithDefaultTimeout()
   885  		Expect(session).Should(Exit(0))
   886  		capEff := strings.Split(session.OutputToString(), " ")
   887  		Expect("0000000000000000").To(Equal(capEff[1]))
   888  	})
   889  
   890  	It("podman run with attach stdin outputs container ID", func() {
   891  		session := podmanTest.Podman([]string{"run", "--attach", "stdin", ALPINE, "printenv"})
   892  		session.WaitWithDefaultTimeout()
   893  		Expect(session).Should(Exit(0))
   894  		ps := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"})
   895  		ps.WaitWithDefaultTimeout()
   896  		Expect(ps).Should(Exit(0))
   897  		Expect(ps.LineInOutputContains(session.OutputToString())).To(BeTrue())
   898  	})
   899  
   900  	It("podman run with attach stdout does not print stderr", func() {
   901  		session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stdout", ALPINE, "ls", "/doesnotexist"})
   902  		session.WaitWithDefaultTimeout()
   903  		Expect(session.OutputToString()).To(Equal(""))
   904  	})
   905  
   906  	It("podman run with attach stderr does not print stdout", func() {
   907  		session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stderr", ALPINE, "ls", "/"})
   908  		session.WaitWithDefaultTimeout()
   909  		Expect(session).Should(Exit(0))
   910  		Expect(session.OutputToString()).To(Equal(""))
   911  	})
   912  
   913  	It("podman run attach nonsense errors", func() {
   914  		session := podmanTest.Podman([]string{"run", "--rm", "--attach", "asdfasdf", ALPINE, "ls", "/"})
   915  		session.WaitWithDefaultTimeout()
   916  		Expect(session).Should(Exit(125))
   917  	})
   918  
   919  	It("podman run exit code on failure to exec", func() {
   920  		session := podmanTest.Podman([]string{"run", ALPINE, "/etc"})
   921  		session.WaitWithDefaultTimeout()
   922  		Expect(session).Should(Exit(126))
   923  	})
   924  
   925  	It("podman run error on exec", func() {
   926  		session := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 100"})
   927  		session.WaitWithDefaultTimeout()
   928  		Expect(session).Should(Exit(100))
   929  	})
   930  
   931  	It("podman run with named volume", func() {
   932  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"})
   933  		session.WaitWithDefaultTimeout()
   934  		Expect(session).Should(Exit(0))
   935  		perms := session.OutputToString()
   936  
   937  		session = podmanTest.Podman([]string{"run", "--rm", "-v", "test:/var/tmp", ALPINE, "stat", "-c", "%a %Y", "/var/tmp"})
   938  		session.WaitWithDefaultTimeout()
   939  		Expect(session).Should(Exit(0))
   940  		Expect(session.OutputToString()).To(Equal(perms))
   941  	})
   942  
   943  	It("podman run with built-in volume image", func() {
   944  		session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
   945  		session.WaitWithDefaultTimeout()
   946  		Expect(session).Should(Exit(0))
   947  
   948  		dockerfile := fmt.Sprintf(`FROM %s
   949  RUN mkdir -p /myvol/data && chown -R mail.0 /myvol
   950  VOLUME ["/myvol/data"]
   951  USER mail`, BB)
   952  
   953  		podmanTest.BuildImage(dockerfile, "test", "false")
   954  		session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"})
   955  		session.WaitWithDefaultTimeout()
   956  		Expect(session).Should(Exit(0))
   957  		Expect(session.OutputToString()).To(ContainSubstring("mail root"))
   958  	})
   959  
   960  	It("podman run --volumes-from flag", func() {
   961  		vol := filepath.Join(podmanTest.TempDir, "vol-test")
   962  		err := os.MkdirAll(vol, 0755)
   963  		Expect(err).To(BeNil())
   964  
   965  		filename := "test.txt"
   966  		volFile := filepath.Join(vol, filename)
   967  		data := "Testing --volumes-from!!!"
   968  		err = ioutil.WriteFile(volFile, []byte(data), 0755)
   969  		Expect(err).To(BeNil())
   970  		mountpoint := "/myvol/"
   971  
   972  		session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":z", ALPINE, "cat", mountpoint + filename})
   973  		session.WaitWithDefaultTimeout()
   974  		Expect(session).Should(Exit(0))
   975  		ctrID := session.OutputToString()
   976  
   977  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "cat", mountpoint + filename})
   978  		session.WaitWithDefaultTimeout()
   979  		Expect(session).Should(Exit(0))
   980  		Expect(session.OutputToString()).To(Equal(data))
   981  
   982  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "sh", "-c", "echo test >> " + mountpoint + filename})
   983  		session.WaitWithDefaultTimeout()
   984  		Expect(session).Should(Exit(0))
   985  
   986  		session = podmanTest.Podman([]string{"start", "--attach", ctrID})
   987  		session.WaitWithDefaultTimeout()
   988  		Expect(session).Should(Exit(0))
   989  		Expect(session.OutputToString()).To(Equal(data + "test"))
   990  	})
   991  
   992  	It("podman run --volumes-from flag options", func() {
   993  		vol := filepath.Join(podmanTest.TempDir, "vol-test")
   994  		err := os.MkdirAll(vol, 0755)
   995  		Expect(err).To(BeNil())
   996  
   997  		filename := "test.txt"
   998  		volFile := filepath.Join(vol, filename)
   999  		data := "Testing --volumes-from!!!"
  1000  		err = ioutil.WriteFile(volFile, []byte(data), 0755)
  1001  		Expect(err).To(BeNil())
  1002  		mountpoint := "/myvol/"
  1003  
  1004  		session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
  1005  		session.WaitWithDefaultTimeout()
  1006  		Expect(session).Should(Exit(0))
  1007  		ctrID := session.OutputToString()
  1008  
  1009  		// check that the read only option works
  1010  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro", ALPINE, "touch", mountpoint + "abc.txt"})
  1011  		session.WaitWithDefaultTimeout()
  1012  		Expect(session).Should(Exit(1))
  1013  		Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system"))
  1014  
  1015  		// check that both z and ro options work
  1016  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,z", ALPINE, "cat", mountpoint + filename})
  1017  		session.WaitWithDefaultTimeout()
  1018  		Expect(session).Should(Exit(0))
  1019  		Expect(session.OutputToString()).To(Equal(data))
  1020  
  1021  		// check that multiple ro/rw are not working
  1022  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,rw", ALPINE, "cat", mountpoint + filename})
  1023  		session.WaitWithDefaultTimeout()
  1024  		Expect(session).Should(Exit(125))
  1025  		Expect(session.ErrorToString()).To(ContainSubstring("cannot set ro or rw options more than once"))
  1026  
  1027  		// check that multiple z options are not working
  1028  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z,z,ro", ALPINE, "cat", mountpoint + filename})
  1029  		session.WaitWithDefaultTimeout()
  1030  		Expect(session).Should(Exit(125))
  1031  		Expect(session.ErrorToString()).To(ContainSubstring("cannot set :z more than once in mount options"))
  1032  
  1033  		// create new read only volume
  1034  		session = podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":ro", ALPINE, "cat", mountpoint + filename})
  1035  		session.WaitWithDefaultTimeout()
  1036  		Expect(session).Should(Exit(0))
  1037  		ctrID = session.OutputToString()
  1038  
  1039  		// check if the original volume was mounted as read only that --volumes-from also mount it as read only
  1040  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "touch", mountpoint + "abc.txt"})
  1041  		session.WaitWithDefaultTimeout()
  1042  		Expect(session).Should(Exit(1))
  1043  		Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system"))
  1044  	})
  1045  
  1046  	It("podman run --volumes-from flag with built-in volumes", func() {
  1047  		session := podmanTest.Podman([]string{"create", redis, "sh"})
  1048  		session.WaitWithDefaultTimeout()
  1049  		Expect(session).Should(Exit(0))
  1050  		ctrID := session.OutputToString()
  1051  
  1052  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "ls"})
  1053  		session.WaitWithDefaultTimeout()
  1054  		Expect(session).Should(Exit(0))
  1055  		Expect(session.OutputToString()).To(ContainSubstring("data"))
  1056  	})
  1057  
  1058  	It("podman run --volumes flag with multiple volumes", func() {
  1059  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
  1060  		err := os.MkdirAll(vol1, 0755)
  1061  		Expect(err).To(BeNil())
  1062  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
  1063  		err = os.MkdirAll(vol2, 0755)
  1064  		Expect(err).To(BeNil())
  1065  
  1066  		session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", ALPINE, "touch", "/myvol2/foo.txt"})
  1067  		session.WaitWithDefaultTimeout()
  1068  		Expect(session).Should(Exit(0))
  1069  	})
  1070  
  1071  	It("podman run --volumes flag with empty host dir", func() {
  1072  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
  1073  		err := os.MkdirAll(vol1, 0755)
  1074  		Expect(err).To(BeNil())
  1075  
  1076  		session := podmanTest.Podman([]string{"run", "--volume", ":/myvol1:z", ALPINE, "touch", "/myvol2/foo.txt"})
  1077  		session.WaitWithDefaultTimeout()
  1078  		Expect(session).To(ExitWithError())
  1079  		Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
  1080  		session = podmanTest.Podman([]string{"run", "--volume", vol1 + ":", ALPINE, "touch", "/myvol2/foo.txt"})
  1081  		session.WaitWithDefaultTimeout()
  1082  		Expect(session).To(ExitWithError())
  1083  		Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
  1084  	})
  1085  
  1086  	It("podman run --mount flag with multiple mounts", func() {
  1087  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
  1088  		err := os.MkdirAll(vol1, 0755)
  1089  		Expect(err).To(BeNil())
  1090  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
  1091  		err = os.MkdirAll(vol2, 0755)
  1092  		Expect(err).To(BeNil())
  1093  
  1094  		session := podmanTest.Podman([]string{"run", "--mount", "type=bind,src=" + vol1 + ",target=/myvol1,z", "--mount", "type=bind,src=" + vol2 + ",target=/myvol2,z", ALPINE, "touch", "/myvol2/foo.txt"})
  1095  		session.WaitWithDefaultTimeout()
  1096  		Expect(session).Should(Exit(0))
  1097  	})
  1098  
  1099  	It("podman run findmnt nothing shared", func() {
  1100  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
  1101  		err := os.MkdirAll(vol1, 0755)
  1102  		Expect(err).To(BeNil())
  1103  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
  1104  		err = os.MkdirAll(vol2, 0755)
  1105  		Expect(err).To(BeNil())
  1106  
  1107  		session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
  1108  		session.WaitWithDefaultTimeout()
  1109  		Expect(session).Should(Exit(0))
  1110  		match, _ := session.GrepString("shared")
  1111  		Expect(match).Should(BeFalse())
  1112  	})
  1113  
  1114  	It("podman run findmnt shared", func() {
  1115  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
  1116  		err := os.MkdirAll(vol1, 0755)
  1117  		Expect(err).To(BeNil())
  1118  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
  1119  		err = os.MkdirAll(vol2, 0755)
  1120  		Expect(err).To(BeNil())
  1121  
  1122  		session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:shared,z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
  1123  		session.WaitWithDefaultTimeout()
  1124  		Expect(session).Should(Exit(0))
  1125  		match, shared := session.GrepString("shared")
  1126  		Expect(match).Should(BeTrue())
  1127  		// make sure it's only shared (and not 'shared,slave')
  1128  		isSharedOnly := !strings.Contains(shared[0], "shared,")
  1129  		Expect(isSharedOnly).Should(BeTrue())
  1130  	})
  1131  
  1132  	It("podman run --security-opts proc-opts=", func() {
  1133  		session := podmanTest.Podman([]string{"run", "--security-opt", "proc-opts=nosuid,exec", fedoraMinimal, "findmnt", "-noOPTIONS", "/proc"})
  1134  		session.WaitWithDefaultTimeout()
  1135  		Expect(session).Should(Exit(0))
  1136  		output := session.OutputToString()
  1137  		Expect(output).To(ContainSubstring("nosuid"))
  1138  		Expect(output).To(Not(ContainSubstring("exec")))
  1139  	})
  1140  
  1141  	It("podman run --mount type=bind,bind-nonrecursive", func() {
  1142  		SkipIfRootless("FIXME: rootless users are not allowed to mount bind-nonrecursive (Could this be a Kernel bug?")
  1143  		session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"})
  1144  		session.WaitWithDefaultTimeout()
  1145  		Expect(session).Should(Exit(0))
  1146  		Expect(len(session.OutputToStringArray())).To(Equal(1))
  1147  	})
  1148  
  1149  	It("podman run --mount type=devpts,target=/foo/bar", func() {
  1150  		session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"})
  1151  		session.WaitWithDefaultTimeout()
  1152  		Expect(session).Should(Exit(0))
  1153  		Expect(session.OutputToString()).To(ContainSubstring("devpts"))
  1154  	})
  1155  
  1156  	It("podman run --pod automatically", func() {
  1157  		session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8686"})
  1158  		session.WaitWithDefaultTimeout()
  1159  		Expect(session).Should(Exit(0))
  1160  
  1161  		session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8686"})
  1162  		session.WaitWithDefaultTimeout()
  1163  		Expect(session).Should(Exit(0))
  1164  
  1165  		check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
  1166  		check.WaitWithDefaultTimeout()
  1167  		match, _ := check.GrepString("foobar")
  1168  		Expect(match).To(BeTrue())
  1169  	})
  1170  
  1171  	It("podman run --pod new with hostname", func() {
  1172  		hostname := "abc"
  1173  		session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", "--hostname", hostname, ALPINE, "cat", "/etc/hostname"})
  1174  		session.WaitWithDefaultTimeout()
  1175  		Expect(session).Should(Exit(0))
  1176  		Expect(session.OutputToString()).To(ContainSubstring(hostname))
  1177  	})
  1178  
  1179  	It("podman run --rm should work", func() {
  1180  		session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"})
  1181  		session.WaitWithDefaultTimeout()
  1182  		Expect(session).Should(Exit(0))
  1183  		session = podmanTest.Podman([]string{"wait", "test"})
  1184  		session.WaitWithDefaultTimeout()
  1185  		Expect(session).To(ExitWithError())
  1186  
  1187  		numContainers := podmanTest.NumberOfContainers()
  1188  		Expect(numContainers).To(Equal(0))
  1189  	})
  1190  
  1191  	It("podman run --rm failed container should delete itself", func() {
  1192  		session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "foo"})
  1193  		session.WaitWithDefaultTimeout()
  1194  		Expect(session).To(ExitWithError())
  1195  		session = podmanTest.Podman([]string{"wait", "test"})
  1196  		session.WaitWithDefaultTimeout()
  1197  		Expect(session).To(ExitWithError())
  1198  
  1199  		numContainers := podmanTest.NumberOfContainers()
  1200  		Expect(numContainers).To(Equal(0))
  1201  	})
  1202  
  1203  	It("podman run failed container should NOT delete itself", func() {
  1204  		session := podmanTest.Podman([]string{"run", ALPINE, "foo"})
  1205  		session.WaitWithDefaultTimeout()
  1206  		Expect(session).To(ExitWithError())
  1207  		// If remote we could have a race condition
  1208  		session = podmanTest.Podman([]string{"wait", "test"})
  1209  		session.WaitWithDefaultTimeout()
  1210  		Expect(session).To(ExitWithError())
  1211  
  1212  		numContainers := podmanTest.NumberOfContainers()
  1213  		Expect(numContainers).To(Equal(1))
  1214  	})
  1215  	It("podman run readonly container should NOT mount /dev/shm read/only", func() {
  1216  		session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "mount"})
  1217  		session.WaitWithDefaultTimeout()
  1218  		Expect(session).Should(Exit(0))
  1219  
  1220  		Expect(session.OutputToString()).To(Not(ContainSubstring("/dev/shm type tmpfs (ro,")))
  1221  	})
  1222  
  1223  	It("podman run readonly container should NOT mount /run noexec", func() {
  1224  		session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "sh", "-c", "mount  | grep \"/run \""})
  1225  		session.WaitWithDefaultTimeout()
  1226  		Expect(session).Should(Exit(0))
  1227  
  1228  		Expect(session.OutputToString()).To(Not(ContainSubstring("noexec")))
  1229  	})
  1230  
  1231  	It("podman run with bad healthcheck retries", func() {
  1232  		session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-retries", "0", ALPINE, "top"})
  1233  		session.Wait()
  1234  		Expect(session).To(ExitWithError())
  1235  		Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-retries must be greater than 0"))
  1236  	})
  1237  
  1238  	It("podman run with bad healthcheck timeout", func() {
  1239  		session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-timeout", "0s", ALPINE, "top"})
  1240  		session.WaitWithDefaultTimeout()
  1241  		Expect(session).To(ExitWithError())
  1242  		Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second"))
  1243  	})
  1244  
  1245  	It("podman run with bad healthcheck start-period", func() {
  1246  		session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "foo", "--health-start-period", "-1s", ALPINE, "top"})
  1247  		session.WaitWithDefaultTimeout()
  1248  		Expect(session).To(ExitWithError())
  1249  		Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater"))
  1250  	})
  1251  
  1252  	It("podman run with --add-host and --no-hosts fails", func() {
  1253  		session := podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts", ALPINE, "top"})
  1254  		session.WaitWithDefaultTimeout()
  1255  		Expect(session).To(ExitWithError())
  1256  	})
  1257  
  1258  	It("podman run with restart-policy always restarts containers", func() {
  1259  		testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
  1260  		err := os.MkdirAll(testDir, 0755)
  1261  		Expect(err).To(BeNil())
  1262  
  1263  		aliveFile := filepath.Join(testDir, "running")
  1264  		file, err := os.Create(aliveFile)
  1265  		Expect(err).To(BeNil())
  1266  		file.Close()
  1267  
  1268  		session := podmanTest.Podman([]string{"run", "-dt", "--restart", "always", "-v", fmt.Sprintf("%s:/tmp/runroot:Z", testDir), ALPINE, "sh", "-c", "date +%N > /tmp/runroot/ran && while test -r /tmp/runroot/running; do sleep 0.1s; done"})
  1269  
  1270  		found := false
  1271  		testFile := filepath.Join(testDir, "ran")
  1272  		for i := 0; i < 30; i++ {
  1273  			time.Sleep(1 * time.Second)
  1274  			if _, err := os.Stat(testFile); err == nil {
  1275  				found = true
  1276  				err = os.Remove(testFile)
  1277  				Expect(err).To(BeNil())
  1278  				break
  1279  			}
  1280  		}
  1281  		Expect(found).To(BeTrue())
  1282  
  1283  		err = os.Remove(aliveFile)
  1284  		Expect(err).To(BeNil())
  1285  
  1286  		session.WaitWithDefaultTimeout()
  1287  
  1288  		// 10 seconds to restart the container
  1289  		found = false
  1290  		for i := 0; i < 10; i++ {
  1291  			time.Sleep(1 * time.Second)
  1292  			if _, err := os.Stat(testFile); err == nil {
  1293  				found = true
  1294  				break
  1295  			}
  1296  		}
  1297  		Expect(found).To(BeTrue())
  1298  	})
  1299  
  1300  	It("podman run with cgroups=split", func() {
  1301  		SkipIfNotSystemd(podmanTest.CgroupManager, "do not test --cgroups=split if not running on systemd")
  1302  		SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
  1303  		SkipIfRemote("--cgroups=split cannot be used in remote mode")
  1304  
  1305  		checkLines := func(lines []string) {
  1306  			cgroup := ""
  1307  			for _, line := range lines {
  1308  				parts := strings.SplitN(line, ":", 3)
  1309  				if len(parts) < 2 {
  1310  					continue
  1311  				}
  1312  				if !CGROUPSV2 {
  1313  					// ignore unified on cgroup v1.
  1314  					// both runc and crun do not set it.
  1315  					// crun does not set named hierarchies.
  1316  					if parts[1] == "" || strings.Contains(parts[1], "name=") {
  1317  						continue
  1318  					}
  1319  				}
  1320  				if parts[2] == "/" {
  1321  					continue
  1322  				}
  1323  				if cgroup == "" {
  1324  					cgroup = parts[2]
  1325  					continue
  1326  				}
  1327  				Expect(cgroup).To(Equal(parts[2]))
  1328  			}
  1329  		}
  1330  
  1331  		container := podmanTest.PodmanSystemdScope([]string{"run", "--rm", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"})
  1332  		container.WaitWithDefaultTimeout()
  1333  		Expect(container).Should(Exit(0))
  1334  		checkLines(container.OutputToStringArray())
  1335  
  1336  		// check that --cgroups=split is honored also when a container runs in a pod
  1337  		container = podmanTest.PodmanSystemdScope([]string{"run", "--rm", "--pod", "new:split-test-pod", "--cgroups=split", ALPINE, "cat", "/proc/self/cgroup"})
  1338  		container.WaitWithDefaultTimeout()
  1339  		Expect(container).Should(Exit(0))
  1340  		checkLines(container.OutputToStringArray())
  1341  	})
  1342  
  1343  	It("podman run with cgroups=disabled runs without cgroups", func() {
  1344  		SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
  1345  		// Only works on crun
  1346  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1347  			Skip("Test only works on crun")
  1348  		}
  1349  
  1350  		ownsCgroup, err := cgroups.UserOwnsCurrentSystemdCgroup()
  1351  		Expect(err).ShouldNot(HaveOccurred())
  1352  		if !ownsCgroup {
  1353  			// Podman moves itself to a new cgroup if it doesn't own the current cgroup
  1354  			Skip("Test only works when Podman owns the current cgroup")
  1355  		}
  1356  
  1357  		trim := func(i string) string {
  1358  			return strings.TrimSuffix(i, "\n")
  1359  		}
  1360  
  1361  		curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup")
  1362  		Expect(err).ShouldNot(HaveOccurred())
  1363  		curCgroups := trim(string(curCgroupsBytes))
  1364  		fmt.Printf("Output:\n%s\n", curCgroups)
  1365  		Expect(curCgroups).ToNot(Equal(""))
  1366  
  1367  		container := podmanTest.Podman([]string{"run", "--cgroupns=host", "--cgroups=disabled", ALPINE, "cat", "/proc/self/cgroup"})
  1368  		container.WaitWithDefaultTimeout()
  1369  		Expect(container).Should(Exit(0))
  1370  
  1371  		ctrCgroups := trim(container.OutputToString())
  1372  		fmt.Printf("Output\n:%s\n", ctrCgroups)
  1373  
  1374  		Expect(ctrCgroups).To(Equal(curCgroups))
  1375  	})
  1376  
  1377  	It("podman run with cgroups=enabled makes cgroups", func() {
  1378  		SkipIfRootlessCgroupsV1("Enable cgroups not supported on cgroupv1 for rootless users")
  1379  		// Only works on crun
  1380  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1381  			Skip("Test only works on crun")
  1382  		}
  1383  
  1384  		curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup")
  1385  		Expect(err).To(BeNil())
  1386  		var curCgroups string = string(curCgroupsBytes)
  1387  		fmt.Printf("Output:\n%s\n", curCgroups)
  1388  		Expect(curCgroups).To(Not(Equal("")))
  1389  
  1390  		ctrName := "testctr"
  1391  		container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=enabled", ALPINE, "top"})
  1392  		container.WaitWithDefaultTimeout()
  1393  		Expect(container).Should(Exit(0))
  1394  
  1395  		// Get PID and get cgroups of that PID
  1396  		inspectOut := podmanTest.InspectContainer(ctrName)
  1397  		Expect(len(inspectOut)).To(Equal(1))
  1398  		pid := inspectOut[0].State.Pid
  1399  		Expect(pid).To(Not(Equal(0)))
  1400  
  1401  		ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
  1402  		Expect(err).To(BeNil())
  1403  		var ctrCgroups string = string(ctrCgroupsBytes)
  1404  		fmt.Printf("Output\n:%s\n", ctrCgroups)
  1405  		Expect(curCgroups).To(Not(Equal(ctrCgroups)))
  1406  	})
  1407  
  1408  	It("podman run with cgroups=garbage errors", func() {
  1409  		session := podmanTest.Podman([]string{"run", "-d", "--cgroups=garbage", ALPINE, "top"})
  1410  		session.WaitWithDefaultTimeout()
  1411  		Expect(session).To(ExitWithError())
  1412  	})
  1413  
  1414  	It("podman run should fail with nonexistent authfile", func() {
  1415  		session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexistent", ALPINE, "ls"})
  1416  		session.WaitWithDefaultTimeout()
  1417  		Expect(session).To(ExitWithError())
  1418  	})
  1419  
  1420  	It("podman run --device-cgroup-rule", func() {
  1421  		SkipIfRootless("rootless users are not allowed to mknod")
  1422  		deviceCgroupRule := "c 42:* rwm"
  1423  		session := podmanTest.Podman([]string{"run", "--cap-add", "mknod", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"})
  1424  		session.WaitWithDefaultTimeout()
  1425  		Expect(session).Should(Exit(0))
  1426  		session = podmanTest.Podman([]string{"exec", "test", "mknod", "newDev", "c", "42", "1"})
  1427  		session.WaitWithDefaultTimeout()
  1428  		Expect(session).Should(Exit(0))
  1429  	})
  1430  
  1431  	It("podman run --replace", func() {
  1432  		// Make sure we error out with --name.
  1433  		session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})
  1434  		session.WaitWithDefaultTimeout()
  1435  		Expect(session).Should(Exit(125))
  1436  
  1437  		// Run and replace 5 times in a row the "same" container.
  1438  		ctrName := "testCtr"
  1439  		for i := 0; i < 5; i++ {
  1440  			session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"})
  1441  			session.WaitWithDefaultTimeout()
  1442  			Expect(session).Should(Exit(0))
  1443  		}
  1444  	})
  1445  
  1446  	It("podman run --preserve-fds", func() {
  1447  		devNull, err := os.Open("/dev/null")
  1448  		Expect(err).To(BeNil())
  1449  		defer devNull.Close()
  1450  		files := []*os.File{
  1451  			devNull,
  1452  		}
  1453  		session := podmanTest.PodmanExtraFiles([]string{"run", "--preserve-fds", "1", ALPINE, "ls"}, files)
  1454  		session.WaitWithDefaultTimeout()
  1455  		Expect(session).Should(Exit(0))
  1456  	})
  1457  
  1458  	It("podman run --preserve-fds invalid fd", func() {
  1459  		session := podmanTest.Podman([]string{"run", "--preserve-fds", "2", ALPINE})
  1460  		session.WaitWithDefaultTimeout()
  1461  		Expect(session).To(ExitWithError())
  1462  		Expect(session.ErrorToString()).To(ContainSubstring("file descriptor 3 is not available"))
  1463  	})
  1464  
  1465  	It("podman run --privileged and --group-add", func() {
  1466  		groupName := "mail"
  1467  		session := podmanTest.Podman([]string{"run", "-t", "-i", "--group-add", groupName, "--privileged", fedoraMinimal, "groups"})
  1468  		session.WaitWithDefaultTimeout()
  1469  		Expect(session).Should(Exit(0))
  1470  		Expect(strings.Contains(session.OutputToString(), groupName)).To(BeTrue())
  1471  	})
  1472  
  1473  	It("podman run --tz", func() {
  1474  		testDir := filepath.Join(podmanTest.RunRoot, "tz-test")
  1475  		err := os.MkdirAll(testDir, 0755)
  1476  		Expect(err).To(BeNil())
  1477  
  1478  		tzFile := filepath.Join(testDir, "tzfile.txt")
  1479  		file, err := os.Create(tzFile)
  1480  		Expect(err).To(BeNil())
  1481  
  1482  		_, err = file.WriteString("Hello")
  1483  		Expect(err).To(BeNil())
  1484  		file.Close()
  1485  
  1486  		badTZFile := fmt.Sprintf("../../../%s", tzFile)
  1487  		session := podmanTest.Podman([]string{"run", "--tz", badTZFile, "--rm", ALPINE, "date"})
  1488  		session.WaitWithDefaultTimeout()
  1489  		Expect(session).To(ExitWithError())
  1490  		Expect(session.ErrorToString()).To(ContainSubstring("error finding timezone for container"))
  1491  
  1492  		err = os.Remove(tzFile)
  1493  		Expect(err).To(BeNil())
  1494  
  1495  		session = podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"})
  1496  		session.WaitWithDefaultTimeout()
  1497  		Expect(session).To(ExitWithError())
  1498  
  1499  		session = podmanTest.Podman([]string{"run", "--tz", "America", "--rm", ALPINE, "date"})
  1500  		session.WaitWithDefaultTimeout()
  1501  		Expect(session).To(ExitWithError())
  1502  
  1503  		session = podmanTest.Podman([]string{"run", "--tz", "Pacific/Honolulu", "--rm", ALPINE, "date", "+'%H %Z'"})
  1504  		session.WaitWithDefaultTimeout()
  1505  		Expect(session).Should(Exit(0))
  1506  		Expect(session.OutputToString()).To(ContainSubstring("HST"))
  1507  
  1508  		session = podmanTest.Podman([]string{"run", "--tz", "local", "--rm", ALPINE, "date", "+'%H %Z'"})
  1509  		session.WaitWithDefaultTimeout()
  1510  		Expect(session).Should(Exit(0))
  1511  		t := time.Now()
  1512  		z, _ := t.Zone()
  1513  		h := strconv.Itoa(t.Hour())
  1514  		Expect(session.OutputToString()).To(ContainSubstring(z))
  1515  		Expect(session.OutputToString()).To(ContainSubstring(h))
  1516  
  1517  	})
  1518  
  1519  	It("podman run verify pids-limit", func() {
  1520  		SkipIfCgroupV1("pids-limit not supported on cgroup V1")
  1521  		limit := "4321"
  1522  		session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"})
  1523  		session.WaitWithDefaultTimeout()
  1524  		Expect(session).Should(Exit(0))
  1525  		Expect(session.OutputToString()).To(ContainSubstring(limit))
  1526  	})
  1527  
  1528  	It("podman run umask", func() {
  1529  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1530  			Skip("Test only works on crun")
  1531  		}
  1532  
  1533  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
  1534  		session.WaitWithDefaultTimeout()
  1535  		Expect(session).Should(Exit(0))
  1536  		Expect(session.OutputToString()).To(Equal("0022"))
  1537  
  1538  		session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"})
  1539  		session.WaitWithDefaultTimeout()
  1540  		Expect(session).Should(Exit(0))
  1541  		Expect(session.OutputToString()).To(Equal("0002"))
  1542  
  1543  		session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"})
  1544  		session.WaitWithDefaultTimeout()
  1545  		Expect(session).Should(Exit(0))
  1546  		Expect(session.OutputToString()).To(Equal("0077"))
  1547  
  1548  		session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"})
  1549  		session.WaitWithDefaultTimeout()
  1550  		Expect(session).Should(Exit(0))
  1551  		Expect(session.OutputToString()).To(Equal("0022"))
  1552  
  1553  		session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"})
  1554  		session.WaitWithDefaultTimeout()
  1555  		Expect(session).To(ExitWithError())
  1556  		Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask"))
  1557  	})
  1558  
  1559  	It("podman run makes workdir from image", func() {
  1560  		// BuildImage does not seem to work remote
  1561  		dockerfile := fmt.Sprintf(`FROM %s
  1562  WORKDIR /madethis`, BB)
  1563  		podmanTest.BuildImage(dockerfile, "test", "false")
  1564  		session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"})
  1565  		session.WaitWithDefaultTimeout()
  1566  		Expect(session).Should(Exit(0))
  1567  		Expect(session.OutputToString()).To(ContainSubstring("/madethis"))
  1568  	})
  1569  
  1570  	It("podman run --entrypoint does not use image command", func() {
  1571  		session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE})
  1572  		session.WaitWithDefaultTimeout()
  1573  		Expect(session).Should(Exit(0))
  1574  		// We can't guarantee the output is completely empty, some
  1575  		// nonprintables seem to work their way in.
  1576  		Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh")))
  1577  	})
  1578  
  1579  	It("podman run a container with log-level (lower case)", func() {
  1580  		session := podmanTest.Podman([]string{"--log-level=info", "run", ALPINE, "ls"})
  1581  		session.WaitWithDefaultTimeout()
  1582  		Expect(session).Should(Exit(0))
  1583  	})
  1584  
  1585  	It("podman run a container with log-level (upper case)", func() {
  1586  		session := podmanTest.Podman([]string{"--log-level=INFO", "run", ALPINE, "ls"})
  1587  		session.WaitWithDefaultTimeout()
  1588  		Expect(session).Should(Exit(0))
  1589  	})
  1590  
  1591  	It("podman run a container with --pull never should fail if no local store", func() {
  1592  		session := podmanTest.Podman([]string{"run", "--pull", "never", "docker.io/library/debian:latest", "ls"})
  1593  		session.WaitWithDefaultTimeout()
  1594  		Expect(session).Should(Exit(125))
  1595  	})
  1596  
  1597  	It("podman run container with --pull missing and only pull once", func() {
  1598  		session := podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"})
  1599  		session.WaitWithDefaultTimeout()
  1600  		Expect(session).Should(Exit(0))
  1601  		Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
  1602  
  1603  		session = podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"})
  1604  		session.WaitWithDefaultTimeout()
  1605  		Expect(session).Should(Exit(0))
  1606  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
  1607  	})
  1608  
  1609  	It("podman run container with --pull missing should pull image multiple times", func() {
  1610  		session := podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"})
  1611  		session.WaitWithDefaultTimeout()
  1612  		Expect(session).Should(Exit(0))
  1613  		Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
  1614  
  1615  		session = podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"})
  1616  		session.WaitWithDefaultTimeout()
  1617  		Expect(session).Should(Exit(0))
  1618  		Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
  1619  	})
  1620  
  1621  	It("podman run container with hostname and hostname environment variable", func() {
  1622  		hostnameEnv := "test123"
  1623  		session := podmanTest.Podman([]string{"run", "--hostname", "testctr", "--env", fmt.Sprintf("HOSTNAME=%s", hostnameEnv), ALPINE, "printenv", "HOSTNAME"})
  1624  		session.WaitWithDefaultTimeout()
  1625  		Expect(session).Should(Exit(0))
  1626  		Expect(session.OutputToString()).To(ContainSubstring(hostnameEnv))
  1627  	})
  1628  
  1629  	It("podman run --secret", func() {
  1630  		secretsString := "somesecretdata"
  1631  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1632  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1633  		Expect(err).To(BeNil())
  1634  
  1635  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1636  		session.WaitWithDefaultTimeout()
  1637  		Expect(session).Should(Exit(0))
  1638  
  1639  		session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
  1640  		session.WaitWithDefaultTimeout()
  1641  		Expect(session).Should(Exit(0))
  1642  		Expect(session.OutputToString()).To(Equal(secretsString))
  1643  
  1644  		session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"})
  1645  		session.WaitWithDefaultTimeout()
  1646  		Expect(session).Should(Exit(0))
  1647  		Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
  1648  
  1649  	})
  1650  
  1651  	It("podman run --secret source=mysecret,type=mount", func() {
  1652  		secretsString := "somesecretdata"
  1653  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1654  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1655  		Expect(err).To(BeNil())
  1656  
  1657  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1658  		session.WaitWithDefaultTimeout()
  1659  		Expect(session).Should(Exit(0))
  1660  
  1661  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount", "--name", "secr", ALPINE, "cat", "/run/secrets/mysecret"})
  1662  		session.WaitWithDefaultTimeout()
  1663  		Expect(session).Should(Exit(0))
  1664  		Expect(session.OutputToString()).To(Equal(secretsString))
  1665  
  1666  		session = podmanTest.Podman([]string{"inspect", "secr", "--format", " {{(index .Config.Secrets 0).Name}}"})
  1667  		session.WaitWithDefaultTimeout()
  1668  		Expect(session).Should(Exit(0))
  1669  		Expect(session.OutputToString()).To(ContainSubstring("mysecret"))
  1670  
  1671  	})
  1672  
  1673  	It("podman run --secret source=mysecret,type=mount with target", func() {
  1674  		secretsString := "somesecretdata"
  1675  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1676  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1677  		Expect(err).To(BeNil())
  1678  
  1679  		session := podmanTest.Podman([]string{"secret", "create", "mysecret_target", secretFilePath})
  1680  		session.WaitWithDefaultTimeout()
  1681  		Expect(session).Should(Exit(0))
  1682  
  1683  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target,type=mount,target=hello", "--name", "secr_target", ALPINE, "cat", "/run/secrets/hello"})
  1684  		session.WaitWithDefaultTimeout()
  1685  		Expect(session).Should(Exit(0))
  1686  		Expect(session.OutputToString()).To(Equal(secretsString))
  1687  
  1688  		session = podmanTest.Podman([]string{"inspect", "secr_target", "--format", " {{(index .Config.Secrets 0).Name}}"})
  1689  		session.WaitWithDefaultTimeout()
  1690  		Expect(session).Should(Exit(0))
  1691  		Expect(session.OutputToString()).To(ContainSubstring("mysecret_target"))
  1692  
  1693  	})
  1694  
  1695  	It("podman run --secret source=mysecret,type=mount with target at /tmp", func() {
  1696  		secretsString := "somesecretdata"
  1697  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1698  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1699  		Expect(err).To(BeNil())
  1700  
  1701  		session := podmanTest.Podman([]string{"secret", "create", "mysecret_target2", secretFilePath})
  1702  		session.WaitWithDefaultTimeout()
  1703  		Expect(session).Should(Exit(0))
  1704  
  1705  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret_target2,type=mount,target=/tmp/hello", "--name", "secr_target2", ALPINE, "cat", "/tmp/hello"})
  1706  		session.WaitWithDefaultTimeout()
  1707  		Expect(session).Should(Exit(0))
  1708  		Expect(session.OutputToString()).To(Equal(secretsString))
  1709  
  1710  		session = podmanTest.Podman([]string{"inspect", "secr_target2", "--format", " {{(index .Config.Secrets 0).Name}}"})
  1711  		session.WaitWithDefaultTimeout()
  1712  		Expect(session).Should(Exit(0))
  1713  		Expect(session.OutputToString()).To(ContainSubstring("mysecret_target2"))
  1714  
  1715  	})
  1716  
  1717  	It("podman run --secret source=mysecret,type=env", func() {
  1718  		secretsString := "somesecretdata"
  1719  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1720  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1721  		Expect(err).To(BeNil())
  1722  
  1723  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1724  		session.WaitWithDefaultTimeout()
  1725  		Expect(session).Should(Exit(0))
  1726  
  1727  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
  1728  		session.WaitWithDefaultTimeout()
  1729  		Expect(session).Should(Exit(0))
  1730  		Expect(session.OutputToString()).To(Equal(secretsString))
  1731  	})
  1732  
  1733  	It("podman run --secret target option", func() {
  1734  		secretsString := "somesecretdata"
  1735  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1736  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1737  		Expect(err).To(BeNil())
  1738  
  1739  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1740  		session.WaitWithDefaultTimeout()
  1741  		Expect(session).Should(Exit(0))
  1742  
  1743  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,target=anotherplace", "--name", "secr", ALPINE, "printenv", "anotherplace"})
  1744  		session.WaitWithDefaultTimeout()
  1745  		Expect(session).Should(Exit(0))
  1746  		Expect(session.OutputToString()).To(Equal(secretsString))
  1747  	})
  1748  
  1749  	It("podman run --secret mount with uid, gid, mode options", func() {
  1750  		secretsString := "somesecretdata"
  1751  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1752  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1753  		Expect(err).To(BeNil())
  1754  
  1755  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1756  		session.WaitWithDefaultTimeout()
  1757  		Expect(session).Should(Exit(0))
  1758  
  1759  		// check default permissions
  1760  		session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "secr", ALPINE, "ls", "-l", "/run/secrets/mysecret"})
  1761  		session.WaitWithDefaultTimeout()
  1762  		Expect(session).Should(Exit(0))
  1763  		output := session.OutputToString()
  1764  		Expect(output).To(ContainSubstring("-r--r--r--"))
  1765  		Expect(output).To(ContainSubstring("root"))
  1766  
  1767  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=mount,uid=1000,gid=1001,mode=777", "--name", "secr2", ALPINE, "ls", "-ln", "/run/secrets/mysecret"})
  1768  		session.WaitWithDefaultTimeout()
  1769  		Expect(session).Should(Exit(0))
  1770  		output = session.OutputToString()
  1771  		Expect(output).To(ContainSubstring("-rwxrwxrwx"))
  1772  		Expect(output).To(ContainSubstring("1000"))
  1773  		Expect(output).To(ContainSubstring("1001"))
  1774  	})
  1775  
  1776  	It("podman run --secret with --user", func() {
  1777  		secretsString := "somesecretdata"
  1778  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1779  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1780  		Expect(err).To(BeNil())
  1781  
  1782  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1783  		session.WaitWithDefaultTimeout()
  1784  		Expect(session).Should(Exit(0))
  1785  
  1786  		session = podmanTest.Podman([]string{"run", "--secret", "mysecret", "--name", "nonroot", "--user", "200:200", ALPINE, "cat", "/run/secrets/mysecret"})
  1787  		session.WaitWithDefaultTimeout()
  1788  		Expect(session).Should(Exit(0))
  1789  		Expect(session.OutputToString()).To(Equal(secretsString))
  1790  	})
  1791  
  1792  	It("podman run invalid secret option", func() {
  1793  		secretsString := "somesecretdata"
  1794  		secretFilePath := filepath.Join(podmanTest.TempDir, "secret")
  1795  		err := ioutil.WriteFile(secretFilePath, []byte(secretsString), 0755)
  1796  		Expect(err).To(BeNil())
  1797  
  1798  		session := podmanTest.Podman([]string{"secret", "create", "mysecret", secretFilePath})
  1799  		session.WaitWithDefaultTimeout()
  1800  		Expect(session).Should(Exit(0))
  1801  
  1802  		// Invalid type
  1803  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=other", "--name", "secr", ALPINE, "printenv", "mysecret"})
  1804  		session.WaitWithDefaultTimeout()
  1805  		Expect(session).To(ExitWithError())
  1806  
  1807  		// Invalid option
  1808  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,invalid=invalid", "--name", "secr", ALPINE, "printenv", "mysecret"})
  1809  		session.WaitWithDefaultTimeout()
  1810  		Expect(session).To(ExitWithError())
  1811  
  1812  		// Option syntax not valid
  1813  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type", "--name", "secr", ALPINE, "printenv", "mysecret"})
  1814  		session.WaitWithDefaultTimeout()
  1815  		Expect(session).To(ExitWithError())
  1816  
  1817  		// mount option with env type
  1818  		session = podmanTest.Podman([]string{"run", "--secret", "source=mysecret,type=env,uid=1000", "--name", "secr", ALPINE, "printenv", "mysecret"})
  1819  		session.WaitWithDefaultTimeout()
  1820  		Expect(session).To(ExitWithError())
  1821  
  1822  		// No source given
  1823  		session = podmanTest.Podman([]string{"run", "--secret", "type=env", "--name", "secr", ALPINE, "printenv", "mysecret"})
  1824  		session.WaitWithDefaultTimeout()
  1825  		Expect(session).To(ExitWithError())
  1826  	})
  1827  
  1828  	It("podman run --requires", func() {
  1829  		depName := "ctr1"
  1830  		depContainer := podmanTest.Podman([]string{"create", "--name", depName, ALPINE, "top"})
  1831  		depContainer.WaitWithDefaultTimeout()
  1832  		Expect(depContainer).Should(Exit(0))
  1833  
  1834  		mainName := "ctr2"
  1835  		mainContainer := podmanTest.Podman([]string{"run", "--name", mainName, "--requires", depName, "-d", ALPINE, "top"})
  1836  		mainContainer.WaitWithDefaultTimeout()
  1837  		Expect(mainContainer).Should(Exit(0))
  1838  
  1839  		stop := podmanTest.Podman([]string{"stop", "--all"})
  1840  		stop.WaitWithDefaultTimeout()
  1841  		Expect(stop).Should(Exit(0))
  1842  
  1843  		start := podmanTest.Podman([]string{"start", mainName})
  1844  		start.WaitWithDefaultTimeout()
  1845  		Expect(start).Should(Exit(0))
  1846  
  1847  		running := podmanTest.Podman([]string{"ps", "-q"})
  1848  		running.WaitWithDefaultTimeout()
  1849  		Expect(running).Should(Exit(0))
  1850  		Expect(len(running.OutputToStringArray())).To(Equal(2))
  1851  	})
  1852  
  1853  	It("podman run with pidfile", func() {
  1854  		SkipIfRemote("pidfile not handled by remote")
  1855  		pidfile := tempdir + "pidfile"
  1856  		session := podmanTest.Podman([]string{"run", "--pidfile", pidfile, ALPINE, "ls"})
  1857  		session.WaitWithDefaultTimeout()
  1858  		Expect(session).Should(Exit(0))
  1859  		readFirstLine := func(path string) string {
  1860  			content, err := ioutil.ReadFile(path)
  1861  			Expect(err).To(BeNil())
  1862  			return strings.Split(string(content), "\n")[0]
  1863  		}
  1864  		containerPID := readFirstLine(pidfile)
  1865  		_, err = strconv.Atoi(containerPID) // Make sure it's a proper integer
  1866  		Expect(err).To(BeNil())
  1867  	})
  1868  
  1869  	It("podman run check personality support", func() {
  1870  		// TODO: Remove this as soon as this is merged and made available in our CI https://github.com/opencontainers/runc/pull/3126.
  1871  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1872  			Skip("Test only works on crun")
  1873  		}
  1874  		session := podmanTest.Podman([]string{"run", "--personality=LINUX32", "--name=testpersonality", ALPINE, "uname", "-a"})
  1875  		session.WaitWithDefaultTimeout()
  1876  		Expect(session).Should(Exit(0))
  1877  		Expect(session.OutputToString()).To(ContainSubstring("i686"))
  1878  	})
  1879  })