Skip to content

Commit

Permalink
Merge pull request #4017 from thaJeztah/migrate_libcontainer_user
Browse files Browse the repository at this point in the history
Deprecate libcontainer/user, and migrate to github.com/moby/sys/user
  • Loading branch information
AkihiroSuda committed Sep 21, 2023
2 parents 1614cab + d9ea71b commit 1d9b158
Show file tree
Hide file tree
Showing 12 changed files with 437 additions and 532 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/docker/go-units v0.5.0
github.com/godbus/dbus/v5 v5.1.0
github.com/moby/sys/mountinfo v0.6.2
github.com/moby/sys/user v0.1.0
github.com/mrunalp/fileutils v0.5.0
github.com/opencontainers/runtime-spec v1.1.1-0.20230823135140-4fec88fd00a4
github.com/opencontainers/selinux v1.11.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/opencontainers/runtime-spec v1.1.1-0.20230823135140-4fec88fd00a4 h1:EctkgBjZ1y4q+sibyuuIgiKpa0QSd2elFtSSdNvBVow=
Expand Down
2 changes: 1 addition & 1 deletion libcontainer/init_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"strings"

"github.com/containerd/console"
"github.com/moby/sys/user"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"github.com/vishvananda/netlink"
Expand All @@ -22,7 +23,6 @@ import (
"github.com/opencontainers/runc/libcontainer/cgroups"
"github.com/opencontainers/runc/libcontainer/configs"
"github.com/opencontainers/runc/libcontainer/system"
"github.com/opencontainers/runc/libcontainer/user"
"github.com/opencontainers/runc/libcontainer/utils"
)

Expand Down
81 changes: 81 additions & 0 deletions libcontainer/user/lookup_deprecated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package user

import (
"io"

"github.com/moby/sys/user"
)

// LookupUser looks up a user by their username in /etc/passwd. If the user
// cannot be found (or there is no /etc/passwd file on the filesystem), then
// LookupUser returns an error.
func LookupUser(username string) (user.User, error) {
return user.LookupUser(username)
}

// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot
// be found (or there is no /etc/passwd file on the filesystem), then LookupId
// returns an error.
func LookupUid(uid int) (user.User, error) { //nolint:revive // ignore var-naming: func LookupUid should be LookupUID
return user.LookupUid(uid)
}

// LookupGroup looks up a group by its name in /etc/group. If the group cannot
// be found (or there is no /etc/group file on the filesystem), then LookupGroup
// returns an error.
func LookupGroup(groupname string) (user.Group, error) {
return user.LookupGroup(groupname)
}

// LookupGid looks up a group by its group id in /etc/group. If the group cannot
// be found (or there is no /etc/group file on the filesystem), then LookupGid
// returns an error.
func LookupGid(gid int) (user.Group, error) {
return user.LookupGid(gid)
}

func GetPasswdPath() (string, error) {
return user.GetPasswdPath()
}

func GetPasswd() (io.ReadCloser, error) {
return user.GetPasswd()
}

func GetGroupPath() (string, error) {
return user.GetGroupPath()
}

func GetGroup() (io.ReadCloser, error) {
return user.GetGroup()
}

// CurrentUser looks up the current user by their user id in /etc/passwd. If the
// user cannot be found (or there is no /etc/passwd file on the filesystem),
// then CurrentUser returns an error.
func CurrentUser() (user.User, error) {
return user.CurrentUser()
}

// CurrentGroup looks up the current user's group by their primary group id's
// entry in /etc/passwd. If the group cannot be found (or there is no
// /etc/group file on the filesystem), then CurrentGroup returns an error.
func CurrentGroup() (user.Group, error) {
return user.CurrentGroup()
}

func CurrentUserSubUIDs() ([]user.SubID, error) {
return user.CurrentUserSubUIDs()
}

func CurrentUserSubGIDs() ([]user.SubID, error) {
return user.CurrentUserSubGIDs()
}

func CurrentProcessUIDMap() ([]user.IDMap, error) {
return user.CurrentProcessUIDMap()
}

func CurrentProcessGIDMap() ([]user.IDMap, error) {
return user.CurrentProcessGIDMap()
}
146 changes: 146 additions & 0 deletions libcontainer/user/user_deprecated.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// Package user is an alias for [github.com/moby/sys/user].
//
// Deprecated: use [github.com/moby/sys/user].
package user

import (
"io"

"github.com/moby/sys/user"
)

var (
// ErrNoPasswdEntries is returned if no matching entries were found in /etc/group.
ErrNoPasswdEntries = user.ErrNoPasswdEntries
// ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd.
ErrNoGroupEntries = user.ErrNoGroupEntries
// ErrRange is returned if a UID or GID is outside of the valid range.
ErrRange = user.ErrRange
)

type (
User = user.User

Group = user.Group

// SubID represents an entry in /etc/sub{u,g}id.
SubID = user.SubID

// IDMap represents an entry in /proc/PID/{u,g}id_map.
IDMap = user.IDMap

ExecUser = user.ExecUser
)

func ParsePasswdFile(path string) ([]user.User, error) {
return user.ParsePasswdFile(path)
}

func ParsePasswd(passwd io.Reader) ([]user.User, error) {
return user.ParsePasswd(passwd)
}

func ParsePasswdFileFilter(path string, filter func(user.User) bool) ([]user.User, error) {
return user.ParsePasswdFileFilter(path, filter)
}

func ParsePasswdFilter(r io.Reader, filter func(user.User) bool) ([]user.User, error) {
return user.ParsePasswdFilter(r, filter)
}

func ParseGroupFile(path string) ([]user.Group, error) {
return user.ParseGroupFile(path)
}

func ParseGroup(group io.Reader) ([]user.Group, error) {
return user.ParseGroup(group)
}

func ParseGroupFileFilter(path string, filter func(user.Group) bool) ([]user.Group, error) {
return user.ParseGroupFileFilter(path, filter)
}

func ParseGroupFilter(r io.Reader, filter func(user.Group) bool) ([]user.Group, error) {
return user.ParseGroupFilter(r, filter)
}

// GetExecUserPath is a wrapper for GetExecUser. It reads data from each of the
// given file paths and uses that data as the arguments to GetExecUser. If the
// files cannot be opened for any reason, the error is ignored and a nil
// io.Reader is passed instead.
func GetExecUserPath(userSpec string, defaults *user.ExecUser, passwdPath, groupPath string) (*user.ExecUser, error) {
return user.GetExecUserPath(userSpec, defaults, passwdPath, groupPath)
}

// GetExecUser parses a user specification string (using the passwd and group
// readers as sources for /etc/passwd and /etc/group data, respectively). In
// the case of blank fields or missing data from the sources, the values in
// defaults is used.
//
// GetExecUser will return an error if a user or group literal could not be
// found in any entry in passwd and group respectively.
//
// Examples of valid user specifications are:
// - ""
// - "user"
// - "uid"
// - "user:group"
// - "uid:gid
// - "user:gid"
// - "uid:group"
//
// It should be noted that if you specify a numeric user or group id, they will
// not be evaluated as usernames (only the metadata will be filled). So attempting
// to parse a user with user.Name = "1337" will produce the user with a UID of
// 1337.
func GetExecUser(userSpec string, defaults *user.ExecUser, passwd, group io.Reader) (*user.ExecUser, error) {
return user.GetExecUser(userSpec, defaults, passwd, group)
}

// GetAdditionalGroups looks up a list of groups by name or group id
// against the given /etc/group formatted data. If a group name cannot
// be found, an error will be returned. If a group id cannot be found,
// or the given group data is nil, the id will be returned as-is
// provided it is in the legal range.
func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {
return user.GetAdditionalGroups(additionalGroups, group)
}

// GetAdditionalGroupsPath is a wrapper around GetAdditionalGroups
// that opens the groupPath given and gives it as an argument to
// GetAdditionalGroups.
func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) {
return user.GetAdditionalGroupsPath(additionalGroups, groupPath)
}

func ParseSubIDFile(path string) ([]user.SubID, error) {
return user.ParseSubIDFile(path)
}

func ParseSubID(subid io.Reader) ([]user.SubID, error) {
return user.ParseSubID(subid)
}

func ParseSubIDFileFilter(path string, filter func(user.SubID) bool) ([]user.SubID, error) {
return user.ParseSubIDFileFilter(path, filter)
}

func ParseSubIDFilter(r io.Reader, filter func(user.SubID) bool) ([]user.SubID, error) {
return user.ParseSubIDFilter(r, filter)
}

func ParseIDMapFile(path string) ([]user.IDMap, error) {
return user.ParseIDMapFile(path)
}

func ParseIDMap(r io.Reader) ([]user.IDMap, error) {
return user.ParseIDMap(r)
}

func ParseIDMapFileFilter(path string, filter func(user.IDMap) bool) ([]user.IDMap, error) {
return user.ParseIDMapFileFilter(path, filter)
}

func ParseIDMapFilter(r io.Reader, filter func(user.IDMap) bool) ([]user.IDMap, error) {
return user.ParseIDMapFilter(r, filter)
}

0 comments on commit 1d9b158

Please sign in to comment.