Files
Linux_post_install/postinstall.sh
T
Your Name 414a990801 refactor: pos system event-trigger → pos system schedule — per-job timers, notify policies, legacy migrate
The single-timer threshold monitor generalizes into a scheduler: each job is a
chmod-600 file in schedule.d/<name>.env (INTERVAL 5m..59m/1h..23h/hourly/daily/
weekly/OnCalendar=..., NOTIFY policy, optional MSG, RULE for threshold,
COMMAND = literal rest of line) with its own systemd user timer pair
(pos-schedule-<name>.timer + oneshot .service, Persistent, reconciled on
enable/disable — orphan units + the legacy pos-event-trigger timer
auto-removed). Policies: always (full output every run), onchange (diff vs
last run, first run sends), onerror (non-zero exit or empty output),
threshold (old event-trigger behavior: first numeric vs RULE, alert on
false→true + recovery, per-job firing state), never (silent side-effect jobs).
run [name|all], list, config (interactive add/edit/remove/enable/disable with
validation), enable/disable [name|all], status, migrate (converts legacy
event.env rules → rule-N.env threshold jobs, verbatim LHS as COMMAND, adopts
the legacy timer's OnCalendar or 5m, removes the old timer). Per-run logs +
state in ~/.local/share/linux_post_install/schedule/{logs,state}/.
config/event.env + event-rules.template → config/schedule.d/ starter jobs
(nvme-health, cpu-temp, disk-root, silent log-cleanup); postinstall installs
them no-clobber into an empty schedule.d/ (legacy event.env users get a
migrate hint instead). bin/pos EXAMPLES + INTERACTIVE_CMDS
(system-schedule config) updated; install.sh ships the renamed tool+lib.
2026-08-13 02:14:25 -04:00

159 lines
6.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
source "$(dirname "$0")/lib/common.sh"
source "$(dirname "$0")/lib/flags.sh"
log "Running post-install..."
# ── rclone config ──────────────────────────────────────────────
# Place your rclone.conf in config/ (gitignored) and this will install it.
if [ -f config/rclone.conf ]; then
run mkdir -p "$HOME/.config/rclone"
run cp config/rclone.conf "$HOME/.config/rclone/rclone.conf"
run chmod 600 "$HOME/.config/rclone/rclone.conf"
log "Installed rclone.conf"
else
warn "config/rclone.conf not found, skipping"
fi
# ── entertainment config ───────────────────────────────────────
# Generic template for the weather plugin — copied only if the user
# has not already created their own entertainment.env (no clobber).
ENT_DIR="$HOME/.config/linux_post_install"
if [ -f config/entertainment.env ]; then
run mkdir -p "$ENT_DIR"
if [ -f "$ENT_DIR/entertainment.env" ]; then
log "entertainment.env already exists, keeping it"
else
run cp config/entertainment.env "$ENT_DIR/entertainment.env"
run chmod 600 "$ENT_DIR/entertainment.env"
log "Installed entertainment.env — set your location:"
cat "$ENT_DIR/entertainment.env"
fi
else
warn "config/entertainment.env not found, skipping"
fi
# ── system + notify config templates ───────────────────────────
# Copied only if the user has not already created their own (no clobber).
run mkdir -p "$ENT_DIR"
for tpl in system.env notify.env ai.env; do
if [ -f "config/$tpl" ]; then
if [ -f "$ENT_DIR/$tpl" ]; then
log "$tpl already exists, keeping it"
else
run cp "config/$tpl" "$ENT_DIR/$tpl"
run chmod 600 "$ENT_DIR/$tpl"
log "Installed $tpl — edit $ENT_DIR/$tpl"
fi
fi
done
# ── schedule starter jobs (interactive) ────────────────────────
# config/schedule.d has ready-made example jobs (NVMe health, CPU/disk
# thresholds, silent log cleanup). Ask before copying — only into an empty
# schedule.d/ (never overwrite existing jobs). Users with legacy event.env
# rules are pointed at `pos system schedule migrate` instead.
if [ -d config/schedule.d ] && [ ! -d "$ENT_DIR/schedule.d" ]; then
if [ -f "$ENT_DIR/event.env" ] && grep -vE '^[[:space:]]*(#.*)?$' "$ENT_DIR/event.env" >/dev/null 2>&1; then
log "legacy event.env rules found — convert them with 'pos system schedule migrate'"
elif confirm "Install the starter schedule jobs (NVMe health, CPU/disk thresholds, log cleanup)?"; then
if [ "${DRY_RUN:-0}" -eq 1 ]; then
log "(dry-run) would copy config/schedule.d/* → $ENT_DIR/schedule.d/"
else
run mkdir -p "$ENT_DIR/schedule.d"
for jf in config/schedule.d/*.env; do
[ -f "$jf" ] || continue
run cp "$jf" "$ENT_DIR/schedule.d/"
run chmod 600 "$ENT_DIR/schedule.d/${jf##*/}"
done
log "Installed starter schedule jobs — check them with 'pos system schedule list'"
fi
else
log "Skipping starter schedule jobs"
fi
fi
# ── Ensure all bin dirs are in PATH ────────────────────────────
PATH_LINE='export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$HOME/.local/bin:$PATH"'
BASHRC="$HOME/.bashrc"
if grep -qsF "$PATH_LINE" "$BASHRC" 2>/dev/null; then
log "PATH already configured"
else
run echo "$PATH_LINE" >> "$BASHRC"
log "Added PATH to ~/.bashrc"
fi
# ── Bash completion for pos ─────────────────────────────────────
COMPLETION_LINE='source /usr/local/share/bash-completion/completions/pos.bash 2>/dev/null || true'
if grep -qsF "pos.bash" "$BASHRC" 2>/dev/null; then
log "pos completion already configured"
else
run echo "$COMPLETION_LINE" >> "$BASHRC"
log "Added pos completion to ~/.bashrc"
fi
if [ -f completions/pos.bash ]; then
run sudo mkdir -p /usr/local/share/bash-completion/completions
run sudo install -m 644 completions/pos.bash \
/usr/local/share/bash-completion/completions/pos.bash
log "Installed pos completion"
else
warn "completions/pos.bash not found, skipping"
fi
# ── SSH authorized keys ────────────────────────────────────────
SSH_DIR="$HOME/.ssh"
AUTH_FILE="$SSH_DIR/authorized_keys"
KEY_FILE="config/authorized_keys"
if [ -f "$KEY_FILE" ]; then
run mkdir -p "$SSH_DIR"
run chmod 700 "$SSH_DIR"
run touch "$AUTH_FILE"
run chmod 600 "$AUTH_FILE"
added=0
while IFS= read -r key; do
[[ -z "$key" || "$key" == \#* ]] && continue
if grep -qsF "$key" "$AUTH_FILE" 2>/dev/null; then
log "SSH key already present"
else
run echo "$key" >> "$AUTH_FILE"
added=$((added + 1))
fi
done < "$KEY_FILE"
if [ "$added" -gt 0 ]; then
log "Installed $added SSH key(s)"
fi
else
warn "config/authorized_keys not found, skipping SSH setup"
fi
# ── systemd services ───────────────────────────────────────────
if [ -d systemd ] && [ -n "$(ls -A systemd/*.service 2>/dev/null)" ]; then
run sudo cp systemd/*.service /etc/systemd/system/
if [ -n "$(ls -A systemd/*.timer 2>/dev/null)" ]; then
run sudo cp systemd/*.timer /etc/systemd/system/
fi
run sudo systemctl daemon-reload
for svc in systemd/*.service; do
svc_name=$(basename "$svc")
# autostart.service runs features/autostart.sh — enable only when
# the autostart feature flag is green (set by ./install.sh --feature)
if [ "$svc_name" = "autostart.service" ] && ! flag_is_set autostart; then
warn "autostart feature not installed — skipping autostart.service (run ./install.sh --feature)"
continue
fi
run sudo systemctl enable --now "$svc_name" 2>/dev/null || \
run sudo systemctl enable "$svc_name"
done
log "Systemd services installed and enabled"
else
warn "No systemd services found, skipping"
fi
log "Post-install completed."