Skip to content

Commit bac6cc2

Browse files
fmoessbauerjan-kiszka
authored andcommitted
kas-container: add limited support for docker rootless
Docker rootless mode is similar to podman rootless mode, except that it does not support to share the userid namespace. By that, the bind mounted directories (like /repo, /work, /build) which are owned by the calling user, are mapped with uid==gid==0 inside the container. While we could align this by running as root inside the container, this is not an option as bitbake does not allow this. This comes with the following limitations: - /repo must be mounted ro to not destroy the uid mappings on the host - /work, /build shall be exclusive dirs on the host that is only written to by the tooling inside kas-container - a git safe.dirs exception is needed as git operates as builder on repos owned by root - only operations that do not strictly require /repo:rw are supported. - ISAR mode is not supported in rootless mode, fallback to system docker Closes: #124 Signed-off-by: Felix Moessbauer <[email protected]> Signed-off-by: Jan Kiszka <[email protected]>
1 parent cb3db1a commit bac6cc2

File tree

3 files changed

+80
-3
lines changed

3 files changed

+80
-3
lines changed

container-entrypoint

+33-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@
2424

2525
# kas-isar: sudo update-binfmts --enable && [ -f /proc/sys/fs/binfmt_misc/status ]
2626

27+
chown_managed_dirs()
28+
{
29+
for DIR in /build /work /sstate /downloads /repo-ref; do
30+
if [ -d "$DIR" ]; then
31+
chown "$1":"$2" "$DIR"
32+
fi
33+
done
34+
}
35+
36+
restore_managed_dirs_owner()
37+
{
38+
chown_managed_dirs 0 0
39+
}
40+
2741
if mount | grep -q "on / type aufs"; then
2842
cat <<EOF >&2
2943
WARNING: Generation of wic images will fail!
@@ -51,6 +65,15 @@ else
5165

5266
GOSU="gosu builder"
5367
fi
68+
# kas-container on rootless docker workaround
69+
if [ -n "$USER_ID" ] && [ "$USER_ID" -ne 0 ] && \
70+
[ "$KAS_DOCKER_ROOTLESS" = "1" ] && [ "$(stat -c %u /repo)" -eq 0 ]; then
71+
# Docker rootless does not support keeping the user namespace
72+
# (podman option --userns=keep-id). By that, the bind mounts
73+
# are owned by root.
74+
sudo git config --system safe.directory /repo
75+
chown_managed_dirs "$USER_ID" "$GROUP_ID"
76+
fi
5477

5578
if [ "$PWD" = / ]; then
5679
cd /builder || exit 1
@@ -59,9 +82,16 @@ fi
5982
if [ -n "$1" ]; then
6083
case "$1" in
6184
build|checkout|clean*|dump|for-all-repos|lock|menu|purge|shell|-*)
62-
# SC2086: Double quote to prevent globbing and word splitting.
63-
# shellcheck disable=2086
64-
exec $GOSU kas "$@"
85+
# We must restore the dir owner after every kas invocation.
86+
# This is cheap as only the top-level dirs are changed (non recursive).
87+
if [ "$KAS_DOCKER_ROOTLESS" = "1" ]; then
88+
trap restore_managed_dirs_owner EXIT INT TERM
89+
$GOSU kas "$@"
90+
else
91+
# SC2086: Double quote to prevent globbing and word splitting.
92+
# shellcheck disable=2086
93+
exec $GOSU kas "$@"
94+
fi
6595
;;
6696
*)
6797
# SC2086: Double quote to prevent globbing and word splitting.

docs/userguide/kas-container-description.inc

+12
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ By default ``kas-container`` uses the official images provided by the kas projec
1414
``KAS_CONTAINER_IMAGE`` environment variable. As container backends, Docker and
1515
Podman are supported. To force the use of podman over docker, set
1616
``KAS_CONTAINER_ENGINE=podman``. For details, see :ref:`env-vars-label`.
17+
18+
Running under docker in `rootless mode <https://docs.docker.com/engine/security/rootless/>`_
19+
is partially supported. It is recommended to use a distinct ``KAS_WORK_DIR`` outside of the
20+
calling directory (repo-dir), as kas temporarily changes the ownership of the working
21+
directory during its operation. All files managed by kas (including the repos) must not be
22+
written to from the host. To completely remove all data managed by kas, use
23+
``kas-container purge``. This also restores the directory owners of the dirs passed to kas,
24+
so they can be removed from the host.
25+
26+
.. note::
27+
The ISAR build system is not compatible with rootless execution. By that,
28+
we fall back to the system docker or podman instance.

kas-container

+35
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ enable_isar_mode()
130130
KAS_CONTAINER_COMMAND="sudo --preserve-env ${KAS_CONTAINER_COMMAND}"
131131
# preserved user PATH may lack sbin needed by privileged podman
132132
export PATH="${PATH}:/usr/sbin"
133+
elif [ "${KAS_DOCKER_ROOTLESS}" = "1" ]; then
134+
export DOCKER_HOST="${DOCKER_HOST:-unix:///var/run/docker.sock}"
135+
debug "kas-isar does not support rootless docker. Using system docker"
136+
# force use of well-known system docker socket
137+
KAS_CONTAINER_COMMAND="sudo --preserve-env ${KAS_CONTAINER_COMMAND}"
138+
KAS_DOCKER_ROOTLESS=0
133139
fi
134140
}
135141

@@ -190,6 +196,27 @@ forward_dir()
190196
fi
191197
}
192198

199+
check_docker_rootless()
200+
{
201+
KAS_DOCKER_ROOTLESS=0
202+
if [ "$(docker context show)" = "rootless" ]; then
203+
KAS_DOCKER_ROOTLESS=1
204+
fi
205+
}
206+
207+
enable_docker_rootless()
208+
{
209+
warning "Rootless docker used, only limited functionality available."
210+
if [ "${KAS_WORK_DIR}" = "${KAS_REPO_DIR}" ]; then
211+
warning "On docker rootless a exclusive KAS_WORK_DIR should be used" \
212+
"as kas temporarily changes the ownership of this directory."
213+
fi
214+
if [ "${KAS_REPO_MOUNT_OPT}" = "rw" ]; then
215+
fatal_error "Docker rootless requires read-only repo."
216+
fi
217+
KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} -e KAS_DOCKER_ROOTLESS=1"
218+
}
219+
193220
KAS_GIT_OVERLAY_FILE=""
194221
kas_container_cleanup()
195222
{
@@ -251,6 +278,7 @@ case "${KAS_CONTAINER_ENGINE}" in
251278
docker)
252279
KAS_CONTAINER_COMMAND="docker"
253280
enable_unpriv_userns_docker
281+
check_docker_rootless
254282
;;
255283
podman)
256284
KAS_CONTAINER_COMMAND="podman"
@@ -494,6 +522,9 @@ fi
494522

495523
set_container_image_var
496524

525+
if [ "${KAS_DOCKER_ROOTLESS}" = "1" ]; then
526+
KAS_REPO_MOUNT_OPT_DEFAULT="ro"
527+
fi
497528
KAS_REPO_MOUNT_OPT="${KAS_REPO_MOUNT_OPT:-${KAS_REPO_MOUNT_OPT_DEFAULT}}"
498529

499530
KAS_FILES="$(echo "${KAS_FILES}" | sed 's|'"${KAS_REPO_DIR}"'/|/repo/|g')"
@@ -504,6 +535,10 @@ if [ "$(id -u)" -eq 0 ] && [ "${KAS_ALLOW_ROOT}" != "yes" ] ; then
504535
"KAS_ALLOW_ROOT=yes to override."
505536
fi
506537

538+
if [ "${KAS_DOCKER_ROOTLESS}" = "1" ]; then
539+
enable_docker_rootless
540+
fi
541+
507542
set -- "$@" -v "${KAS_REPO_DIR}:/repo:${KAS_REPO_MOUNT_OPT}" \
508543
-v "${KAS_WORK_DIR}":/work:rw -e KAS_WORK_DIR=/work \
509544
--workdir=/repo \

0 commit comments

Comments
 (0)