Skip to content

Commit 3772eff

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 122583a commit 3772eff

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

pkg/machine/e2e/init_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,54 @@ var _ = Describe("podman machine init", func() {
124124
Expect(repeatSession.errorToString()).To(ContainSubstring(fmt.Sprintf("Error: machine %q already exists", mb.names[0])))
125125
})
126126

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

0 commit comments

Comments
 (0)