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

     1  package integration
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"os/user"
     8  	"strings"
     9  
    10  	. "github.com/containers/podman/v3/test/utils"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/gexec"
    14  )
    15  
    16  var _ = Describe("Podman UserNS support", func() {
    17  	var (
    18  		tempdir    string
    19  		err        error
    20  		podmanTest *PodmanTestIntegration
    21  	)
    22  
    23  	BeforeEach(func() {
    24  		if os.Getenv("SKIP_USERNS") != "" {
    25  			Skip("Skip userns tests.")
    26  		}
    27  		if _, err := os.Stat("/proc/self/uid_map"); err != nil {
    28  			Skip("User namespaces not supported.")
    29  		}
    30  		tempdir, err = CreateTempDirInTempDir()
    31  		if err != nil {
    32  			os.Exit(1)
    33  		}
    34  		podmanTest = PodmanTestCreate(tempdir)
    35  		podmanTest.Setup()
    36  		podmanTest.SeedImages()
    37  	})
    38  
    39  	AfterEach(func() {
    40  		podmanTest.Cleanup()
    41  		f := CurrentGinkgoTestDescription()
    42  		processTestResult(f)
    43  
    44  	})
    45  
    46  	It("podman uidmapping and gidmapping", func() {
    47  		session := podmanTest.Podman([]string{"run", "--uidmap=0:100:5000", "--gidmap=0:200:5000", "alpine", "echo", "hello"})
    48  		session.WaitWithDefaultTimeout()
    49  		Expect(session).Should(Exit(0))
    50  		ok, _ := session.GrepString("hello")
    51  		Expect(ok).To(BeTrue())
    52  	})
    53  
    54  	// It essentially repeats the test above but with the `-it` short option
    55  	// that broke execution at:
    56  	//     https://github.com/containers/podman/pull/1066#issuecomment-403562116
    57  	// To avoid a potential future regression, use this as a test.
    58  	It("podman uidmapping and gidmapping with short-opts", func() {
    59  		session := podmanTest.Podman([]string{"run", "--uidmap=0:1:5000", "--gidmap=0:200:5000", "-it", "alpine", "echo", "hello"})
    60  		session.WaitWithDefaultTimeout()
    61  		Expect(session).Should(Exit(0))
    62  		ok, _ := session.GrepString("hello")
    63  		Expect(ok).To(BeTrue())
    64  	})
    65  
    66  	It("podman uidmapping and gidmapping with a volume", func() {
    67  		session := podmanTest.Podman([]string{"run", "--uidmap=0:1:500", "--gidmap=0:200:5000", "-v", "my-foo-volume:/foo:Z", "alpine", "echo", "hello"})
    68  		session.WaitWithDefaultTimeout()
    69  		Expect(session).Should(Exit(0))
    70  		ok, _ := session.GrepString("hello")
    71  		Expect(ok).To(BeTrue())
    72  	})
    73  
    74  	It("podman uidmapping and gidmapping --net=host", func() {
    75  		session := podmanTest.Podman([]string{"run", "--net=host", "--uidmap=0:1:5000", "--gidmap=0:200:5000", "alpine", "echo", "hello"})
    76  		session.WaitWithDefaultTimeout()
    77  		Expect(session).Should(Exit(0))
    78  		ok, _ := session.GrepString("hello")
    79  		Expect(ok).To(BeTrue())
    80  	})
    81  
    82  	It("podman --userns=keep-id", func() {
    83  		session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-u"})
    84  		session.WaitWithDefaultTimeout()
    85  		Expect(session).Should(Exit(0))
    86  		uid := fmt.Sprintf("%d", os.Geteuid())
    87  		ok, _ := session.GrepString(uid)
    88  		Expect(ok).To(BeTrue())
    89  	})
    90  
    91  	It("podman --userns=keep-id check passwd", func() {
    92  		session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "id", "-un"})
    93  		session.WaitWithDefaultTimeout()
    94  		Expect(session).Should(Exit(0))
    95  		u, err := user.Current()
    96  		Expect(err).To(BeNil())
    97  		ok, _ := session.GrepString(u.Name)
    98  		Expect(ok).To(BeTrue())
    99  	})
   100  
   101  	It("podman --userns=keep-id root owns /usr", func() {
   102  		session := podmanTest.Podman([]string{"run", "--userns=keep-id", "alpine", "stat", "-c%u", "/usr"})
   103  		session.WaitWithDefaultTimeout()
   104  		Expect(session).Should(Exit(0))
   105  		Expect(session.OutputToString()).To(Equal("0"))
   106  	})
   107  
   108  	It("podman --userns=keep-id --user root:root", func() {
   109  		session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "alpine", "id", "-u"})
   110  		session.WaitWithDefaultTimeout()
   111  		Expect(session).Should(Exit(0))
   112  		Expect(session.OutputToString()).To(Equal("0"))
   113  	})
   114  
   115  	It("podman run --userns=keep-id can add users", func() {
   116  		if os.Geteuid() == 0 {
   117  			Skip("Test only runs without root")
   118  		}
   119  
   120  		userName := os.Getenv("USER")
   121  		if userName == "" {
   122  			Skip("Can't complete test if no username available")
   123  		}
   124  
   125  		ctrName := "ctr-name"
   126  		session := podmanTest.Podman([]string{"run", "--userns=keep-id", "--user", "root:root", "-d", "--stop-signal", "9", "--name", ctrName, fedoraMinimal, "sleep", "600"})
   127  		session.WaitWithDefaultTimeout()
   128  		Expect(session).Should(Exit(0))
   129  
   130  		exec1 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "cat", "/etc/passwd"})
   131  		exec1.WaitWithDefaultTimeout()
   132  		Expect(exec1).Should(Exit(0))
   133  		Expect(exec1.OutputToString()).To(ContainSubstring(userName))
   134  
   135  		exec2 := podmanTest.Podman([]string{"exec", "-t", "-i", ctrName, "useradd", "testuser"})
   136  		exec2.WaitWithDefaultTimeout()
   137  		Expect(exec2).Should(Exit(0))
   138  	})
   139  
   140  	It("podman --userns=auto", func() {
   141  		u, err := user.Current()
   142  		Expect(err).To(BeNil())
   143  		name := u.Name
   144  		if name == "root" {
   145  			name = "containers"
   146  		}
   147  
   148  		content, err := ioutil.ReadFile("/etc/subuid")
   149  		if err != nil {
   150  			Skip("cannot read /etc/subuid")
   151  		}
   152  		if !strings.Contains(string(content), name) {
   153  			Skip("cannot find mappings for the current user")
   154  		}
   155  
   156  		m := make(map[string]string)
   157  		for i := 0; i < 5; i++ {
   158  			session := podmanTest.Podman([]string{"run", "--userns=auto", "alpine", "cat", "/proc/self/uid_map"})
   159  			session.WaitWithDefaultTimeout()
   160  			Expect(session).Should(Exit(0))
   161  			l := session.OutputToString()
   162  			Expect(strings.Contains(l, "1024")).To(BeTrue())
   163  			m[l] = l
   164  		}
   165  		// check for no duplicates
   166  		Expect(len(m)).To(Equal(5))
   167  	})
   168  
   169  	It("podman --userns=auto:size=%d", func() {
   170  		u, err := user.Current()
   171  		Expect(err).To(BeNil())
   172  
   173  		name := u.Name
   174  		if name == "root" {
   175  			name = "containers"
   176  		}
   177  
   178  		content, err := ioutil.ReadFile("/etc/subuid")
   179  		if err != nil {
   180  			Skip("cannot read /etc/subuid")
   181  		}
   182  		if !strings.Contains(string(content), name) {
   183  			Skip("cannot find mappings for the current user")
   184  		}
   185  
   186  		session := podmanTest.Podman([]string{"run", "--userns=auto:size=500", "alpine", "cat", "/proc/self/uid_map"})
   187  		session.WaitWithDefaultTimeout()
   188  		Expect(session).Should(Exit(0))
   189  		ok, _ := session.GrepString("500")
   190  
   191  		session = podmanTest.Podman([]string{"run", "--userns=auto:size=3000", "alpine", "cat", "/proc/self/uid_map"})
   192  		session.WaitWithDefaultTimeout()
   193  		Expect(session).Should(Exit(0))
   194  		ok, _ = session.GrepString("3000")
   195  
   196  		session = podmanTest.Podman([]string{"run", "--userns=auto", "--user=2000:3000", "alpine", "cat", "/proc/self/uid_map"})
   197  		session.WaitWithDefaultTimeout()
   198  		Expect(session).Should(Exit(0))
   199  		ok, _ = session.GrepString("3001")
   200  
   201  		session = podmanTest.Podman([]string{"run", "--userns=auto", "--user=4000:1000", "alpine", "cat", "/proc/self/uid_map"})
   202  		session.WaitWithDefaultTimeout()
   203  		Expect(session).Should(Exit(0))
   204  		ok, _ = session.GrepString("4001")
   205  		Expect(ok).To(BeTrue())
   206  	})
   207  
   208  	It("podman --userns=auto:uidmapping=", func() {
   209  		u, err := user.Current()
   210  		Expect(err).To(BeNil())
   211  
   212  		name := u.Name
   213  		if name == "root" {
   214  			name = "containers"
   215  		}
   216  
   217  		content, err := ioutil.ReadFile("/etc/subuid")
   218  		if err != nil {
   219  			Skip("cannot read /etc/subuid")
   220  		}
   221  		if !strings.Contains(string(content), name) {
   222  			Skip("cannot find mappings for the current user")
   223  		}
   224  
   225  		session := podmanTest.Podman([]string{"run", "--userns=auto:uidmapping=0:0:1", "alpine", "cat", "/proc/self/uid_map"})
   226  		session.WaitWithDefaultTimeout()
   227  		Expect(session).Should(Exit(0))
   228  		output := session.OutputToString()
   229  		Expect(output).To(MatchRegexp("\\s0\\s0\\s1"))
   230  
   231  		session = podmanTest.Podman([]string{"run", "--userns=auto:size=8192,uidmapping=0:0:1", "alpine", "cat", "/proc/self/uid_map"})
   232  		session.WaitWithDefaultTimeout()
   233  		Expect(session).Should(Exit(0))
   234  		ok, _ := session.GrepString("8191")
   235  		Expect(ok).To(BeTrue())
   236  	})
   237  
   238  	It("podman --userns=auto:gidmapping=", func() {
   239  		u, err := user.Current()
   240  		Expect(err).To(BeNil())
   241  
   242  		name := u.Name
   243  		if name == "root" {
   244  			name = "containers"
   245  		}
   246  
   247  		content, err := ioutil.ReadFile("/etc/subuid")
   248  		if err != nil {
   249  			Skip("cannot read /etc/subuid")
   250  		}
   251  		if !strings.Contains(string(content), name) {
   252  			Skip("cannot find mappings for the current user")
   253  		}
   254  
   255  		session := podmanTest.Podman([]string{"run", "--userns=auto:gidmapping=0:0:1", "alpine", "cat", "/proc/self/gid_map"})
   256  		session.WaitWithDefaultTimeout()
   257  		Expect(session).Should(Exit(0))
   258  		output := session.OutputToString()
   259  		Expect(output).To(MatchRegexp("\\s0\\s0\\s1"))
   260  
   261  		session = podmanTest.Podman([]string{"run", "--userns=auto:size=8192,gidmapping=0:0:1", "alpine", "cat", "/proc/self/gid_map"})
   262  		session.WaitWithDefaultTimeout()
   263  		Expect(session).Should(Exit(0))
   264  		ok, _ := session.GrepString("8191")
   265  		Expect(ok).To(BeTrue())
   266  	})
   267  
   268  	It("podman --userns=container:CTR", func() {
   269  		ctrName := "userns-ctr"
   270  		session := podmanTest.Podman([]string{"run", "-d", "--uidmap=0:0:1", "--uidmap=1:1:4998", "--name", ctrName, "alpine", "top"})
   271  		session.WaitWithDefaultTimeout()
   272  		Expect(session).Should(Exit(0))
   273  
   274  		// runc has an issue and we also need to join the IPC namespace.
   275  		session = podmanTest.Podman([]string{"run", "--rm", "--userns=container:" + ctrName, "--ipc=container:" + ctrName, "alpine", "cat", "/proc/self/uid_map"})
   276  		session.WaitWithDefaultTimeout()
   277  		Expect(session).Should(Exit(0))
   278  
   279  		ok, _ := session.GrepString("4998")
   280  		Expect(ok).To(BeTrue())
   281  
   282  		session = podmanTest.Podman([]string{"run", "--rm", "--userns=container:" + ctrName, "--net=container:" + ctrName, "alpine", "cat", "/proc/self/uid_map"})
   283  		session.WaitWithDefaultTimeout()
   284  		Expect(session).Should(Exit(0))
   285  
   286  		ok, _ = session.GrepString("4998")
   287  		Expect(ok).To(BeTrue())
   288  	})
   289  
   290  	It("podman --user with volume", func() {
   291  		tests := []struct {
   292  			uid, gid, arg, vol string
   293  		}{
   294  			{"0", "0", "0:0", "vol-0"},
   295  			{"1000", "0", "1000", "vol-1"},
   296  			{"1000", "1000", "1000:1000", "vol-2"},
   297  		}
   298  
   299  		for _, tt := range tests {
   300  			session := podmanTest.Podman([]string{"run", "-d", "--user", tt.arg, "--mount", "type=volume,src=" + tt.vol + ",dst=/home/user", "alpine", "top"})
   301  			session.WaitWithDefaultTimeout()
   302  			Expect(session).Should(Exit(0))
   303  
   304  			inspectUID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .UID }}", tt.vol})
   305  			inspectUID.WaitWithDefaultTimeout()
   306  			Expect(inspectUID).Should(Exit(0))
   307  			Expect(inspectUID.OutputToString()).To(Equal(tt.uid))
   308  
   309  			// Make sure we're defaulting to 0.
   310  			inspectGID := podmanTest.Podman([]string{"volume", "inspect", "--format", "{{ .GID }}", tt.vol})
   311  			inspectGID.WaitWithDefaultTimeout()
   312  			Expect(inspectGID).Should(Exit(0))
   313  			Expect(inspectGID.OutputToString()).To(Equal(tt.gid))
   314  		}
   315  	})
   316  })