@@ -803,6 +803,63 @@ func WithAdditionalGIDs(userstr string) SpecOpts {
803
803
}
804
804
}
805
805
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
+
806
863
// WithCapabilities sets Linux capabilities on the process
807
864
func WithCapabilities (caps []string ) SpecOpts {
808
865
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) {
907
964
// ErrNoGroupsFound can be returned from GIDFromPath
908
965
var ErrNoGroupsFound = errors .New ("no groups found" )
909
966
910
- // GIDFromPath inspects the GID using /etc/passwd in the specified rootfs.
967
+ // GIDFromPath inspects the GID using /etc/group in the specified rootfs.
911
968
// filter can be nil.
912
969
func GIDFromPath (root string , filter func (user.Group ) bool ) (gid uint32 , err error ) {
913
970
gpath , err := fs .RootPath (root , "/etc/group" )
0 commit comments