Try to inject the parent image in slopslopstrap

This commit is contained in:
Samuel Aubertin
2026-03-10 01:22:58 +01:00
parent 3731094f60
commit 438959ca03
3 changed files with 428 additions and 12 deletions

288
sloptrap
View File

@@ -245,6 +245,7 @@ CAPABILITY_TRUST_ROOT_HOST=""
CAPABILITY_TRUST_FILE_HOST=""
CAPABILITY_BUILD_STAMP_HOST=""
CAPABILITY_STATE_HOST=""
CAPABILITY_PRELOAD_DIR_HOST=""
IGNORE_STUB_BASE=""
IGNORE_HELPER_ROOT=""
ALLOW_HOST_NETWORK=false
@@ -355,6 +356,7 @@ write_embedded_helper() {
set -euo pipefail
helper_pid=""
helperd_bin=${SLOPTRAP_HELPERD_BIN:-/usr/local/bin/sloptrap-helperd}
has_capability() {
local needle=$1
@@ -440,12 +442,16 @@ lookup_account_name() {
ensure_subid_mappings() {
local account_id account_gid account_name=""
local subuid_file subgid_file
local range_start="" range_count="" gid_start="" gid_count=""
local detected_range=""
account_id=${SLOPTRAP_HOST_UID:-$(id -u)}
account_gid=${SLOPTRAP_HOST_GID:-$(id -g)}
if ! account_name=$(lookup_account_name "$account_id"); then
account_name=${SLOPTRAP_HOST_USER:-}
subuid_file=${SLOPTRAP_PODMAN_SUBUID_FILE:-/etc/subuid}
subgid_file=${SLOPTRAP_PODMAN_SUBGID_FILE:-/etc/subgid}
if [[ -z $account_name ]] && ! account_name=$(lookup_account_name "$account_id"); then
account_name=""
fi
@@ -463,10 +469,10 @@ ensure_subid_mappings() {
fi
if [[ -n $range_start && -n $range_count ]]; then
ensure_subid_mapping_file /etc/subuid "$account_name" "$account_id" "$range_start" "$range_count"
ensure_subid_mapping_file "$subuid_file" "$account_name" "$account_id" "$range_start" "$range_count"
fi
if [[ -n $gid_start && -n $gid_count ]]; then
ensure_subid_mapping_file /etc/subgid "$account_name" "$account_id" "$gid_start" "$gid_count"
ensure_subid_mapping_file "$subgid_file" "$account_name" "$account_id" "$gid_start" "$gid_count"
fi
}
@@ -495,7 +501,7 @@ if [[ $(id -u) -eq 0 ]]; then
ensure_subid_mappings
fi
if [[ -n ${SLOPTRAP_ACTIVE_CAPABILITIES:-} ]]; then
/usr/local/bin/sloptrap-helperd &
"$helperd_bin" &
helper_pid=$!
fi
if [[ -n $target_uid && -n $target_gid ]]; then
@@ -1129,7 +1135,7 @@ has_capability() {
}
if [[ $# -eq 0 ]]; then
printf 'usage: sloppodman <pull|build|tag|run|ps|logs|stop|rm|inspect> ...\n' >&2
printf 'usage: sloppodman <pull|build|tag|load|import|run|ps|logs|stop|rm|inspect> ...\n' >&2
exit 2
fi
@@ -1139,7 +1145,7 @@ shift
subcommand_prefix=("$subcommand")
case "$subcommand" in
pull|build|tag|run|ps|logs|stop|rm|inspect|rmi)
pull|build|tag|load|import|run|ps|logs|stop|rm|inspect|rmi)
;;
image)
[[ $# -gt 0 ]] || {
@@ -1204,6 +1210,7 @@ CONTAINERS_CONF_EOF
export CONTAINERS_STORAGE_CONF="$storage_conf"
export CONTAINERS_CONF="$containers_conf"
export BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}"
export _CONTAINERS_USERNS_CONFIGURED="${_CONTAINERS_USERNS_CONFIGURED:-done}"
detect_subid_range_from_map() {
local map_path=$1
@@ -1320,6 +1327,7 @@ exec_podman() {
CONTAINERS_STORAGE_CONF="$CONTAINERS_STORAGE_CONF" \
CONTAINERS_CONF="$CONTAINERS_CONF" \
BUILDAH_ISOLATION="$BUILDAH_ISOLATION" \
_CONTAINERS_USERNS_CONFIGURED="$_CONTAINERS_USERNS_CONFIGURED" \
XDG_RUNTIME_DIR="$runtime_dir" \
SLOPTRAP_PODMAN_ESCALATED=1 \
SLOPTRAP_PODMAN_CALLER_UID="${SLOPTRAP_PODMAN_CALLER_UID:-$(id -u)}" \
@@ -1352,6 +1360,19 @@ validate_workspace_path() {
esac
}
validate_archive_path() {
local path=$1
local resolved allowed_archive=""
resolved=$(resolve_inner_path "$path")
if [[ -n ${SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE:-} ]]; then
allowed_archive=$(resolve_inner_path "$SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE")
if [[ $resolved == "$allowed_archive" ]]; then
return 0
fi
fi
validate_workspace_path "$path"
}
reject_flag() {
local flag=$1
printf 'sloppodman: %s is not permitted\n' "$flag" >&2
@@ -1450,6 +1471,60 @@ if [[ $subcommand == "build" ]]; then
fi
fi
if [[ $subcommand == "import" ]]; then
args=("$@")
archive_path=""
idx=0
while (( idx < ${#args[@]} )); do
arg=${args[$idx]}
case "$arg" in
--change|--message)
((idx+=1))
(( idx < ${#args[@]} )) || { printf 'sloppodman: %s requires a value\n' "$arg" >&2; exit 2; }
;;
--change=*|--message=*|-q|--quiet)
;;
-*)
;;
*)
archive_path=$arg
break
;;
esac
((idx+=1))
done
[[ -n $archive_path ]] || { printf 'sloppodman: import requires an archive path\n' >&2; exit 2; }
validate_archive_path "$archive_path"
fi
if [[ $subcommand == "load" ]]; then
args=("$@")
archive_path=""
idx=0
while (( idx < ${#args[@]} )); do
arg=${args[$idx]}
case "$arg" in
-i|--input)
((idx+=1))
(( idx < ${#args[@]} )) || { printf 'sloppodman: %s requires a path\n' "$arg" >&2; exit 2; }
archive_path=${args[$idx]}
;;
--input=*|-i=*)
archive_path=${arg#*=}
;;
-*)
;;
*)
archive_path=$arg
break
;;
esac
((idx+=1))
done
[[ -n $archive_path ]] || { printf 'sloppodman: load requires an archive path\n' >&2; exit 2; }
validate_archive_path "$archive_path"
fi
if [[ $subcommand == "run" ]]; then
args=("$@")
idx=0
@@ -1684,6 +1759,7 @@ select_capability_state_paths() {
CAPABILITY_TRUST_FILE_HOST="$CAPABILITY_TRUST_ROOT_HOST/$CODEX_STATE_KEY.trust"
CAPABILITY_BUILD_STAMP_HOST="$capability_root/builds/$CODEX_STATE_KEY.stamp"
CAPABILITY_STATE_HOST="$CODEX_STATE_HOME_HOST/capabilities"
CAPABILITY_PRELOAD_DIR_HOST="$CAPABILITY_STATE_HOST/podman-preload"
}
ensure_capability_state_paths() {
@@ -1696,6 +1772,7 @@ ensure_capability_state_paths() {
ensure_codex_directory "$CAPABILITY_STATE_HOST/podman-storage" "nested podman storage state"
ensure_codex_directory "$CAPABILITY_STATE_HOST/podman-run" "nested podman runroot state"
ensure_codex_directory "$CAPABILITY_STATE_HOST/podman-runtime" "nested podman runtime state"
ensure_codex_directory "$CAPABILITY_PRELOAD_DIR_HOST" "nested podman preload state"
fi
}
@@ -1768,6 +1845,16 @@ capability_build_stamp_matches_current() {
[[ $stamp_digest == "$CAPABILITY_MANIFEST_DIGEST" && $stamp_caps == "$REQUESTED_CAPABILITIES" ]]
}
run_with_nested_podman_root() {
if capability_list_contains "${SLOPTRAP_ACTIVE_CAPABILITIES:-}" "nested-podman" \
&& [[ $(id -u) -ne 0 ]] \
&& command -v setpriv >/dev/null 2>&1; then
setpriv --reuid 0 --regid 0 --clear-groups -- "$@"
return
fi
"$@"
}
assert_path_within_code_dir() {
local candidate=$1
local resolved
@@ -2057,7 +2144,9 @@ detect_container_engine() {
local override=${SLOPTRAP_CONTAINER_ENGINE-}
if [[ -n $override ]]; then
local engine="${override,,}"
if ! command -v "$engine" >/dev/null 2>&1; then
if [[ $engine == */* ]]; then
[[ -x $engine ]] || error "container engine '$engine' is not executable"
elif ! command -v "$engine" >/dev/null 2>&1; then
error "container engine '$engine' not found in PATH"
fi
printf '%s' "$engine"
@@ -2706,6 +2795,7 @@ prepare_container_runtime() {
-v "$CAPABILITY_STATE_HOST/podman-storage:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/storage$SLOPTRAP_VOLUME_LABEL"
-v "$CAPABILITY_STATE_HOST/podman-run:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/run$SLOPTRAP_VOLUME_LABEL"
-v "$CAPABILITY_STATE_HOST/podman-runtime:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/runtime$SLOPTRAP_VOLUME_LABEL"
-v "$CAPABILITY_PRELOAD_DIR_HOST:$SLOPTRAP_CODEX_HOME_CONT/capabilities/podman/preload$SLOPTRAP_VOLUME_LABEL"
)
fi
@@ -2728,14 +2818,24 @@ prepare_container_runtime() {
if capability_list_contains "$ENABLED_CAPABILITIES" "nested-podman" && [[ $SLOPTRAP_NETWORK_NAME == "host" ]]; then
env_args+=(-e "SLOPTRAP_INNER_PODMAN_HOST_NETWORK=1")
fi
if capability_list_contains "$ENABLED_CAPABILITIES" "nested-podman"; then
env_args+=(
-e "SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE=$(recursive_preload_archive_container_path)"
-e "SLOPTRAP_RECURSIVE_PARENT_IMAGE_NAME=$SLOPTRAP_IMAGE_NAME"
)
fi
local uid gid
local uid gid user
uid=$(id -u)
gid=$(id -g)
user=$(id -un 2>/dev/null || true)
env_args+=(
-e "SLOPTRAP_HOST_UID=$uid"
-e "SLOPTRAP_HOST_GID=$gid"
)
if [[ -n $user ]]; then
env_args+=(-e "SLOPTRAP_HOST_USER=$user")
fi
local -a user_opts=("--user" "$uid:$gid")
if [[ $CONTAINER_ENGINE == "podman" ]]; then
user_opts=(--userns="keep-id:uid=$uid,gid=$gid" "${user_opts[@]}")
@@ -2860,6 +2960,169 @@ rebuild_image() {
write_capability_build_stamp
}
compute_recursive_preload_stamp() {
local launcher_source=${BASH_SOURCE[0]:-$0}
local launcher_digest
launcher_digest=$(sha256sum "$launcher_source")
printf '%s\n%s\n' "${launcher_digest%% *}" "$SLOPTRAP_IMAGE_NAME"
}
recursive_preload_archive_host_path() {
printf '%s/%s.tar\n' "$CAPABILITY_PRELOAD_DIR_HOST" "$SLOPTRAP_IMAGE_NAME"
}
recursive_preload_archive_container_path() {
printf '%s/capabilities/podman/preload/%s.tar\n' "$SLOPTRAP_CODEX_HOME_CONT" "$SLOPTRAP_IMAGE_NAME"
}
prepare_recursive_parent_image_preload() {
capability_list_contains "$ENABLED_CAPABILITIES" "nested-podman" || return 0
local engine_name=${CONTAINER_ENGINE##*/}
case "$engine_name" in
sloppodman|sloppodman*|.sloppodman*)
return 0
;;
esac
local archive_path stamp_path image_id recorded_id=""
archive_path=$(recursive_preload_archive_host_path)
stamp_path="${archive_path}.stamp"
if ! image_id=$("$CONTAINER_ENGINE" image inspect --format '{{.Id}}' "$SLOPTRAP_IMAGE_NAME" 2>/dev/null); then
return 1
fi
if [[ -f $archive_path && -f $stamp_path ]]; then
recorded_id=$(sed -n '1p' "$stamp_path" 2>/dev/null || true)
if [[ $recorded_id == "$image_id" ]]; then
return 0
fi
fi
local tmp_archive="${archive_path}.tmp"
if ! "$CONTAINER_ENGINE" save -o "$tmp_archive" "$SLOPTRAP_IMAGE_NAME"; then
rm -f "$tmp_archive"
return 1
fi
mv "$tmp_archive" "$archive_path"
printf '%s\n%s\n' "$image_id" "$SLOPTRAP_IMAGE_NAME" >"$stamp_path"
}
load_recursive_parent_image() {
local engine_name=${CONTAINER_ENGINE##*/}
local archive_path=${SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE:-}
local source_image_name=${SLOPTRAP_RECURSIVE_PARENT_IMAGE_NAME:-$SLOPTRAP_IMAGE_NAME}
case "$engine_name" in
sloppodman|sloppodman*|.sloppodman*)
;;
*)
return 1
;;
esac
capability_list_contains "${SLOPTRAP_ACTIVE_CAPABILITIES:-}" "nested-podman" || return 1
[[ -n $archive_path && -r $archive_path ]] || return 1
if ! "$CONTAINER_ENGINE" load -i "$archive_path"; then
return 1
fi
if ! "$CONTAINER_ENGINE" image inspect "$SLOPTRAP_IMAGE_NAME" >/dev/null 2>&1; then
[[ -n $source_image_name ]] || return 1
"$CONTAINER_ENGINE" tag "$source_image_name" "$SLOPTRAP_IMAGE_NAME" || return 1
fi
"$CONTAINER_ENGINE" image inspect "$SLOPTRAP_IMAGE_NAME" >/dev/null 2>&1 || return 1
write_capability_build_stamp
return 0
}
prepare_recursive_parent_image_archive() {
local archive_dir="$CODE_DIR/.sloptrap-preload"
local archive_path="$archive_dir/${SLOPTRAP_IMAGE_NAME}.tar"
local stamp_path="$archive_path.stamp"
local desired_stamp current_stamp=""
desired_stamp=$(compute_recursive_preload_stamp)
if [[ -f $archive_path && -f $stamp_path ]]; then
current_stamp=$(cat "$stamp_path" 2>/dev/null || true)
if [[ $current_stamp == "$desired_stamp" ]]; then
printf '%s\n' "$archive_path"
return 0
fi
fi
assert_path_within_code_dir "$archive_dir"
mkdir -p "$archive_dir"
local overlay_dir
overlay_dir=$(create_temp_dir "recursive-preload")
local helper
for helper in sloptrap-entrypoint sloptrap-helperd slop-apt slopcap sloppodman; do
populate_embedded_helper "$helper" "$overlay_dir/usr/local/bin/$helper"
done
chmod 0755 \
"$overlay_dir/usr/local/bin/sloptrap-entrypoint" \
"$overlay_dir/usr/local/bin/sloptrap-helperd" \
"$overlay_dir/usr/local/bin/slop-apt" \
"$overlay_dir/usr/local/bin/slopcap" \
"$overlay_dir/usr/local/bin/sloppodman"
local tmp_archive="$archive_path.tmp"
rm -f "$tmp_archive"
if ! run_with_nested_podman_root tar --numeric-owner --one-file-system \
--exclude=./proc \
--exclude=./sys \
--exclude=./dev \
--exclude=./run \
--exclude=./tmp \
--exclude=./workspace \
--exclude=./codex \
--exclude=./usr/local/bin/sloptrap-entrypoint \
--exclude=./usr/local/bin/sloptrap-helperd \
--exclude=./usr/local/bin/slop-apt \
--exclude=./usr/local/bin/slopcap \
--exclude=./usr/local/bin/sloppodman \
-cf "$tmp_archive" -C / .; then
rm -f "$tmp_archive"
return 1
fi
if ! tar --numeric-owner -rf "$tmp_archive" -C "$overlay_dir" .; then
rm -f "$tmp_archive"
return 1
fi
mv "$tmp_archive" "$archive_path"
printf '%s\n' "$desired_stamp" >"$stamp_path"
printf '%s\n' "$archive_path"
}
import_recursive_parent_image() {
local engine_name=${CONTAINER_ENGINE##*/}
local archive_path=${SLOPTRAP_RECURSIVE_PARENT_IMAGE_ARCHIVE:-}
case "$engine_name" in
sloppodman|sloppodman*|.sloppodman*)
;;
*)
return 1
;;
esac
capability_list_contains "${SLOPTRAP_ACTIVE_CAPABILITIES:-}" "nested-podman" || return 1
if [[ -n $archive_path ]]; then
[[ -r $archive_path ]] || return 1
else
if ! archive_path=$(prepare_recursive_parent_image_archive); then
return 1
fi
fi
if ! "$CONTAINER_ENGINE" import \
--change 'ENTRYPOINT ["/usr/local/bin/sloptrap-entrypoint"]' \
--change 'WORKDIR /workspace' \
--change 'ENV SHELL=/bin/bash' \
--change 'ENV HOME=/home/sloptrap' \
--change "LABEL $SLOPTRAP_IMAGE_LABEL" \
"$archive_path" \
"$SLOPTRAP_IMAGE_NAME"; then
return 1
fi
write_capability_build_stamp
return 0
}
build_if_missing() {
ensure_capability_trust
if $DRY_RUN; then
@@ -2888,6 +3151,12 @@ build_if_missing() {
fi
return 0
fi
if load_recursive_parent_image; then
return 0
fi
if import_recursive_parent_image; then
return 0
fi
build_image
}
@@ -2934,6 +3203,7 @@ prune_sloptrap_images() {
run_codex_command() {
local -a extra_args=("$@")
ensure_codex_storage_paths
prepare_recursive_parent_image_preload || true
local -a cmd=("${BASE_CONTAINER_CMD[@]}" "$SLOPTRAP_IMAGE_NAME" "codex")
if [[ ${#CODEX_ARGS_ARRAY[@]} -gt 0 ]]; then
cmd+=("${CODEX_ARGS_ARRAY[@]}")
@@ -2955,6 +3225,7 @@ run_codex() {
run_login_target() {
ensure_codex_storage_paths
prepare_recursive_parent_image_preload || true
if ! $DRY_RUN; then
status_line "Login %s\n" "$SLOPTRAP_IMAGE_NAME"
fi
@@ -2964,6 +3235,7 @@ run_login_target() {
run_shell_target() {
ensure_codex_storage_paths
prepare_recursive_parent_image_preload || true
if ! $DRY_RUN; then
status_line "Shell %s\n" "$SLOPTRAP_IMAGE_NAME"
fi