Merge pull request #2641 from Random-Liu/support-uid-in-additional-group

Support uid in WithAdditionalGIDs.
This commit is contained in:
Michael Crosby 2018-09-13 18:51:22 -04:00 committed by GitHub
commit 1950f791d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -478,12 +478,13 @@ func WithUser(userstr string) SpecOpts {
} }
f := func(root string) error { f := func(root string) error {
if username != "" { if username != "" {
uid, _, err = getUIDGIDFromPath(root, func(u user.User) bool { user, err := getUserFromPath(root, func(u user.User) bool {
return u.Name == username return u.Name == username
}) })
if err != nil { if err != nil {
return err return err
} }
uid = uint32(user.Uid)
} }
if groupname != "" { if groupname != "" {
gid, err = getGIDFromPath(root, func(g user.Group) bool { gid, err = getGIDFromPath(root, func(g user.Group) bool {
@ -541,7 +542,7 @@ func WithUserID(uid uint32) SpecOpts {
if !isRootfsAbs(s.Root.Path) { if !isRootfsAbs(s.Root.Path) {
return errors.Errorf("rootfs absolute path is required") return errors.Errorf("rootfs absolute path is required")
} }
uuid, ugid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { user, err := getUserFromPath(s.Root.Path, func(u user.User) bool {
return u.Uid == int(uid) return u.Uid == int(uid)
}) })
if err != nil { if err != nil {
@ -551,7 +552,7 @@ func WithUserID(uid uint32) SpecOpts {
} }
return err return err
} }
s.Process.User.UID, s.Process.User.GID = uuid, ugid s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil return nil
} }
@ -567,7 +568,7 @@ func WithUserID(uid uint32) SpecOpts {
return err return err
} }
return mount.WithTempMount(ctx, mounts, func(root string) error { return mount.WithTempMount(ctx, mounts, func(root string) error {
uuid, ugid, err := getUIDGIDFromPath(root, func(u user.User) bool { user, err := getUserFromPath(root, func(u user.User) bool {
return u.Uid == int(uid) return u.Uid == int(uid)
}) })
if err != nil { if err != nil {
@ -577,7 +578,7 @@ func WithUserID(uid uint32) SpecOpts {
} }
return err return err
} }
s.Process.User.UID, s.Process.User.GID = uuid, ugid s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil return nil
}) })
} }
@ -595,13 +596,13 @@ func WithUsername(username string) SpecOpts {
if !isRootfsAbs(s.Root.Path) { if !isRootfsAbs(s.Root.Path) {
return errors.Errorf("rootfs absolute path is required") return errors.Errorf("rootfs absolute path is required")
} }
uid, gid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool { user, err := getUserFromPath(s.Root.Path, func(u user.User) bool {
return u.Name == username return u.Name == username
}) })
if err != nil { if err != nil {
return err return err
} }
s.Process.User.UID, s.Process.User.GID = uid, gid s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil return nil
} }
if c.Snapshotter == "" { if c.Snapshotter == "" {
@ -616,13 +617,13 @@ func WithUsername(username string) SpecOpts {
return err return err
} }
return mount.WithTempMount(ctx, mounts, func(root string) error { return mount.WithTempMount(ctx, mounts, func(root string) error {
uid, gid, err := getUIDGIDFromPath(root, func(u user.User) bool { user, err := getUserFromPath(root, func(u user.User) bool {
return u.Name == username return u.Name == username
}) })
if err != nil { if err != nil {
return err return err
} }
s.Process.User.UID, s.Process.User.GID = uid, gid s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil return nil
}) })
} else if s.Windows != nil { } else if s.Windows != nil {
@ -636,43 +637,27 @@ func WithUsername(username string) SpecOpts {
// WithAdditionalGIDs sets the OCI spec's additionalGids array to any additional groups listed // 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 // for a particular user in the /etc/groups file of the image's root filesystem
func WithAdditionalGIDs(username string) SpecOpts { // The passed in user can be either a uid or a username.
func WithAdditionalGIDs(userstr string) SpecOpts {
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) { return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
setProcess(s) setProcess(s)
if c.Snapshotter == "" && c.SnapshotKey == "" { setAdditionalGids := func(root string) error {
if !isRootfsAbs(s.Root.Path) { var username string
return errors.Errorf("rootfs absolute path is required") uid, err := strconv.Atoi(userstr)
} if err == nil {
gids, err := getSupplementalGroupsFromPath(s.Root.Path, func(g user.Group) bool { user, err := getUserFromPath(root, func(u user.User) bool {
// we only want supplemental groups return u.Uid == uid
if g.Name == username {
return false
}
for _, entry := range g.List {
if entry == username {
return true
}
}
return false
}) })
if err != nil { if err != nil {
return err if os.IsNotExist(err) || err == errNoUsersFound {
}
s.Process.User.AdditionalGids = gids
return nil 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 err
} }
return mount.WithTempMount(ctx, mounts, func(root string) error { username = user.Name
} else {
username = userstr
}
gids, err := getSupplementalGroupsFromPath(root, func(g user.Group) bool { gids, err := getSupplementalGroupsFromPath(root, func(g user.Group) bool {
// we only want supplemental groups // we only want supplemental groups
if g.Name == username { if g.Name == username {
@ -686,11 +671,32 @@ func WithAdditionalGIDs(username string) SpecOpts {
return false return false
}) })
if err != nil { if err != nil {
if os.IsNotExist(err) {
return nil
}
return err return err
} }
s.Process.User.AdditionalGids = gids s.Process.User.AdditionalGids = gids
return nil return nil
}) }
if c.Snapshotter == "" && c.SnapshotKey == "" {
if !isRootfsAbs(s.Root.Path) {
return errors.Errorf("rootfs absolute path is required")
}
return setAdditionalGids(s.Root.Path)
}
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, setAdditionalGids)
} }
} }
@ -741,20 +747,19 @@ func WithAmbientCapabilities(caps []string) SpecOpts {
var errNoUsersFound = errors.New("no users found") var errNoUsersFound = errors.New("no users found")
func getUIDGIDFromPath(root string, filter func(user.User) bool) (uid, gid uint32, err error) { func getUserFromPath(root string, filter func(user.User) bool) (user.User, error) {
ppath, err := fs.RootPath(root, "/etc/passwd") ppath, err := fs.RootPath(root, "/etc/passwd")
if err != nil { if err != nil {
return 0, 0, err return user.User{}, err
} }
users, err := user.ParsePasswdFileFilter(ppath, filter) users, err := user.ParsePasswdFileFilter(ppath, filter)
if err != nil { if err != nil {
return 0, 0, err return user.User{}, err
} }
if len(users) == 0 { if len(users) == 0 {
return 0, 0, errNoUsersFound return user.User{}, errNoUsersFound
} }
u := users[0] return users[0], nil
return uint32(u.Uid), uint32(u.Gid), nil
} }
var errNoGroupsFound = errors.New("no groups found") var errNoGroupsFound = errors.New("no groups found")