Merge pull request #2009 from crosbymichael/user-path
Support getting uid/gid from rootfs path
This commit is contained in:
commit
aaf930eaf9
@ -257,7 +257,24 @@ 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 == "" && c.SnapshotKey == "" {
|
||||||
|
if !isRootfsAbs(s.Root.Path) {
|
||||||
|
return errors.Errorf("rootfs absolute path is required")
|
||||||
|
}
|
||||||
|
uuid, ugid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool {
|
||||||
|
return u.Uid == int(uid)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) || err == errNoUsersFound {
|
||||||
|
s.Process.User.UID, s.Process.User.GID = uid, uid
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Process.User.UID, s.Process.User.GID = uuid, ugid
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
if c.Snapshotter == "" {
|
if c.Snapshotter == "" {
|
||||||
return errors.Errorf("no snapshotter set for container")
|
return errors.Errorf("no snapshotter set for container")
|
||||||
}
|
}
|
||||||
@ -269,33 +286,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,8 +308,20 @@ 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 == "" && c.SnapshotKey == "" {
|
||||||
|
if !isRootfsAbs(s.Root.Path) {
|
||||||
|
return errors.Errorf("rootfs absolute path is required")
|
||||||
|
}
|
||||||
|
uid, gid, err := getUIDGIDFromPath(s.Root.Path, func(u user.User) bool {
|
||||||
|
return u.Name == username
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Process.User.UID, s.Process.User.GID = uid, gid
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if c.Snapshotter == "" {
|
if c.Snapshotter == "" {
|
||||||
return errors.Errorf("no snapshotter set for container")
|
return errors.Errorf("no snapshotter set for container")
|
||||||
}
|
}
|
||||||
@ -320,27 +334,41 @@ 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
|
||||||
|
}
|
||||||
|
|
||||||
|
func isRootfsAbs(root string) bool {
|
||||||
|
return filepath.IsAbs(root)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user