99 lines
2.7 KiB
Bash
99 lines
2.7 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
UID="$(id -u)"
|
|
USER_NAME="$(id -un)"
|
|
USER_BUS="/run/user/$UID/bus"
|
|
HM_DIR="$HOME/.config/home-manager"
|
|
SKEL_DIR="/etc/skel/.config/home-manager"
|
|
EXPECTED_USER="${NANUQSAURUS_ADMIN_USER:-}"
|
|
HM_TARGET="${NANUQSAURUS_HM_TARGET:-$USER_NAME}"
|
|
|
|
# Ensure basic PATH for user units
|
|
export PATH="/run/current-system/sw/bin:${PATH:-}"
|
|
|
|
# Attach to session bus if possible
|
|
if [[ -z "${DBUS_SESSION_BUS_ADDRESS:-}" && -S "$USER_BUS" ]]; then
|
|
export DBUS_SESSION_BUS_ADDRESS="unix:path=$USER_BUS"
|
|
fi
|
|
|
|
have() { command -v "$1" >/dev/null 2>&1; }
|
|
|
|
# ---- Session sanity check ---------------------------------------------------
|
|
|
|
if have loginctl && [[ -n "${XDG_SESSION_ID:-}" ]]; then
|
|
# One loginctl call instead of three
|
|
eval "$(
|
|
loginctl show-session "$XDG_SESSION_ID" \
|
|
-p Class -p State -p LockedHint \
|
|
--value 2>/dev/null |
|
|
awk '
|
|
NR==1{print "SESSION_CLASS="$0}
|
|
NR==2{print "SESSION_STATE="$0}
|
|
NR==3{print "SESSION_LOCKED="$0}
|
|
'
|
|
)"
|
|
|
|
[[ "${SESSION_CLASS:-}" == "user" ]] || exit 0
|
|
[[ "${SESSION_STATE:-}" == "active" ]] || exit 0
|
|
[[ "${SESSION_LOCKED:-yes}" == "no" ]] || exit 0
|
|
fi
|
|
|
|
# ---- Notifications ----------------------------------------------------------
|
|
|
|
notifications_ready() {
|
|
[[ "${XDG_SESSION_CLASS:-user}" == "user" ]] || return 1
|
|
[[ -n "${DBUS_SESSION_BUS_ADDRESS:-}" ]] || return 1
|
|
have gdbus || return 1
|
|
|
|
# Wait for unlock if loginctl is present
|
|
if have loginctl && [[ -n "${XDG_SESSION_ID:-}" ]]; then
|
|
for _ in {1..7}; do
|
|
[[ "$(loginctl show-session "$XDG_SESSION_ID" \
|
|
-p LockedHint --value 2>/dev/null)" == "no" ]] && break
|
|
sleep 2
|
|
done
|
|
fi
|
|
|
|
# Wait for notification service
|
|
for _ in {1..7}; do
|
|
gdbus introspect --session \
|
|
--dest org.freedesktop.Notifications \
|
|
--object-path /org/freedesktop/Notifications \
|
|
>/dev/null 2>&1 && return 0
|
|
sleep 2
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
notify() {
|
|
have notify-send || return 0
|
|
notifications_ready || return 0
|
|
notify-send \
|
|
--app-name="Bootstrap" \
|
|
--urgency=critical \
|
|
--expire-time=0 \
|
|
"$@" >/dev/null 2>&1 || true
|
|
}
|
|
|
|
notify "Reticulating Splines" "Bootstrapping. Please stay tuned."
|
|
trap 'notify "Bootstrap finished" "Your system is fully hydrated. It is recommended to logout and back in."' EXIT
|
|
|
|
# ---- Home Manager bootstrap -------------------------------------------------
|
|
|
|
if [[ -n "$EXPECTED_USER" && "$USER_NAME" != "$EXPECTED_USER" ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
mkdir -p "$HM_DIR"
|
|
|
|
for f in flake.nix home.nix; do
|
|
src="$SKEL_DIR/$f"
|
|
dst="$HM_DIR/$f"
|
|
[[ -f "$src" && ! -e "$dst" ]] || continue
|
|
install -m 600 "$src" "$dst"
|
|
done
|
|
|
|
home-manager switch --flake "$HM_DIR#$HM_TARGET"
|
|
touch "$HM_DIR/.hm_bootstrap_done"
|