Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oci-unpack to handle UID/GID mappings #33

Open
glestaris opened this issue Oct 3, 2016 · 4 comments
Open

oci-unpack to handle UID/GID mappings #33

glestaris opened this issue Oct 3, 2016 · 4 comments

Comments

@glestaris
Copy link
Contributor

glestaris commented Oct 3, 2016

As discussed lately in #3, oci-unpack could also be handling UID/GID translation to prepare the unpacked image (rootfs) for a container that uses a user namespace with UID/GID mappings. There are, so far, the following use cases:

  1. Multiple mappings: the UID/GIDs defined in the tar-ball need to be translated accordingly.
  2. Single mapped user (host user X): all the files and directories of the rootfs are owned by X.
  3. Mapped users are less than the users defined in the tar-ball (by @cyphar)

I would propose extiending the oci-unpack interface by adding:

*--uid-mapping <Namespace UID>:<Host UID>:<Size> (similar to the /proc/$PID/uid_map structure). It can be provided multiple times.

  • --gid-mapping which handles the GID mappings similarly.
  • --fallback-uid <Namespace UID> When provided, if a tar entry UID is not mapped the unpacked file will be owned by <Namespace UID>. If the flag is not provided and a unmapped UID is encountered, oci-unpack should fail.

Grootfs is implementing the --uid-mapping and --gid-mapping flags but I would prefer this translation logic to live in oci-unpack.

@wking
Copy link
Contributor

wking commented Oct 3, 2016

On Mon, Oct 03, 2016 at 03:05:50PM -0700, George Lestaris wrote:

*--uid-mapping <Host UID>:<Namespace UID>:<Size> (similar to the /proc/$PID/uid_map structure). It can be provided multiple times.

  • --gid-mapping which handles the GID mappings similarly.
  • --fallback-uid <Namespace UID> When provided, if a tar entry UID
    is not mapped the unpacked file will be owned by <Namespace UID>. If the flag is not provided and a unmapped UID is
    encountered, oci-unpack should fail.

I don't think you need the first two, and --fallback-uid can always be
the current user. oci-unpack would need to learn an option to switch
between:

  1. Always chown, die on errors (this is Apply ownership in unpacked entries #3's --same-owner).
  2. Always chown, warn on errors (maybe --try-same-owner?).
  3. Never chown (this is Apply ownership in unpacked entries #3's default for non-root users, and would
    match --no-same-owner).

Then you can achieve your desired semantics by unpacking in a user
namespace that has your intended UID/GID mappings.

@glestaris
Copy link
Contributor Author

glestaris commented Oct 4, 2016

I agree that we can avoid something like --fallback-user. However, I think having oci-unpack dealing with translation is important. Imagine the following workflow:

oci-download --ref 3.2.5 oci://registry.opencontainers.org/redis ./redis-image
oci-unpack --ref 3.2.5 --uid-mapping 1000:0:1000 ./redis-image ./redis-bundle
cd ./redis-bundle
oci-runtime-tool generate --uidmappings 1000:0:1000 --args redis-server
runc create my-redis

If we have to create the user namespace before unpacking the rootfs we would either have to use unshare or call oci-unpack through runc (which would probably mean calling runc twice).

@wking
Copy link
Contributor

wking commented Oct 4, 2016

On Tue, Oct 04, 2016 at 01:30:55AM -0700, George Lestaris wrote:

oci-download --ref 3.2.5 oci://registry.opencontainers.org/redis ./redis-image
oci-unpack --ref 3.2.5 --uid-mapping 1000:0:1000 ./redis-image ./redis-bundle
cd ./redis-bundle
oci-runtime-tool generate --uidmappings 1000:0:1000 --args redis-server
runc create my-redis

If we have to create the user namespace before unpacking the rootfs
we would either have to use unshare or call oci-unpack through
runc (which would probably mean calling runc twice).

I don't mind calling unshare or runC for this. And the OCI spec is a
bit tedious, but here's the ccon version:

ccon -s '

{
"version": "0.1.0",
"namespaces": {
"user": {
"setgroups": true,
"uidMappings": [
{"containerID": 0, "hostID": 2000, "size": 10}
],
"gidMappings": [
{"containerID": 0, "hostID": 3000, "size": 10}
]
}
},
"process": {
"user": {
"uid": 0,
"gid": 0
},
"args": ["sh", "-c", "touch /tmp/a && chown 1:1 /tmp/a"]
}
}'

ls -l /tmp/a

-rw-r--r-- 1 2001 3001 0 Oct 4 10:11 /tmp/a

That's more typing than a two command line options, but you could wrap
it up in a script if you don't want to retype it. And it makes it
clear that without the ability to create such user-namespace mappings
to execute the container, there's not much point in such a mapped
unpacking.

@cyphar
Copy link
Member

cyphar commented Nov 5, 2016

To be honest, all I really want for umoci is if I can use an []idtools.IDMap (or whatever the runtime-spec equivalent is) to specify what translation I would like during unpacking. That's all I'm looking for here, because currently you need to run umoci as root (which is simply a non-starter for building things within OBS or KIWI).

The discussion in #3 about whether it can ever be "correct" to output such a rootfs is missing the point IMO. What matters is that I can set the correct owners inside the diff layers (whether or not I had to cheat to do it is a separate issue -- and outside the concern of the extraction API).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants