Refactor get uid/gid from path

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
Michael Crosby 2018-01-16 12:01:31 -05:00
parent bbb5b2f15e
commit 5b042945b0

View File

@ -257,7 +257,6 @@ func WithUIDGID(uid, gid uint32) SpecOpts {
// uid, and not returns error. // uid, and not returns error.
func WithUserID(uid uint32) SpecOpts { func WithUserID(uid uint32) SpecOpts {
return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) { return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) {
// TODO: support non-snapshot rootfs
if c.Snapshotter == "" { if c.Snapshotter == "" {
return errors.Errorf("no snapshotter set for container") return errors.Errorf("no snapshotter set for container")
} }
@ -269,33 +268,18 @@ func WithUserID(uid uint32) SpecOpts {
if err != nil { if err != nil {
return err return err
} }
return mount.WithTempMount(ctx, mounts, func(root string) error { return mount.WithTempMount(ctx, mounts, func(root string) error {
ppath, err := fs.RootPath(root, "/etc/passwd") uuid, ugid, err := getUidGidFromPath(root, func(u user.User) bool {
if err != nil {
return err
}
f, err := os.Open(ppath)
if err != nil {
if os.IsNotExist(err) {
s.Process.User.UID, s.Process.User.GID = uid, uid
return nil
}
return err
}
defer f.Close()
users, err := user.ParsePasswdFilter(f, func(u user.User) bool {
return u.Uid == int(uid) return u.Uid == int(uid)
}) })
if err != nil { if err != nil {
return err if os.IsNotExist(err) || err == errNoUsersFound {
}
if len(users) == 0 {
s.Process.User.UID, s.Process.User.GID = uid, uid s.Process.User.UID, s.Process.User.GID = uid, uid
return nil return nil
} }
u := users[0] return err
s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid) }
s.Process.User.UID, s.Process.User.GID = uuid, ugid
return nil return nil
}) })
} }
@ -306,7 +290,6 @@ func WithUserID(uid uint32) SpecOpts {
// does not exist, or the username is not found in /etc/passwd, // does not exist, or the username is not found in /etc/passwd,
// it returns error. // it returns error.
func WithUsername(username string) SpecOpts { func WithUsername(username string) SpecOpts {
// TODO: support non-snapshot rootfs
return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) { return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) {
if c.Snapshotter == "" { if c.Snapshotter == "" {
return errors.Errorf("no snapshotter set for container") return errors.Errorf("no snapshotter set for container")
@ -320,27 +303,37 @@ 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 {
ppath, err := fs.RootPath(root, "/etc/passwd") uid, gid, err := getUidGidFromPath(root, func(u user.User) bool {
if err != nil {
return err
}
f, err := os.Open(ppath)
if err != nil {
return err
}
defer f.Close()
users, err := user.ParsePasswdFilter(f, func(u user.User) bool {
return u.Name == username return u.Name == username
}) })
if err != nil { if err != nil {
return err return err
} }
if len(users) == 0 { s.Process.User.UID, s.Process.User.GID = uid, gid
return errors.Errorf("no users found for %s", username)
}
u := users[0]
s.Process.User.UID, s.Process.User.GID = uint32(u.Uid), uint32(u.Gid)
return nil return nil
}) })
} }
} }
var errNoUsersFound = errors.New("no users found")
func getUidGidFromPath(root string, filter func(user.User) bool) (uid, gid uint32, err error) {
ppath, err := fs.RootPath(root, "/etc/passwd")
if err != nil {
return 0, 0, err
}
f, err := os.Open(ppath)
if err != nil {
return 0, 0, err
}
defer f.Close()
users, err := user.ParsePasswdFilter(f, filter)
if err != nil {
return 0, 0, err
}
if len(users) == 0 {
return 0, 0, errNoUsersFound
}
u := users[0]
return uint32(u.Uid), uint32(u.Gid), nil
}