Skip to content

Commit 22cdf7a

Browse files
authored
fix: work around issue with user.Lookup not returning UnknownUserError (#427)
Per golang/go#67912, under some circumstances (on my machine) user.Lookup isn't returning UnknownUserError when it should. So before this fix I get the following test failures: ``` $ go test ./internals/osutil ... FAIL: user_test.go:44: userSuite.TestRealUser user_test.go:71: c.Assert(err, check.IsNil) ... value *errors.errorString = &errors.errorString{s:"user: lookup username guy: no such file or directory"} ("user: lookup username guy: no such file or directory") ... ``` And: ``` $ go test ./internals/daemon ... ---------------------------------------------------------------------- FAIL: api_files_test.go:1128: filesSuite.TestWriteErrors api_files_test.go:1195: checkFileResult(c, r.Result[4], pathUserNotFound, "generic-file-error", ".*unknown user.*") api_files_test.go:273: c.Check(r.Error.Message, Matches, errorMsg) ... value string = "cannot look up user and group: user: lookup username user-not-found: no such file or directory" ... regex string = ".*unknown user.*" api_files_test.go:1196: checkFileResult(c, r.Result[5], pathGroupNotFound, "generic-file-error", ".*unknown group.*") api_files_test.go:273: c.Check(r.Error.Message, Matches, errorMsg) ... value string = "cannot look up user and group: user: lookup groupname group-not-found: no such file or directory" ... regex string = ".*unknown group.*" ... ```
1 parent 85e9a1c commit 22cdf7a

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

internals/osutil/user.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import (
1919
"os"
2020
"os/user"
2121
"strconv"
22+
"strings"
23+
"syscall"
2224

2325
"github.com/canonical/pebble/internals/osutil/sys"
2426
)
@@ -27,6 +29,8 @@ var (
2729
userCurrent = user.Current
2830
userLookup = user.Lookup
2931
userLookupGroup = user.LookupGroup
32+
33+
enoentMessage = syscall.ENOENT.Error()
3034
)
3135

3236
// RealUser finds the user behind a sudo invocation when root, if applicable
@@ -56,6 +60,12 @@ func RealUser() (*user.User, error) {
5660
if _, ok := err.(user.UnknownUserError); ok {
5761
return cur, nil
5862
}
63+
// Workaround for https://github.com/golang/go/issues/67912, until our
64+
// minimum Go version has a fix for that. In short, user.Lookup sometimes
65+
// doesn't return UnknownUserError when it should.
66+
if err != nil && strings.Contains(err.Error(), enoentMessage) {
67+
return cur, nil
68+
}
5969
if err != nil {
6070
return nil, err
6171
}
@@ -90,6 +100,10 @@ func NormalizeUidGid(uid, gid *int, username, group string) (*int, *int, error)
90100
if username != "" {
91101
u, err := userLookup(username)
92102
if err != nil {
103+
if strings.Contains(err.Error(), enoentMessage) {
104+
// Better error message to work around https://github.com/golang/go/issues/67912
105+
return nil, nil, user.UnknownUserError(username)
106+
}
93107
return nil, nil, err
94108
}
95109
n, _ := strconv.Atoi(u.Uid)
@@ -107,6 +121,10 @@ func NormalizeUidGid(uid, gid *int, username, group string) (*int, *int, error)
107121
if group != "" {
108122
g, err := userLookupGroup(group)
109123
if err != nil {
124+
if strings.Contains(err.Error(), enoentMessage) {
125+
// Better error message to work around https://github.com/golang/go/issues/67912
126+
return nil, nil, user.UnknownGroupError(group)
127+
}
110128
return nil, nil, err
111129
}
112130
n, _ := strconv.Atoi(g.Gid)

0 commit comments

Comments
 (0)