github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/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/v2/test/utils"
    15  	"github.com/containers/storage/pkg/stringid"
    16  	"github.com/mrunalp/fileutils"
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  )
    20  
    21  var _ = Describe("Podman run", func() {
    22  	var (
    23  		tempdir    string
    24  		err        error
    25  		podmanTest *PodmanTestIntegration
    26  	)
    27  
    28  	BeforeEach(func() {
    29  		tempdir, err = CreateTempDirInTempDir()
    30  		if err != nil {
    31  			os.Exit(1)
    32  		}
    33  		podmanTest = PodmanTestCreate(tempdir)
    34  		podmanTest.Setup()
    35  		podmanTest.SeedImages()
    36  	})
    37  
    38  	AfterEach(func() {
    39  		podmanTest.Cleanup()
    40  		f := CurrentGinkgoTestDescription()
    41  		processTestResult(f)
    42  	})
    43  
    44  	It("podman run a container based on local image", func() {
    45  		session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
    46  		session.WaitWithDefaultTimeout()
    47  		Expect(session.ExitCode()).To(Equal(0))
    48  	})
    49  
    50  	It("podman run a container based on a complex local image name", func() {
    51  		imageName := strings.TrimPrefix(nginx, "quay.io/")
    52  		session := podmanTest.Podman([]string{"run", imageName, "ls"})
    53  		session.WaitWithDefaultTimeout()
    54  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
    55  		Expect(session.ExitCode()).To(Equal(0))
    56  	})
    57  
    58  	It("podman run --signature-policy", func() {
    59  		SkipIfRemote("SigPolicy not handled by remote")
    60  		session := podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/no/such/file", ALPINE})
    61  		session.WaitWithDefaultTimeout()
    62  		Expect(session.ExitCode()).To(Not(Equal(0)))
    63  
    64  		session = podmanTest.Podman([]string{"run", "--pull=always", "--signature-policy", "/etc/containers/policy.json", ALPINE})
    65  		session.WaitWithDefaultTimeout()
    66  		Expect(session.ExitCode()).To(Equal(0))
    67  	})
    68  
    69  	It("podman run --rm with --restart", func() {
    70  		session := podmanTest.Podman([]string{"run", "--rm", "--restart", "", ALPINE})
    71  		session.WaitWithDefaultTimeout()
    72  		Expect(session.ExitCode()).To(Equal(0))
    73  
    74  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "no", ALPINE})
    75  		session.WaitWithDefaultTimeout()
    76  		Expect(session.ExitCode()).To(Equal(0))
    77  
    78  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "on-failure", ALPINE})
    79  		session.WaitWithDefaultTimeout()
    80  		Expect(session.ExitCode()).To(Equal(0))
    81  
    82  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "always", ALPINE})
    83  		session.WaitWithDefaultTimeout()
    84  		Expect(session.ExitCode()).To(Not(Equal(0)))
    85  
    86  		session = podmanTest.Podman([]string{"run", "--rm", "--restart", "unless-stopped", ALPINE})
    87  		session.WaitWithDefaultTimeout()
    88  		Expect(session.ExitCode()).To(Not(Equal(0)))
    89  	})
    90  
    91  	It("podman run a container based on on a short name with localhost", func() {
    92  		tag := podmanTest.Podman([]string{"tag", nginx, "localhost/libpod/alpine_nginx:latest"})
    93  		tag.WaitWithDefaultTimeout()
    94  
    95  		rmi := podmanTest.Podman([]string{"rmi", nginx})
    96  		rmi.WaitWithDefaultTimeout()
    97  
    98  		session := podmanTest.Podman([]string{"run", "libpod/alpine_nginx:latest", "ls"})
    99  		session.WaitWithDefaultTimeout()
   100  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
   101  		Expect(session.ExitCode()).To(Equal(0))
   102  	})
   103  
   104  	It("podman container run a container based on on a short name with localhost", func() {
   105  		tag := podmanTest.Podman([]string{"image", "tag", nginx, "localhost/libpod/alpine_nginx:latest"})
   106  		tag.WaitWithDefaultTimeout()
   107  
   108  		rmi := podmanTest.Podman([]string{"image", "rm", nginx})
   109  		rmi.WaitWithDefaultTimeout()
   110  
   111  		session := podmanTest.Podman([]string{"container", "run", "libpod/alpine_nginx:latest", "ls"})
   112  		session.WaitWithDefaultTimeout()
   113  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
   114  		Expect(session.ExitCode()).To(Equal(0))
   115  	})
   116  
   117  	It("podman run a container based on local image with short options", func() {
   118  		session := podmanTest.Podman([]string{"run", "-dt", ALPINE, "ls"})
   119  		session.WaitWithDefaultTimeout()
   120  		Expect(session.ExitCode()).To(Equal(0))
   121  	})
   122  
   123  	It("podman run a container based on local image with short options and args", func() {
   124  		// regression test for #714
   125  		session := podmanTest.Podman([]string{"run", ALPINE, "find", "/etc", "-name", "hosts"})
   126  		session.WaitWithDefaultTimeout()
   127  		Expect(session.ExitCode()).To(Equal(0))
   128  		match, _ := session.GrepString("/etc/hosts")
   129  		Expect(match).Should(BeTrue())
   130  	})
   131  
   132  	It("podman create pod with name in /etc/hosts", func() {
   133  		name := "test_container"
   134  		hostname := "test_hostname"
   135  		session := podmanTest.Podman([]string{"run", "-ti", "--rm", "--name", name, "--hostname", hostname, ALPINE, "cat", "/etc/hosts"})
   136  		session.WaitWithDefaultTimeout()
   137  		Expect(session.ExitCode()).To(Equal(0))
   138  		match, _ := session.GrepString(name)
   139  		Expect(match).Should(BeTrue())
   140  		match, _ = session.GrepString(hostname)
   141  		Expect(match).Should(BeTrue())
   142  	})
   143  
   144  	It("podman run a container based on remote image", func() {
   145  		session := podmanTest.Podman([]string{"run", "-dt", BB_GLIBC, "ls"})
   146  		session.WaitWithDefaultTimeout()
   147  		Expect(session.ExitCode()).To(Equal(0))
   148  	})
   149  
   150  	It("podman run a container with a --rootfs", func() {
   151  		rootfs := filepath.Join(tempdir, "rootfs")
   152  		uls := filepath.Join("/", "usr", "local", "share")
   153  		uniqueString := stringid.GenerateNonCryptoID()
   154  		testFilePath := filepath.Join(uls, uniqueString)
   155  		tarball := filepath.Join(tempdir, "rootfs.tar")
   156  
   157  		err := os.Mkdir(rootfs, 0770)
   158  		Expect(err).Should(BeNil())
   159  
   160  		// Change image in predictable way to validate export
   161  		csession := podmanTest.Podman([]string{"run", "--name", uniqueString, ALPINE,
   162  			"/bin/sh", "-c", fmt.Sprintf("echo %s > %s", uniqueString, testFilePath)})
   163  		csession.WaitWithDefaultTimeout()
   164  		Expect(csession.ExitCode()).To(Equal(0))
   165  
   166  		// Export from working container image guarantees working root
   167  		esession := podmanTest.Podman([]string{"export", "--output", tarball, uniqueString})
   168  		esession.WaitWithDefaultTimeout()
   169  		Expect(esession.ExitCode()).To(Equal(0))
   170  		Expect(tarball).Should(BeARegularFile())
   171  
   172  		// N/B: This will loose any extended attributes like SELinux types
   173  		fmt.Fprintf(os.Stderr, "Extracting container root tarball\n")
   174  		tarsession := SystemExec("tar", []string{"xf", tarball, "-C", rootfs})
   175  		Expect(tarsession.ExitCode()).To(Equal(0))
   176  		Expect(filepath.Join(rootfs, uls)).Should(BeADirectory())
   177  
   178  		// Other tests confirm SELinux types, just confirm --rootfs is working.
   179  		session := podmanTest.Podman([]string{"run", "-i", "--security-opt", "label=disable",
   180  			"--rootfs", rootfs, "cat", testFilePath})
   181  		session.WaitWithDefaultTimeout()
   182  		Expect(session.ExitCode()).To(Equal(0))
   183  
   184  		// Validate changes made in original container and export
   185  		stdoutLines := session.OutputToStringArray()
   186  		Expect(stdoutLines).Should(HaveLen(1))
   187  		Expect(stdoutLines[0]).Should(Equal(uniqueString))
   188  	})
   189  
   190  	It("podman run a container with --init", func() {
   191  		session := podmanTest.Podman([]string{"run", "--name", "test", "--init", ALPINE, "ls"})
   192  		session.WaitWithDefaultTimeout()
   193  		Expect(session.ExitCode()).To(Equal(0))
   194  		result := podmanTest.Podman([]string{"inspect", "test"})
   195  		result.WaitWithDefaultTimeout()
   196  		Expect(result.ExitCode()).To(Equal(0))
   197  		conData := result.InspectContainerToJSON()
   198  		Expect(conData[0].Path).To(Equal("/dev/init"))
   199  		Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE"))
   200  	})
   201  
   202  	It("podman run a container with --init and --init-path", func() {
   203  		session := podmanTest.Podman([]string{"run", "--name", "test", "--init", "--init-path", "/usr/libexec/podman/catatonit", ALPINE, "ls"})
   204  		session.WaitWithDefaultTimeout()
   205  		Expect(session.ExitCode()).To(Equal(0))
   206  		result := podmanTest.Podman([]string{"inspect", "test"})
   207  		result.WaitWithDefaultTimeout()
   208  		Expect(result.ExitCode()).To(Equal(0))
   209  		conData := result.InspectContainerToJSON()
   210  		Expect(conData[0].Path).To(Equal("/dev/init"))
   211  		Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("TRUE"))
   212  	})
   213  
   214  	It("podman run a container without --init", func() {
   215  		session := podmanTest.Podman([]string{"run", "--name", "test", ALPINE, "ls"})
   216  		session.WaitWithDefaultTimeout()
   217  		Expect(session.ExitCode()).To(Equal(0))
   218  		result := podmanTest.Podman([]string{"inspect", "test"})
   219  		result.WaitWithDefaultTimeout()
   220  		Expect(result.ExitCode()).To(Equal(0))
   221  		conData := result.InspectContainerToJSON()
   222  		Expect(conData[0].Path).To(Equal("ls"))
   223  		Expect(conData[0].Config.Annotations["io.podman.annotations.init"]).To(Equal("FALSE"))
   224  	})
   225  
   226  	forbidGetCWDSeccompProfile := func() string {
   227  		in := []byte(`{"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"getcwd","action":"SCMP_ACT_ERRNO"}]}`)
   228  		jsonFile, err := podmanTest.CreateSeccompJson(in)
   229  		if err != nil {
   230  			fmt.Println(err)
   231  			Skip("Failed to prepare seccomp.json for test.")
   232  		}
   233  		return jsonFile
   234  	}
   235  
   236  	It("podman run seccomp test", func() {
   237  		session := podmanTest.Podman([]string{"run", "-it", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"})
   238  		session.WaitWithDefaultTimeout()
   239  		Expect(session).To(ExitWithError())
   240  		match, _ := session.GrepString("Operation not permitted")
   241  		Expect(match).Should(BeTrue())
   242  	})
   243  
   244  	It("podman run seccomp test --privileged", func() {
   245  		session := podmanTest.Podman([]string{"run", "-it", "--privileged", "--security-opt", strings.Join([]string{"seccomp=", forbidGetCWDSeccompProfile()}, ""), ALPINE, "pwd"})
   246  		session.WaitWithDefaultTimeout()
   247  		Expect(session).To(ExitWithError())
   248  		match, _ := session.GrepString("Operation not permitted")
   249  		Expect(match).Should(BeTrue())
   250  	})
   251  
   252  	It("podman run seccomp test --privileged no profile should be unconfined", func() {
   253  		session := podmanTest.Podman([]string{"run", "-it", "--privileged", ALPINE, "grep", "Seccomp", "/proc/self/status"})
   254  		session.WaitWithDefaultTimeout()
   255  		Expect(session.OutputToString()).To(ContainSubstring("0"))
   256  		Expect(session.ExitCode()).To(Equal(0))
   257  	})
   258  
   259  	It("podman run seccomp test no profile should be default", func() {
   260  		session := podmanTest.Podman([]string{"run", "-it", ALPINE, "grep", "Seccomp", "/proc/self/status"})
   261  		session.WaitWithDefaultTimeout()
   262  		Expect(session.OutputToString()).To(ContainSubstring("2"))
   263  		Expect(session.ExitCode()).To(Equal(0))
   264  	})
   265  
   266  	It("podman run capabilities test", func() {
   267  		session := podmanTest.Podman([]string{"run", "--rm", "--cap-add", "all", ALPINE, "cat", "/proc/self/status"})
   268  		session.WaitWithDefaultTimeout()
   269  		Expect(session.ExitCode()).To(Equal(0))
   270  
   271  		session = podmanTest.Podman([]string{"run", "--rm", "--cap-add", "sys_admin", ALPINE, "cat", "/proc/self/status"})
   272  		session.WaitWithDefaultTimeout()
   273  		Expect(session.ExitCode()).To(Equal(0))
   274  
   275  		session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "all", ALPINE, "cat", "/proc/self/status"})
   276  		session.WaitWithDefaultTimeout()
   277  		Expect(session.ExitCode()).To(Equal(0))
   278  
   279  		session = podmanTest.Podman([]string{"run", "--rm", "--cap-drop", "setuid", ALPINE, "cat", "/proc/self/status"})
   280  		session.WaitWithDefaultTimeout()
   281  		Expect(session.ExitCode()).To(Equal(0))
   282  	})
   283  
   284  	It("podman run user capabilities test", func() {
   285  		// We need to ignore the containers.conf on the test distribution for this test
   286  		os.Setenv("CONTAINERS_CONF", "/dev/null")
   287  		session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapBnd", "/proc/self/status"})
   288  		session.WaitWithDefaultTimeout()
   289  		Expect(session.ExitCode()).To(Equal(0))
   290  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   291  
   292  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", ALPINE, "grep", "CapEff", "/proc/self/status"})
   293  		session.WaitWithDefaultTimeout()
   294  		Expect(session.ExitCode()).To(Equal(0))
   295  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   296  
   297  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapBnd", "/proc/self/status"})
   298  		session.WaitWithDefaultTimeout()
   299  		Expect(session.ExitCode()).To(Equal(0))
   300  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   301  
   302  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "root", ALPINE, "grep", "CapEff", "/proc/self/status"})
   303  		session.WaitWithDefaultTimeout()
   304  		Expect(session.ExitCode()).To(Equal(0))
   305  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   306  
   307  		session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapBnd", "/proc/self/status"})
   308  		session.WaitWithDefaultTimeout()
   309  		Expect(session.ExitCode()).To(Equal(0))
   310  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   311  
   312  		session = podmanTest.Podman([]string{"run", "--rm", ALPINE, "grep", "CapEff", "/proc/self/status"})
   313  		session.WaitWithDefaultTimeout()
   314  		Expect(session.ExitCode()).To(Equal(0))
   315  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   316  
   317  		session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   318  		session.WaitWithDefaultTimeout()
   319  		Expect(session.ExitCode()).To(Equal(0))
   320  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
   321  
   322  		session = podmanTest.Podman([]string{"run", "--user=1000:1000", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   323  		session.WaitWithDefaultTimeout()
   324  		Expect(session.ExitCode()).To(Equal(0))
   325  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   326  
   327  		session = podmanTest.Podman([]string{"run", "--user=0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   328  		session.WaitWithDefaultTimeout()
   329  		Expect(session.ExitCode()).To(Equal(0))
   330  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   331  
   332  		session = podmanTest.Podman([]string{"run", "--user=0:0", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   333  		session.WaitWithDefaultTimeout()
   334  		Expect(session.ExitCode()).To(Equal(0))
   335  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   336  
   337  		if os.Geteuid() > 0 {
   338  			if os.Getenv("SKIP_USERNS") != "" {
   339  				Skip("Skip userns tests.")
   340  			}
   341  			if _, err := os.Stat("/proc/self/uid_map"); err != nil {
   342  				Skip("User namespaces not supported.")
   343  			}
   344  			session = podmanTest.Podman([]string{"run", "--userns=keep-id", "--cap-add=DAC_OVERRIDE", "--rm", ALPINE, "grep", "CapAmb", "/proc/self/status"})
   345  			session.WaitWithDefaultTimeout()
   346  			Expect(session.ExitCode()).To(Equal(0))
   347  			Expect(session.OutputToString()).To(ContainSubstring("0000000000000002"))
   348  		}
   349  	})
   350  
   351  	It("podman run user capabilities test with image", func() {
   352  		// We need to ignore the containers.conf on the test distribution for this test
   353  		os.Setenv("CONTAINERS_CONF", "/dev/null")
   354  		dockerfile := `FROM busybox
   355  USER bin`
   356  		podmanTest.BuildImage(dockerfile, "test", "false")
   357  		session := podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapBnd", "/proc/self/status"})
   358  		session.WaitWithDefaultTimeout()
   359  		Expect(session.ExitCode()).To(Equal(0))
   360  		Expect(session.OutputToString()).To(ContainSubstring("00000000a80425fb"))
   361  
   362  		session = podmanTest.Podman([]string{"run", "--rm", "--user", "bin", "test", "grep", "CapEff", "/proc/self/status"})
   363  		session.WaitWithDefaultTimeout()
   364  		Expect(session.ExitCode()).To(Equal(0))
   365  		Expect(session.OutputToString()).To(ContainSubstring("0000000000000000"))
   366  	})
   367  
   368  	It("podman run limits test", func() {
   369  		SkipIfRootlessCgroupsV1("Setting limits not supported on cgroupv1 for rootless users")
   370  
   371  		if !isRootless() {
   372  			session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "rtprio=99", "--cap-add=sys_nice", fedoraMinimal, "cat", "/proc/self/sched"})
   373  			session.WaitWithDefaultTimeout()
   374  			Expect(session.ExitCode()).To(Equal(0))
   375  		}
   376  
   377  		session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=2048:2048", fedoraMinimal, "ulimit", "-n"})
   378  		session.WaitWithDefaultTimeout()
   379  		Expect(session.ExitCode()).To(Equal(0))
   380  		Expect(session.OutputToString()).To(ContainSubstring("2048"))
   381  
   382  		session = podmanTest.Podman([]string{"run", "--rm", "--ulimit", "nofile=1024:1028", fedoraMinimal, "ulimit", "-n"})
   383  		session.WaitWithDefaultTimeout()
   384  		Expect(session.ExitCode()).To(Equal(0))
   385  		Expect(session.OutputToString()).To(ContainSubstring("1024"))
   386  
   387  		if !CGROUPSV2 {
   388  			// --oom-kill-disable not supported on cgroups v2.
   389  			session = podmanTest.Podman([]string{"run", "--rm", "--oom-kill-disable=true", fedoraMinimal, "echo", "memory-hog"})
   390  			session.WaitWithDefaultTimeout()
   391  			Expect(session.ExitCode()).To(Equal(0))
   392  		}
   393  
   394  		session = podmanTest.Podman([]string{"run", "--rm", "--oom-score-adj=111", fedoraMinimal, "cat", "/proc/self/oom_score_adj"})
   395  		session.WaitWithDefaultTimeout()
   396  		Expect(session.ExitCode()).To(Equal(0))
   397  		Expect(session.OutputToString()).To(Equal("111"))
   398  	})
   399  
   400  	It("podman run limits host test", func() {
   401  		SkipIfRemote("This can only be used for local tests")
   402  
   403  		var l syscall.Rlimit
   404  
   405  		err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &l)
   406  		Expect(err).To(BeNil())
   407  
   408  		session := podmanTest.Podman([]string{"run", "--rm", "--ulimit", "host", fedoraMinimal, "ulimit", "-Hn"})
   409  		session.WaitWithDefaultTimeout()
   410  		Expect(session.ExitCode()).To(Equal(0))
   411  
   412  		ulimitCtrStr := strings.TrimSpace(session.OutputToString())
   413  		ulimitCtr, err := strconv.ParseUint(ulimitCtrStr, 10, 0)
   414  		Expect(err).To(BeNil())
   415  
   416  		Expect(ulimitCtr).Should(BeNumerically(">=", l.Max))
   417  	})
   418  
   419  	It("podman run with cidfile", func() {
   420  		session := podmanTest.Podman([]string{"run", "--cidfile", tempdir + "cidfile", ALPINE, "ls"})
   421  		session.WaitWithDefaultTimeout()
   422  		Expect(session.ExitCode()).To(Equal(0))
   423  		err := os.Remove(tempdir + "cidfile")
   424  		Expect(err).To(BeNil())
   425  	})
   426  
   427  	It("podman run sysctl test", func() {
   428  		SkipIfRootless("Network sysctls are not available root rootless")
   429  		session := podmanTest.Podman([]string{"run", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
   430  		session.WaitWithDefaultTimeout()
   431  		Expect(session.ExitCode()).To(Equal(0))
   432  		Expect(session.OutputToString()).To(ContainSubstring("net.core.somaxconn = 65535"))
   433  
   434  		// network sysctls should fail if --net=host is set
   435  		session = podmanTest.Podman([]string{"run", "--net", "host", "--rm", "--sysctl", "net.core.somaxconn=65535", ALPINE, "sysctl", "net.core.somaxconn"})
   436  		session.WaitWithDefaultTimeout()
   437  		Expect(session.ExitCode()).To(Equal(125))
   438  	})
   439  
   440  	It("podman run blkio-weight test", func() {
   441  		SkipIfRootless("FIXME: This is blowing up because of no /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control file")
   442  		SkipIfRootlessCgroupsV1("Setting blkio-weight not supported on cgroupv1 for rootless users")
   443  		if !CGROUPSV2 {
   444  			if _, err := os.Stat("/sys/fs/cgroup/blkio/blkio.weight"); os.IsNotExist(err) {
   445  				Skip("Kernel does not support blkio.weight")
   446  			}
   447  		}
   448  
   449  		if CGROUPSV2 {
   450  			// convert linearly from [10-1000] to [1-10000]
   451  			session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "sh", "-c", "cat /sys/fs/cgroup/$(sed -e 's|0::||' < /proc/self/cgroup)/io.bfq.weight"})
   452  			session.WaitWithDefaultTimeout()
   453  			Expect(session.ExitCode()).To(Equal(0))
   454  			Expect(session.OutputToString()).To(ContainSubstring("51"))
   455  		} else {
   456  			session := podmanTest.Podman([]string{"run", "--rm", "--blkio-weight=15", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.weight"})
   457  			session.WaitWithDefaultTimeout()
   458  			Expect(session.ExitCode()).To(Equal(0))
   459  			Expect(session.OutputToString()).To(ContainSubstring("15"))
   460  		}
   461  	})
   462  
   463  	It("podman run device-read-bps test", func() {
   464  		SkipIfRootless("FIXME: Missing /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control")
   465  		SkipIfRootlessCgroupsV1("Setting device-read-bps not supported on cgroupv1 for rootless users")
   466  
   467  		var session *PodmanSessionIntegration
   468  
   469  		if CGROUPSV2 {
   470  			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"})
   471  		} else {
   472  			session = podmanTest.Podman([]string{"run", "--rm", "--device-read-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_bps_device"})
   473  		}
   474  
   475  		session.WaitWithDefaultTimeout()
   476  		Expect(session.ExitCode()).To(Equal(0))
   477  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   478  			Expect(session.OutputToString()).To(ContainSubstring("1048576"))
   479  		}
   480  	})
   481  
   482  	It("podman run device-write-bps test", func() {
   483  		SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist")
   484  		SkipIfRootlessCgroupsV1("Setting device-write-bps not supported on cgroupv1 for rootless users")
   485  
   486  		var session *PodmanSessionIntegration
   487  
   488  		if CGROUPSV2 {
   489  			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"})
   490  		} else {
   491  			session = podmanTest.Podman([]string{"run", "--rm", "--device-write-bps=/dev/zero:1mb", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_bps_device"})
   492  		}
   493  		session.WaitWithDefaultTimeout()
   494  		Expect(session.ExitCode()).To(Equal(0))
   495  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   496  			Expect(session.OutputToString()).To(ContainSubstring("1048576"))
   497  		}
   498  	})
   499  
   500  	It("podman run device-read-iops test", func() {
   501  		SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist")
   502  		SkipIfRootlessCgroupsV1("Setting device-read-iops not supported on cgroupv1 for rootless users")
   503  		var session *PodmanSessionIntegration
   504  
   505  		if CGROUPSV2 {
   506  			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"})
   507  		} else {
   508  			session = podmanTest.Podman([]string{"run", "--rm", "--device-read-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.read_iops_device"})
   509  		}
   510  
   511  		session.WaitWithDefaultTimeout()
   512  		Expect(session.ExitCode()).To(Equal(0))
   513  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   514  			Expect(session.OutputToString()).To(ContainSubstring("100"))
   515  		}
   516  	})
   517  
   518  	It("podman run device-write-iops test", func() {
   519  		SkipIfRootless("FIXME /sys/fs/cgroup/user.slice/user-14467.slice/user@14467.service/cgroup.subtree_control does not exist")
   520  		SkipIfRootlessCgroupsV1("Setting device-write-iops not supported on cgroupv1 for rootless users")
   521  		var session *PodmanSessionIntegration
   522  
   523  		if CGROUPSV2 {
   524  			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"})
   525  		} else {
   526  			session = podmanTest.Podman([]string{"run", "--rm", "--device-write-iops=/dev/zero:100", ALPINE, "cat", "/sys/fs/cgroup/blkio/blkio.throttle.write_iops_device"})
   527  		}
   528  
   529  		session.WaitWithDefaultTimeout()
   530  		Expect(session.ExitCode()).To(Equal(0))
   531  		if !CGROUPSV2 { // TODO: Test Simplification.  For now, we only care about exit(0) w/ cgroupsv2
   532  			Expect(session.OutputToString()).To(ContainSubstring("100"))
   533  		}
   534  	})
   535  
   536  	It("podman run notify_socket", func() {
   537  		SkipIfRemote("This can only be used for local tests")
   538  
   539  		host := GetHostDistributionInfo()
   540  		if host.Distribution != "rhel" && host.Distribution != "centos" && host.Distribution != "fedora" {
   541  			Skip("this test requires a working runc")
   542  		}
   543  		sock := filepath.Join(podmanTest.TempDir, "notify")
   544  		addr := net.UnixAddr{
   545  			Name: sock,
   546  			Net:  "unixgram",
   547  		}
   548  		socket, err := net.ListenUnixgram("unixgram", &addr)
   549  		Expect(err).To(BeNil())
   550  		defer os.Remove(sock)
   551  		defer socket.Close()
   552  
   553  		os.Setenv("NOTIFY_SOCKET", sock)
   554  		defer os.Unsetenv("NOTIFY_SOCKET")
   555  
   556  		session := podmanTest.Podman([]string{"run", ALPINE, "printenv", "NOTIFY_SOCKET"})
   557  		session.WaitWithDefaultTimeout()
   558  		Expect(session.ExitCode()).To(Equal(0))
   559  		Expect(len(session.OutputToStringArray())).To(BeNumerically(">", 0))
   560  	})
   561  
   562  	It("podman run log-opt", func() {
   563  		log := filepath.Join(podmanTest.TempDir, "/container.log")
   564  		session := podmanTest.Podman([]string{"run", "--rm", "--log-opt", fmt.Sprintf("path=%s", log), ALPINE, "ls"})
   565  		session.WaitWithDefaultTimeout()
   566  		Expect(session.ExitCode()).To(Equal(0))
   567  		_, err := os.Stat(log)
   568  		Expect(err).To(BeNil())
   569  		_ = os.Remove(log)
   570  	})
   571  
   572  	It("podman run tagged image", func() {
   573  		podmanTest.AddImageToRWStore(BB)
   574  		tag := podmanTest.Podman([]string{"tag", BB, "bb"})
   575  		tag.WaitWithDefaultTimeout()
   576  		Expect(tag.ExitCode()).To(Equal(0))
   577  
   578  		session := podmanTest.Podman([]string{"run", "--rm", "bb", "ls"})
   579  		session.WaitWithDefaultTimeout()
   580  		Expect(session.ExitCode()).To(Equal(0))
   581  	})
   582  
   583  	It("podman test hooks", func() {
   584  		hcheck := "/run/hookscheck"
   585  		hooksDir := tempdir + "/hooks"
   586  		os.Mkdir(hooksDir, 0755)
   587  		fileutils.CopyFile("hooks/hooks.json", hooksDir)
   588  		os.Setenv("HOOK_OPTION", fmt.Sprintf("--hooks-dir=%s", hooksDir))
   589  		os.Remove(hcheck)
   590  		session := podmanTest.Podman([]string{"run", ALPINE, "ls"})
   591  		session.Wait(10)
   592  		os.Unsetenv("HOOK_OPTION")
   593  		Expect(session.ExitCode()).To(Equal(0))
   594  	})
   595  
   596  	It("podman run with secrets", func() {
   597  		SkipIfRemote("--default-mount-file option is not supported in podman-remote")
   598  		containersDir := filepath.Join(podmanTest.TempDir, "containers")
   599  		err := os.MkdirAll(containersDir, 0755)
   600  		Expect(err).To(BeNil())
   601  
   602  		secretsDir := filepath.Join(podmanTest.TempDir, "rhel", "secrets")
   603  		err = os.MkdirAll(secretsDir, 0755)
   604  		Expect(err).To(BeNil())
   605  
   606  		mountsFile := filepath.Join(containersDir, "mounts.conf")
   607  		mountString := secretsDir + ":/run/secrets"
   608  		err = ioutil.WriteFile(mountsFile, []byte(mountString), 0755)
   609  		Expect(err).To(BeNil())
   610  
   611  		secretsFile := filepath.Join(secretsDir, "test.txt")
   612  		secretsString := "Testing secrets mount. I am mounted!"
   613  		err = ioutil.WriteFile(secretsFile, []byte(secretsString), 0755)
   614  		Expect(err).To(BeNil())
   615  
   616  		targetDir := tempdir + "/symlink/target"
   617  		err = os.MkdirAll(targetDir, 0755)
   618  		Expect(err).To(BeNil())
   619  		keyFile := filepath.Join(targetDir, "key.pem")
   620  		err = ioutil.WriteFile(keyFile, []byte(mountString), 0755)
   621  		Expect(err).To(BeNil())
   622  		execSession := SystemExec("ln", []string{"-s", targetDir, filepath.Join(secretsDir, "mysymlink")})
   623  		Expect(execSession.ExitCode()).To(Equal(0))
   624  
   625  		session := podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "cat", "/run/secrets/test.txt"})
   626  		session.WaitWithDefaultTimeout()
   627  		Expect(session.ExitCode()).To(Equal(0))
   628  		Expect(session.OutputToString()).To(Equal(secretsString))
   629  
   630  		session = podmanTest.Podman([]string{"--default-mounts-file=" + mountsFile, "run", "--rm", ALPINE, "ls", "/run/secrets/mysymlink"})
   631  		session.WaitWithDefaultTimeout()
   632  		Expect(session.ExitCode()).To(Equal(0))
   633  		Expect(session.OutputToString()).To(ContainSubstring("key.pem"))
   634  	})
   635  
   636  	It("podman run with FIPS mode secrets", func() {
   637  		SkipIfRootless("rootless can not manipulate system-fips file")
   638  		fipsFile := "/etc/system-fips"
   639  		err = ioutil.WriteFile(fipsFile, []byte{}, 0755)
   640  		Expect(err).To(BeNil())
   641  
   642  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "ls", "/run/secrets"})
   643  		session.WaitWithDefaultTimeout()
   644  		Expect(session.ExitCode()).To(Equal(0))
   645  		Expect(session.OutputToString()).To(ContainSubstring("system-fips"))
   646  
   647  		err = os.Remove(fipsFile)
   648  		Expect(err).To(BeNil())
   649  	})
   650  
   651  	It("podman run without group-add", func() {
   652  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
   653  		session.WaitWithDefaultTimeout()
   654  		Expect(session.ExitCode()).To(Equal(0))
   655  		Expect(session.LineInOutputContains("27(video),777,65533(nogroup)")).To(BeFalse())
   656  	})
   657  
   658  	It("podman run with group-add", func() {
   659  		session := podmanTest.Podman([]string{"run", "--rm", "--group-add=audio", "--group-add=nogroup", "--group-add=777", ALPINE, "id"})
   660  		session.WaitWithDefaultTimeout()
   661  		Expect(session.ExitCode()).To(Equal(0))
   662  		Expect(session.LineInOutputContains("777,65533(nogroup)")).To(BeTrue())
   663  	})
   664  
   665  	It("podman run with user (default)", func() {
   666  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "id"})
   667  		session.WaitWithDefaultTimeout()
   668  		Expect(session.ExitCode()).To(Equal(0))
   669  		Expect(session.LineInOutputContains("uid=0(root) gid=0(root)")).To(BeTrue())
   670  	})
   671  
   672  	It("podman run with user (integer, not in /etc/passwd)", func() {
   673  		session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "id"})
   674  		session.WaitWithDefaultTimeout()
   675  		Expect(session.ExitCode()).To(Equal(0))
   676  		Expect(session.OutputToString()).To(Equal("uid=1234(1234) gid=0(root)"))
   677  	})
   678  
   679  	It("podman run with user (integer, in /etc/passwd)", func() {
   680  		session := podmanTest.Podman([]string{"run", "--rm", "--user=8", ALPINE, "id"})
   681  		session.WaitWithDefaultTimeout()
   682  		Expect(session.ExitCode()).To(Equal(0))
   683  		Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue())
   684  	})
   685  
   686  	It("podman run with user (username)", func() {
   687  		session := podmanTest.Podman([]string{"run", "--rm", "--user=mail", ALPINE, "id"})
   688  		session.WaitWithDefaultTimeout()
   689  		Expect(session.ExitCode()).To(Equal(0))
   690  		Expect(session.LineInOutputContains("uid=8(mail) gid=12(mail)")).To(BeTrue())
   691  	})
   692  
   693  	It("podman run with user:group (username:integer)", func() {
   694  		session := podmanTest.Podman([]string{"run", "--rm", "--user=mail:21", ALPINE, "id"})
   695  		session.WaitWithDefaultTimeout()
   696  		Expect(session.ExitCode()).To(Equal(0))
   697  		Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)"))
   698  	})
   699  
   700  	It("podman run with user:group (integer:groupname)", func() {
   701  		session := podmanTest.Podman([]string{"run", "--rm", "--user=8:ftp", ALPINE, "id"})
   702  		session.WaitWithDefaultTimeout()
   703  		Expect(session.ExitCode()).To(Equal(0))
   704  		Expect(session.OutputToString()).To(Equal("uid=8(mail) gid=21(ftp)"))
   705  	})
   706  
   707  	It("podman run with user, verify caps dropped", func() {
   708  		session := podmanTest.Podman([]string{"run", "--rm", "--user=1234", ALPINE, "grep", "CapEff", "/proc/self/status"})
   709  		session.WaitWithDefaultTimeout()
   710  		Expect(session.ExitCode()).To(Equal(0))
   711  		capEff := strings.Split(session.OutputToString(), " ")
   712  		Expect("0000000000000000").To(Equal(capEff[1]))
   713  	})
   714  
   715  	It("podman run with attach stdin outputs container ID", func() {
   716  		session := podmanTest.Podman([]string{"run", "--attach", "stdin", ALPINE, "printenv"})
   717  		session.WaitWithDefaultTimeout()
   718  		Expect(session.ExitCode()).To(Equal(0))
   719  		ps := podmanTest.Podman([]string{"ps", "-aq", "--no-trunc"})
   720  		ps.WaitWithDefaultTimeout()
   721  		Expect(ps.ExitCode()).To(Equal(0))
   722  		Expect(ps.LineInOutputContains(session.OutputToString())).To(BeTrue())
   723  	})
   724  
   725  	It("podman run with attach stdout does not print stderr", func() {
   726  		session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stdout", ALPINE, "ls", "/doesnotexist"})
   727  		session.WaitWithDefaultTimeout()
   728  		Expect(session.OutputToString()).To(Equal(""))
   729  	})
   730  
   731  	It("podman run with attach stderr does not print stdout", func() {
   732  		session := podmanTest.Podman([]string{"run", "--rm", "--attach", "stderr", ALPINE, "ls", "/"})
   733  		session.WaitWithDefaultTimeout()
   734  		Expect(session.ExitCode()).To(Equal(0))
   735  		Expect(session.OutputToString()).To(Equal(""))
   736  	})
   737  
   738  	It("podman run attach nonsense errors", func() {
   739  		session := podmanTest.Podman([]string{"run", "--rm", "--attach", "asdfasdf", ALPINE, "ls", "/"})
   740  		session.WaitWithDefaultTimeout()
   741  		Expect(session.ExitCode()).To(Equal(125))
   742  	})
   743  
   744  	It("podman run exit code on failure to exec", func() {
   745  		session := podmanTest.Podman([]string{"run", ALPINE, "/etc"})
   746  		session.WaitWithDefaultTimeout()
   747  		Expect(session.ExitCode()).To(Equal(126))
   748  	})
   749  
   750  	It("podman run error on exec", func() {
   751  		session := podmanTest.Podman([]string{"run", ALPINE, "sh", "-c", "exit 100"})
   752  		session.WaitWithDefaultTimeout()
   753  		Expect(session.ExitCode()).To(Equal(100))
   754  	})
   755  
   756  	It("podman run with built-in volume image", func() {
   757  		session := podmanTest.Podman([]string{"run", "--rm", redis, "ls"})
   758  		session.WaitWithDefaultTimeout()
   759  		Expect(session.ExitCode()).To(Equal(0))
   760  
   761  		dockerfile := `FROM busybox
   762  RUN mkdir -p /myvol/data && chown -R mail.0 /myvol
   763  VOLUME ["/myvol/data"]
   764  USER mail`
   765  
   766  		podmanTest.BuildImage(dockerfile, "test", "false")
   767  		session = podmanTest.Podman([]string{"run", "--rm", "test", "ls", "-al", "/myvol/data"})
   768  		session.WaitWithDefaultTimeout()
   769  		Expect(session.ExitCode()).To(Equal(0))
   770  		Expect(session.OutputToString()).To(ContainSubstring("mail root"))
   771  	})
   772  
   773  	It("podman run --volumes-from flag", func() {
   774  		vol := filepath.Join(podmanTest.TempDir, "vol-test")
   775  		err := os.MkdirAll(vol, 0755)
   776  		Expect(err).To(BeNil())
   777  
   778  		filename := "test.txt"
   779  		volFile := filepath.Join(vol, filename)
   780  		data := "Testing --volumes-from!!!"
   781  		err = ioutil.WriteFile(volFile, []byte(data), 0755)
   782  		Expect(err).To(BeNil())
   783  		mountpoint := "/myvol/"
   784  
   785  		session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
   786  		session.WaitWithDefaultTimeout()
   787  		Expect(session.ExitCode()).To(Equal(0))
   788  		ctrID := session.OutputToString()
   789  
   790  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "cat", mountpoint + filename})
   791  		session.WaitWithDefaultTimeout()
   792  		Expect(session.ExitCode()).To(Equal(0))
   793  		Expect(session.OutputToString()).To(Equal(data))
   794  
   795  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "sh", "-c", "echo test >> " + mountpoint + filename})
   796  		session.WaitWithDefaultTimeout()
   797  		Expect(session.ExitCode()).To(Equal(0))
   798  
   799  		session = podmanTest.Podman([]string{"start", "--attach", ctrID})
   800  		session.WaitWithDefaultTimeout()
   801  		Expect(session.ExitCode()).To(Equal(0))
   802  		Expect(session.OutputToString()).To(Equal(data + "test"))
   803  	})
   804  
   805  	It("podman run --volumes-from flag options", func() {
   806  		vol := filepath.Join(podmanTest.TempDir, "vol-test")
   807  		err := os.MkdirAll(vol, 0755)
   808  		Expect(err).To(BeNil())
   809  
   810  		filename := "test.txt"
   811  		volFile := filepath.Join(vol, filename)
   812  		data := "Testing --volumes-from!!!"
   813  		err = ioutil.WriteFile(volFile, []byte(data), 0755)
   814  		Expect(err).To(BeNil())
   815  		mountpoint := "/myvol/"
   816  
   817  		session := podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint, ALPINE, "cat", mountpoint + filename})
   818  		session.WaitWithDefaultTimeout()
   819  		Expect(session.ExitCode()).To(Equal(0))
   820  		ctrID := session.OutputToString()
   821  
   822  		// check that the read only option works
   823  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro", ALPINE, "touch", mountpoint + "abc.txt"})
   824  		session.WaitWithDefaultTimeout()
   825  		Expect(session.ExitCode()).To(Equal(1))
   826  		Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system"))
   827  
   828  		// check that both z and ro options work
   829  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,z", ALPINE, "cat", mountpoint + filename})
   830  		session.WaitWithDefaultTimeout()
   831  		Expect(session.ExitCode()).To(Equal(0))
   832  		Expect(session.OutputToString()).To(Equal(data))
   833  
   834  		// check that multiple ro/rw are not working
   835  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":ro,rw", ALPINE, "cat", mountpoint + filename})
   836  		session.WaitWithDefaultTimeout()
   837  		Expect(session.ExitCode()).To(Equal(125))
   838  		Expect(session.ErrorToString()).To(ContainSubstring("cannot set ro or rw options more than once"))
   839  
   840  		// check that multiple z options are not working
   841  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID + ":z,z,ro", ALPINE, "cat", mountpoint + filename})
   842  		session.WaitWithDefaultTimeout()
   843  		Expect(session.ExitCode()).To(Equal(125))
   844  		Expect(session.ErrorToString()).To(ContainSubstring("cannot set :z more than once in mount options"))
   845  
   846  		// create new read only volume
   847  		session = podmanTest.Podman([]string{"create", "--volume", vol + ":" + mountpoint + ":ro", ALPINE, "cat", mountpoint + filename})
   848  		session.WaitWithDefaultTimeout()
   849  		Expect(session.ExitCode()).To(Equal(0))
   850  		ctrID = session.OutputToString()
   851  
   852  		// check if the original volume was mounted as read only that --volumes-from also mount it as read only
   853  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "touch", mountpoint + "abc.txt"})
   854  		session.WaitWithDefaultTimeout()
   855  		Expect(session.ExitCode()).To(Equal(1))
   856  		Expect(session.ErrorToString()).To(ContainSubstring("Read-only file system"))
   857  	})
   858  
   859  	It("podman run --volumes-from flag with built-in volumes", func() {
   860  		session := podmanTest.Podman([]string{"create", redis, "sh"})
   861  		session.WaitWithDefaultTimeout()
   862  		Expect(session.ExitCode()).To(Equal(0))
   863  		ctrID := session.OutputToString()
   864  
   865  		session = podmanTest.Podman([]string{"run", "--volumes-from", ctrID, ALPINE, "ls"})
   866  		session.WaitWithDefaultTimeout()
   867  		Expect(session.ExitCode()).To(Equal(0))
   868  		Expect(session.OutputToString()).To(ContainSubstring("data"))
   869  	})
   870  
   871  	It("podman run --volumes flag with multiple volumes", func() {
   872  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
   873  		err := os.MkdirAll(vol1, 0755)
   874  		Expect(err).To(BeNil())
   875  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
   876  		err = os.MkdirAll(vol2, 0755)
   877  		Expect(err).To(BeNil())
   878  
   879  		session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", ALPINE, "touch", "/myvol2/foo.txt"})
   880  		session.WaitWithDefaultTimeout()
   881  		Expect(session.ExitCode()).To(Equal(0))
   882  	})
   883  
   884  	It("podman run --volumes flag with empty host dir", func() {
   885  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
   886  		err := os.MkdirAll(vol1, 0755)
   887  		Expect(err).To(BeNil())
   888  
   889  		session := podmanTest.Podman([]string{"run", "--volume", ":/myvol1:z", ALPINE, "touch", "/myvol2/foo.txt"})
   890  		session.WaitWithDefaultTimeout()
   891  		Expect(session).To(ExitWithError())
   892  		Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
   893  		session = podmanTest.Podman([]string{"run", "--volume", vol1 + ":", ALPINE, "touch", "/myvol2/foo.txt"})
   894  		session.WaitWithDefaultTimeout()
   895  		Expect(session).To(ExitWithError())
   896  		Expect(session.ErrorToString()).To(ContainSubstring("directory cannot be empty"))
   897  	})
   898  
   899  	It("podman run --mount flag with multiple mounts", func() {
   900  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
   901  		err := os.MkdirAll(vol1, 0755)
   902  		Expect(err).To(BeNil())
   903  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
   904  		err = os.MkdirAll(vol2, 0755)
   905  		Expect(err).To(BeNil())
   906  
   907  		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"})
   908  		session.WaitWithDefaultTimeout()
   909  		Expect(session.ExitCode()).To(Equal(0))
   910  	})
   911  
   912  	It("podman run findmnt nothing shared", func() {
   913  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
   914  		err := os.MkdirAll(vol1, 0755)
   915  		Expect(err).To(BeNil())
   916  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
   917  		err = os.MkdirAll(vol2, 0755)
   918  		Expect(err).To(BeNil())
   919  
   920  		session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
   921  		session.WaitWithDefaultTimeout()
   922  		Expect(session.ExitCode()).To(Equal(0))
   923  		match, _ := session.GrepString("shared")
   924  		Expect(match).Should(BeFalse())
   925  	})
   926  
   927  	It("podman run findmnt shared", func() {
   928  		vol1 := filepath.Join(podmanTest.TempDir, "vol-test1")
   929  		err := os.MkdirAll(vol1, 0755)
   930  		Expect(err).To(BeNil())
   931  		vol2 := filepath.Join(podmanTest.TempDir, "vol-test2")
   932  		err = os.MkdirAll(vol2, 0755)
   933  		Expect(err).To(BeNil())
   934  
   935  		session := podmanTest.Podman([]string{"run", "--volume", vol1 + ":/myvol1:z", "--volume", vol2 + ":/myvol2:shared,z", fedoraMinimal, "findmnt", "-o", "TARGET,PROPAGATION"})
   936  		session.WaitWithDefaultTimeout()
   937  		Expect(session.ExitCode()).To(Equal(0))
   938  		match, shared := session.GrepString("shared")
   939  		Expect(match).Should(BeTrue())
   940  		// make sure it's only shared (and not 'shared,slave')
   941  		isSharedOnly := !strings.Contains(shared[0], "shared,")
   942  		Expect(isSharedOnly).Should(BeTrue())
   943  	})
   944  
   945  	It("podman run --security-opts proc-opts=", func() {
   946  		session := podmanTest.Podman([]string{"run", "--security-opt", "proc-opts=nosuid,exec", fedoraMinimal, "findmnt", "-noOPTIONS", "/proc"})
   947  		session.WaitWithDefaultTimeout()
   948  		Expect(session.ExitCode()).To(Equal(0))
   949  		output := session.OutputToString()
   950  		Expect(output).To(ContainSubstring("nosuid"))
   951  		Expect(output).To(Not(ContainSubstring("exec")))
   952  	})
   953  
   954  	It("podman run --mount type=bind,bind-nonrecursive", func() {
   955  		SkipIfRootless("FIXME: rootless users are not allowed to mount bind-nonrecursive (Could this be a Kernel bug?")
   956  		session := podmanTest.Podman([]string{"run", "--mount", "type=bind,bind-nonrecursive,slave,src=/,target=/host", fedoraMinimal, "findmnt", "-nR", "/host"})
   957  		session.WaitWithDefaultTimeout()
   958  		Expect(session.ExitCode()).To(Equal(0))
   959  		Expect(len(session.OutputToStringArray())).To(Equal(1))
   960  	})
   961  
   962  	It("podman run --mount type=devpts,target=/foo/bar", func() {
   963  		session := podmanTest.Podman([]string{"run", "--mount", "type=devpts,target=/foo/bar", fedoraMinimal, "stat", "-f", "-c%T", "/foo/bar"})
   964  		session.WaitWithDefaultTimeout()
   965  		Expect(session.ExitCode()).To(Equal(0))
   966  		Expect(session.OutputToString()).To(ContainSubstring("devpts"))
   967  	})
   968  
   969  	It("podman run --pod automatically", func() {
   970  		session := podmanTest.Podman([]string{"run", "-d", "--pod", "new:foobar", ALPINE, "nc", "-l", "-p", "8080"})
   971  		session.WaitWithDefaultTimeout()
   972  		Expect(session.ExitCode()).To(Equal(0))
   973  
   974  		session = podmanTest.Podman([]string{"run", "--pod", "foobar", ALPINE, "/bin/sh", "-c", "echo test | nc -w 1 127.0.0.1 8080"})
   975  		session.WaitWithDefaultTimeout()
   976  		Expect(session.ExitCode()).To(Equal(0))
   977  
   978  		check := podmanTest.Podman([]string{"pod", "ps", "--no-trunc"})
   979  		check.WaitWithDefaultTimeout()
   980  		match, _ := check.GrepString("foobar")
   981  		Expect(match).To(BeTrue())
   982  	})
   983  
   984  	It("podman run --pod new with hostname", func() {
   985  		hostname := "abc"
   986  		session := podmanTest.Podman([]string{"run", "--pod", "new:foobar", "--hostname", hostname, ALPINE, "cat", "/etc/hostname"})
   987  		session.WaitWithDefaultTimeout()
   988  		Expect(session.ExitCode()).To(Equal(0))
   989  		Expect(session.OutputToString()).To(ContainSubstring(hostname))
   990  	})
   991  
   992  	It("podman run --rm should work", func() {
   993  		session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "ls"})
   994  		session.WaitWithDefaultTimeout()
   995  		Expect(session.ExitCode()).To(Equal(0))
   996  		session = podmanTest.Podman([]string{"wait", "test"})
   997  		session.WaitWithDefaultTimeout()
   998  		Expect(session).To(ExitWithError())
   999  
  1000  		numContainers := podmanTest.NumberOfContainers()
  1001  		Expect(numContainers).To(Equal(0))
  1002  	})
  1003  
  1004  	It("podman run --rm failed container should delete itself", func() {
  1005  		session := podmanTest.Podman([]string{"run", "--name", "test", "--rm", ALPINE, "foo"})
  1006  		session.WaitWithDefaultTimeout()
  1007  		Expect(session).To(ExitWithError())
  1008  		session = podmanTest.Podman([]string{"wait", "test"})
  1009  		session.WaitWithDefaultTimeout()
  1010  		Expect(session).To(ExitWithError())
  1011  
  1012  		numContainers := podmanTest.NumberOfContainers()
  1013  		Expect(numContainers).To(Equal(0))
  1014  	})
  1015  
  1016  	It("podman run failed container should NOT delete itself", func() {
  1017  		session := podmanTest.Podman([]string{"run", ALPINE, "foo"})
  1018  		session.WaitWithDefaultTimeout()
  1019  		Expect(session).To(ExitWithError())
  1020  		// If remote we could have a race condition
  1021  		session = podmanTest.Podman([]string{"wait", "test"})
  1022  		session.WaitWithDefaultTimeout()
  1023  		Expect(session).To(ExitWithError())
  1024  
  1025  		numContainers := podmanTest.NumberOfContainers()
  1026  		Expect(numContainers).To(Equal(1))
  1027  	})
  1028  	It("podman run readonly container should NOT mount /dev/shm read/only", func() {
  1029  		session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "mount"})
  1030  		session.WaitWithDefaultTimeout()
  1031  		Expect(session.ExitCode()).To(Equal(0))
  1032  
  1033  		Expect(session.OutputToString()).To(Not(ContainSubstring("/dev/shm type tmpfs (ro,")))
  1034  	})
  1035  
  1036  	It("podman run readonly container should NOT mount /run noexec", func() {
  1037  		session := podmanTest.Podman([]string{"run", "--read-only", ALPINE, "sh", "-c", "mount  | grep \"/run \""})
  1038  		session.WaitWithDefaultTimeout()
  1039  		Expect(session.ExitCode()).To(Equal(0))
  1040  
  1041  		Expect(session.OutputToString()).To(Not(ContainSubstring("noexec")))
  1042  	})
  1043  
  1044  	It("podman run with bad healthcheck retries", func() {
  1045  		session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-retries", "0", ALPINE, "top"})
  1046  		session.Wait()
  1047  		Expect(session).To(ExitWithError())
  1048  		Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-retries must be greater than 0"))
  1049  	})
  1050  
  1051  	It("podman run with bad healthcheck timeout", func() {
  1052  		session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-timeout", "0s", ALPINE, "top"})
  1053  		session.WaitWithDefaultTimeout()
  1054  		Expect(session).To(ExitWithError())
  1055  		Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second"))
  1056  	})
  1057  
  1058  	It("podman run with bad healthcheck start-period", func() {
  1059  		session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-start-period", "-1s", ALPINE, "top"})
  1060  		session.WaitWithDefaultTimeout()
  1061  		Expect(session).To(ExitWithError())
  1062  		Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater"))
  1063  	})
  1064  
  1065  	It("podman run with --add-host and --no-hosts fails", func() {
  1066  		session := podmanTest.Podman([]string{"run", "-dt", "--add-host", "test1:127.0.0.1", "--no-hosts", ALPINE, "top"})
  1067  		session.WaitWithDefaultTimeout()
  1068  		Expect(session).To(ExitWithError())
  1069  	})
  1070  
  1071  	It("podman run with restart-policy always restarts containers", func() {
  1072  		testDir := filepath.Join(podmanTest.RunRoot, "restart-test")
  1073  		err := os.MkdirAll(testDir, 0755)
  1074  		Expect(err).To(BeNil())
  1075  
  1076  		aliveFile := filepath.Join(testDir, "running")
  1077  		file, err := os.Create(aliveFile)
  1078  		Expect(err).To(BeNil())
  1079  		file.Close()
  1080  
  1081  		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"})
  1082  
  1083  		found := false
  1084  		testFile := filepath.Join(testDir, "ran")
  1085  		for i := 0; i < 30; i++ {
  1086  			time.Sleep(1 * time.Second)
  1087  			if _, err := os.Stat(testFile); err == nil {
  1088  				found = true
  1089  				err = os.Remove(testFile)
  1090  				Expect(err).To(BeNil())
  1091  				break
  1092  			}
  1093  		}
  1094  		Expect(found).To(BeTrue())
  1095  
  1096  		err = os.Remove(aliveFile)
  1097  		Expect(err).To(BeNil())
  1098  
  1099  		session.WaitWithDefaultTimeout()
  1100  
  1101  		// 10 seconds to restart the container
  1102  		found = false
  1103  		for i := 0; i < 10; i++ {
  1104  			time.Sleep(1 * time.Second)
  1105  			if _, err := os.Stat(testFile); err == nil {
  1106  				found = true
  1107  				break
  1108  			}
  1109  		}
  1110  		Expect(found).To(BeTrue())
  1111  	})
  1112  
  1113  	It("podman run with cgroups=disabled runs without cgroups", func() {
  1114  		SkipIfRootless("FIXME:  I believe this should work but need to fix this test")
  1115  		SkipIfRootlessCgroupsV1("Disable cgroups not supported on cgroupv1 for rootless users")
  1116  		// Only works on crun
  1117  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1118  			Skip("Test only works on crun")
  1119  		}
  1120  
  1121  		curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup")
  1122  		Expect(err).To(BeNil())
  1123  		var curCgroups string = string(curCgroupsBytes)
  1124  		fmt.Printf("Output:\n%s\n", curCgroups)
  1125  		Expect(curCgroups).To(Not(Equal("")))
  1126  
  1127  		ctrName := "testctr"
  1128  		container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=disabled", ALPINE, "top"})
  1129  		container.WaitWithDefaultTimeout()
  1130  		Expect(container.ExitCode()).To(Equal(0))
  1131  
  1132  		// Get PID and get cgroups of that PID
  1133  		inspectOut := podmanTest.InspectContainer(ctrName)
  1134  		Expect(len(inspectOut)).To(Equal(1))
  1135  		pid := inspectOut[0].State.Pid
  1136  		Expect(pid).To(Not(Equal(0)))
  1137  		Expect(inspectOut[0].HostConfig.CgroupParent).To(Equal(""))
  1138  
  1139  		ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
  1140  		Expect(err).To(BeNil())
  1141  		var ctrCgroups string = string(ctrCgroupsBytes)
  1142  		fmt.Printf("Output\n:%s\n", ctrCgroups)
  1143  		Expect(curCgroups).To(Equal(ctrCgroups))
  1144  	})
  1145  
  1146  	It("podman run with cgroups=enabled makes cgroups", func() {
  1147  		SkipIfRootlessCgroupsV1("Enable cgroups not supported on cgroupv1 for rootless users")
  1148  		// Only works on crun
  1149  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1150  			Skip("Test only works on crun")
  1151  		}
  1152  
  1153  		curCgroupsBytes, err := ioutil.ReadFile("/proc/self/cgroup")
  1154  		Expect(err).To(BeNil())
  1155  		var curCgroups string = string(curCgroupsBytes)
  1156  		fmt.Printf("Output:\n%s\n", curCgroups)
  1157  		Expect(curCgroups).To(Not(Equal("")))
  1158  
  1159  		ctrName := "testctr"
  1160  		container := podmanTest.Podman([]string{"run", "--name", ctrName, "-d", "--cgroups=enabled", ALPINE, "top"})
  1161  		container.WaitWithDefaultTimeout()
  1162  		Expect(container.ExitCode()).To(Equal(0))
  1163  
  1164  		// Get PID and get cgroups of that PID
  1165  		inspectOut := podmanTest.InspectContainer(ctrName)
  1166  		Expect(len(inspectOut)).To(Equal(1))
  1167  		pid := inspectOut[0].State.Pid
  1168  		Expect(pid).To(Not(Equal(0)))
  1169  
  1170  		ctrCgroupsBytes, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cgroup", pid))
  1171  		Expect(err).To(BeNil())
  1172  		var ctrCgroups string = string(ctrCgroupsBytes)
  1173  		fmt.Printf("Output\n:%s\n", ctrCgroups)
  1174  		Expect(curCgroups).To(Not(Equal(ctrCgroups)))
  1175  	})
  1176  
  1177  	It("podman run with cgroups=garbage errors", func() {
  1178  		session := podmanTest.Podman([]string{"run", "-d", "--cgroups=garbage", ALPINE, "top"})
  1179  		session.WaitWithDefaultTimeout()
  1180  		Expect(session).To(ExitWithError())
  1181  	})
  1182  
  1183  	It("podman run should fail with nonexist authfile", func() {
  1184  		session := podmanTest.Podman([]string{"run", "--authfile", "/tmp/nonexist", ALPINE, "ls"})
  1185  		session.WaitWithDefaultTimeout()
  1186  		Expect(session.ExitCode()).To(Not(Equal(0)))
  1187  	})
  1188  
  1189  	It("podman run --device-cgroup-rule", func() {
  1190  		SkipIfRootless("rootless users are not allowed to mknod")
  1191  		deviceCgroupRule := "c 42:* rwm"
  1192  		session := podmanTest.Podman([]string{"run", "--cap-add", "mknod", "--name", "test", "-d", "--device-cgroup-rule", deviceCgroupRule, ALPINE, "top"})
  1193  		session.WaitWithDefaultTimeout()
  1194  		Expect(session.ExitCode()).To(Equal(0))
  1195  		session = podmanTest.Podman([]string{"exec", "test", "mknod", "newDev", "c", "42", "1"})
  1196  		session.WaitWithDefaultTimeout()
  1197  		Expect(session.ExitCode()).To(Equal(0))
  1198  	})
  1199  
  1200  	It("podman run --replace", func() {
  1201  		// Make sure we error out with --name.
  1202  		session := podmanTest.Podman([]string{"create", "--replace", ALPINE, "/bin/sh"})
  1203  		session.WaitWithDefaultTimeout()
  1204  		Expect(session.ExitCode()).To(Equal(125))
  1205  
  1206  		// Run and replace 5 times in a row the "same" container.
  1207  		ctrName := "testCtr"
  1208  		for i := 0; i < 5; i++ {
  1209  			session := podmanTest.Podman([]string{"run", "--detach", "--replace", "--name", ctrName, ALPINE, "/bin/sh"})
  1210  			session.WaitWithDefaultTimeout()
  1211  			Expect(session.ExitCode()).To(Equal(0))
  1212  		}
  1213  	})
  1214  
  1215  	It("podman run --preserve-fds", func() {
  1216  		devNull, err := os.Open("/dev/null")
  1217  		Expect(err).To(BeNil())
  1218  		defer devNull.Close()
  1219  		files := []*os.File{
  1220  			devNull,
  1221  		}
  1222  		session := podmanTest.PodmanExtraFiles([]string{"run", "--preserve-fds", "1", ALPINE, "ls"}, files)
  1223  		session.WaitWithDefaultTimeout()
  1224  		Expect(session.ExitCode()).To(Equal(0))
  1225  	})
  1226  
  1227  	It("podman run --preserve-fds invalid fd", func() {
  1228  		session := podmanTest.Podman([]string{"run", "--preserve-fds", "2", ALPINE})
  1229  		session.WaitWithDefaultTimeout()
  1230  		Expect(session.ExitCode()).To(Not(Equal(0)))
  1231  		Expect(session.ErrorToString()).To(ContainSubstring("file descriptor 3 is not available"))
  1232  	})
  1233  
  1234  	It("podman run --privileged and --group-add", func() {
  1235  		groupName := "kvm"
  1236  		session := podmanTest.Podman([]string{"run", "-t", "-i", "--group-add", groupName, "--privileged", fedoraMinimal, "groups"})
  1237  		session.WaitWithDefaultTimeout()
  1238  		Expect(session.ExitCode()).To(Equal(0))
  1239  		Expect(strings.Contains(session.OutputToString(), groupName)).To(BeTrue())
  1240  	})
  1241  
  1242  	It("podman run --tz", func() {
  1243  		session := podmanTest.Podman([]string{"run", "--tz", "foo", "--rm", ALPINE, "date"})
  1244  		session.WaitWithDefaultTimeout()
  1245  		Expect(session.ExitCode()).To(Not(Equal(0)))
  1246  
  1247  		session = podmanTest.Podman([]string{"run", "--tz", "America", "--rm", ALPINE, "date"})
  1248  		session.WaitWithDefaultTimeout()
  1249  		Expect(session.ExitCode()).To(Not(Equal(0)))
  1250  
  1251  		session = podmanTest.Podman([]string{"run", "--tz", "Pacific/Honolulu", "--rm", ALPINE, "date", "+'%H %Z'"})
  1252  		session.WaitWithDefaultTimeout()
  1253  		Expect(session.ExitCode()).To(Equal(0))
  1254  		Expect(session.OutputToString()).To(ContainSubstring("HST"))
  1255  
  1256  		session = podmanTest.Podman([]string{"run", "--tz", "local", "--rm", ALPINE, "date", "+'%H %Z'"})
  1257  		session.WaitWithDefaultTimeout()
  1258  		Expect(session.ExitCode()).To(Equal(0))
  1259  		t := time.Now()
  1260  		z, _ := t.Zone()
  1261  		h := strconv.Itoa(t.Hour())
  1262  		Expect(session.OutputToString()).To(ContainSubstring(z))
  1263  		Expect(session.OutputToString()).To(ContainSubstring(h))
  1264  
  1265  	})
  1266  
  1267  	It("podman run verify pids-limit", func() {
  1268  		SkipIfCgroupV1("pids-limit not supported on cgroup V1")
  1269  		limit := "4321"
  1270  		session := podmanTest.Podman([]string{"run", "--pids-limit", limit, "--net=none", "--rm", ALPINE, "cat", "/sys/fs/cgroup/pids.max"})
  1271  		session.WaitWithDefaultTimeout()
  1272  		Expect(session.ExitCode()).To(Equal(0))
  1273  		Expect(session.OutputToString()).To(ContainSubstring(limit))
  1274  	})
  1275  
  1276  	It("podman run umask", func() {
  1277  		if !strings.Contains(podmanTest.OCIRuntime, "crun") {
  1278  			Skip("Test only works on crun")
  1279  		}
  1280  
  1281  		session := podmanTest.Podman([]string{"run", "--rm", ALPINE, "sh", "-c", "umask"})
  1282  		session.WaitWithDefaultTimeout()
  1283  		Expect(session.ExitCode()).To(Equal(0))
  1284  		Expect(session.OutputToString()).To(Equal("0022"))
  1285  
  1286  		session = podmanTest.Podman([]string{"run", "--umask", "0002", "--rm", ALPINE, "sh", "-c", "umask"})
  1287  		session.WaitWithDefaultTimeout()
  1288  		Expect(session.ExitCode()).To(Equal(0))
  1289  		Expect(session.OutputToString()).To(Equal("0002"))
  1290  
  1291  		session = podmanTest.Podman([]string{"run", "--umask", "0077", "--rm", fedoraMinimal, "umask"})
  1292  		session.WaitWithDefaultTimeout()
  1293  		Expect(session.ExitCode()).To(Equal(0))
  1294  		Expect(session.OutputToString()).To(Equal("0077"))
  1295  
  1296  		session = podmanTest.Podman([]string{"run", "--umask", "22", "--rm", ALPINE, "sh", "-c", "umask"})
  1297  		session.WaitWithDefaultTimeout()
  1298  		Expect(session.ExitCode()).To(Equal(0))
  1299  		Expect(session.OutputToString()).To(Equal("0022"))
  1300  
  1301  		session = podmanTest.Podman([]string{"run", "--umask", "9999", "--rm", ALPINE, "sh", "-c", "umask"})
  1302  		session.WaitWithDefaultTimeout()
  1303  		Expect(session.ExitCode()).To(Not(Equal(0)))
  1304  		Expect(session.ErrorToString()).To(ContainSubstring("Invalid umask"))
  1305  	})
  1306  
  1307  	It("podman run makes workdir from image", func() {
  1308  		// BuildImage does not seem to work remote
  1309  		dockerfile := `FROM busybox
  1310  WORKDIR /madethis`
  1311  		podmanTest.BuildImage(dockerfile, "test", "false")
  1312  		session := podmanTest.Podman([]string{"run", "--rm", "test", "pwd"})
  1313  		session.WaitWithDefaultTimeout()
  1314  		Expect(session.ExitCode()).To(Equal(0))
  1315  		Expect(session.OutputToString()).To(ContainSubstring("/madethis"))
  1316  	})
  1317  
  1318  	It("podman run --entrypoint does not use image command", func() {
  1319  		session := podmanTest.Podman([]string{"run", "--entrypoint", "/bin/echo", ALPINE})
  1320  		session.WaitWithDefaultTimeout()
  1321  		Expect(session.ExitCode()).To(Equal(0))
  1322  		// We can't guarantee the output is completely empty, some
  1323  		// nonprintables seem to work their way in.
  1324  		Expect(session.OutputToString()).To(Not(ContainSubstring("/bin/sh")))
  1325  	})
  1326  
  1327  	It("podman run a container with log-level (lower case)", func() {
  1328  		session := podmanTest.Podman([]string{"--log-level=info", "run", ALPINE, "ls"})
  1329  		session.WaitWithDefaultTimeout()
  1330  		Expect(session.ExitCode()).To(Equal(0))
  1331  	})
  1332  
  1333  	It("podman run a container with log-level (upper case)", func() {
  1334  		session := podmanTest.Podman([]string{"--log-level=INFO", "run", ALPINE, "ls"})
  1335  		session.WaitWithDefaultTimeout()
  1336  		Expect(session.ExitCode()).To(Equal(0))
  1337  	})
  1338  
  1339  	It("podman run a container with --pull never should fail if no local store", func() {
  1340  		session := podmanTest.Podman([]string{"run", "--pull", "never", "docker.io/library/debian:latest", "ls"})
  1341  		session.WaitWithDefaultTimeout()
  1342  		Expect(session.ExitCode()).To(Equal(125))
  1343  	})
  1344  
  1345  	It("podman run container with --pull missing and only pull once", func() {
  1346  		session := podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"})
  1347  		session.WaitWithDefaultTimeout()
  1348  		Expect(session.ExitCode()).To(Equal(0))
  1349  		Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
  1350  
  1351  		session = podmanTest.Podman([]string{"run", "--pull", "missing", cirros, "ls"})
  1352  		session.WaitWithDefaultTimeout()
  1353  		Expect(session.ExitCode()).To(Equal(0))
  1354  		Expect(session.ErrorToString()).ToNot(ContainSubstring("Trying to pull"))
  1355  	})
  1356  
  1357  	It("podman run container with --pull missing should pull image multiple times", func() {
  1358  		session := podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"})
  1359  		session.WaitWithDefaultTimeout()
  1360  		Expect(session.ExitCode()).To(Equal(0))
  1361  		Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
  1362  
  1363  		session = podmanTest.Podman([]string{"run", "--pull", "always", cirros, "ls"})
  1364  		session.WaitWithDefaultTimeout()
  1365  		Expect(session.ExitCode()).To(Equal(0))
  1366  		Expect(session.ErrorToString()).To(ContainSubstring("Trying to pull"))
  1367  	})
  1368  })