#!/bin/bash # Bienvenue + Maestro, in one command, on a freshly installed Ubuntu Desktop. # Run it from the account that will use the machine (not as root): # # wget -qO- https://welcome.debuck.info/install.sh | bash # wget -qO- https://welcome.debuck.info/install.sh | bash -s -- [options] # (curl -fsSL … | bash works too, but a fresh Ubuntu Desktop ships wget, not curl) # # Options: # --light do not download the AI image and model now (they can be fetched later in Maestro) # --vpn-address 10.42.0.NN/32 create the VPN profile for remote help (prints the public key to register) # --support-key "ssh-ed25519 …" public key allowed for remote help # --no-arm do not arm the first-login assistant set -euo pipefail BASE="${DBT_WELCOME_BASE:-https://welcome.debuck.info}" say() { printf '\n\033[1m== %s\033[0m\n' "$*"; } die() { printf '\033[31m%s\033[0m\n' "$*" >&2; exit 1; } CODE=""; LIGHT=0; ARGS=() while [ $# -gt 0 ]; do case "$1" in --light) LIGHT=1 ;; --vpn-address|--support-key|--ai-download) [ $# -ge 2 ] || die "$1 needs a value"; ARGS+=("$1" "$2"); shift ;; --no-arm|--ai-pull) ARGS+=("$1") ;; --*) die "unknown option $1" ;; *) [ -z "$CODE" ] || die "only one client code, got '$CODE' and '$1'"; CODE="$1" ;; esac shift done [[ "${CODE:-default}" =~ ^[a-z0-9][a-z0-9-]{0,40}$ ]] || die "that client code does not look right" [ "$(id -u)" != 0 ] || die "Run this from the user's own account, not as root: it asks for the password itself." command -v apt-get >/dev/null || die "This installer is made for Ubuntu." . /etc/os-release 2>/dev/null || true [ "${ID:-}" = ubuntu ] || echo "Note: made and tested for Ubuntu 26.10; this is ${PRETTY_NAME:-another system}." ACCOUNT="$(id -un)" WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT cd "$WORK" # a fresh Ubuntu Desktop has wget but not curl: use whichever is there if command -v curl >/dev/null; then get() { curl -fsSL --retry 3 -o "$2" "$BASE/$1" || die "could not download $BASE/$1"; } elif command -v wget >/dev/null; then get() { wget -q --tries=3 -O "$2" "$BASE/$1" || die "could not download $BASE/$1"; } else die "Neither curl nor wget is installed."; fi say "Downloading" get SHA256SUMS SHA256SUMS mkdir debs while read -r sum path; do case "$path" in debs/*.deb) echo " $path"; get "$path" "$path" ;; esac done < SHA256SUMS CLIENT_FILE="c/${CODE:-default}.tar.gz" grep -q " $CLIENT_FILE\$" SHA256SUMS || die "unknown client code '${CODE}'" mkdir c; get "$CLIENT_FILE" "$CLIENT_FILE" sha256sum --quiet -c <(grep -E " (debs/.*\.deb|$CLIENT_FILE)\$" SHA256SUMS) || die "a download is corrupted, try again" mkdir client && tar xzf "$CLIENT_FILE" -C client --strip-components=1 say "Installing the packages (your password is asked once)" sudo apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ./debs/*.deb papirus-icon-theme say "Preparing this machine" [ "$LIGHT" = 1 ] || ARGS=(--ai-pull --ai-download default "${ARGS[@]}") sudo dbt-welcome-prep --client "$WORK/client" --user "$ACCOUNT" --ai "${ARGS[@]}" say "Done" echo "Log out and back in: the Welcome assistant opens by itself." echo "Check the AI on this hardware first if you wish: maestro-validate"