@@ -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
539545var 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
557562var errNoGroupsFound = errors .New ("no groups found" )
0 commit comments