Skip to content

Commit 9823a56

Browse files
committed
Backport #2641 to release/1.1.
Signed-off-by: Lantao Liu <[email protected]>
1 parent b28cd80 commit 9823a56

1 file changed

Lines changed: 44 additions & 39 deletions

File tree

oci/spec_opts_unix.go

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -294,12 +294,13 @@ func WithUser(userstr string) SpecOpts {
294294
}
295295
f := func(root string) error {
296296
if username != "" {
297-
uid, _, err = getUIDGIDFromPath(root, func(u user.User) bool {
297+
user, err := getUserFromPath(root, func(u user.User) bool {
298298
return u.Name == username
299299
})
300300
if err != nil {
301301
return err
302302
}
303+
uid = uint32(user.Uid)
303304
}
304305
if groupname != "" {
305306
gid, err = getGIDFromPath(root, func(g user.Group) bool {
@@ -357,7 +358,7 @@ func WithUserID(uid uint32) SpecOpts {
357358
if !isRootfsAbs(s.Root.Path) {
358359
return errors.Errorf("rootfs absolute path is required")
359360
}
360-
uuid, ugid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool {
361+
user, err := getUserFromPath(s.Root.Path, func(u user.User) bool {
361362
return u.Uid == int(uid)
362363
})
363364
if err != nil {
@@ -367,7 +368,7 @@ func WithUserID(uid uint32) SpecOpts {
367368
}
368369
return err
369370
}
370-
s.Process.User.UID, s.Process.User.GID = uuid, ugid
371+
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
371372
return nil
372373

373374
}
@@ -383,7 +384,7 @@ func WithUserID(uid uint32) SpecOpts {
383384
return err
384385
}
385386
return mount.WithTempMount(ctx, mounts, func(root string) error {
386-
uuid, ugid, err := getUIDGIDFromPath(root, func(u user.User) bool {
387+
user, err := getUserFromPath(root, func(u user.User) bool {
387388
return u.Uid == int(uid)
388389
})
389390
if err != nil {
@@ -393,7 +394,7 @@ func WithUserID(uid uint32) SpecOpts {
393394
}
394395
return err
395396
}
396-
s.Process.User.UID, s.Process.User.GID = uuid, ugid
397+
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
397398
return nil
398399
})
399400
}
@@ -410,13 +411,13 @@ func WithUsername(username string) SpecOpts {
410411
if !isRootfsAbs(s.Root.Path) {
411412
return errors.Errorf("rootfs absolute path is required")
412413
}
413-
uid, gid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool {
414+
user, err := getUserFromPath(s.Root.Path, func(u user.User) bool {
414415
return u.Name == username
415416
})
416417
if err != nil {
417418
return err
418419
}
419-
s.Process.User.UID, s.Process.User.GID = uid, gid
420+
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
420421
return nil
421422
}
422423
if c.Snapshotter == "" {
@@ -431,28 +432,42 @@ func WithUsername(username string) SpecOpts {
431432
return err
432433
}
433434
return mount.WithTempMount(ctx, mounts, func(root string) error {
434-
uid, gid, err := getUIDGIDFromPath(root, func(u user.User) bool {
435+
user, err := getUserFromPath(root, func(u user.User) bool {
435436
return u.Name == username
436437
})
437438
if err != nil {
438439
return err
439440
}
440-
s.Process.User.UID, s.Process.User.GID = uid, gid
441+
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
441442
return nil
442443
})
443444
}
444445
}
445446

446447
// WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed
447448
// for a particular user in the /etc/groups file of the image's root filesystem
448-
func WithAdditionalGIDs(username string) SpecOpts {
449+
// The passed in user can be either a uid or a username.
450+
func WithAdditionalGIDs(userstr string) SpecOpts {
449451
return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) {
450452
setProcess(s)
451-
if c.Snapshotter == "" && c.SnapshotKey == "" {
452-
if !isRootfsAbs(s.Root.Path) {
453-
return errors.Errorf("rootfs absolute path is required")
453+
setAdditionalGids := func(root string) error {
454+
var username string
455+
uid, err := strconv.Atoi(userstr)
456+
if err == nil {
457+
user, err := getUserFromPath(root, func(u user.User) bool {
458+
return u.Uid == uid
459+
})
460+
if err != nil {
461+
if os.IsNotExist(err) || err == errNoUsersFound {
462+
return nil
463+
}
464+
return err
465+
}
466+
username = user.Name
467+
} else {
468+
username = userstr
454469
}
455-
gids, err := getSupplementalGroupsFromPath(s.Root.Path, func(g user.Group) bool {
470+
gids, err := getSupplementalGroupsFromPath(root, func(g user.Group) bool {
456471
// we only want supplemental groups
457472
if g.Name == username {
458473
return false
@@ -465,11 +480,20 @@ func WithAdditionalGIDs(username string) SpecOpts {
465480
return false
466481
})
467482
if err != nil {
483+
if os.IsNotExist(err) {
484+
return nil
485+
}
468486
return err
469487
}
470488
s.Process.User.AdditionalGids = gids
471489
return nil
472490
}
491+
if c.Snapshotter == "" && c.SnapshotKey == "" {
492+
if !isRootfsAbs(s.Root.Path) {
493+
return errors.Errorf("rootfs absolute path is required")
494+
}
495+
return setAdditionalGids(s.Root.Path)
496+
}
473497
if c.Snapshotter == "" {
474498
return errors.Errorf("no snapshotter set for container")
475499
}
@@ -481,25 +505,7 @@ func WithAdditionalGIDs(username string) SpecOpts {
481505
if err != nil {
482506
return err
483507
}
484-
return mount.WithTempMount(ctx, mounts, func(root string) error {
485-
gids, err := getSupplementalGroupsFromPath(root, func(g user.Group) bool {
486-
// we only want supplemental groups
487-
if g.Name == username {
488-
return false
489-
}
490-
for _, entry := range g.List {
491-
if entry == username {
492-
return true
493-
}
494-
}
495-
return false
496-
})
497-
if err != nil {
498-
return err
499-
}
500-
s.Process.User.AdditionalGids = gids
501-
return nil
502-
})
508+
return mount.WithTempMount(ctx, mounts, setAdditionalGids)
503509
}
504510
}
505511

@@ -538,20 +544,19 @@ func getAllCapabilities() []string {
538544

539545
var errNoUsersFound = errors.New("no users found")
540546

541-
func getUIDGIDFromPath(root string, filter func(user.User) bool) (uid, gid uint32, err error) {
547+
func getUserFromPath(root string, filter func(user.User) bool) (user.User, error) {
542548
ppath, err := fs.RootPath(root, "/etc/passwd")
543549
if err != nil {
544-
return 0, 0, err
550+
return user.User{}, err
545551
}
546552
users, err := user.ParsePasswdFileFilter(ppath, filter)
547553
if err != nil {
548-
return 0, 0, err
554+
return user.User{}, err
549555
}
550556
if len(users) == 0 {
551-
return 0, 0, errNoUsersFound
557+
return user.User{}, errNoUsersFound
552558
}
553-
u := users[0]
554-
return uint32(u.Uid), uint32(u.Gid), nil
559+
return users[0], nil
555560
}
556561

557562
var errNoGroupsFound = errors.New("no groups found")

0 commit comments

Comments
 (0)