diff options
author | W. Trevor King <wking@tremily.us> | 2018-12-04 11:46:17 -0800 |
---|---|---|
committer | W. Trevor King <wking@tremily.us> | 2018-12-04 12:00:42 -0800 |
commit | 650f95cb06cb5a4e979fbe9f9fcd125a229e4e09 (patch) | |
tree | 596e05f14d58d6993667452ce3c111642f593da8 | |
parent | 480a179f019c343d8f778c0e0576390e7130b375 (diff) | |
download | podman-650f95cb06cb5a4e979fbe9f9fcd125a229e4e09.tar.gz podman-650f95cb06cb5a4e979fbe9f9fcd125a229e4e09.tar.bz2 podman-650f95cb06cb5a4e979fbe9f9fcd125a229e4e09.zip |
libpod/container_internal_linux: Allow gids that aren't in the group file
When an image config sets config.User [1] to a numeric group (like
1000:1000), but those values do not exist in the container's
/etc/group, libpod is currently breaking:
$ podman run --rm registry.svc.ci.openshift.org/ci-op-zvml7cd6/pipeline:installer --help
error creating temporary passwd file for container 228f6e9943d6f18b93c19644e9b619ec4d459a3e0eb31680e064eeedf6473678: unable to get gid 1000 from group file: no matching entries in group file
However, the OCI spec requires converters to copy numeric uid and gid
to the runtime config verbatim [2].
With this commit, I'm frontloading the "is groupspec an integer?"
check and only bothering with lookup.GetGroup when it was not.
I've also removed a few .Mounted checks, which are originally from
00d38cb3 (podman create/run need to load information from the image,
2017-12-18, #110). We don't need a mounted container filesystem to
translate integers. And when the lookup code needs to fall back to
the mounted root to translate names, it can handle erroring out
internally (and looking it over, it seems to do that already).
[1]: https://github.com/opencontainers/image-spec/blame/v1.0.1/config.md#L118-L123
[2]: https://github.com/opencontainers/image-spec/blame/v1.0.1/conversion.md#L70
Signed-off-by: W. Trevor King <wking@tremily.us>
-rw-r--r-- | libpod/container_internal_linux.go | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 8861d7728..b72eefdf1 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -238,9 +238,6 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } if c.config.User != "" { - if !c.state.Mounted { - return nil, errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate User field", c.ID()) - } // User and Group must go together g.SetProcessUID(uint32(execUser.Uid)) g.SetProcessGID(uint32(execUser.Gid)) @@ -248,9 +245,6 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { // Add addition groups if c.config.GroupAdd is not empty if len(c.config.Groups) > 0 { - if !c.state.Mounted { - return nil, errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to add additional groups", c.ID()) - } gids, _ := lookup.GetContainerGroups(c.config.Groups, c.state.Mountpoint, nil) for _, gid := range gids { g.AddProcessAdditionalGid(gid) @@ -802,7 +796,6 @@ func (c *Container) generateHosts() (string, error) { func (c *Container) generatePasswd() (string, error) { var ( groupspec string - group *user.Group gid int ) if c.config.User == "" { @@ -827,17 +820,16 @@ func (c *Container) generatePasswd() (string, error) { return "", nil } if groupspec != "" { - if !c.state.Mounted { - return "", errors.Wrapf(ErrCtrStateInvalid, "container %s must be mounted in order to translate group field for passwd record", c.ID()) - } - group, err = lookup.GetGroup(c.state.Mountpoint, groupspec) - if err != nil { - if err == user.ErrNoGroupEntries { + ugid, err := strconv.ParseUint(groupspec, 10, 32) + if err == nil { + gid = int(ugid) + } else { + group, err := lookup.GetGroup(c.state.Mountpoint, groupspec) + if err != nil { return "", errors.Wrapf(err, "unable to get gid %s from group file", groupspec) } - return "", err + gid = group.Gid } - gid = group.Gid } originPasswdFile := filepath.Join(c.state.Mountpoint, "/etc/passwd") orig, err := ioutil.ReadFile(originPasswdFile) |