From 87a23e97725f2af24ed20c4e1d71afe4d6529ffc Mon Sep 17 00:00:00 2001 From: Samuel Aubertin Date: Mon, 9 Mar 2026 19:23:21 +0100 Subject: [PATCH] Self contained sloptrap with helpers within --- .sloptrap | 2 +- README.md | 2 +- slop-apt | 43 ----- slopcap | 85 --------- sloppodman | 97 ---------- sloptrap | 442 +++++++++++++++++++++++++++++++++++++++++++- sloptrap-entrypoint | 30 --- sloptrap-helperd | 146 --------------- tests/run_tests.sh | 45 +++++ 9 files changed, 485 insertions(+), 407 deletions(-) delete mode 100644 slop-apt delete mode 100644 slopcap delete mode 100644 sloppodman delete mode 100644 sloptrap-entrypoint delete mode 100644 sloptrap-helperd diff --git a/.sloptrap b/.sloptrap index 0900dce..d09d324 100644 --- a/.sloptrap +++ b/.sloptrap @@ -1,4 +1,4 @@ name=skz-sloptrap -packages_extra=make shellcheck jq podman +packages_extra=bash make shellcheck jq podman capabilities=apt-install nested-podman packet-capture allow_host_network=false diff --git a/README.md b/README.md index 799ff52..cb8afbf 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ brew install coreutils gnu-tar jq ## Quick Start -1. Place `sloptrap` somewhere on your PATH/shared drive (the helper Dockerfile and Codex binary are bundled and downloaded automatically). +1. Place `sloptrap` somewhere on your PATH/shared drive, for example with `make install` (the helper payload, helper Dockerfile, and Codex binary handling are bundled into the launcher). 2. (Optional) Create a project-specific manifest and ignore file: ```bash cat > path/to/project/.sloptrap <<'EOF' diff --git a/slop-apt b/slop-apt deleted file mode 100644 index f0efa03..0000000 --- a/slop-apt +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} -queue_dir="$helper_dir/queue" -mkdir -p "$queue_dir" - -if [[ ${1-} != "install" ]]; then - printf 'usage: slop-apt install \n' >&2 - exit 2 -fi -shift - -if [[ $# -eq 0 ]]; then - printf 'slop-apt: at least one package is required\n' >&2 - exit 2 -fi - -for package in "$@"; do - if [[ ! $package =~ ^[A-Za-z0-9+.-]+$ ]]; then - printf 'slop-apt: invalid package name %s\n' "$package" >&2 - exit 2 - fi -done - -request_dir=$(mktemp -d "$queue_dir/request.XXXXXX.req") -trap 'rm -rf "$request_dir"' EXIT INT TERM HUP -printf 'apt-install\n' >"$request_dir/op" -printf '%s\n' "$@" >"$request_dir/packages" - -while [[ ! -f "$request_dir/status" ]]; do - sleep 1 -done - -if [[ -s "$request_dir/stdout" ]]; then - cat "$request_dir/stdout" -fi -if [[ -s "$request_dir/stderr" ]]; then - cat "$request_dir/stderr" >&2 -fi - -status=$(<"$request_dir/status") -exit "$status" diff --git a/slopcap b/slopcap deleted file mode 100644 index 5776d88..0000000 --- a/slopcap +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} -queue_dir="$helper_dir/queue" -default_output=${SLOPTRAP_CAPTURE_DIR:-/codex/state/captures} -mkdir -p "$queue_dir" "$default_output" - -if [[ ${1-} != "capture" ]]; then - printf 'usage: slopcap capture --interface [--filter ] [--output ] [--stdout]\n' >&2 - exit 2 -fi -shift - -iface="" -filter="" -output="" -stdout_mode=0 - -while [[ $# -gt 0 ]]; do - case "$1" in - --interface) - shift - [[ $# -gt 0 ]] || { printf 'slopcap: --interface requires a value\n' >&2; exit 2; } - iface=$1 - ;; - --filter) - shift - [[ $# -gt 0 ]] || { printf 'slopcap: --filter requires a value\n' >&2; exit 2; } - filter=$1 - ;; - --output) - shift - [[ $# -gt 0 ]] || { printf 'slopcap: --output requires a value\n' >&2; exit 2; } - output=$1 - ;; - --stdout) - stdout_mode=1 - ;; - *) - printf 'slopcap: unsupported argument %s\n' "$1" >&2 - exit 2 - ;; - esac - shift -done - -[[ -n $iface ]] || { printf 'slopcap: --interface is required\n' >&2; exit 2; } -if [[ -z $output && $stdout_mode -eq 0 ]]; then - output="$default_output/capture-$(date +%s).pcap" -fi - -request_dir=$(mktemp -d "$queue_dir/request.XXXXXX.req") -trap 'rm -rf "$request_dir"' EXIT INT TERM HUP -printf 'packet-capture\n' >"$request_dir/op" -printf '%s\n' "$iface" >"$request_dir/interface" -printf '%s\n' "$filter" >"$request_dir/filter" -printf '%s\n' "$output" >"$request_dir/output" -printf '%s\n' "$stdout_mode" >"$request_dir/stdout_mode" - -stream_pid="" -if [[ $stdout_mode -eq 1 ]]; then - touch "$request_dir/stdout" - tail -f "$request_dir/stdout" & - stream_pid=$! -fi - -while [[ ! -f "$request_dir/status" ]]; do - sleep 1 -done - -if [[ -n $stream_pid ]]; then - kill "$stream_pid" >/dev/null 2>&1 || true - wait "$stream_pid" >/dev/null 2>&1 || true -fi - -if [[ $stdout_mode -eq 0 && -s "$request_dir/stdout" ]]; then - cat "$request_dir/stdout" -fi -if [[ -s "$request_dir/stderr" ]]; then - cat "$request_dir/stderr" >&2 -fi - -status=$(<"$request_dir/status") -exit "$status" diff --git a/sloppodman b/sloppodman deleted file mode 100644 index 1eb874a..0000000 --- a/sloppodman +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -if [[ $# -eq 0 ]]; then - printf 'usage: sloppodman ...\n' >&2 - exit 2 -fi - -subcommand=$1 -shift - -case "$subcommand" in - pull|build|tag|run|ps|logs|stop|rm|inspect) - ;; - *) - printf 'sloppodman: unsupported subcommand %s\n' "$subcommand" >&2 - exit 2 - ;; -esac - -workspace_root=${SLOPTRAP_WORKDIR:-/workspace} -podman_root=${SLOPTRAP_INNER_PODMAN_ROOT:-/codex/capabilities/podman/storage} -podman_runroot=${SLOPTRAP_INNER_PODMAN_RUNROOT:-/codex/capabilities/podman/run} -runtime_dir=${XDG_RUNTIME_DIR:-/codex/capabilities/podman/runtime} -mkdir -p "$podman_root" "$podman_runroot" "$runtime_dir" - -resolve_inner_path() { - local raw=$1 - if command -v realpath >/dev/null 2>&1; then - realpath -m "$raw" - return - fi - case "$raw" in - /*) printf '%s\n' "$raw" ;; - *) printf '%s/%s\n' "$(pwd -P)" "$raw" ;; - esac -} - -validate_workspace_path() { - local path=$1 - path=$(resolve_inner_path "$path") - case "$path" in - "$workspace_root"|"${workspace_root}/"*) ;; - *) - printf 'sloppodman: path must stay within %s (%s)\n' "$workspace_root" "$path" >&2 - exit 2 - ;; - esac -} - -if [[ $subcommand == "build" ]]; then - args=("$@") - context="" - idx=0 - while (( idx < ${#args[@]} )); do - arg=${args[$idx]} - case "$arg" in - -f|--file) - ((idx+=1)) - (( idx < ${#args[@]} )) || { printf 'sloppodman: %s requires a path\n' "$arg" >&2; exit 2; } - validate_workspace_path "${args[$idx]}" - ;; - --network) - ((idx+=1)) - (( idx < ${#args[@]} )) || { printf 'sloppodman: --network requires a value\n' >&2; exit 2; } - if [[ ${args[$idx]} == "host" && ${SLOPTRAP_INNER_PODMAN_HOST_NETWORK:-0} != 1 ]]; then - printf 'sloppodman: host networking is not available in this session\n' >&2 - exit 2 - fi - ;; - esac - ((idx+=1)) - done - if [[ ${#args[@]} -gt 0 ]]; then - context=${args[$(( ${#args[@]} - 1 ))]} - validate_workspace_path "$context" - fi -fi - -if [[ $subcommand == "run" ]]; then - args=("$@") - idx=0 - while (( idx < ${#args[@]} )); do - arg=${args[$idx]} - if [[ $arg == "--network" ]]; then - ((idx+=1)) - (( idx < ${#args[@]} )) || { printf 'sloppodman: --network requires a value\n' >&2; exit 2; } - if [[ ${args[$idx]} == "host" && ${SLOPTRAP_INNER_PODMAN_HOST_NETWORK:-0} != 1 ]]; then - printf 'sloppodman: host networking is not available in this session\n' >&2 - exit 2 - fi - fi - ((idx+=1)) - done -fi - -exec podman --root "$podman_root" --runroot "$podman_runroot" "$subcommand" "$@" diff --git a/sloptrap b/sloptrap index 5783e3b..9e2dfa6 100755 --- a/sloptrap +++ b/sloptrap @@ -346,6 +346,443 @@ ENTRYPOINT ["/usr/local/bin/sloptrap-entrypoint"] EOF } +write_embedded_helper() { + local helper=$1 + case "$helper" in + sloptrap-entrypoint) + cat <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +helper_pid="" + +cleanup() { + if [[ -n $helper_pid ]]; then + kill "$helper_pid" >/dev/null 2>&1 || true + wait "$helper_pid" >/dev/null 2>&1 || true + fi +} + +trap cleanup EXIT INT TERM HUP + +if [[ $# -eq 0 ]]; then + set -- codex +fi + +if [[ $(id -u) -eq 0 ]]; then + helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} + mkdir -p "$helper_dir/queue" + chmod 700 "$helper_dir" + if [[ -n ${SLOPTRAP_ACTIVE_CAPABILITIES:-} ]]; then + /usr/local/bin/sloptrap-helperd & + helper_pid=$! + fi + exec runuser -u sloptrap --preserve-environment -- "$@" +fi + +exec "$@" +EOF + ;; + sloptrap-helperd) + cat <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} +queue_dir="$helper_dir/queue" +caps=${SLOPTRAP_ACTIVE_CAPABILITIES:-} +audit_log=${SLOPTRAP_AUDIT_LOG:-/codex/state/capabilities.log} +mkdir -p "$queue_dir" "$(dirname "$audit_log")" + +has_capability() { + local needle=$1 + local token + for token in $caps; do + if [[ $token == "$needle" ]]; then + return 0 + fi + done + return 1 +} + +log_action() { + local op=$1 + local details=$2 + local status=$3 + printf '%s op=%s status=%s %s\n' "$(date -u +%FT%TZ)" "$op" "$status" "$details" >>"$audit_log" +} + +write_status() { + local request_dir=$1 + local status=$2 + printf '%s\n' "$status" >"$request_dir/status" +} + +run_apt_install() { + local request_dir=$1 + has_capability "apt-install" || { + printf 'capability apt-install is not active\n' >"$request_dir/stderr" + write_status "$request_dir" 126 + log_action "apt-install" "packages=denied" 126 + return + } + local packages_file="$request_dir/packages" + if [[ ! -f $packages_file ]]; then + printf 'missing package list\n' >"$request_dir/stderr" + write_status "$request_dir" 2 + log_action "apt-install" "packages=missing" 2 + return + fi + mapfile -t packages <"$packages_file" + if [[ ${#packages[@]} -eq 0 ]]; then + printf 'package list is empty\n' >"$request_dir/stderr" + write_status "$request_dir" 2 + log_action "apt-install" "packages=empty" 2 + return + fi + if apt-get update >"$request_dir/stdout" 2>"$request_dir/stderr" \ + && apt-get install -y --no-install-recommends "${packages[@]}" >>"$request_dir/stdout" 2>>"$request_dir/stderr"; then + write_status "$request_dir" 0 + log_action "apt-install" "packages=${packages[*]}" 0 + return + fi + write_status "$request_dir" 1 + log_action "apt-install" "packages=${packages[*]}" 1 +} + +run_packet_capture() { + local request_dir=$1 + has_capability "packet-capture" || { + printf 'capability packet-capture is not active\n' >"$request_dir/stderr" + write_status "$request_dir" 126 + log_action "packet-capture" "interface=denied" 126 + return + } + local iface_file="$request_dir/interface" + [[ -f $iface_file ]] || { + printf 'missing interface\n' >"$request_dir/stderr" + write_status "$request_dir" 2 + log_action "packet-capture" "interface=missing" 2 + return + } + local iface filter_file output_file stdout_mode + iface=$(<"$iface_file") + filter_file="$request_dir/filter" + output_file="$request_dir/output" + stdout_mode=0 + [[ -f "$request_dir/stdout_mode" ]] && stdout_mode=$(<"$request_dir/stdout_mode") + local -a cmd=(tcpdump -i "$iface") + if [[ -s $filter_file ]]; then + local filter + filter=$(<"$filter_file") + local -a filter_tokens=() + read -r -a filter_tokens <<< "$filter" + cmd+=("${filter_tokens[@]}") + fi + if [[ -s $output_file ]]; then + local capture_path + capture_path=$(<"$output_file") + mkdir -p "$(dirname "$capture_path")" + cmd+=(-w "$capture_path") + fi + if [[ $stdout_mode == "1" ]]; then + "${cmd[@]}" >"$request_dir/stdout" 2>"$request_dir/stderr" || { + write_status "$request_dir" 1 + log_action "packet-capture" "interface=$iface stdout=1" 1 + return + } + else + "${cmd[@]}" >"$request_dir/stdout" 2>"$request_dir/stderr" || { + write_status "$request_dir" 1 + log_action "packet-capture" "interface=$iface stdout=0" 1 + return + } + fi + write_status "$request_dir" 0 + log_action "packet-capture" "interface=$iface stdout=$stdout_mode" 0 +} + +while true; do + shopt -s nullglob + request_dirs=("$queue_dir"/*.req) + shopt -u nullglob + if [[ ${#request_dirs[@]} -eq 0 ]]; then + sleep 1 + continue + fi + for request_dir in "${request_dirs[@]}"; do + [[ -d $request_dir ]] || continue + [[ ! -f "$request_dir/status" ]] || continue + op=$(<"$request_dir/op") + : >"$request_dir/stdout" + : >"$request_dir/stderr" + case "$op" in + apt-install) + run_apt_install "$request_dir" + ;; + packet-capture) + run_packet_capture "$request_dir" + ;; + *) + printf 'unknown operation %s\n' "$op" >"$request_dir/stderr" + write_status "$request_dir" 2 + log_action "$op" "unknown=1" 2 + ;; + esac + done +done +EOF + ;; + slop-apt) + cat <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} +queue_dir="$helper_dir/queue" +mkdir -p "$queue_dir" + +if [[ ${1-} != "install" ]]; then + printf 'usage: slop-apt install \n' >&2 + exit 2 +fi +shift + +if [[ $# -eq 0 ]]; then + printf 'slop-apt: at least one package is required\n' >&2 + exit 2 +fi + +for package in "$@"; do + if [[ ! $package =~ ^[A-Za-z0-9+.-]+$ ]]; then + printf 'slop-apt: invalid package name %s\n' "$package" >&2 + exit 2 + fi +done + +request_dir=$(mktemp -d "$queue_dir/request.XXXXXX.req") +trap 'rm -rf "$request_dir"' EXIT INT TERM HUP +printf 'apt-install\n' >"$request_dir/op" +printf '%s\n' "$@" >"$request_dir/packages" + +while [[ ! -f "$request_dir/status" ]]; do + sleep 1 +done + +if [[ -s "$request_dir/stdout" ]]; then + cat "$request_dir/stdout" +fi +if [[ -s "$request_dir/stderr" ]]; then + cat "$request_dir/stderr" >&2 +fi + +status=$(<"$request_dir/status") +exit "$status" +EOF + ;; + slopcap) + cat <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} +queue_dir="$helper_dir/queue" +default_output=${SLOPTRAP_CAPTURE_DIR:-/codex/state/captures} +mkdir -p "$queue_dir" "$default_output" + +if [[ ${1-} != "capture" ]]; then + printf 'usage: slopcap capture --interface [--filter ] [--output ] [--stdout]\n' >&2 + exit 2 +fi +shift + +iface="" +filter="" +output="" +stdout_mode=0 + +while [[ $# -gt 0 ]]; do + case "$1" in + --interface) + shift + [[ $# -gt 0 ]] || { printf 'slopcap: --interface requires a value\n' >&2; exit 2; } + iface=$1 + ;; + --filter) + shift + [[ $# -gt 0 ]] || { printf 'slopcap: --filter requires a value\n' >&2; exit 2; } + filter=$1 + ;; + --output) + shift + [[ $# -gt 0 ]] || { printf 'slopcap: --output requires a value\n' >&2; exit 2; } + output=$1 + ;; + --stdout) + stdout_mode=1 + ;; + *) + printf 'slopcap: unsupported argument %s\n' "$1" >&2 + exit 2 + ;; + esac + shift +done + +[[ -n $iface ]] || { printf 'slopcap: --interface is required\n' >&2; exit 2; } +if [[ -z $output && $stdout_mode -eq 0 ]]; then + output="$default_output/capture-$(date +%s).pcap" +fi + +request_dir=$(mktemp -d "$queue_dir/request.XXXXXX.req") +trap 'rm -rf "$request_dir"' EXIT INT TERM HUP +printf 'packet-capture\n' >"$request_dir/op" +printf '%s\n' "$iface" >"$request_dir/interface" +printf '%s\n' "$filter" >"$request_dir/filter" +printf '%s\n' "$output" >"$request_dir/output" +printf '%s\n' "$stdout_mode" >"$request_dir/stdout_mode" + +stream_pid="" +if [[ $stdout_mode -eq 1 ]]; then + touch "$request_dir/stdout" + tail -f "$request_dir/stdout" & + stream_pid=$! +fi + +while [[ ! -f "$request_dir/status" ]]; do + sleep 1 +done + +if [[ -n $stream_pid ]]; then + kill "$stream_pid" >/dev/null 2>&1 || true + wait "$stream_pid" >/dev/null 2>&1 || true +fi + +if [[ $stdout_mode -eq 0 && -s "$request_dir/stdout" ]]; then + cat "$request_dir/stdout" +fi +if [[ -s "$request_dir/stderr" ]]; then + cat "$request_dir/stderr" >&2 +fi + +status=$(<"$request_dir/status") +exit "$status" +EOF + ;; + sloppodman) + cat <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -eq 0 ]]; then + printf 'usage: sloppodman ...\n' >&2 + exit 2 +fi + +subcommand=$1 +shift + +case "$subcommand" in + pull|build|tag|run|ps|logs|stop|rm|inspect) + ;; + *) + printf 'sloppodman: unsupported subcommand %s\n' "$subcommand" >&2 + exit 2 + ;; +esac + +workspace_root=${SLOPTRAP_WORKDIR:-/workspace} +podman_root=${SLOPTRAP_INNER_PODMAN_ROOT:-/codex/capabilities/podman/storage} +podman_runroot=${SLOPTRAP_INNER_PODMAN_RUNROOT:-/codex/capabilities/podman/run} +runtime_dir=${XDG_RUNTIME_DIR:-/codex/capabilities/podman/runtime} +mkdir -p "$podman_root" "$podman_runroot" "$runtime_dir" + +resolve_inner_path() { + local raw=$1 + if command -v realpath >/dev/null 2>&1; then + realpath -m "$raw" + return + fi + case "$raw" in + /*) printf '%s\n' "$raw" ;; + *) printf '%s/%s\n' "$(pwd -P)" "$raw" ;; + esac +} + +validate_workspace_path() { + local path=$1 + path=$(resolve_inner_path "$path") + case "$path" in + "$workspace_root"|"${workspace_root}/"*) ;; + *) + printf 'sloppodman: path must stay within %s (%s)\n' "$workspace_root" "$path" >&2 + exit 2 + ;; + esac +} + +if [[ $subcommand == "build" ]]; then + args=("$@") + context="" + idx=0 + while (( idx < ${#args[@]} )); do + arg=${args[$idx]} + case "$arg" in + -f|--file) + ((idx+=1)) + (( idx < ${#args[@]} )) || { printf 'sloppodman: %s requires a path\n' "$arg" >&2; exit 2; } + validate_workspace_path "${args[$idx]}" + ;; + --network) + ((idx+=1)) + (( idx < ${#args[@]} )) || { printf 'sloppodman: --network requires a value\n' >&2; exit 2; } + if [[ ${args[$idx]} == "host" && ${SLOPTRAP_INNER_PODMAN_HOST_NETWORK:-0} != 1 ]]; then + printf 'sloppodman: host networking is not available in this session\n' >&2 + exit 2 + fi + ;; + esac + ((idx+=1)) + done + if [[ ${#args[@]} -gt 0 ]]; then + context=${args[$(( ${#args[@]} - 1 ))]} + validate_workspace_path "$context" + fi +fi + +if [[ $subcommand == "run" ]]; then + args=("$@") + idx=0 + while (( idx < ${#args[@]} )); do + arg=${args[$idx]} + if [[ $arg == "--network" ]]; then + ((idx+=1)) + (( idx < ${#args[@]} )) || { printf 'sloppodman: --network requires a value\n' >&2; exit 2; } + if [[ ${args[$idx]} == "host" && ${SLOPTRAP_INNER_PODMAN_HOST_NETWORK:-0} != 1 ]]; then + printf 'sloppodman: host networking is not available in this session\n' >&2 + exit 2 + fi + fi + ((idx+=1)) + done +fi + +exec podman --root "$podman_root" --runroot "$podman_runroot" "$subcommand" "$@" +EOF + ;; + *) + error "unknown embedded helper '$helper'" + ;; + esac +} + +populate_embedded_helper() { + local helper=$1 + local destination=$2 + mkdir -p "$(dirname "$destination")" + write_embedded_helper "$helper" >"$destination" +} + populate_dockerfile() { local destination=$1 mkdir -p "$(dirname "$destination")" @@ -387,10 +824,7 @@ prepare_build_context() { CODEX_BIN_PATH="$SLOPTRAP_BUILD_CONTEXT/$SLOPTRAP_CODEX_BIN_NAME" local helper for helper in sloptrap-entrypoint sloptrap-helperd slop-apt slopcap sloppodman; do - if [[ ! -f "$SCRIPT_DIR/$helper" ]]; then - error "required helper '$SCRIPT_DIR/$helper' not found" - fi - cp "$SCRIPT_DIR/$helper" "$SLOPTRAP_BUILD_CONTEXT/$helper" + populate_embedded_helper "$helper" "$SLOPTRAP_BUILD_CONTEXT/$helper" done } diff --git a/sloptrap-entrypoint b/sloptrap-entrypoint deleted file mode 100644 index d0f58ac..0000000 --- a/sloptrap-entrypoint +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -helper_pid="" - -cleanup() { - if [[ -n $helper_pid ]]; then - kill "$helper_pid" >/dev/null 2>&1 || true - wait "$helper_pid" >/dev/null 2>&1 || true - fi -} - -trap cleanup EXIT INT TERM HUP - -if [[ $# -eq 0 ]]; then - set -- codex -fi - -if [[ $(id -u) -eq 0 ]]; then - helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} - mkdir -p "$helper_dir/queue" - chmod 700 "$helper_dir" - if [[ -n ${SLOPTRAP_ACTIVE_CAPABILITIES:-} ]]; then - /usr/local/bin/sloptrap-helperd & - helper_pid=$! - fi - exec runuser -u sloptrap --preserve-environment -- "$@" -fi - -exec "$@" diff --git a/sloptrap-helperd b/sloptrap-helperd deleted file mode 100644 index 3860574..0000000 --- a/sloptrap-helperd +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -helper_dir=${SLOPTRAP_HELPER_DIR:-/run/sloptrap-helper} -queue_dir="$helper_dir/queue" -caps=${SLOPTRAP_ACTIVE_CAPABILITIES:-} -audit_log=${SLOPTRAP_AUDIT_LOG:-/codex/state/capabilities.log} -mkdir -p "$queue_dir" "$(dirname "$audit_log")" - -has_capability() { - local needle=$1 - local token - for token in $caps; do - if [[ $token == "$needle" ]]; then - return 0 - fi - done - return 1 -} - -log_action() { - local op=$1 - local details=$2 - local status=$3 - printf '%s op=%s status=%s %s\n' "$(date -u +%FT%TZ)" "$op" "$status" "$details" >>"$audit_log" -} - -write_status() { - local request_dir=$1 - local status=$2 - printf '%s\n' "$status" >"$request_dir/status" -} - -run_apt_install() { - local request_dir=$1 - has_capability "apt-install" || { - printf 'capability apt-install is not active\n' >"$request_dir/stderr" - write_status "$request_dir" 126 - log_action "apt-install" "packages=denied" 126 - return - } - local packages_file="$request_dir/packages" - if [[ ! -f $packages_file ]]; then - printf 'missing package list\n' >"$request_dir/stderr" - write_status "$request_dir" 2 - log_action "apt-install" "packages=missing" 2 - return - fi - mapfile -t packages <"$packages_file" - if [[ ${#packages[@]} -eq 0 ]]; then - printf 'package list is empty\n' >"$request_dir/stderr" - write_status "$request_dir" 2 - log_action "apt-install" "packages=empty" 2 - return - fi - if apt-get update >"$request_dir/stdout" 2>"$request_dir/stderr" \ - && apt-get install -y --no-install-recommends "${packages[@]}" >>"$request_dir/stdout" 2>>"$request_dir/stderr"; then - write_status "$request_dir" 0 - log_action "apt-install" "packages=${packages[*]}" 0 - return - fi - write_status "$request_dir" 1 - log_action "apt-install" "packages=${packages[*]}" 1 -} - -run_packet_capture() { - local request_dir=$1 - has_capability "packet-capture" || { - printf 'capability packet-capture is not active\n' >"$request_dir/stderr" - write_status "$request_dir" 126 - log_action "packet-capture" "interface=denied" 126 - return - } - local iface_file="$request_dir/interface" - [[ -f $iface_file ]] || { - printf 'missing interface\n' >"$request_dir/stderr" - write_status "$request_dir" 2 - log_action "packet-capture" "interface=missing" 2 - return - } - local iface filter_file output_file stdout_mode - iface=$(<"$iface_file") - filter_file="$request_dir/filter" - output_file="$request_dir/output" - stdout_mode=0 - [[ -f "$request_dir/stdout_mode" ]] && stdout_mode=$(<"$request_dir/stdout_mode") - local -a cmd=(tcpdump -i "$iface") - if [[ -s $filter_file ]]; then - local filter - filter=$(<"$filter_file") - local -a filter_tokens=() - read -r -a filter_tokens <<< "$filter" - cmd+=("${filter_tokens[@]}") - fi - if [[ -s $output_file ]]; then - local capture_path - capture_path=$(<"$output_file") - mkdir -p "$(dirname "$capture_path")" - cmd+=(-w "$capture_path") - fi - if [[ $stdout_mode == "1" ]]; then - "${cmd[@]}" >"$request_dir/stdout" 2>"$request_dir/stderr" || { - write_status "$request_dir" 1 - log_action "packet-capture" "interface=$iface stdout=1" 1 - return - } - else - "${cmd[@]}" >"$request_dir/stdout" 2>"$request_dir/stderr" || { - write_status "$request_dir" 1 - log_action "packet-capture" "interface=$iface stdout=0" 1 - return - } - fi - write_status "$request_dir" 0 - log_action "packet-capture" "interface=$iface stdout=$stdout_mode" 0 -} - -while true; do - shopt -s nullglob - request_dirs=("$queue_dir"/*.req) - shopt -u nullglob - if [[ ${#request_dirs[@]} -eq 0 ]]; then - sleep 1 - continue - fi - for request_dir in "${request_dirs[@]}"; do - [[ -d $request_dir ]] || continue - [[ ! -f "$request_dir/status" ]] || continue - op=$(<"$request_dir/op") - : >"$request_dir/stdout" - : >"$request_dir/stderr" - case "$op" in - apt-install) - run_apt_install "$request_dir" - ;; - packet-capture) - run_packet_capture "$request_dir" - ;; - *) - printf 'unknown operation %s\n' "$op" >"$request_dir/stderr" - write_status "$request_dir" 2 - log_action "$op" "unknown=1" 2 - ;; - esac - done -done diff --git a/tests/run_tests.sh b/tests/run_tests.sh index ee6a710..1b090f0 100755 --- a/tests/run_tests.sh +++ b/tests/run_tests.sh @@ -717,6 +717,50 @@ run_capability_profiles() { teardown_stub_env } +run_make_install_single_file() { + local scenario_dir="$TEST_ROOT/resume_target" + printf '==> make_install_single_file\n' + if ! command -v make >/dev/null 2>&1; then + record_failure "make_install_single_file: make binary not found in PATH" + return + fi + setup_stub_env + local install_root install_dir installed_bin + install_root=$(mktemp -d) + install_dir="$install_root/bin" + installed_bin="$install_dir/sloptrap" + if ! make -C "$ROOT_DIR" install INSTALL_DIR="$install_dir" >/dev/null 2>&1; then + record_failure "make_install_single_file: make install failed" + teardown_stub_env + rm -rf "$install_root" + return + fi + if [[ ! -x $installed_bin ]]; then + record_failure "make_install_single_file: installed launcher missing" + fi + local helper + for helper in sloptrap-entrypoint sloptrap-helperd slop-apt slopcap sloppodman; do + if [[ -e $install_dir/$helper ]]; then + record_failure "make_install_single_file: unexpected helper installed ($helper)" + fi + done + if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \ + "$installed_bin" "$scenario_dir" /dev/null 2>&1; then + record_failure "make_install_single_file: installed launcher failed" + fi + if ! grep -q -- "FAKE PODMAN: build " "$STUB_LOG"; then + record_failure "make_install_single_file: installed launcher did not reach build path" + fi + if ! make -C "$ROOT_DIR" uninstall INSTALL_DIR="$install_dir" >/dev/null 2>&1; then + record_failure "make_install_single_file: make uninstall failed" + fi + if [[ -e $installed_bin ]]; then + record_failure "make_install_single_file: installed launcher not removed by uninstall" + fi + teardown_stub_env + rm -rf "$install_root" +} + run_shellcheck run_mount_injection run_root_target @@ -747,6 +791,7 @@ run_wizard_existing_defaults run_wizard_build_trigger run_capability_trust_required run_capability_profiles +run_make_install_single_file if [[ ${#failures[@]} -gt 0 ]]; then printf '\nTest failures:\n'