#!/usr/bin/env bash # Thin curl-compatible entry point: # curl -fsSL https://install.ursalinux.de/install.sh | bash # Ensures Git exists, clones or updates the bootstrap, and starts it. set -euo pipefail REPO_URL="${URSA_REPO:-https://git.mamabaer.dev/UrsaLinux/bootstrap.git}" TARGET="${URSA_DIR:-$HOME/.local/share/ursa-linux/bootstrap}" SIGNING_FINGERPRINT="${URSA_SIGNING_FINGERPRINT-F9A12709A9C6F074D3D855334948330DA732F976}" info() { printf '[ursa][info] %s\n' "$*"; } fail() { printf '[ursa][error] %s\n' "$*" >&2; exit 1; } verify_git_signature() { local kind=$1 ref=$2 output if ! output="$(git -C "$TARGET" "verify-$kind" --raw "$ref" 2>&1)"; then printf '%s\n' "$output" >&2 fail "$ref does not have a valid signature" fi [[ -z $SIGNING_FINGERPRINT ]] && return 0 if ! awk -v expected="${SIGNING_FINGERPRINT^^}" ' $1 == "[GNUPG:]" && $2 == "VALIDSIG" && (toupper($3) == expected || toupper($NF) == expected) { found = 1 } END { exit !found } ' <<<"$output"; then fail "$ref was not signed by the expected Ursa key $SIGNING_FINGERPRINT" fi } if [[ ${EUID:-$(id -u)} -eq 0 ]]; then fail 'do not run as root or through sudo; the bootstrap requests privileges for individual changes' fi info "Ursa Linux bootstrap for ${USER:-$(id -un)}" info "Target: $TARGET" command -v sudo >/dev/null 2>&1 || fail 'sudo is missing; install it and add the user to the wheel group' if ! command -v git >/dev/null 2>&1; then info 'Git is missing; installing it with pacman' sudo pacman -S --needed --noconfirm git fi if [[ -d $TARGET/.git ]]; then info 'Updating the existing repository by fast-forward' git -C "$TARGET" pull --ff-only || fail "Update failed; inspect local changes in $TARGET" elif [[ -e $TARGET ]]; then fail "$TARGET exists but is not a Git repository" else info "Cloning $REPO_URL" mkdir -p "$(dirname "$TARGET")" git clone "$REPO_URL" "$TARGET" fi # The first-boot service enables signed-commit verification. Manual runs can # select their own verification mode. case "${URSA_VERIFY_REF:-}" in '') ;; signed-commit) info 'Verifying the HEAD signature' verify_git_signature commit HEAD ;; signed-tag) tag="$(git -C "$TARGET" describe --tags --abbrev=0 2>/dev/null)" || fail 'No tag found' info "Verifying tag signature: $tag" verify_git_signature tag "$tag" git -C "$TARGET" merge-base --is-ancestor "$tag" HEAD || fail "HEAD is not at or after signed tag $tag" ;; *) fail "Unknown URSA_VERIFY_REF value: $URSA_VERIFY_REF (expected signed-commit or signed-tag)" ;; esac exec "$TARGET/bootstrap.sh" "$@"