run: user LookupId
Signed-off-by: Yoan Blanc <yoan@dosimple.ch>
This commit is contained in:
parent
c553184416
commit
c7028c6d2f
|
|
@ -20,8 +20,16 @@ RUN touch $HOME/hello
|
|||
# testuser1 with the default home created by useradd.
|
||||
|
||||
RUN groupadd testgroup && \
|
||||
useradd --create-home --gid testgroup alice
|
||||
useradd --create-home --gid testgroup alice && \
|
||||
useradd --create-home --uid 1111 --home-dir /home/john --gid testgroup bob
|
||||
|
||||
USER alice:testgroup
|
||||
|
||||
RUN touch $HOME/hello
|
||||
|
||||
USER bob
|
||||
RUN touch $HOME/hello
|
||||
|
||||
USER root
|
||||
|
||||
USER 1111
|
||||
RUN touch $HOME/world
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ type RunCommand struct {
|
|||
|
||||
// for testing
|
||||
var (
|
||||
userLookup = user.Lookup
|
||||
userLookup = user.Lookup
|
||||
userLookupId = user.LookupId
|
||||
)
|
||||
|
||||
func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
||||
|
|
@ -68,18 +69,29 @@ func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
|
|||
cmd.Stderr = os.Stderr
|
||||
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
||||
var userStr string
|
||||
|
||||
u := config.User
|
||||
userAndGroup := strings.Split(u, ":")
|
||||
userStr, err := util.ResolveEnvironmentReplacement(userAndGroup[0], replacementEnvs, false)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "resolving user %s", userAndGroup[0])
|
||||
}
|
||||
|
||||
// If specified, run the command as a specific user
|
||||
if config.User != "" {
|
||||
userStr = config.User
|
||||
uid, gid, err := util.GetUIDAndGIDFromString(config.User, true)
|
||||
if userStr != "" {
|
||||
uid, gid, err := util.GetUIDAndGIDFromString(userStr, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
|
||||
}
|
||||
|
||||
cmd.Env = addDefaultHOME(userStr, replacementEnvs)
|
||||
env, err := addDefaultHOME(userStr, replacementEnvs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "adding default HOME variable")
|
||||
}
|
||||
|
||||
cmd.Env = env
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return errors.Wrap(err, "starting command")
|
||||
|
|
@ -102,32 +114,31 @@ func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
|
|||
}
|
||||
|
||||
// addDefaultHOME adds the default value for HOME if it isn't already set
|
||||
func addDefaultHOME(u string, envs []string) []string {
|
||||
func addDefaultHOME(u string, envs []string) ([]string, error) {
|
||||
for _, env := range envs {
|
||||
split := strings.SplitN(env, "=", 2)
|
||||
if split[0] == constants.HOME {
|
||||
return envs
|
||||
return envs, nil
|
||||
}
|
||||
}
|
||||
|
||||
// If user isn't set, set default value of HOME
|
||||
if u == "" || u == constants.RootUser {
|
||||
return append(envs, fmt.Sprintf("%s=%s", constants.HOME, constants.DefaultHOMEValue))
|
||||
return append(envs, fmt.Sprintf("%s=%s", constants.HOME, constants.DefaultHOMEValue)), nil
|
||||
}
|
||||
|
||||
// If user is set to username, set value of HOME to /home/${user}
|
||||
// Otherwise the user is set to uid and HOME is /
|
||||
home := "/"
|
||||
userObj, err := userLookup(u)
|
||||
if err == nil {
|
||||
if userObj.HomeDir != "" {
|
||||
home = userObj.HomeDir
|
||||
if uo, e := userLookupId(u); e == nil {
|
||||
userObj = uo
|
||||
} else {
|
||||
home = fmt.Sprintf("/home/%s", userObj.Username)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return append(envs, fmt.Sprintf("%s=%s", constants.HOME, home))
|
||||
return append(envs, fmt.Sprintf("%s=%s", constants.HOME, userObj.HomeDir)), nil
|
||||
}
|
||||
|
||||
// String returns some information about the command for the image config
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package commands
|
|||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
|
|
@ -33,11 +34,13 @@ import (
|
|||
|
||||
func Test_addDefaultHOME(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
user string
|
||||
mockUser *user.User
|
||||
initial []string
|
||||
expected []string
|
||||
name string
|
||||
user string
|
||||
mockUser *user.User
|
||||
lookupError error
|
||||
mockUserId *user.User
|
||||
initial []string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "HOME already set",
|
||||
|
|
@ -78,31 +81,19 @@ func Test_addDefaultHOME(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "HOME not set and user set",
|
||||
user: "www-add",
|
||||
mockUser: &user.User{
|
||||
Username: "www-add",
|
||||
name: "USER is set using the UID",
|
||||
user: "newuser",
|
||||
lookupError: errors.New("User not found"),
|
||||
mockUserId: &user.User{
|
||||
Username: "user",
|
||||
HomeDir: "/home/user",
|
||||
},
|
||||
initial: []string{
|
||||
"PATH=/something/else",
|
||||
},
|
||||
expected: []string{
|
||||
"PATH=/something/else",
|
||||
"HOME=/home/www-add",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "HOME not set and user is set",
|
||||
user: "newuser",
|
||||
mockUser: &user.User{
|
||||
Username: "newuser",
|
||||
},
|
||||
initial: []string{
|
||||
"PATH=/something/else",
|
||||
},
|
||||
expected: []string{
|
||||
"PATH=/something/else",
|
||||
"HOME=/home/newuser",
|
||||
"HOME=/home/user",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -122,10 +113,14 @@ func Test_addDefaultHOME(t *testing.T) {
|
|||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
userLookup = func(username string) (*user.User, error) { return test.mockUser, nil }
|
||||
defer func() { userLookup = user.Lookup }()
|
||||
actual := addDefaultHOME(test.user, test.initial)
|
||||
testutil.CheckErrorAndDeepEqual(t, false, nil, test.expected, actual)
|
||||
userLookup = func(username string) (*user.User, error) { return test.mockUser, test.lookupError }
|
||||
userLookupId = func(username string) (*user.User, error) { return test.mockUserId, nil }
|
||||
defer func() {
|
||||
userLookup = user.Lookup
|
||||
userLookupId = user.LookupId
|
||||
}()
|
||||
actual, err := addDefaultHOME(test.user, test.initial)
|
||||
testutil.CheckErrorAndDeepEqual(t, false, err, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue