Files
computer-playbook/scripts/tests/deploy.sh
T

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."