* [isar-cip-core][PATCH v3 1/5] update to kas 5.5
2026-08-27 6:22 [isar-cip-core][PATCH v3 0/5] Rootless builds, again Jan Kiszka
@ 2026-08-27 6:22 ` Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 2/5] Update Isar revision Jan Kiszka
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Jan Kiszka @ 2026-08-27 6:22 UTC (permalink / raw)
To: cip-dev; +Cc: Felix Moessbauer, Quirin Gylstorff, Michael Adler
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
[Jan: moved from 5.4 to 5.5]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
.gitlab-ci.yml | 2 +-
Kconfig | 2 +-
kas-cip.yml | 2 +-
kas-container | 329 +++++++++++++++++++++++++++----------------------
4 files changed, 187 insertions(+), 148 deletions(-)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d46a9efb..9aa186c6 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -34,7 +34,7 @@ stages:
- cve-check
default:
- image: ghcr.io/siemens/kas/kas-isar:5.2
+ image: ghcr.io/siemens/kas/kas-isar:5.5
before_script:
- export http_proxy=$HTTP_PROXY
- export https_proxy=$HTTPS_PROXY
diff --git a/Kconfig b/Kconfig
index 19f8e24b..3a9444db 100644
--- a/Kconfig
+++ b/Kconfig
@@ -17,7 +17,7 @@ config KAS_INCLUDE_MAIN
config KAS_BUILD_SYSTEM
string
- default "isar"
+ default "isar-privileged"
config ARCH_AMD64
bool
diff --git a/kas-cip.yml b/kas-cip.yml
index 7a3af452..97b333a1 100644
--- a/kas-cip.yml
+++ b/kas-cip.yml
@@ -15,7 +15,7 @@ header:
distro: cip-core-trixie
target: cip-core-image
-build_system: isar
+build_system: isar-privileged
repos:
cip-core:
diff --git a/kas-container b/kas-container
index 993f0bb8..d03717f0 100755
--- a/kas-container
+++ b/kas-container
@@ -27,7 +27,7 @@
set -e
-KAS_CONTAINER_SCRIPT_VERSION="5.2"
+KAS_CONTAINER_SCRIPT_VERSION="5.5"
KAS_IMAGE_VERSION_DEFAULT="${KAS_CONTAINER_SCRIPT_VERSION}"
KAS_CONTAINER_IMAGE_DISTRO_DEFAULT=""
KAS_CONTAINER_IMAGE_PATH_DEFAULT="ghcr.io/siemens/kas"
@@ -49,9 +49,10 @@ usage()
printf "%b" "\nPositional arguments:\n"
printf "%b" "build\t\t\tCheck out repositories and build target.\n"
printf "%b" "checkout\t\tCheck out repositories but do not build.\n"
+ printf "%b" "diff\t\t\tCompare two kas configurations.\n"
printf "%b" "dump\t\t\tCheck out repositories and write flat version\n"
printf "%b" " \t\t\tof config to stdout.\n"
- printf "%b" "lock\t\t\tCreate and update kas project lockfiles\n"
+ printf "%b" "lock\t\t\tCreate and update kas project lockfiles.\n"
printf "%b" "shell\t\t\tRun a shell in the build environment.\n"
printf "%b" "for-all-repos\t\tRun specified command in each repository.\n"
printf "%b" "clean\t\t\tClean build artifacts, keep sstate cache and " \
@@ -61,20 +62,21 @@ usage()
printf "%b" "cleanall\t\tClean build artifacts, sstate cache and " \
"downloads.\n"
printf "%b" "purge\t\t\tRemove all data managed by kas. Run with '--dry-run'\n"
- printf "%b" " \t\t\tto check what would be removed\n"
+ printf "%b" " \t\t\tto check what would be removed.\n"
printf "%b" "menu\t\t\tProvide configuration menu and trigger " \
"configured build.\n"
printf "%b" "\nOptional arguments:\n"
- printf "%b" "--isar\t\t\tUse kas-isar container to build Isar image. To force\n"
- printf "%b" " \t\t\tthe use of run0 over sudo, set KAS_SUDO_CMD=run0.\n"
- printf "%b" "--with-loop-dev Pass a loop device to the " \
- "container. Only required if\n"
- printf "%b" "\t\t\tloop-mounting is used by recipes.\n"
+ printf "%b" "--isar-privileged\tRun an Isar build in privileged mode. " \
+ "To force the use\n"
+ printf "%b" "\t\t\tof run0 over sudo, set KAS_SUDO_CMD=run0.\n"
+ printf "%b" "--isar-rootless\t\tRun an Isar build in rootless mode.\n"
+ printf "%b" "--kvm\t\tPass /dev/kvm into the container (for runqemu/testimage KVM\n" \
+ "acceleration) and grant the build user access to it."
printf "%b" "--runtime-args\t\tAdditional arguments to pass to the " \
- "container runtime\n"
+ "container runtime.\n"
printf "%b" "\t\t\tfor running the build.\n"
printf "%b" "-l, --log-level\t\tSet log level (default=info).\n"
- printf "%b" "--version\t\tprint program version.\n"
+ printf "%b" "--version\t\tPrint program version.\n"
printf "%b" "--ssh-dir\t\tDirectory containing SSH configurations.\n"
printf "%b" "\t\t\tAvoid \$HOME/.ssh unless you fully trust the " \
"container.\n"
@@ -83,13 +85,15 @@ usage()
printf "%b" "\t\t\tAvoid \$HOME/.aws unless you fully trust the " \
"container.\n"
printf "%b" "--git-credential-store\tFile path to the git credential " \
- "store\n"
+ "store.\n"
+ printf "%b" "--git-credential-socket\tPath to the git credential cache " \
+ "socket.\n"
printf "%b" "--no-proxy-from-env\tDo not inherit proxy settings from " \
"environment.\n"
printf "%b" "--repo-ro\t\tMount current repository read-only\n" \
- "\t\t\t(default for build command)\n"
+ "\t\t\t(default for build command).\n"
printf "%b" "--repo-rw\t\tMount current repository writable\n" \
- "\t\t\t(default for shell command)\n"
+ "\t\t\t(default for shell command).\n"
printf "%b" "-h, --help\t\tShow this help message and exit.\n"
printf "%b" "\n"
printf "%b" "You can force the use of podman over docker using " \
@@ -143,11 +147,6 @@ prepare_sudo_cmd()
enable_isar_mode()
{
- if [ -n "${ISAR_MODE}" ]; then
- return
- fi
- ISAR_MODE=1
-
KAS_CONTAINER_IMAGE_NAME_DEFAULT="kas-isar"
KAS_ISAR_ARGS="--privileged"
@@ -159,14 +158,38 @@ enable_isar_mode()
export PATH="${PATH}:/usr/sbin"
elif [ "${KAS_DOCKER_ROOTLESS}" = "1" ]; then
prepare_sudo_cmd
- export DOCKER_HOST="${DOCKER_HOST:-unix:///var/run/docker.sock}"
- debug "kas-isar does not support rootless docker. Using system docker"
+ DOCKER_HOST_DEFAULT="$(docker context inspect default --format '{{.Endpoints.docker.Host}}')"
+ export DOCKER_HOST="${DOCKER_HOST:-$DOCKER_HOST_DEFAULT}"
+ debug "kas-isar does not support rootless docker. Using system docker in $DOCKER_HOST"
# force use of well-known system docker socket
KAS_CONTAINER_COMMAND="${_KAS_SUDO_CMD} ${KAS_CONTAINER_COMMAND}"
KAS_DOCKER_ROOTLESS=0
fi
}
+enable_isar_rootless_mode()
+{
+ KAS_CONTAINER_IMAGE_NAME_DEFAULT="kas-isar"
+
+ # Use --privileged to pass the ambient capabilities into the container.
+ # When calling from the user session (podman or docker-rootless), this
+ # is fundamentally different from the system docker run --privileged
+ if [ "${KAS_CONTAINER_ENGINE}" = "podman" ]; then
+ KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} --userns=keep-id --privileged"
+ elif [ "${KAS_DOCKER_ROOTLESS}" = "1" ]; then
+ KAS_ISAR_ARGS="--privileged"
+ else
+ # we don't need --privileged, but we need to run with SYS_ADMIN
+ # to be able to unshare.
+ KAS_ISAR_ARGS=" \
+ --security-opt seccomp=unconfined \
+ --security-opt apparmor=unconfined \
+ --security-opt systempaths=unconfined \
+ --cap-add=SYS_ADMIN \
+ "
+ fi
+}
+
enable_oe_mode()
{
if [ "${KAS_CONTAINER_ENGINE}" = "podman" ]; then
@@ -174,6 +197,7 @@ enable_oe_mode()
# calling "podman run" has a 1:1 mapping
KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} --userns=keep-id"
fi
+ BUILD_SYSTEM="openembedded"
}
enable_unpriv_userns_docker()
@@ -210,6 +234,20 @@ check_and_expand()
realpath -e "$_varval"
}
+# SC2034: DIR appears unused (ignore, as they are used inside eval)
+# shellcheck disable=2034
+setup_kas_dirs()
+{
+ KAS_WORK_DIR="${KAS_WORK_DIR:-$(pwd)}"
+ KAS_WORK_DIR="$(check_and_expand KAS_WORK_DIR required)"
+ KAS_BUILD_DIR="$(check_and_expand KAS_BUILD_DIR create)"
+ KAS_REPO_REF_DIR="$(check_and_expand KAS_REPO_REF_DIR required)"
+ DL_DIR="$(check_and_expand DL_DIR createrec)"
+ SSTATE_DIR="$(check_and_expand SSTATE_DIR createrec)"
+ BB_HASHSERVE_DB_DIR="$(check_and_expand BB_HASHSERVE_DB_DIR createrec)"
+ KAS_BUILDTOOLS_DIR="$(check_and_expand KAS_BUILDTOOLS_DIR createrec)"
+}
+
# Params: FILE
# Returns: root repo dir of file
repo_path_of_file()
@@ -260,14 +298,6 @@ forward_dir()
fi
}
-check_docker_rootless()
-{
- KAS_DOCKER_ROOTLESS=0
- if [ "$(docker context show)" = "rootless" ]; then
- KAS_DOCKER_ROOTLESS=1
- fi
-}
-
enable_docker_rootless()
{
warning "Rootless docker used, only limited functionality available."
@@ -281,122 +311,52 @@ enable_docker_rootless()
KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} -e KAS_DOCKER_ROOTLESS=1"
}
-KAS_GIT_OVERLAY_FILE=""
-kas_container_cleanup()
-{
- if [ -f "${KAS_GIT_OVERLAY_FILE}" ]; then
- trace rm -f "${KAS_GIT_OVERLAY_FILE}"
- fi
-}
-trap kas_container_cleanup EXIT INT TERM
-
set_container_image_var()
{
+ # if the image is explicitly set, use that
+ if [ -n "${KAS_CONTAINER_IMAGE}" ]; then
+ return
+ fi
KAS_IMAGE_VERSION="${KAS_IMAGE_VERSION:-${KAS_IMAGE_VERSION_DEFAULT}}"
KAS_CONTAINER_IMAGE_DISTRO="${KAS_CONTAINER_IMAGE_DISTRO:-${KAS_CONTAINER_IMAGE_DISTRO_DEFAULT}}"
KAS_CONTAINER_IMAGE_NAME="${KAS_CONTAINER_IMAGE_NAME:-${KAS_CONTAINER_IMAGE_NAME_DEFAULT}}"
KAS_CONTAINER_IMAGE_PATH="${KAS_CONTAINER_IMAGE_PATH:-${KAS_CONTAINER_IMAGE_PATH_DEFAULT}}"
- KAS_CONTAINER_IMAGE_DEFAULT="${KAS_CONTAINER_IMAGE_PATH}/${KAS_CONTAINER_IMAGE_NAME}:${KAS_IMAGE_VERSION}"
- KAS_CONTAINER_IMAGE="${KAS_CONTAINER_IMAGE:-${KAS_CONTAINER_IMAGE_DEFAULT}}"
+ KAS_CONTAINER_IMAGE="${KAS_CONTAINER_IMAGE_PATH}/${KAS_CONTAINER_IMAGE_NAME}:${KAS_IMAGE_VERSION}"
if [ -n "${KAS_CONTAINER_IMAGE_DISTRO}" ]; then
KAS_CONTAINER_IMAGE="${KAS_CONTAINER_IMAGE}-${KAS_CONTAINER_IMAGE_DISTRO}"
fi
}
-# SC2034: DIR appears unused (ignore, as they are used inside eval)
-# shellcheck disable=2034
-setup_kas_dirs()
-{
- KAS_WORK_DIR="${KAS_WORK_DIR:-$(pwd)}"
- KAS_WORK_DIR="$(check_and_expand KAS_WORK_DIR required)"
- KAS_BUILD_DIR="$(check_and_expand KAS_BUILD_DIR create)"
- KAS_REPO_REF_DIR="$(check_and_expand KAS_REPO_REF_DIR required)"
- DL_DIR="$(check_and_expand DL_DIR createrec)"
- SSTATE_DIR="$(check_and_expand SSTATE_DIR createrec)"
- KAS_BUILDTOOLS_DIR="$(check_and_expand KAS_BUILDTOOLS_DIR createrec)"
-}
-setup_kas_dirs
-
-KAS_CONTAINER_ENGINE="${KAS_CONTAINER_ENGINE:-${KAS_DOCKER_ENGINE}}"
-if [ -z "${KAS_CONTAINER_ENGINE}" ]; then
- # Try to auto-detect a container engine
- if command -v docker >/dev/null; then
- case $(docker -v 2>/dev/null) in
- podman*)
- # The docker command is an alias for podman
- KAS_CONTAINER_ENGINE=podman
- ;;
- Docker*)
- # The docker command is the real docker
- KAS_CONTAINER_ENGINE=docker
- ;;
- *)
- # The docker command is an unknown engine
- fatal_error "docker command found, but unknown engine detected"
- esac
- elif command -v podman >/dev/null; then
- KAS_CONTAINER_ENGINE=podman
- else
- fatal_error "no container engine found, need docker or podman"
- fi
-fi
-
-KAS_RUNTIME_ARGS="--log-driver=none --user=root"
-
-case "${KAS_CONTAINER_ENGINE}" in
-docker)
- KAS_CONTAINER_COMMAND="docker"
- enable_unpriv_userns_docker
- check_docker_rootless
- ;;
-podman)
- KAS_CONTAINER_COMMAND="podman"
- KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} --security-opt label=disable"
- ;;
-*)
- fatal_error "unknown container engine '${KAS_CONTAINER_ENGINE}'"
- ;;
-esac
-
-# parse kas-container options
+# parse kas-container options, leave build system empty to distinguish between
+# explicitly set via flag and implicitly via config.
+BUILD_SYSTEM=""
+KAS_OPTIONS_DIRECT=""
+KAS_EXTRA_RUNTIME_ARGS=""
while [ $# -gt 0 ]; do
case "$1" in
- --isar)
- enable_isar_mode
+ --isar | --isar-privileged)
+ if [ "$1" = "--isar" ]; then
+ warning "The semantic of '--isar' might change in the" \
+ "future. Please use '--isar-privileged' instead."
+ fi
+ BUILD_SYSTEM="isar-privileged"
shift 1
;;
- --with-loop-dev)
- if ! KAS_LOOP_DEV=$(/sbin/losetup -f 2>/dev/null); then
- if [ "$(id -u)" -eq 0 ]; then
- fatal_error "loop device not available!"
- fi
- prepare_sudo_cmd
- if ! [ "$KAS_SUDO_CMD" = "sudo" ]; then
- fatal_error '--with-loop-dev requires sudo for device setup.'
- fi
- sudo_command="/sbin/losetup -f"
- sudo_message="[sudo] enter password to setup loop"
- sudo_message="$sudo_message devices by calling"
- sudo_message="$sudo_message '$sudo_command': "
- # SC2086: Double quote to prevent globbing and word splitting.
- # shellcheck disable=2086
- if ! KAS_LOOP_DEV=$(sudo -p "$sudo_message" $sudo_command \
- 2>/dev/null); then
- fatal_error "loop device setup unsuccessful!" \
- "try calling '$sudo_command' with root" \
- "permissions manually."
- fi
- fi
- KAS_WITH_LOOP_DEV="--device ${KAS_LOOP_DEV}"
+ --isar-rootless)
+ BUILD_SYSTEM="isar-rootless"
+ shift 1
+ ;;
+ --kvm)
+ KAS_KVM="1"
shift 1
;;
- --runtime-args|--docker-args)
- [ $# -gt 0 ] || usage
- KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} $2"
+ --runtime-args | --docker-args)
+ [ $# -gt 1 ] || usage
+ KAS_EXTRA_RUNTIME_ARGS="${KAS_EXTRA_RUNTIME_ARGS} $2"
shift 2
;;
--ssh-dir)
- [ $# -gt 2 ] || usage
+ [ $# -gt 1 ] || usage
KAS_SSH_DIR="$2"
shift 2
;;
@@ -408,15 +368,22 @@ while [ $# -gt 0 ]; do
shift 1
;;
--aws-dir)
- [ $# -gt 2 ] || usage
+ [ $# -gt 1 ] || usage
KAS_AWS_DIR="$2"
shift 2
;;
--git-credential-store)
- [ $# -gt 2 ] || usage
+ [ $# -gt 1 ] || usage
KAS_GIT_CREDENTIAL_STORE="$2"
shift 2
;;
+
+ --git-credential-socket)
+ [ $# -gt 1 ] || usage
+ KAS_GIT_CREDENTIAL_SOCKET="$2"
+ shift 2
+ ;;
+
--no-proxy-from-env)
KAS_NO_PROXY_FROM_ENV=1
shift 1
@@ -446,19 +413,19 @@ while [ $# -gt 0 ]; do
--*)
usage
;;
- clean|cleansstate|cleanall|purge)
+ clean | cleansstate | cleanall | purge)
KAS_REPO_MOUNT_OPT_DEFAULT="ro"
KAS_CMD=$1
shift 1
break
;;
- shell|lock)
+ shell | lock)
KAS_REPO_MOUNT_OPT_DEFAULT="rw"
KAS_CMD=$1
shift 1
break
;;
- build|checkout|for-all-repos|menu)
+ build | checkout | for-all-repos | menu)
KAS_REPO_MOUNT_OPT_DEFAULT="ro"
KAS_CMD=$1
shift 1
@@ -486,6 +453,10 @@ while [ $# -gt 0 ]; do
esac
done
+KAS_RUNTIME_ARGS="--log-driver=none --user=root"
+
+setup_kas_dirs
+
[ -n "${KAS_CMD}" ] || usage
KAS_EXTRA_BITBAKE_ARGS=0
@@ -494,17 +465,17 @@ KAS_FILES=
# parse kas sub-command options
while [ $# -gt 0 ] && [ $KAS_EXTRA_BITBAKE_ARGS -eq 0 ]; do
case "$1" in
- --format|--indent|--provenance|--skip|--target|--task)
+ --format | --indent | --provenance | --skip | --target | --task)
KAS_OPTIONS="${KAS_OPTIONS} $1 $2"
shift 1
shift 1 || KAS_OPTIONS="--help"
;;
- -c|--cmd|--command)
+ -c | --cmd | --command)
KAS_BITBAKE_C_OPTION_ARGS="$2"
shift 1
shift 1 || KAS_OPTIONS="--help"
;;
- -E|--preserve-env)
+ -E | --preserve-env)
fatal_error "$1 is not supported with ${KAS_CONTAINER_SELF_NAME}"
;;
--)
@@ -551,7 +522,7 @@ if [ "${KAS_CMD}" = "menu" ]; then
# When using the menu plugin, we need to track the KAS_REPO_DIR outside
# of the container to later allow a simple `kas-container build`. For
- # that, we tell the kas menu plugin via an env-var about the location
+ # that, we tell the kas menu command via an env-var about the location
# on the host. This data is then added to the .config.yaml where it can
# be evaluated by the next invocation of kas-container.
@@ -563,10 +534,10 @@ if [ "${KAS_CMD}" = "menu" ]; then
if [ "$(echo "${KAS_FIRST_FILES}" | wc -w)" -ne "1" ]; then
fatal_error "menu plugin only supports a single Kconfig file"
fi
- BUILD_SYSTEM=$(tr '\n' '\f' 2>/dev/null < "${KAS_FIRST_FILES}" | \
+ BUILD_SYSTEM=${BUILD_SYSTEM:-$(tr '\n' '\f' 2>/dev/null < "${KAS_FIRST_FILES}" |
sed -e 's/\(.*\fconfig KAS_BUILD_SYSTEM\f\(.*\)\|.*\)/\2/' \
-e 's/\f\([[:alpha:]].*\|$\)//' \
- -e 's/.*default \"\(.*\)\".*/\1/')
+ -e 's/.*default \"\(.*\)\".*/\1/')}
else
if [ -z "${KAS_FIRST_FILES}" ]; then
KAS_FIRST_FILES="${KAS_WORK_DIR}/.config.yaml"
@@ -574,20 +545,60 @@ else
# We only get the first build system and let kas check if mixed
_KAS_FIRST_FILE=$(echo "${KAS_FIRST_FILES}" | awk '{print $1}')
- BUILD_SYSTEM=$(grep -e "^build_system: " "${_KAS_FIRST_FILE}" 2>/dev/null | \
- sed 's/build_system:[ ]\+//')
+ BUILD_SYSTEM=${BUILD_SYSTEM:-$(grep -e "^build_system: " "${_KAS_FIRST_FILE}" 2>/dev/null |
+ sed 's/build_system:[ ]\+//')}
+fi
+
+KAS_CONTAINER_ENGINE="${KAS_CONTAINER_ENGINE:-${KAS_DOCKER_ENGINE}}"
+if [ -z "${KAS_CONTAINER_ENGINE}" ]; then
+ # Try to auto-detect a container engine
+ # Defaults if there are multiple options:
+ # podman if build system is isar-rootless, docker otherwise
+ if [ "${BUILD_SYSTEM}" = "isar-rootless" ] && command -v podman >/dev/null 2>&1; then
+ KAS_CONTAINER_ENGINE=podman
+ elif command -v docker >/dev/null 2>&1 && docker -v 2>/dev/null | grep -q '^Docker'; then
+ KAS_CONTAINER_ENGINE=docker
+ elif command -v podman >/dev/null 2>&1; then
+ KAS_CONTAINER_ENGINE=podman
+ else
+ fatal_error "no container engine found, need docker or podman"
+ fi
fi
-if [ "${BUILD_SYSTEM}" = "isar" ]; then
+KAS_DOCKER_ROOTLESS=0
+case "${KAS_CONTAINER_ENGINE}" in
+docker)
+ KAS_CONTAINER_COMMAND="docker"
+ enable_unpriv_userns_docker
+ if [ "$(docker context show)" = "rootless" ]; then
+ KAS_DOCKER_ROOTLESS=1
+ fi
+ ;;
+podman)
+ KAS_CONTAINER_COMMAND="podman"
+ KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} --security-opt label=disable"
+ ;;
+*)
+ fatal_error "unknown container engine '${KAS_CONTAINER_ENGINE}'"
+ ;;
+esac
+
+if [ "${BUILD_SYSTEM}" = "isar" ] || [ "${BUILD_SYSTEM}" = "isar-privileged" ]; then
enable_isar_mode
-elif [ -z "${ISAR_MODE}" ]; then
+elif [ "${BUILD_SYSTEM}" = "isar-rootless" ]; then
+ enable_isar_rootless_mode
+else
enable_oe_mode
fi
# clean can be executed without config, hence manually forward the build system
-if [ "${ISAR_MODE}" = "1" ] && echo "${KAS_CMD}" | grep -qe "^clean\|purge"; then
- KAS_OPTIONS="${KAS_OPTIONS} --isar"
-fi
+case "${BUILD_SYSTEM}" in
+isar*)
+ if echo "${KAS_CMD}" | grep -qe "^clean\|purge"; then
+ KAS_OPTIONS="${KAS_OPTIONS} --${BUILD_SYSTEM}"
+ fi
+ ;;
+esac
set_container_image_var
@@ -628,10 +639,21 @@ forward_dir KAS_BUILD_DIR "/build" "rw"
forward_dir DL_DIR "/downloads" "rw"
forward_dir KAS_REPO_REF_DIR "/repo-ref" "rw"
forward_dir SSTATE_DIR "/sstate" "rw"
+forward_dir BB_HASHSERVE_DB_DIR "/bb-hashserve-db" "rw"
forward_dir KAS_BUILDTOOLS_DIR "/buildtools" "rw"
if git_com_dir=$(git -C "${KAS_REPO_DIR}" rev-parse --git-common-dir 2>/dev/null) \
&& [ "$git_com_dir" != "$(git -C "${KAS_REPO_DIR}" rev-parse --git-dir)" ]; then
+
+ KAS_GIT_OVERLAY_FILE=""
+ kas_container_cleanup()
+ {
+ if [ -f "${KAS_GIT_OVERLAY_FILE}" ]; then
+ trace rm -f "${KAS_GIT_OVERLAY_FILE}"
+ fi
+ }
+ trap kas_container_cleanup EXIT INT TERM
+
# If (it's a git repo) and the common dir isn't the git-dir, it is shared worktree and
# we have to mount the common dir in the container to make git work
# The mount path inside the container is different from the host path. Hence, we over-mount
@@ -675,6 +697,14 @@ if [ -n "${AWS_WEB_IDENTITY_TOKEN_FILE}" ] ; then
-e AWS_ROLE_ARN="${AWS_ROLE_ARN}"
fi
+if [ -n "${KAS_KVM}" ]; then
+ if [ -c /dev/kvm ]; then
+ set -- "$@" --device=/dev/kvm
+ else
+ warning "--kvm given but /dev/kvm not present on host; skipping"
+ fi
+fi
+
KAS_GIT_CREDENTIAL_HELPER_DEFAULT=""
if [ -n "${KAS_GIT_CREDENTIAL_STORE}" ] ; then
@@ -685,6 +715,14 @@ if [ -n "${KAS_GIT_CREDENTIAL_STORE}" ] ; then
set -- "$@" -v "$(realpath -e "${KAS_GIT_CREDENTIAL_STORE}")":/var/kas/userdata/.git-credentials:ro
fi
+if [ -n "${KAS_GIT_CREDENTIAL_SOCKET}" ] ; then
+ if [ ! -S "${KAS_GIT_CREDENTIAL_SOCKET}" ]; then
+ fatal_error "passed KAS_GIT_CREDENTIAL_SOCKET '${KAS_GIT_CREDENTIAL_SOCKET}' is not a socket"
+ fi
+ KAS_GIT_CREDENTIAL_HELPER_DEFAULT="cache --socket=/var/kas/userdata/.git-cache-socket"
+ set -- "$@" -v "$(realpath -e "${KAS_GIT_CREDENTIAL_SOCKET}")":/var/kas/userdata/.git-cache-socket
+fi
+
GIT_CREDENTIAL_HELPER="${GIT_CREDENTIAL_HELPER:-${KAS_GIT_CREDENTIAL_HELPER_DEFAULT}}"
if [ -n "${GIT_CREDENTIAL_HELPER}" ] ; then
@@ -731,7 +769,8 @@ fi
for var in TERM KAS_DISTRO KAS_MACHINE KAS_TARGET KAS_TASK KAS_CLONE_DEPTH \
KAS_PREMIRRORS DISTRO_APT_PREMIRRORS BB_NUMBER_THREADS PARALLEL_MAKE \
GIT_CREDENTIAL_USEHTTPPATH \
- TZ; do
+ BB_HASHSERVE BB_HASHSERVE_UPSTREAM \
+ NO_COLOR TZ; do
if [ -n "$(eval echo \$${var})" ]; then
set -- "$@" -e "${var}=$(eval echo \"\$${var}\")"
fi
@@ -739,7 +778,7 @@ done
# propagate only supported SHELL settings
case "$SHELL" in
-/bin/sh|/bin/bash|/bin/dash)
+/bin/sh | /bin/bash | /bin/dash)
set -- "$@" -e "SHELL=$SHELL"
;;
*)
@@ -757,7 +796,7 @@ fi
# SC2086: Double quote to prevent globbing and word splitting.
# shellcheck disable=2086
-set -- "$@" ${KAS_ISAR_ARGS} ${KAS_WITH_LOOP_DEV} ${KAS_RUNTIME_ARGS} \
+set -- "$@" ${KAS_ISAR_ARGS} ${KAS_RUNTIME_ARGS} ${KAS_EXTRA_RUNTIME_ARGS} \
${KAS_CONTAINER_IMAGE} ${KAS_OPTIONS_DIRECT} ${KAS_CMD} ${KAS_OPTIONS}
if [ -n "${KAS_BITBAKE_C_OPTION_ARGS}" ]; then
set -- "$@" -c "${KAS_BITBAKE_C_OPTION_ARGS}"
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [isar-cip-core][PATCH v3 2/5] Update Isar revision
2026-08-27 6:22 [isar-cip-core][PATCH v3 0/5] Rootless builds, again Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 1/5] update to kas 5.5 Jan Kiszka
@ 2026-08-27 6:22 ` Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 3/5] switch to isar-rootless Jan Kiszka
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Jan Kiszka @ 2026-08-27 6:22 UTC (permalink / raw)
To: cip-dev; +Cc: Felix Moessbauer, Quirin Gylstorff, Michael Adler
From: Jan Kiszka <jan.kiszka@siemens.com>
One not-yet-merged patch is needed to make Isar compatible with
gitlab-cloud-ci in rootless mode.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
...map-nobody-nogroup-as-dedicated-bloc.patch | 68 +++++++++++++++++++
kas-cip.yml | 6 +-
2 files changed, 73 insertions(+), 1 deletion(-)
create mode 100644 isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
diff --git a/isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch b/isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
new file mode 100644
index 00000000..6c58c194
--- /dev/null
+++ b/isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
@@ -0,0 +1,68 @@
+From ea8f6d883a494430ff7db4ee95a875edee23c020 Mon Sep 17 00:00:00 2001
+From: Felix Moessbauer <felix.moessbauer@siemens.com>
+Date: Thu, 20 Aug 2026 17:10:29 +0200
+Subject: [PATCH] rootless: always map nobody/nogroup as dedicated block
+
+The nobody/nogroup ids were mapped as part of the linear id range,
+with an extra single-id mapping added only if the range was too small
+to contain them. The extra mapping was guarded by "uid_cnt < nobody_id",
+but the linear range ends at uid_cnt-2, so it covers nobody only for
+uid_cnt >= 65536. For a count of 65534 or 65535 neither the linear range
+nor the guard mapped nobody.
+
+Relying on the linear range to cover nobody is unsafe in general. If that
+range covers the outer id that --map-root-user maps to, unshare punches a
+hole out of the mapping, and per unshare(1) this "may result in the
+highest user ID of the mapping not being mapped". That highest id is
+exactly nobody. This happens whenever the subid range overlaps the id of
+the calling user, e.g. with
+
+ builder:0:65536
+
+where the mapped block 1..65534 contains the builder's own uid. The
+resulting namespace then silently lacks a nobody mapping, while a range
+like 100000:65536 is unaffected and hides the problem.
+
+Map nobody/nogroup as a separate block at the top of the range and cap
+the linear range at nobody_id-1. The separate block does not overlap
+--map-root-user, so it survives, and a hole now at most costs id 65533.
+
+Fixes: 4fedb1ae ("add support for fully rootless builds")
+Signed-off-by: Felix Moessbauer <felix.moessbauer@siemens.com>
+---
+ meta/classes-global/base.bbclass | 16 ++++++++++------
+ 1 file changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/meta/classes-global/base.bbclass b/meta/classes-global/base.bbclass
+index d96ebef4..8f81ab70 100644
+--- a/meta/classes-global/base.bbclass
++++ b/meta/classes-global/base.bbclass
+@@ -470,15 +470,19 @@ def run_privileged_cmd(d):
+ nobody_subid = uid_base + uid_cnt - 1
+ gid_base, gid_cnt = get_subid_range('/etc/subgid', d)
+ nogroup_subid = gid_base + gid_cnt - 1
++ # nobody/nogroup need a dedicated block at the top of the range. As part
++ # of the linear range they are lost whenever that range covers the outer
++ # id of --map-root-user, because unshare then punches out a hole and
++ # drops the highest id of the range.
++ uid_linear_cnt = min(uid_cnt - 2, nobody_id - 1)
++ gid_linear_cnt = min(gid_cnt - 2, nobody_id - 1)
+ cmd = 'unshare --mount --pid --uts --ipc --user' \
+ ' --kill-child' \
+ ' --setuid 0 --setgid 0 --fork' \
+- f' --map-users 1:{uid_base+1}:{uid_cnt-2}' \
+- f' --map-groups 1:{gid_base+1}:{gid_cnt-2}'
+- if uid_cnt < nobody_id:
+- cmd += f' --map-users {nobody_id}:{nobody_subid}:1'
+- if gid_cnt < nobody_id:
+- cmd += f' --map-groups {nobody_id}:{nogroup_subid}:1'
++ f' --map-users 1:{uid_base+1}:{uid_linear_cnt}' \
++ f' --map-groups 1:{gid_base+1}:{gid_linear_cnt}' \
++ f' --map-users {nobody_id}:{nobody_subid}:1' \
++ f' --map-groups {nobody_id}:{nogroup_subid}:1'
+ cmd += " --map-root-user"
+ else:
+ cmd = 'sudo -E'
+--
+2.47.3
+
diff --git a/kas-cip.yml b/kas-cip.yml
index 97b333a1..61cc9225 100644
--- a/kas-cip.yml
+++ b/kas-cip.yml
@@ -22,9 +22,13 @@ repos:
isar:
url: https://github.com/ilbers/isar.git
- commit: 481db3b2e8949336576e50a78aaf5d101f52c8d2
+ commit: 436bc96f3869b4a139357afbabb039caf4df7c5c
layers:
meta:
+ patches:
+ p1:
+ path: isar-patches/0001-rootless-always-map-nobody-nogroup-as-dedicated-bloc.patch
+ repo: cip-core
bblayers_conf_header:
standard: |
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [isar-cip-core][PATCH v3 3/5] switch to isar-rootless
2026-08-27 6:22 [isar-cip-core][PATCH v3 0/5] Rootless builds, again Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 1/5] update to kas 5.5 Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 2/5] Update Isar revision Jan Kiszka
@ 2026-08-27 6:22 ` Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 4/5] update README.md for rootless build Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 5/5] ci: Select rootless runner Jan Kiszka
4 siblings, 0 replies; 6+ messages in thread
From: Jan Kiszka @ 2026-08-27 6:22 UTC (permalink / raw)
To: cip-dev; +Cc: Felix Moessbauer, Quirin Gylstorff, Michael Adler
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
.reproducible-check-ci.yml | 3 +--
Kconfig | 2 +-
kas-cip.yml | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/.reproducible-check-ci.yml b/.reproducible-check-ci.yml
index 1246a641..4f4649ee 100644
--- a/.reproducible-check-ci.yml
+++ b/.reproducible-check-ci.yml
@@ -39,8 +39,7 @@
# Deploy .wic, .swu and wic partitions for build1
- deploy_rb_artifacts build1
# clean
- - sudo rm -rf build/tmp
- - sudo rm -rf build/sstate-cache
+ - kas purge --isar-rootless ${base_yaml}
# Build 2nd time
- !reference [.build_base, script]
# Deploy .wic, .swu and wic partitions for build2
diff --git a/Kconfig b/Kconfig
index 3a9444db..7575d89c 100644
--- a/Kconfig
+++ b/Kconfig
@@ -17,7 +17,7 @@ config KAS_INCLUDE_MAIN
config KAS_BUILD_SYSTEM
string
- default "isar-privileged"
+ default "isar-rootless"
config ARCH_AMD64
bool
diff --git a/kas-cip.yml b/kas-cip.yml
index 61cc9225..43aeb2d6 100644
--- a/kas-cip.yml
+++ b/kas-cip.yml
@@ -15,7 +15,7 @@ header:
distro: cip-core-trixie
target: cip-core-image
-build_system: isar-privileged
+build_system: isar-rootless
repos:
cip-core:
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [isar-cip-core][PATCH v3 4/5] update README.md for rootless build
2026-08-27 6:22 [isar-cip-core][PATCH v3 0/5] Rootless builds, again Jan Kiszka
` (2 preceding siblings ...)
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 3/5] switch to isar-rootless Jan Kiszka
@ 2026-08-27 6:22 ` Jan Kiszka
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 5/5] ci: Select rootless runner Jan Kiszka
4 siblings, 0 replies; 6+ messages in thread
From: Jan Kiszka @ 2026-08-27 6:22 UTC (permalink / raw)
To: cip-dev; +Cc: Felix Moessbauer, Quirin Gylstorff, Michael Adler
From: Quirin Gylstorff <quirin.gylstorff@siemens.com>
Signed-off-by: Quirin Gylstorff <quirin.gylstorff@siemens.com>
[Jan: adjust wording, reference kas docs]
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
README.md | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 05291744..f84adadc 100644
--- a/README.md
+++ b/README.md
@@ -10,10 +10,9 @@ from scratch.
## Building Target Images
-Install docker or podman and make sure you have required permissions to start
-privileged containers. For docker, you need to be part of respective docker
-group (`sudo usermod -aG docker <USER>`). Privileged podman requires sudo
-rights for the caller (`<USER> ALL=(root) SETENV: /usr/bin/podman` in sudoers).
+Install docker or podman. For true unprivileged builds, podman is recommended.
+See [kas documentation](https://kas.readthedocs.io/en/latest/userguide/kas-container.html)
+for more details.
Open up the image configuration menu and select the desired target and its
options:
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread* [isar-cip-core][PATCH v3 5/5] ci: Select rootless runner
2026-08-27 6:22 [isar-cip-core][PATCH v3 0/5] Rootless builds, again Jan Kiszka
` (3 preceding siblings ...)
2026-08-27 6:22 ` [isar-cip-core][PATCH v3 4/5] update README.md for rootless build Jan Kiszka
@ 2026-08-27 6:22 ` Jan Kiszka
4 siblings, 0 replies; 6+ messages in thread
From: Jan Kiszka @ 2026-08-27 6:22 UTC (permalink / raw)
To: cip-dev; +Cc: Felix Moessbauer, Quirin Gylstorff, Michael Adler
From: Jan Kiszka <jan.kiszka@siemens.com>
We need to explicitly select a runner that is launching build containers
in unprivileged mode. This is primarily due to the bug in kas 5.4 which
breaks the parallel start of multiple kas-isar containers on the same
host. At the same time, such tagging allows us to phase out the
privileged runner at some point in way that would clearly block legacy
jobs.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
.gitlab-ci.yml | 8 ++++----
.reproducible-check-ci.yml | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9aa186c6..8dbe62d2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
#
# CIP Core, generic profile
#
-# Copyright (c) Siemens AG, 2019-2025
+# Copyright (c) Siemens AG, 2019-2026
# Copyright (c) Toshiba Corporation, 2020
#
# Authors:
@@ -53,7 +53,7 @@ default:
when: never
- if: $CI_COMMIT_BRANCH != "master"
tags:
- - large
+ - large-rootless
variables:
base_yaml: "kas-cip.yml:kas/board/${target}.yml"
script:
@@ -917,7 +917,7 @@ cve-checks:
needs: []
image: registry.gitlab.com/cip-project/cip-core/debian-cve-checker:build-latest
tags:
- - large
+ - large-rootless
script:
- scripts/run-cve-checks.sh
rules:
@@ -936,7 +936,7 @@ lavacli-container:
stage: build
image: quay.io/buildah/stable:v1.41.4
tags:
- - large
+ - large-rootless
before_script:
- buildah login -u $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
diff --git a/.reproducible-check-ci.yml b/.reproducible-check-ci.yml
index 4f4649ee..de9f3fbd 100644
--- a/.reproducible-check-ci.yml
+++ b/.reproducible-check-ci.yml
@@ -21,7 +21,7 @@
extension: security
stage: build
tags:
- - large
+ - large-rootless
rules:
- if: $CI_PIPELINE_SOURCE == "schedule" && $REPRODUCIBLE_BUILDS
script:
--
2.47.3
^ permalink raw reply related [flat|nested] 6+ messages in thread