Skip to content

Commit 67371a5

Browse files
committed
Test: init subid range check for rootless PinP
in pkg/machine/e2e/init_test.go Signed-off-by: dvorst <[email protected]>
1 parent 1ecf851 commit 67371a5

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

pkg/machine/e2e/init_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"os"
66
"path/filepath"
7+
"regexp"
78
"runtime"
89
"strconv"
910
"strings"
@@ -124,6 +125,62 @@ var _ = Describe("podman machine init", func() {
124125
Expect(repeatSession.errorToString()).To(ContainSubstring(fmt.Sprintf("Error: machine %q already exists", mb.names[0])))
125126
})
126127

128+
It("init subid range check for rootless PinP", func() {
129+
/* By default, a new user is assigned the following sub-ID ranges (see manual useradd):
130+
* SUB_UID_MIN=100000, SUB_GID_MIN=100000, SUB_UID_COUNT=65536, SUB_GID_COUNT=65536
131+
* This means the default sub-UID and sub-GID ranges are 100000–165535.
132+
*
133+
* When the container is run rootless by the user in WSL, ID mappings occur as follows:
134+
* Container ID 0 (root) maps to user ID on the host.
135+
* Container IDs 1–65536 map to IDs 100000–165535 on host (range previously mentioned).
136+
*
137+
* If a new user is created inside the container and used to build containers with
138+
* (rootless PinP), it will attempt to use the default sub-ID range (100000–165535). Given
139+
* the mapping, this means that the host must at least have a SUB_UID_COUNT and
140+
* SUB_GID_COUNT of 165536. Since 165536 would only allow rootless PinP for the first
141+
* user (with ID 1000), the check is run against a count of 166536 (=165536+1000) as to
142+
* provide additional margin.
143+
*/
144+
145+
count_min := 166536
146+
i := new(initMachine)
147+
name := randomString()
148+
session, err := mb.setName(name).setCmd(i.withImage(mb.imagePath)).run()
149+
Expect(err).ToNot(HaveOccurred())
150+
Expect(session).To(Exit(0))
151+
152+
// obtain the users subid range from the machine
153+
ssh := new(sshMachine)
154+
sshSession, err := mb.setName(name).setCmd(ssh.withSSHCommand([]string{"cat", "/etc/subuid", "/etc/subgid"})).run()
155+
Expect(err).ToNot(HaveOccurred())
156+
if sshSession.ExitCode() != 0 {
157+
Fail(fmt.Sprintf("SSH session failed with exit code %d\nstdout:\n%s\nstderr:\n%s",
158+
sshSession.ExitCode(),
159+
sshSession.outputToString(),
160+
sshSession.errorToString(),
161+
))
162+
}
163+
Expect(sshSession).To(Exit(0))
164+
output := strings.TrimSpace(sshSession.outputToString())
165+
166+
// subuid and subgid have the format 'USER:SUB_ID_MIN:SUB_ID_COUNT', for example
167+
// 'user:100000:65536', only count is of interest.
168+
re := regexp.MustCompile(`(?m):(\d+)$`)
169+
counts := re.FindAllStringSubmatch(output, -1)
170+
171+
// A user must exist in order to run podman rootless, a line in both subuid and subgid
172+
// should exist for it, so 2 lines in total.
173+
Expect(len(counts)).To(BeNumerically(">=", 2), "expected at least 1 user/line in /etc/subuid and /etc/subgid each, got %d", len(counts))
174+
175+
// Verify the count. At the moment only 1 user is created in the machine. If multiple users
176+
// are ever created, this will check that all users have a sufficient subid range.
177+
for _, count := range counts {
178+
n, err := strconv.Atoi(count[1])
179+
Expect(err).ToNot(HaveOccurred())
180+
Expect(n).To(BeNumerically(">=", count_min), "expected last number %d to be >= %d", n, count_min)
181+
}
182+
})
183+
127184
It("run playbook", func() {
128185
str := randomString()
129186

0 commit comments

Comments
 (0)