image-tools
image-tools copied to clipboard
oci-unpack to handle UID/GID mappings
As discussed lately in https://github.com/opencontainers/image-tools/pull/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:
- Multiple mappings: the UID/GIDs defined in the tar-ball need to be translated accordingly.
- Single mapped user (host user X): all the files and directories of the rootfs are owned by X.
- 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
.
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:
- Always chown, die on errors (this is #3's --same-owner).
- Always chown, warn on errors (maybe --try-same-owner?).
- Never chown (this is #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.
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).
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 calloci-unpack
throughrunc
(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.
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).