Skip to content

Commit bcc209d

Browse files
feat: add userns
Signed-off-by: Shubharanshu Mahapatra <shubhum@amazon.com>
1 parent 0e29586 commit bcc209d

15 files changed

+1233
-177
lines changed

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ linters:
114114
arguments: [7]
115115
- name: function-length
116116
# 155 occurrences (at default 0, 75). Really long functions should really be broken up in most cases.
117-
arguments: [0, 400]
117+
arguments: [0, 450]
118118
- name: cyclomatic
119119
# 204 occurrences (at default 10)
120120
arguments: [100]

cmd/nerdctl/container/container_create_linux_test.go

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import (
3030

3131
"github.com/opencontainers/go-digest"
3232
"gotest.tools/v3/assert"
33-
"gotest.tools/v3/icmd"
3433

3534
"github.com/containerd/containerd/v2/defaults"
3635
"github.com/containerd/nerdctl/mod/tigron/require"
@@ -337,26 +336,24 @@ func TestUsernsMappingCreateCmd(t *testing.T) {
337336
testCase := &test.Case{
338337
Require: require.All(
339338
nerdtest.AllowModifyUserns,
340-
require.Not(nerdtest.ContainerdV1),
341339
require.Not(nerdtest.Docker)),
342340
SubTests: []*test.Case{
343341
{
344342
Description: "Test container start with valid Userns",
345343
NoParallel: true, // Changes system config so running in non parallel mode
346344
Setup: func(data test.Data, helpers test.Helpers) {
347-
data.Set("validUserns", "nerdctltestuser")
348-
data.Set("expectedHostUID", "123456789")
349-
// need to be compiled with containerd version >2.0.2 to support multi uidmap and gidmap.
350-
if err := appendUsernsConfig(data.Get("validUserns"), data.Get("expectedHostUID")); err != nil {
345+
data.Labels().Set("validUserns", "nerdctltestuser")
346+
data.Labels().Set("expectedHostUID", "123456789")
347+
if err := appendUsernsConfig(data.Labels().Get("validUserns"), data.Labels().Get("expectedHostUID")); err != nil {
351348
t.Fatalf("Failed to append Userns config: %v", err)
352349
}
353350
},
354351
Cleanup: func(data test.Data, helpers test.Helpers) {
355-
removeUsernsConfig(t, data.Get("validUserns"), data.Get("expectedHostUID"))
352+
removeUsernsConfig(t, data.Labels().Get("validUserns"))
356353
helpers.Anyhow("rm", "-f", data.Identifier())
357354
},
358355
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
359-
helpers.Ensure("create", "--tty", "--userns", data.Get("validUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
356+
helpers.Ensure("create", "--tty", "--userns", data.Labels().Get("validUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
360357
return helpers.Command("start", data.Identifier())
361358
},
362359
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
@@ -367,7 +364,7 @@ func TestUsernsMappingCreateCmd(t *testing.T) {
367364
if err != nil {
368365
t.Fatalf("Failed to get container host UID: %v", err)
369366
}
370-
assert.Assert(t, actualHostUID == data.Get("expectedHostUID"), info)
367+
assert.Assert(t, actualHostUID == data.Labels().Get("expectedHostUID"), info)
371368
},
372369
}
373370
},
@@ -376,13 +373,13 @@ func TestUsernsMappingCreateCmd(t *testing.T) {
376373
Description: "Test container start with invalid Userns",
377374
NoParallel: true, // Changes system config so running in non parallel mode
378375
Setup: func(data test.Data, helpers test.Helpers) {
379-
data.Set("invalidUserns", "invaliduser")
376+
data.Labels().Set("invalidUserns", "invaliduser")
380377
},
381378
Cleanup: func(data test.Data, helpers test.Helpers) {
382379
helpers.Anyhow("rm", "-f", data.Identifier())
383380
},
384381
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
385-
return helpers.Command("create", "--tty", "--userns", data.Get("invalidUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
382+
return helpers.Command("create", "--tty", "--userns", data.Labels().Get("invalidUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
386383
},
387384
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
388385
return &test.Expected{
@@ -395,19 +392,6 @@ func TestUsernsMappingCreateCmd(t *testing.T) {
395392
testCase.Run(t)
396393
}
397394

398-
func runUsernsContainer(t *testing.T, name, Userns, image, cmd string) *icmd.Result {
399-
base := testutil.NewBase(t)
400-
removeContainerArgs := []string{
401-
"rm", "-f", name,
402-
}
403-
base.Cmd(removeContainerArgs...).Run()
404-
405-
args := []string{
406-
"run", "-d", "--userns", Userns, "--name", name, image, "sh", "-c", cmd,
407-
}
408-
return base.Cmd(args...).Run()
409-
}
410-
411395
func getContainerHostUID(helpers test.Helpers, containerName string) (string, error) {
412396
result := helpers.Capture("inspect", "--format", "{{.State.Pid}}", containerName)
413397
pidStr := strings.TrimSpace(result)
@@ -425,12 +409,12 @@ func getContainerHostUID(helpers test.Helpers, containerName string) (string, er
425409
return strconv.Itoa(uid), nil
426410
}
427411

428-
func appendUsernsConfig(Userns string, hostUid string) error {
429-
if err := addUser(Userns, hostUid); err != nil {
430-
return fmt.Errorf("failed to add user %s: %w", Userns, err)
412+
func appendUsernsConfig(userns string, hostUID string) error {
413+
if err := addUser(userns, hostUID); err != nil {
414+
return fmt.Errorf("failed to add user %s: %w", userns, err)
431415
}
432416

433-
entry := fmt.Sprintf("%s:%s:65536\n", Userns, hostUid)
417+
entry := fmt.Sprintf("%s:%s:65536\n", userns, hostUID)
434418

435419
tempDir := os.TempDir()
436420

@@ -468,28 +452,27 @@ func appendUsernsConfig(Userns string, hostUid string) error {
468452
return nil
469453
}
470454

471-
func addUser(username string, hostId string) error {
472-
cmd := exec.Command("groupadd", "-g", hostId, username)
455+
func addUser(username string, hostID string) error {
456+
cmd := exec.Command("groupadd", "-g", hostID, username)
473457
output, err := cmd.CombinedOutput()
474458
if err != nil {
475459
return fmt.Errorf("groupadd failed: %s, %w", string(output), err)
476460
}
477-
cmd = exec.Command("useradd", "-u", hostId, "-g", hostId, "-s", "/bin/false", username)
461+
cmd = exec.Command("useradd", "-u", hostID, "-g", hostID, "-s", "/bin/false", username)
478462
output, err = cmd.CombinedOutput()
479463
if err != nil {
480464
return fmt.Errorf("useradd failed: %s, %w", string(output), err)
481465
}
482466
return nil
483467
}
484468

485-
func removeUsernsConfig(t *testing.T, Userns string, hostUid string) {
486-
487-
if err := delUser(Userns); err != nil {
488-
t.Logf("failed to del user %s, Error: %s", Userns, err)
469+
func removeUsernsConfig(t *testing.T, userns string) {
470+
if err := delUser(userns); err != nil {
471+
t.Logf("failed to del user %s, Error: %s", userns, err)
489472
}
490473

491-
if err := delGroup(Userns); err != nil {
492-
t.Logf("failed to del group %s, Error: %s", Userns, err)
474+
if err := delGroup(userns); err != nil {
475+
t.Logf("failed to del group %s, Error: %s", userns, err)
493476
}
494477

495478
tempDir := os.TempDir()
@@ -521,7 +504,7 @@ func removeUsernsConfig(t *testing.T, Userns string, hostUid string) {
521504
}
522505

523506
func delUser(username string) error {
524-
cmd := exec.Command("sudo", "userdel", username)
507+
cmd := exec.Command("userdel", username)
525508
output, err := cmd.CombinedOutput()
526509
if err != nil {
527510
return fmt.Errorf("userdel failed: %s, %w", string(output), err)
@@ -530,7 +513,7 @@ func delUser(username string) error {
530513
}
531514

532515
func delGroup(groupname string) error {
533-
cmd := exec.Command("sudo", "groupdel", groupname)
516+
cmd := exec.Command("groupdel", groupname)
534517
output, err := cmd.CombinedOutput()
535518
if err != nil {
536519
return fmt.Errorf("groupdel failed: %s, %w", string(output), err)

cmd/nerdctl/container/container_run_user_linux_test.go

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ import (
2020
"fmt"
2121
"testing"
2222

23+
"gotest.tools/v3/assert"
24+
2325
"github.com/containerd/nerdctl/mod/tigron/require"
2426
"github.com/containerd/nerdctl/mod/tigron/test"
27+
2528
"github.com/containerd/nerdctl/v2/pkg/testutil"
2629
"github.com/containerd/nerdctl/v2/pkg/testutil/nerdtest"
27-
"gotest.tools/v3/assert"
2830
)
2931

3032
func TestRunUserGID(t *testing.T) {
@@ -192,25 +194,24 @@ func TestUsernsMappingRunCmd(t *testing.T) {
192194
testCase := &test.Case{
193195
Require: require.All(
194196
nerdtest.AllowModifyUserns,
195-
require.Not(nerdtest.ContainerdV1),
196197
require.Not(nerdtest.Docker)),
197198
SubTests: []*test.Case{
198199
{
199200
Description: "Test container start with valid Userns",
200201
NoParallel: true, // Changes system config so running in non parallel mode
201202
Setup: func(data test.Data, helpers test.Helpers) {
202-
data.Set("validUserns", "nerdctltestuser")
203-
data.Set("expectedHostUID", "123456789")
204-
if err := appendUsernsConfig(data.Get("validUserns"), data.Get("expectedHostUID")); err != nil {
203+
data.Labels().Set("validUserns", "nerdctltestuser")
204+
data.Labels().Set("expectedHostUID", "123456789")
205+
if err := appendUsernsConfig(data.Labels().Get("validUserns"), data.Labels().Get("expectedHostUID")); err != nil {
205206
t.Fatalf("Failed to append Userns config: %v", err)
206207
}
207208
},
208209
Cleanup: func(data test.Data, helpers test.Helpers) {
209210
helpers.Anyhow("rm", "-f", data.Identifier())
210-
removeUsernsConfig(t, data.Get("validUserns"), data.Get("expectedHostUID"))
211+
removeUsernsConfig(t, data.Labels().Get("validUserns"))
211212
},
212213
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
213-
return helpers.Command("run", "--tty", "-d", "--userns", data.Get("validUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
214+
return helpers.Command("run", "--tty", "-d", "--userns", data.Labels().Get("validUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
214215
},
215216
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
216217
return &test.Expected{
@@ -220,7 +221,7 @@ func TestUsernsMappingRunCmd(t *testing.T) {
220221
if err != nil {
221222
t.Fatalf("Failed to get container host UID: %v", err)
222223
}
223-
assert.Assert(t, actualHostUID == data.Get("expectedHostUID"), info)
224+
assert.Assert(t, actualHostUID == data.Labels().Get("expectedHostUID"), info)
224225
},
225226
}
226227
},
@@ -229,22 +230,22 @@ func TestUsernsMappingRunCmd(t *testing.T) {
229230
Description: "Test container network share with valid Userns",
230231
NoParallel: true, // Changes system config so running in non parallel mode
231232
Setup: func(data test.Data, helpers test.Helpers) {
232-
data.Set("validUserns", "nerdctltestuser")
233-
data.Set("expectedHostUID", "123456789")
234-
data.Set("net-container", "net-container")
235-
if err := appendUsernsConfig(data.Get("validUserns"), data.Get("expectedHostUID")); err != nil {
233+
data.Labels().Set("validUserns", "nerdctltestuser")
234+
data.Labels().Set("expectedHostUID", "123456789")
235+
data.Labels().Set("net-container", "net-container")
236+
if err := appendUsernsConfig(data.Labels().Get("validUserns"), data.Labels().Get("expectedHostUID")); err != nil {
236237
t.Fatalf("Failed to append Userns config: %v", err)
237238
}
238239

239-
helpers.Ensure("run", "--tty", "-d", "--userns", data.Get("validUserns"), "--name", data.Get("net-container"), testutil.NginxAlpineImage)
240+
helpers.Ensure("run", "--tty", "-d", "--userns", data.Labels().Get("validUserns"), "--name", data.Labels().Get("net-container"), testutil.NginxAlpineImage)
240241
},
241242
Cleanup: func(data test.Data, helpers test.Helpers) {
242243
helpers.Anyhow("rm", "-f", data.Identifier())
243-
helpers.Anyhow("rm", "-f", data.Get("net-container"))
244-
removeUsernsConfig(t, data.Get("validUserns"), data.Get("expectedHostUID"))
244+
helpers.Anyhow("rm", "-f", data.Labels().Get("net-container"))
245+
removeUsernsConfig(t, data.Labels().Get("validUserns"))
245246
},
246247
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
247-
return helpers.Command("run", "--tty", "-d", "--userns", data.Get("validUserns"), "--net", fmt.Sprintf("container:%s", data.Get("net-container")), "--name", data.Identifier(), testutil.NginxAlpineImage)
248+
return helpers.Command("run", "--tty", "-d", "--userns", data.Labels().Get("validUserns"), "--net", fmt.Sprintf("container:%s", data.Labels().Get("net-container")), "--name", data.Identifier(), testutil.NginxAlpineImage)
248249
},
249250
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
250251
return &test.Expected{
@@ -255,13 +256,13 @@ func TestUsernsMappingRunCmd(t *testing.T) {
255256
{
256257
Description: "Test container start with invalid Userns",
257258
Setup: func(data test.Data, helpers test.Helpers) {
258-
data.Set("invalidUserns", "invaliduser")
259+
data.Labels().Set("invalidUserns", "invaliduser")
259260
},
260261
Cleanup: func(data test.Data, helpers test.Helpers) {
261262
helpers.Anyhow("rm", "-f", data.Identifier())
262263
},
263264
Command: func(data test.Data, helpers test.Helpers) test.TestableCommand {
264-
return helpers.Command("run", "--tty", "-d", "--userns", data.Get("invalidUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
265+
return helpers.Command("run", "--tty", "-d", "--userns", data.Labels().Get("invalidUserns"), "--name", data.Identifier(), testutil.NginxAlpineImage)
265266
},
266267
Expected: func(data test.Data, helpers test.Helpers) *test.Expected {
267268
return &test.Expected{

0 commit comments

Comments
 (0)