|
4 | 4 | "fmt" |
5 | 5 | "os" |
6 | 6 | "path/filepath" |
| 7 | +"regexp" |
7 | 8 | "runtime" |
8 | 9 | "strconv" |
9 | 10 | "strings" |
@@ -124,6 +125,55 @@ var _ = Describe("podman machine init", func() { |
124 | 125 | Expect(repeatSession.errorToString()).To(ContainSubstring(fmt.Sprintf("Error: machine %q already exists",mb.names[0]))) |
125 | 126 | }) |
126 | 127 |
|
| 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 | +Expect(sshSession).To(Exit(0)) |
| 157 | +output:=strings.TrimSpace(sshSession.outputToString()) |
| 158 | + |
| 159 | +// subuid and subgid have the format 'USER:SUB_ID_MIN:SUB_ID_COUNT', for example |
| 160 | +// 'user:100000:65536', only count is of interest. |
| 161 | +re:=regexp.MustCompile(`(?m):(\d+)$`) |
| 162 | +counts:=re.FindAllStringSubmatch(output,-1) |
| 163 | + |
| 164 | +// A user must exist in order to run podman rootless, a line in both subuid and subgid |
| 165 | +// should exist for it, so 2 lines in total. |
| 166 | +Expect(len(counts)).To(BeNumerically(">=",2),"expected at least 1 user/line in /etc/subuid and /etc/subgid each, got %d",len(counts)) |
| 167 | + |
| 168 | +// Verify the count. At the moment only 1 user is created in the machine. If multiple users |
| 169 | +// are ever created, this will check that all users have a sufficient subid range. |
| 170 | +for_,count:=rangecounts { |
| 171 | +n,err:=strconv.Atoi(count[1]) |
| 172 | +Expect(err).ToNot(HaveOccurred()) |
| 173 | +Expect(n).To(BeNumerically(">=",count_min),"expected last number %d to be >= %d",n,count_min) |
| 174 | +} |
| 175 | +}) |
| 176 | + |
127 | 177 | It("run playbook",func() { |
128 | 178 | str:=randomString() |
129 | 179 |
|
|