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 })