mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
258 lines
6.9 KiB
Bash
Executable File
258 lines
6.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# Variant B (local-image + excludes):
|
|
# - Build the local Infinito.Nexus Docker image via Makefile (make build/build-no-cache/build-missing)
|
|
# - Use ONLY that local image tag (e.g. infinito-arch) for the deploy container (no pulling pkgmgr images)
|
|
# - Compute excluded roles automatically based on "invokable" roles and the selected type
|
|
# - Run the real deploy via: python3 -m cli.deploy.container run ...
|
|
#
|
|
# It uses cli/deploy/container.py which supports:
|
|
# python3 -m cli.deploy.container run [container-opts] -- [inventory-args ...] -- [deploy-args ...]
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
|
|
|
|
TYPE=""
|
|
DISTRO=""
|
|
IMAGE=""
|
|
NO_CACHE=0
|
|
MISSING_ONLY=0
|
|
|
|
# -------------------------------------------------------------------
|
|
# Config (kept from the previous version)
|
|
# -------------------------------------------------------------------
|
|
MASK_CREDENTIALS_IN_LOGS_DEFAULT="false"
|
|
MASK_CREDENTIALS_IN_LOGS="${MASK_CREDENTIALS_IN_LOGS:-$MASK_CREDENTIALS_IN_LOGS_DEFAULT}"
|
|
|
|
AUTHORIZED_KEYS_DEFAULT="ssh-ed25519 AAAA_TEST_DUMMY_KEY github-ci-dummy@infinito"
|
|
AUTHORIZED_KEYS="${AUTHORIZED_KEYS:-$AUTHORIZED_KEYS_DEFAULT}"
|
|
|
|
# Optional: allow adding additional excludes globally (comma-separated or newline-separated)
|
|
ALWAYS_EXCLUDE="${ALWAYS_EXCLUDE:-}"
|
|
|
|
# Central excludes (same everywhere) - can be comma-separated or newline-separated.
|
|
BASE_EXCLUDE="${BASE_EXCLUDE:-$(
|
|
cat <<'EOF'
|
|
drv-lid-switch
|
|
svc-db-memcached
|
|
svc-db-redis
|
|
svc-net-wireguard-core
|
|
svc-net-wireguard-firewalled
|
|
svc-net-wireguard-plain
|
|
svc-bkp-loc-2-usb
|
|
svc-bkp-rmt-2-loc
|
|
svc-opt-keyboard-color
|
|
svc-opt-ssd-hdd
|
|
web-app-bridgy-fed
|
|
web-app-oauth2-proxy
|
|
web-app-postmarks
|
|
web-app-elk
|
|
web-app-syncope
|
|
web-app-socialhome
|
|
web-svc-xmpp
|
|
EOF
|
|
)}"
|
|
|
|
usage() {
|
|
cat <<'EOF'
|
|
Usage: scripts/tests/deploy.sh --type <server|workstation|universal> --distro <arch|debian|ubuntu|fedora|centos> [options]
|
|
|
|
Options:
|
|
--image <name> Use a specific local image tag (no pull). Default: infinito-<distro>
|
|
--no-cache Rebuild image with --no-cache (make build-no-cache)
|
|
--missing Build only if missing (make build-missing)
|
|
-h, --help Show this help
|
|
|
|
What it runs:
|
|
1) INFINITO_DISTRO=<distro> make build|build-no-cache|build-missing
|
|
2) Compute excluded roles (invokable-based) + BASE_EXCLUDE + ALWAYS_EXCLUDE
|
|
3) python3 -m cli.deploy.container run --image <local-image> -- [inventory-args] -- [deploy-args]
|
|
EOF
|
|
}
|
|
|
|
die() {
|
|
echo "[ERROR] $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
trim_lines() { sed -e 's/[[:space:]]\+$//' -e '/^$/d'; }
|
|
|
|
join_by_comma() {
|
|
local IFS=","
|
|
echo "$*"
|
|
}
|
|
|
|
get_invokable() {
|
|
docker run --rm \
|
|
-e INSTALL_LOCAL_BUILD=1 \
|
|
-e INSTALL_LOCAL_BUILD_SILENCE=1 \
|
|
-v "${REPO_ROOT}:/opt/src/infinito" \
|
|
-w /opt/src/infinito \
|
|
"${IMAGE}" \
|
|
python3 -m cli.meta.applications.invokable | trim_lines
|
|
}
|
|
|
|
filter_allowed() {
|
|
local type="$1"
|
|
case "$type" in
|
|
workstation)
|
|
# desk-* and util-desk-*
|
|
grep -E '^(desk-|util-desk-)' || true
|
|
;;
|
|
server)
|
|
# web-* (includes web-app-*, web-svc-*, etc.)
|
|
grep -E '^web-|svc-db-' || true
|
|
;;
|
|
universal)
|
|
cat
|
|
;;
|
|
*)
|
|
die "Unknown deploy type: $type (expected: workstation|server|universal)"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
compute_exclude_csv() {
|
|
local type="$1"
|
|
local all allowed computed combined final
|
|
local drv_exclude
|
|
local -a arr=()
|
|
|
|
all="$(get_invokable)" || die "get_invokable failed (cli.meta.applications.invokable not available?)"
|
|
|
|
allowed="$(printf "%s\n" "$all" | filter_allowed "$type")"
|
|
|
|
computed="$(
|
|
comm -23 \
|
|
<(printf "%s\n" "$all" | LC_ALL=C sort) \
|
|
<(printf "%s\n" "$allowed" | LC_ALL=C sort) |
|
|
trim_lines
|
|
)"
|
|
|
|
drv_exclude="$(printf "%s\n" "$all" | grep -E '^drv-' || true)"
|
|
|
|
combined="$(
|
|
printf "%s\n%s\n%s\n%s\n" \
|
|
"$computed" \
|
|
"$drv_exclude" \
|
|
"$(printf "%s\n" "$BASE_EXCLUDE" | tr ',' '\n')" \
|
|
"$(printf "%s\n" "$ALWAYS_EXCLUDE" | tr ',' '\n')" |
|
|
trim_lines | LC_ALL=C sort -u
|
|
)"
|
|
|
|
final="$(
|
|
comm -12 \
|
|
<(printf "%s\n" "$combined" | LC_ALL=C sort) \
|
|
<(printf "%s\n" "$all" | LC_ALL=C sort) |
|
|
trim_lines
|
|
)"
|
|
|
|
# final is newline-separated -> read safely into array (no word-splitting/globbing)
|
|
if [[ -n "${final}" ]]; then
|
|
mapfile -t arr <<<"${final}"
|
|
fi
|
|
|
|
if [[ ${#arr[@]} -eq 0 ]]; then
|
|
echo ""
|
|
else
|
|
join_by_comma "${arr[@]}"
|
|
fi
|
|
}
|
|
|
|
# -------------------------------------------------------------------
|
|
# Args
|
|
# -------------------------------------------------------------------
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--type)
|
|
TYPE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--distro)
|
|
DISTRO="${2:-}"
|
|
shift 2
|
|
;;
|
|
--image)
|
|
IMAGE="${2:-}"
|
|
shift 2
|
|
;;
|
|
--no-cache)
|
|
NO_CACHE=1
|
|
shift
|
|
;;
|
|
--missing)
|
|
MISSING_ONLY=1
|
|
shift
|
|
;;
|
|
-h | --help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*) die "Unknown argument: $1" ;;
|
|
esac
|
|
done
|
|
|
|
[[ -n "${TYPE}" ]] || die "--type is required"
|
|
[[ -n "${DISTRO}" ]] || die "--distro is required"
|
|
|
|
case "${TYPE}" in
|
|
server | workstation | universal) ;;
|
|
*) die "Invalid --type '${TYPE}' (expected: server|workstation|universal)" ;;
|
|
esac
|
|
|
|
case "${DISTRO}" in
|
|
arch | debian | ubuntu | fedora | centos) ;;
|
|
*) die "Invalid --distro '${DISTRO}' (expected: arch|debian|ubuntu|fedora|centos)" ;;
|
|
esac
|
|
|
|
if [[ -z "${IMAGE}" ]]; then
|
|
IMAGE="infinito-${DISTRO}"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Build local image via Makefile
|
|
# ---------------------------------------------------------------------------
|
|
echo ">>> Deploy type: ${TYPE}"
|
|
echo ">>> Distro: ${DISTRO}"
|
|
echo ">>> Local image: ${IMAGE}"
|
|
echo ">>> Repo root: ${REPO_ROOT}"
|
|
|
|
pushd "${REPO_ROOT}" >/dev/null
|
|
|
|
if [[ "${NO_CACHE}" == "1" ]]; then
|
|
echo ">>> make build-no-cache (INFINITO_DISTRO=${DISTRO})"
|
|
INFINITO_DISTRO="${DISTRO}" make build-no-cache
|
|
elif [[ "${MISSING_ONLY}" == "1" ]]; then
|
|
echo ">>> make build-missing (INFINITO_DISTRO=${DISTRO})"
|
|
INFINITO_DISTRO="${DISTRO}" make build-missing
|
|
else
|
|
echo ">>> make build (INFINITO_DISTRO=${DISTRO})"
|
|
INFINITO_DISTRO="${DISTRO}" make build
|
|
fi
|
|
|
|
docker image inspect "${IMAGE}" >/dev/null 2>&1 || die "Local image not found after build: ${IMAGE}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Compute excludes (restored)
|
|
# ---------------------------------------------------------------------------
|
|
EXCLUDE_CSV="$(compute_exclude_csv "${TYPE}")"
|
|
echo ">>> Excluded roles: ${EXCLUDE_CSV:-<none>}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Run deploy via container runner
|
|
# container run -- [inventory-args ...] -- [deploy-args ...]
|
|
# ---------------------------------------------------------------------------
|
|
echo ">>> Running deploy via cli.deploy.container (local image only)..."
|
|
python3 -m cli.deploy.container run \
|
|
--image "${IMAGE}" \
|
|
-- \
|
|
--exclude "${EXCLUDE_CSV}" \
|
|
--vars "{\"MASK_CREDENTIALS_IN_LOGS\": ${MASK_CREDENTIALS_IN_LOGS}}" \
|
|
--authorized-keys "${AUTHORIZED_KEYS}" \
|
|
-- \
|
|
-T "${TYPE}"
|
|
|
|
popd >/dev/null
|
|
echo ">>> Deploy test suite finished successfully."
|