@@ -803,6 +803,63 @@ func WithAdditionalGIDs(userstr string) SpecOpts {
803803 }
804804}
805805
806+ // WithAppendAdditionalGroups append additional groups within the container.
807+ // The passed in groups can be either a gid or a groupname.
808+ func WithAppendAdditionalGroups (groups ... string ) SpecOpts {
809+ return func (ctx context.Context , client Client , c * containers.Container , s * Spec ) (err error ) {
810+ // For LCOW or on Darwin additional GID's are not supported
811+ if s .Windows != nil || runtime .GOOS == "darwin" {
812+ return nil
813+ }
814+ setProcess (s )
815+ setAdditionalGids := func (root string ) error {
816+ gpath , err := fs .RootPath (root , "/etc/group" )
817+ if err != nil {
818+ return err
819+ }
820+ ugroups , err := user .ParseGroupFile (gpath )
821+ if err != nil {
822+ return err
823+ }
824+ groupMap := make (map [string ]user.Group )
825+ for _ , group := range ugroups {
826+ groupMap [group .Name ] = group
827+ groupMap [strconv .Itoa (group .Gid )] = group
828+ }
829+ var gids []uint32
830+ for _ , group := range groups {
831+ g , ok := groupMap [group ]
832+ if ! ok {
833+ return fmt .Errorf ("unable to find group %s" , group )
834+ }
835+ gids = append (gids , uint32 (g .Gid ))
836+ }
837+ s .Process .User .AdditionalGids = append (s .Process .User .AdditionalGids , gids ... )
838+ return nil
839+ }
840+ if c .Snapshotter == "" && c .SnapshotKey == "" {
841+ if ! filepath .IsAbs (s .Root .Path ) {
842+ return errors .New ("rootfs absolute path is required" )
843+ }
844+ return setAdditionalGids (s .Root .Path )
845+ }
846+ if c .Snapshotter == "" {
847+ return errors .New ("no snapshotter set for container" )
848+ }
849+ if c .SnapshotKey == "" {
850+ return errors .New ("rootfs snapshot not created for container" )
851+ }
852+ snapshotter := client .SnapshotService (c .Snapshotter )
853+ mounts , err := snapshotter .Mounts (ctx , c .SnapshotKey )
854+ if err != nil {
855+ return err
856+ }
857+
858+ mounts = tryReadonlyMounts (mounts )
859+ return mount .WithTempMount (ctx , mounts , setAdditionalGids )
860+ }
861+ }
862+
806863// WithCapabilities sets Linux capabilities on the process
807864func WithCapabilities (caps []string ) SpecOpts {
808865 return func (_ context.Context , _ Client , _ * containers.Container , s * Spec ) error {
@@ -907,7 +964,7 @@ func UserFromPath(root string, filter func(user.User) bool) (user.User, error) {
907964// ErrNoGroupsFound can be returned from GIDFromPath
908965var ErrNoGroupsFound = errors .New ("no groups found" )
909966
910- // GIDFromPath inspects the GID using /etc/passwd in the specified rootfs.
967+ // GIDFromPath inspects the GID using /etc/group in the specified rootfs.
911968// filter can be nil.
912969func GIDFromPath (root string , filter func (user.Group ) bool ) (gid uint32 , err error ) {
913970 gpath , err := fs .RootPath (root , "/etc/group" )
0 commit comments