diff --git a/kas-container b/kas-container index 6b2131c3..03f33192 100755 --- a/kas-container +++ b/kas-container @@ -27,24 +27,28 @@ set -e -KAS_IMAGE_VERSION_DEFAULT="4.5" +KAS_IMAGE_VERSION_DEFAULT="4.6" KAS_CONTAINER_IMAGE_PATH_DEFAULT="ghcr.io/siemens/kas" KAS_CONTAINER_IMAGE_NAME_DEFAULT="kas" KAS_CONTAINER_SELF_NAME="$(basename "$0")" +# usage [exit_code] usage() { + EXIT_CODE="$1" SELF="${KAS_CONTAINER_SELF_NAME}" + printf "%b" "Usage: ${SELF} [OPTIONS] { build | shell } [KASOPTIONS] [KASFILE]\n" - printf "%b" " ${SELF} [OPTIONS] { checkout | dump } [KASOPTIONS] [KASFILE]\n" + printf "%b" " ${SELF} [OPTIONS] { checkout | dump | lock } [KASOPTIONS] [KASFILE]\n" printf "%b" " ${SELF} [OPTIONS] for-all-repos [KASOPTIONS] [KASFILE] COMMAND\n" - printf "%b" " ${SELF} [OPTIONS] { clean | cleansstate | cleanall} [KASFILE]\n" + printf "%b" " ${SELF} [OPTIONS] { clean | cleansstate | cleanall } [KASFILE]\n" printf "%b" " ${SELF} [OPTIONS] menu [KCONFIG]\n" 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" "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" "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 " \ @@ -63,9 +67,7 @@ usage() printf "%b" "--runtime-args\t\tAdditional arguments to pass to the " \ "container runtime\n" printf "%b" "\t\t\tfor running the build.\n" - printf "%b" "-d\t\t\tPrint debug output (deprecated, use -l debug).\n" printf "%b" "-l, --log-level\t\tSet log level (default=info).\n" - printf "%b" "-v\t\t\tSame as -d (deprecated).\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 " \ @@ -80,28 +82,39 @@ usage() "\t\t\t(default for build command)\n" printf "%b" "--repo-rw\t\tMount current repository writeable\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 " \ "KAS_CONTAINER_ENGINE=podman.\n" - exit 1 + + exit "${EXIT_CODE:-1}" } -fatal_error(){ +fatal_error() +{ echo "${KAS_CONTAINER_SELF_NAME}: Error: $*" >&2 exit 1 } -warning(){ +warning() +{ echo "${KAS_CONTAINER_SELF_NAME}: Warning: $*" >&2 } +debug(){ + if [ -n "${KAS_VERBOSE}" ]; then + echo "${KAS_CONTAINER_SELF_NAME}: Debug: $*" >&2 + fi +} + trace() { [ -n "${KAS_VERBOSE}" ] && echo "+ $*" >&2 "$@" } -enable_isar_mode() { +enable_isar_mode() +{ if [ -n "${ISAR_MODE}" ]; then return fi @@ -118,7 +131,8 @@ enable_isar_mode() { fi } -enable_oe_mode() { +enable_oe_mode() +{ if [ "${KAS_CONTAINER_ENGINE}" = "podman" ]; then # The container entry point expects that the current userid # calling "podman run" has a 1:1 mapping @@ -126,7 +140,23 @@ enable_oe_mode() { fi } -run_clean() { +enable_unpriv_userns_docker() +{ + if [ -f /etc/os-release ] && grep -q 'NAME="Ubuntu"' /etc/os-release && + [ -f /proc/sys/kernel/apparmor_restrict_unprivileged_userns ] && + [ "$(cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns)" = "1" ]; then + if [ -f /etc/apparmor.d/rootlesskit ]; then + debug "AppArmor restricts unprivileged userns, using \"rootlesskit\" profile" + KAS_RUNTIME_ARGS="${KAS_RUNTIME_ARGS} --security-opt apparmor=rootlesskit" + else + warning "AppArmor restricts unprivileged userns but no suitable apparmor " \ + "profile found. Consider setting apparmor_restrict_unprivileged_userns=0" + fi + fi +} + +run_clean() +{ if [ -n "${KAS_ISAR_ARGS}" ]; then # SC2086: Double quote to prevent globbing and word splitting. # shellcheck disable=2086 @@ -149,7 +179,17 @@ run_clean() { fi } -set_container_image_var() { +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() +{ KAS_IMAGE_VERSION="${KAS_IMAGE_VERSION:-${KAS_IMAGE_VERSION_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}}" @@ -192,6 +232,7 @@ KAS_RUNTIME_ARGS="--log-driver=none --user=root" case "${KAS_CONTAINER_ENGINE}" in docker) KAS_CONTAINER_COMMAND="docker" + enable_unpriv_userns_docker ;; podman) KAS_CONTAINER_COMMAND="podman" @@ -269,11 +310,6 @@ while [ $# -gt 0 ]; do KAS_REPO_MOUNT_OPT="rw" shift 1 ;; - -v | -d) - KAS_VERBOSE=1 - KAS_OPTIONS_DIRECT="${KAS_OPTIONS_DIRECT} -d" - shift 1 - ;; -l | --log-level) if [ "$2" = "debug" ]; then KAS_VERBOSE=1 @@ -285,6 +321,9 @@ while [ $# -gt 0 ]; do echo "${KAS_CONTAINER_SELF_NAME} $KAS_IMAGE_VERSION_DEFAULT" exit 0 ;; + -h | --help) + usage 0 + ;; --*) usage ;; @@ -293,7 +332,7 @@ while [ $# -gt 0 ]; do shift 1 break ;; - shell) + shell|lock) KAS_REPO_MOUNT_OPT_DEFAULT="rw" KAS_CMD=$1 shift 1 @@ -459,6 +498,22 @@ set -- "$@" -v "${KAS_REPO_DIR}:/repo:${KAS_REPO_MOUNT_OPT}" \ -e KAS_BUILD_DIR=/build \ -e USER_ID="$(id -u)" -e GROUP_ID="$(id -g)" --rm --init +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 + # 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 + # the .git file to point to the correct path. + KAS_GIT_OVERLAY_FILE=$(mktemp) + sed "s|gitdir: ${git_com_dir}/|gitdir: /repo-common/|" "${KAS_REPO_DIR}/.git" > "${KAS_GIT_OVERLAY_FILE}" + set -- "$@" -v "${git_com_dir}:/repo-common:${KAS_REPO_MOUNT_OPT}" \ + -v "${KAS_GIT_OVERLAY_FILE}:/repo/.git:ro" + # if the workdir is the same as the repo dir, it is the same shared worktree + if [ "${KAS_WORK_DIR}" = "${KAS_REPO_DIR}" ]; then + set -- "$@" -v "${KAS_GIT_OVERLAY_FILE}:/work/.git:ro" + fi +fi + if [ -n "${KAS_SSH_DIR}" ] ; then if [ ! -d "${KAS_SSH_DIR}" ]; then fatal_error "passed KAS_SSH_DIR '${KAS_SSH_DIR}' is not a directory" diff --git a/mtda/main.py b/mtda/main.py index bba0e647..c0a07b9e 100644 --- a/mtda/main.py +++ b/mtda/main.py @@ -1614,11 +1614,9 @@ def start(self): self._storage_event(CONSTS.STORAGE.UNLOCKED) if self.console is not None or self.monitor is not None: - from mtda.console.logger import ConsoleLogger - - if self.console is not None: # Create a publisher if self.is_server is True: + from mtda.console.logger import ConsoleLogger import zmq context = zmq.Context() socket = context.socket(zmq.PUB) @@ -1627,6 +1625,7 @@ def start(self): socket = None self.socket = socket + if self.console is not None: # Create and start console logger status = self.console.probe() if status is False: diff --git a/setup.py b/setup.py index b7178833..0e662faf 100644 --- a/setup.py +++ b/setup.py @@ -64,7 +64,7 @@ "python-daemon>=2.0", "pyro4>=4.82", "pyusb>=1.0", - "pyzmq>=15.0,<25.0.0", + "pyzmq>=15.0", "psutil", "requests", "systemd-python>=234", diff --git a/tox.ini b/tox.ini index 77d314dc..80cd42fd 100644 --- a/tox.ini +++ b/tox.ini @@ -10,7 +10,7 @@ # --------------------------------------------------------------------------- [tox] -envlist = py38,py39,py310,py311 +envlist = py38,py39,py310,py311,py312 [testenv] allowlist_externals = bash