Add With-helper for supplemental gid support
Can be used to conform to Docker engine behavior of adding additional GIDs to spec when found in /etc/group of image filesystem Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
This commit is contained in:
parent
1597270d04
commit
78e61af47a
@ -634,6 +634,66 @@ func WithUsername(username string) SpecOpts {
|
||||
}
|
||||
}
|
||||
|
||||
// WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed
|
||||
// for a particular user in the /etc/groups file of the image's root filesystem
|
||||
func WithAdditionalGIDs(username string) SpecOpts {
|
||||
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
|
||||
setProcess(s)
|
||||
if c.Snapshotter == "" && c.SnapshotKey == "" {
|
||||
if !isRootfsAbs(s.Root.Path) {
|
||||
return errors.Errorf("rootfs absolute path is required")
|
||||
}
|
||||
gids, err := getSupplementalGroupsFromPath(s.Root.Path, func(g user.Group) bool {
|
||||
// we only want supplemental groups
|
||||
if g.Name == username {
|
||||
return false
|
||||
}
|
||||
for _, entry := range g.List {
|
||||
if entry == username {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Process.User.AdditionalGids = gids
|
||||
return nil
|
||||
}
|
||||
if c.Snapshotter == "" {
|
||||
return errors.Errorf("no snapshotter set for container")
|
||||
}
|
||||
if c.SnapshotKey == "" {
|
||||
return errors.Errorf("rootfs snapshot not created for container")
|
||||
}
|
||||
snapshotter := client.SnapshotService(c.Snapshotter)
|
||||
mounts, err := snapshotter.Mounts(ctx, c.SnapshotKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return mount.WithTempMount(ctx, mounts, func(root string) error {
|
||||
gids, err := getSupplementalGroupsFromPath(root, func(g user.Group) bool {
|
||||
// we only want supplemental groups
|
||||
if g.Name == username {
|
||||
return false
|
||||
}
|
||||
for _, entry := range g.List {
|
||||
if entry == username {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Process.User.AdditionalGids = gids
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithCapabilities sets Linux capabilities on the process
|
||||
func WithCapabilities(caps []string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
@ -715,6 +775,26 @@ func getGIDFromPath(root string, filter func(user.Group) bool) (gid uint32, err
|
||||
return uint32(g.Gid), nil
|
||||
}
|
||||
|
||||
func getSupplementalGroupsFromPath(root string, filter func(user.Group) bool) ([]uint32, error) {
|
||||
gpath, err := fs.RootPath(root, "/etc/group")
|
||||
if err != nil {
|
||||
return []uint32{}, err
|
||||
}
|
||||
groups, err := user.ParseGroupFileFilter(gpath, filter)
|
||||
if err != nil {
|
||||
return []uint32{}, err
|
||||
}
|
||||
if len(groups) == 0 {
|
||||
// if there are no additional groups; just return an empty set
|
||||
return []uint32{}, nil
|
||||
}
|
||||
addlGids := []uint32{}
|
||||
for _, grp := range groups {
|
||||
addlGids = append(addlGids, uint32(grp.Gid))
|
||||
}
|
||||
return addlGids, nil
|
||||
}
|
||||
|
||||
func isRootfsAbs(root string) bool {
|
||||
return filepath.IsAbs(root)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user