diff --git a/daemon/mgr/container_types.go b/daemon/mgr/container_types.go index 985da48ef..54a6e9155 100644 --- a/daemon/mgr/container_types.go +++ b/daemon/mgr/container_types.go @@ -17,6 +17,7 @@ import ( "github.com/containerd/containerd/mount" "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/sirupsen/logrus" ) var ( @@ -386,15 +387,17 @@ func (c *Container) SetSnapshotterMeta(mounts []mount.Mount) { // GetSpecificBasePath accepts a given path, look for whether the path is exist // within container, if has, returns container base path like BaseFS, if not, return empty string func (c *Container) GetSpecificBasePath(path string) string { - // first try container BaseFS, it is a general view, - if utils.IsFileExist(filepath.Join(c.BaseFS, path)) { - return c.BaseFS - } - - // then try lower and upper directory, since overlay filesystem support only. - for _, prefixPath := range c.Snapshotter.Data { - if utils.IsFileExist(filepath.Join(prefixPath, path)) { - return prefixPath + logrus.Debugf("GetSpecificBasePath, snapshotter data: (%v)", c.Snapshotter.Data) + + // try lower and upper directory, since overlay filesystem support only. + for _, key := range []string{"MergedDir", "UpperDir", "LowerDir"} { + if prefixPath, ok := c.Snapshotter.Data[key]; ok && prefixPath != "" { + for _, p := range strings.Split(prefixPath, ":") { + absPath := filepath.Join(p, path) + if utils.IsFileExist(absPath) { + return absPath + } + } } } diff --git a/daemon/mgr/spec.go b/daemon/mgr/spec.go index 5a916fc71..20899d556 100644 --- a/daemon/mgr/spec.go +++ b/daemon/mgr/spec.go @@ -33,6 +33,11 @@ func createSpec(ctx context.Context, c *Container, specWrapper *SpecWrapper) err if err != nil { return errors.Wrapf(err, "failed to generate spec: %s", c.ID) } + + // fix https://github.com/opencontainers/runc/issues/705 + // use ssh connect to container, can't use sudo command. + s.Process.NoNewPrivileges = false + specWrapper.s = s s.Hostname = c.Config.Hostname.String() diff --git a/pkg/user/user.go b/pkg/user/user.go index 00ec50fd8..0f9ae9bc4 100644 --- a/pkg/user/user.go +++ b/pkg/user/user.go @@ -5,9 +5,13 @@ import ( "bytes" "fmt" "io/ioutil" + "os" "path/filepath" "strconv" "strings" + + "github.com/opencontainers/runc/libcontainer/user" + "github.com/sirupsen/logrus" ) var ( @@ -45,13 +49,45 @@ type gidParser struct { // Get accepts user and group slice, return valid uid, gid and additional gids. // Through Get is a interface returns all user informations runtime-spec need, // GetUser, GetIntegerID, GetAdditionalGids still can be used independently. -func Get(passwdPath, groupPath, user string, groups []string) (uint32, uint32, []uint32, error) { - uid, gid, err := GetUser(passwdPath, groupPath, user) +func Get(passwdPath, groupPath, username string, groups []string) (uint32, uint32, []uint32, error) { + logrus.Debugf("get users, passwd path: (%s), group path: (%s), username: (%s), groups: (%v)", + passwdPath, groupPath, username, groups) + + if passwdPath == "" || groupPath == "" { + logrus.Warn("get passwd file or group file is nil") + } + + passwdFile, err := os.Open(passwdPath) + if err == nil { + defer passwdFile.Close() + } + + groupFile, err := os.Open(groupPath) + if err == nil { + defer groupFile.Close() + } + + execUser, err := user.GetExecUser(username, nil, passwdFile, groupFile) if err != nil { return 0, 0, nil, err } - return uid, gid, GetAdditionalGids(groups), nil + var addGroups []int + if len(groups) > 0 { + addGroups, err = user.GetAdditionalGroups(groups, groupFile) + if err != nil { + return 0, 0, nil, err + } + } + uid := uint32(execUser.Uid) + gid := uint32(execUser.Gid) + sgids := append(execUser.Sgids, addGroups...) + var additionalGids []uint32 + for _, g := range sgids { + additionalGids = append(additionalGids, uint32(g)) + } + + return uid, gid, additionalGids, nil } // GetUser accepts user string like :, and transfers them to format valid uid:gid.