Skip to content

Commit

Permalink
fix: work around issue with user.Lookup not returning UnknownUserError (
Browse files Browse the repository at this point in the history
#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.*"
...
```
  • Loading branch information
benhoyt authored Jun 11, 2024
1 parent 85e9a1c commit 22cdf7a
Showing 1 changed file with 18 additions and 0 deletions.
18 changes: 18 additions & 0 deletions internals/osutil/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"os"
"os/user"
"strconv"
"strings"
"syscall"

"github.com/canonical/pebble/internals/osutil/sys"
)
Expand All @@ -27,6 +29,8 @@ var (
userCurrent = user.Current
userLookup = user.Lookup
userLookupGroup = user.LookupGroup

enoentMessage = syscall.ENOENT.Error()
)

// RealUser finds the user behind a sudo invocation when root, if applicable
Expand Down Expand Up @@ -56,6 +60,12 @@ func RealUser() (*user.User, error) {
if _, ok := err.(user.UnknownUserError); ok {
return cur, nil
}
// Workaround for https://github.com/golang/go/issues/67912, until our
// minimum Go version has a fix for that. In short, user.Lookup sometimes
// doesn't return UnknownUserError when it should.
if err != nil && strings.Contains(err.Error(), enoentMessage) {
return cur, nil
}
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -90,6 +100,10 @@ func NormalizeUidGid(uid, gid *int, username, group string) (*int, *int, error)
if username != "" {
u, err := userLookup(username)
if err != nil {
if strings.Contains(err.Error(), enoentMessage) {
// Better error message to work around https://github.com/golang/go/issues/67912
return nil, nil, user.UnknownUserError(username)
}
return nil, nil, err
}
n, _ := strconv.Atoi(u.Uid)
Expand All @@ -107,6 +121,10 @@ func NormalizeUidGid(uid, gid *int, username, group string) (*int, *int, error)
if group != "" {
g, err := userLookupGroup(group)
if err != nil {
if strings.Contains(err.Error(), enoentMessage) {
// Better error message to work around https://github.com/golang/go/issues/67912
return nil, nil, user.UnknownGroupError(group)
}
return nil, nil, err
}
n, _ := strconv.Atoi(g.Gid)
Expand Down

0 comments on commit 22cdf7a

Please sign in to comment.