@@ -478,12 +478,13 @@ func WithUser(userstr string) SpecOpts {
478478 }
479479 f := func (root string ) error {
480480 if username != "" {
481- uid , _ , err = getUIDGIDFromPath (root , func (u user.User ) bool {
481+ user , err := getUserFromPath (root , func (u user.User ) bool {
482482 return u .Name == username
483483 })
484484 if err != nil {
485485 return err
486486 }
487+ uid = uint32 (user .Uid )
487488 }
488489 if groupname != "" {
489490 gid , err = getGIDFromPath (root , func (g user.Group ) bool {
@@ -541,7 +542,7 @@ func WithUserID(uid uint32) SpecOpts {
541542 if ! isRootfsAbs (s .Root .Path ) {
542543 return errors .Errorf ("rootfs absolute path is required" )
543544 }
544- uuid , ugid , err := getUIDGIDFromPath (s .Root .Path , func (u user.User ) bool {
545+ user , err := getUserFromPath (s .Root .Path , func (u user.User ) bool {
545546 return u .Uid == int (uid )
546547 })
547548 if err != nil {
@@ -551,7 +552,7 @@ func WithUserID(uid uint32) SpecOpts {
551552 }
552553 return err
553554 }
554- s .Process .User .UID , s .Process .User .GID = uuid , ugid
555+ s .Process .User .UID , s .Process .User .GID = uint32 ( user . Uid ), uint32 ( user . Gid )
555556 return nil
556557
557558 }
@@ -567,7 +568,7 @@ func WithUserID(uid uint32) SpecOpts {
567568 return err
568569 }
569570 return mount .WithTempMount (ctx , mounts , func (root string ) error {
570- uuid , ugid , err := getUIDGIDFromPath (root , func (u user.User ) bool {
571+ user , err := getUserFromPath (root , func (u user.User ) bool {
571572 return u .Uid == int (uid )
572573 })
573574 if err != nil {
@@ -577,7 +578,7 @@ func WithUserID(uid uint32) SpecOpts {
577578 }
578579 return err
579580 }
580- s .Process .User .UID , s .Process .User .GID = uuid , ugid
581+ s .Process .User .UID , s .Process .User .GID = uint32 ( user . Uid ), uint32 ( user . Gid )
581582 return nil
582583 })
583584 }
@@ -595,13 +596,13 @@ func WithUsername(username string) SpecOpts {
595596 if ! isRootfsAbs (s .Root .Path ) {
596597 return errors .Errorf ("rootfs absolute path is required" )
597598 }
598- uid , gid , err := getUIDGIDFromPath (s .Root .Path , func (u user.User ) bool {
599+ user , err := getUserFromPath (s .Root .Path , func (u user.User ) bool {
599600 return u .Name == username
600601 })
601602 if err != nil {
602603 return err
603604 }
604- s .Process .User .UID , s .Process .User .GID = uid , gid
605+ s .Process .User .UID , s .Process .User .GID = uint32 ( user . Uid ), uint32 ( user . Gid )
605606 return nil
606607 }
607608 if c .Snapshotter == "" {
@@ -616,13 +617,13 @@ func WithUsername(username string) SpecOpts {
616617 return err
617618 }
618619 return mount .WithTempMount (ctx , mounts , func (root string ) error {
619- uid , gid , err := getUIDGIDFromPath (root , func (u user.User ) bool {
620+ user , err := getUserFromPath (root , func (u user.User ) bool {
620621 return u .Name == username
621622 })
622623 if err != nil {
623624 return err
624625 }
625- s .Process .User .UID , s .Process .User .GID = uid , gid
626+ s .Process .User .UID , s .Process .User .GID = uint32 ( user . Uid ), uint32 ( user . Gid )
626627 return nil
627628 })
628629 } else if s .Windows != nil {
@@ -636,14 +637,28 @@ func WithUsername(username string) SpecOpts {
636637
637638// WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed
638639// for a particular user in the /etc/groups file of the image's root filesystem
639- func WithAdditionalGIDs (username string ) SpecOpts {
640+ // The passed in user can be either a uid or a username.
641+ func WithAdditionalGIDs (userstr string ) SpecOpts {
640642 return func (ctx context.Context , client Client , c * containers.Container , s * Spec ) (err error ) {
641643 setProcess (s )
642- if c .Snapshotter == "" && c .SnapshotKey == "" {
643- if ! isRootfsAbs (s .Root .Path ) {
644- return errors .Errorf ("rootfs absolute path is required" )
644+ setAdditionalGids := func (root string ) error {
645+ var username string
646+ uid , err := strconv .Atoi (userstr )
647+ if err == nil {
648+ user , err := getUserFromPath (root , func (u user.User ) bool {
649+ return u .Uid == uid
650+ })
651+ if err != nil {
652+ if os .IsNotExist (err ) || err == errNoUsersFound {
653+ return nil
654+ }
655+ return err
656+ }
657+ username = user .Name
658+ } else {
659+ username = userstr
645660 }
646- gids , err := getSupplementalGroupsFromPath (s . Root . Path , func (g user.Group ) bool {
661+ gids , err := getSupplementalGroupsFromPath (root , func (g user.Group ) bool {
647662 // we only want supplemental groups
648663 if g .Name == username {
649664 return false
@@ -656,11 +671,20 @@ func WithAdditionalGIDs(username string) SpecOpts {
656671 return false
657672 })
658673 if err != nil {
674+ if os .IsNotExist (err ) {
675+ return nil
676+ }
659677 return err
660678 }
661679 s .Process .User .AdditionalGids = gids
662680 return nil
663681 }
682+ if c .Snapshotter == "" && c .SnapshotKey == "" {
683+ if ! isRootfsAbs (s .Root .Path ) {
684+ return errors .Errorf ("rootfs absolute path is required" )
685+ }
686+ return setAdditionalGids (s .Root .Path )
687+ }
664688 if c .Snapshotter == "" {
665689 return errors .Errorf ("no snapshotter set for container" )
666690 }
@@ -672,25 +696,7 @@ func WithAdditionalGIDs(username string) SpecOpts {
672696 if err != nil {
673697 return err
674698 }
675- return mount .WithTempMount (ctx , mounts , func (root string ) error {
676- gids , err := getSupplementalGroupsFromPath (root , func (g user.Group ) bool {
677- // we only want supplemental groups
678- if g .Name == username {
679- return false
680- }
681- for _ , entry := range g .List {
682- if entry == username {
683- return true
684- }
685- }
686- return false
687- })
688- if err != nil {
689- return err
690- }
691- s .Process .User .AdditionalGids = gids
692- return nil
693- })
699+ return mount .WithTempMount (ctx , mounts , setAdditionalGids )
694700 }
695701}
696702
@@ -741,20 +747,19 @@ func WithAmbientCapabilities(caps []string) SpecOpts {
741747
742748var errNoUsersFound = errors .New ("no users found" )
743749
744- func getUIDGIDFromPath (root string , filter func (user.User ) bool ) (uid , gid uint32 , err error ) {
750+ func getUserFromPath (root string , filter func (user.User ) bool ) (user. User , error ) {
745751 ppath , err := fs .RootPath (root , "/etc/passwd" )
746752 if err != nil {
747- return 0 , 0 , err
753+ return user. User {} , err
748754 }
749755 users , err := user .ParsePasswdFileFilter (ppath , filter )
750756 if err != nil {
751- return 0 , 0 , err
757+ return user. User {} , err
752758 }
753759 if len (users ) == 0 {
754- return 0 , 0 , errNoUsersFound
760+ return user. User {} , errNoUsersFound
755761 }
756- u := users [0 ]
757- return uint32 (u .Uid ), uint32 (u .Gid ), nil
762+ return users [0 ], nil
758763}
759764
760765var errNoGroupsFound = errors .New ("no groups found" )
0 commit comments