If the last command that was run interactively inside the toolbox
container had returned with a non-zero return code, then exiting the
toolbox would trigger the fallback to /bin/bash, just like it would
happen if $SHELL was missing from the toolbox. This is because
'podman exec ...' relays the return code of the last command.
Therefore, don't rely on the return code of 'podman exec ...' and check
the availability of $SHELL upfront. This does leave it vulnerable to
races caused by the availability of $SHELL changing between the check
and the actual attempt to use it. However, file I/O is inherently racy,
and this is better than a spurious fallback.
Keep the name of the default interactive shell localized to 'enter' by
using a subshell because 'local' is not mandated by POSIX.
It bind mounts $DBUS_SYSTEM_BUS_ADDRESS, if present, and sets the
DBUS_SYSTEM_BUS_ADDRESS environment variable inside the toolbox.
Otherwise, it defaults to "unix:path=/var/run/dbus/system_bus_socket"
as defined in the D-Bus specification [1].
[1] https://dbus.freedesktop.org/doc/dbus-specification.html
Rootless podman shuld mount a tmpfs at /dev/shm by default. Until that
happens, it's worked around by explicitly specifying the mount point.
Also, the --shm-size flag isn't working with rootless podman [1], so
--tmpfs is used instead.
It tries to mimic the in-kernel tmpfs default [2] of using half the
amount of total RAM. If for some reason /proc/meminfo can't be parsed,
it falls back to using podman's default of 65536k for tmpfs. It's not
clear whether podman uses kibibytes or kilobytes for 'k'. The former
was picked here for consistency.
[1] https://github.com/containers/libpod/issues/1770
[2] https://www.kernel.org/doc/Documentation/filesystems/tmpfs.txthttps://github.com/debarshiray/fedora-toolbox/issues/9
It's the user's responsibility to install any non-default shell inside
the toolbox container.
NB: /bin/bash is the default shell according to /etc/default/useradd.
The base fedora-toolbox images for Fedoras 28, 29 and 30 are now
available from registry.fedoraproject.org. Hence it's no longer
mandatory to build them locally. If they are built locally, then the
local images will be preferred over the ones from the registry.
https://pagure.io/releng/issue/7874
Hard coding 'fedora-toolbox' instead of $0 was necessary to get a
pleasant layout while keeping the code simple. It's not a big deal
because once there's a build system in place most people will type
'fedora-toolbox', instead of the full path to the script.
Normally, registry.fedoraproject.org will be used. The newly added
--candidate-registry flag can be used to change the default and query
candidate-registry.fedoraproject.org instead.
This doesn't matter right now, but a subsequent commit will make
changes to accommodate command-specific options, where this will start
to matter. After all, the case statement is running against $op, not
$1, so this the right thing to do anyway.
Fallout from 678bdbaf4e
It would be good to have Dockerfiles for multiple Fedora versions, and
possibly even other operating systems like Red Hat Enterprise Linux or
CentOS, so that people can use the toolbox on different host OSes.
In the future, it would be nice to have multiple toolbox containers
corresponding to different OSes exist side by side. One could then
have a Fedora 29 environment on a Fedora 28 host and so on.
Assuming a host UID of 1000, the UID mapping inside the user namespace
created by rootless podman for the toolbox container was:
0 1000 1
1 100000 65536
... which was the same as seen from the host:
0 1000 1
1 100000 65536
Therefore, when running with an UID of 1000 inside the container, it
got mapped to UID 100999 on the host. That means, for example, files
created by the user inside the container end up looking funny from the
host.
This is addressed by creating another user namespace that's a child of
the initial user namespace created by rootless podman. Assuming a host
UID of 1000, the UID mapping inside this child namespace is:
1000 0 1
0 1 1000
1001 1001 64536
... which when seen from the host is:
1000 1000 1
0 100000 1000
1001 101000 64536
This means that UID 1000 inside the child namespace is mapped to the
same UID 1000 on the host via the intermediate namespace created by
rootless podman. UIDs 0 to 999 inside the child namespace are mapped
to UIDs 100000 to 100999 in the host.
This change requires this runc pull request to work:
https://github.com/opencontainers/runc/pull/1862
As suggested by Giuseppe Scrivano.