aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--.chezmoiignore1
-rw-r--r--.github/copilot-instructions.md5
-rwxr-xr-xbootstrap.sh30
-rw-r--r--justfile54
-rw-r--r--systemd-units/base.txt13
5 files changed, 73 insertions, 30 deletions
diff --git a/.chezmoiignore b/.chezmoiignore
index 2cde505..f6f6893 100644
--- a/.chezmoiignore
+++ b/.chezmoiignore
@@ -5,6 +5,7 @@ create-efi.sh
.github/
.worktrees/
meta/
+systemd-units/
etc/
firefox/
justfile
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 2a837f5..44239ac 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -15,12 +15,13 @@ The repo root is a chezmoi source directory. Files targeting `$HOME` use chezmoi
- `dot_config/`, `private_dot_gnupg/`, `private_dot_ssh/`, etc. — chezmoi source state mapping to `$HOME`. Prefix meanings: `dot_` → leading `.`, `private_` → restricted permissions, `executable_` → `+x` bit.
- `etc/` contains system-level configs (`/etc/` targets) — systemd units, pacman hooks, sysctl tunables, kernel module loading. Deployed by `run_onchange_after_deploy-etc.sh.tmpl`.
- `meta/` contains plain text package lists for Arch Linux (one package per line, `#` comments). Each `.txt` file represents a group (e.g. `base.txt`, `dev.txt`, `wayland.txt`). Install with `just install base dev` or `just install-all`. Detect drift with `just status`.
+- `systemd-units/` contains plain text systemd unit lists paired by name with `meta/` groups (e.g. `systemd-units/base.txt` ↔ `meta/base.txt`). Units listed here are enabled by `just services-enable` (run automatically by `just init`). Inspect with `just services`, detect drift with `just services-drift`.
- `firefox/` contains Firefox/LibreWolf hardening overrides (`user-overrides.js`) and custom CSS (`chrome/userChrome.css`). Deployed by `run_onchange_after_deploy-firefox.sh.tmpl`.
- `dot_local/bin/executable_create-efi` is an interactive EFI boot entry creation script using `efibootmgr` (deployed to `~/.local/bin/create-efi`).
- `bootstrap.sh` at the repo root is a POSIX shell script that takes a fresh minimal Arch install (only `base`) to a fully deployed state. It installs prerequisites, enables `%wheel` sudoers, bootstraps `paru-bin` from the AUR, clones the repo, runs `just init`, and optionally invokes `create-efi`. Designed to be curlable: `curl -fsSL .../bootstrap.sh | sh`.
-- `.chezmoiignore` excludes non-home files (`etc/`, `meta/`, `firefox/`, docs) from deployment to `$HOME`.
+- `.chezmoiignore` excludes non-home files (`etc/`, `meta/`, `systemd-units/`, `firefox/`, docs) from deployment to `$HOME`.
- `.githooks/` contains git hooks (notably `post-commit` which runs `chezmoi apply`). Activated by `just init`.
-- `justfile` provides recipes: `init` (first-time setup), `sync` (apply + fix), `apply`, `fix`, `status`, `pkg-drift`, `dotfile-drift`, `undeclared`, `diff`, `merge`, `groups`, `install`, `install-all`, `add`, `remove`. Run `just` or `just --list` to see them.
+- `justfile` provides recipes: `init` (first-time setup), `sync` (apply + fix), `apply`, `fix`, `status`, `pkg-drift`, `dotfile-drift`, `undeclared`, `diff`, `merge`, `groups`, `install`, `install-all`, `add`, `remove`, `services`, `services-enable`, `services-drift`. Run `just` or `just --list` to see them.
## Window manager
diff --git a/bootstrap.sh b/bootstrap.sh
index c5cbb26..dbe9495 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -70,43 +70,19 @@ cd "$DOTFILES_DIR"
log 'running just init'
just init
-# 6. enable recommended systemd units for daemons that base.txt installs.
-# Soft-fail: warn on a single failure but keep going.
-log 'enabling system services'
-for u in \
- fstrim.timer \
- systemd-timesyncd.service \
- systemd-resolved.service \
- reflector.timer \
- paccache.timer \
- pkgstats.timer \
- acpid.service \
- cpupower.service \
- iwd.service
-do
- sudo systemctl enable --now "$u" \
- || warn "could not enable $u"
-done
-
-# tlp: laptops only
-if ls /sys/class/power_supply/BAT* >/dev/null 2>&1; then
- sudo systemctl enable --now tlp.service \
- || warn 'could not enable tlp.service'
-fi
-
-# 7. refresh pacman mirrorlist once via reflector (config deployed by chezmoi)
+# 6. refresh pacman mirrorlist once via reflector (config deployed by chezmoi)
log 'refreshing pacman mirrorlist via reflector'
sudo reflector @/etc/xdg/reflector/reflector.conf \
--save /etc/pacman.d/mirrorlist \
|| warn 'reflector failed; keeping existing mirrorlist'
-# 8. create XDG user directories (~/Documents, ~/Downloads, etc.)
+# 7. create XDG user directories (~/Documents, ~/Downloads, etc.)
if command -v xdg-user-dirs-update >/dev/null 2>&1; then
log 'creating XDG user directories'
xdg-user-dirs-update || warn 'xdg-user-dirs-update failed'
fi
-# 9. optional: create an Arch EFI boot entry if none exists
+# 8. optional: create an Arch EFI boot entry if none exists
if [ -d /sys/firmware/efi ]; then
if ! sudo efibootmgr 2>/dev/null | grep -iq arch; then
log 'no Arch Linux EFI boot entry found; launching create-efi'
diff --git a/justfile b/justfile
index ee66284..66bac80 100644
--- a/justfile
+++ b/justfile
@@ -8,7 +8,7 @@ default:
# ═══════════════════════════════════════════════════════════════════
# First-time machine setup: regenerate chezmoi config, install git hooks, deploy dotfiles, install base packages
-init: _chezmoi-init _install-hooks apply (install "base")
+init: _chezmoi-init _install-hooks apply (install "base") services-enable
# ═══════════════════════════════════════════════════════════════════
@@ -122,6 +122,58 @@ groups group="":
# ═══════════════════════════════════════════════════════════════════
+# Services
+# ═══════════════════════════════════════════════════════════════════
+
+# List curated systemd units (grouped by systemd-units/<group>.txt) with state
+services:
+ #!/bin/sh
+ for file in systemd-units/*.txt; do
+ [ -f "$file" ] || continue
+ group=$(basename "$file" .txt)
+ echo "=== $group ==="
+ grep -v '^\s*#' "$file" | grep -v '^\s*$' | while read -r u; do
+ en=$(systemctl is-enabled "$u" 2>/dev/null); en=${en:-unknown}
+ ac=$(systemctl is-active "$u" 2>/dev/null); ac=${ac:-unknown}
+ case "$en" in
+ enabled|static|alias) c_en=32 ;;
+ disabled|masked|not-found) c_en=31 ;;
+ *) c_en=33 ;;
+ esac
+ case "$ac" in
+ active) c_ac=32 ;;
+ inactive|failed) c_ac=31 ;;
+ *) c_ac=33 ;;
+ esac
+ printf ' %-34s \033[%sm%-10s\033[0m \033[%sm%s\033[0m\n' "$u" "$c_en" "$en" "$c_ac" "$ac"
+ done
+ done
+
+# Enable all curated systemd units (idempotent, soft-fail per unit)
+services-enable:
+ #!/bin/sh
+ for file in systemd-units/*.txt; do
+ [ -f "$file" ] || continue
+ grep -v '^\s*#' "$file" | grep -v '^\s*$' | while read -r u; do
+ sudo systemctl enable --now "$u" \
+ || echo " warn: could not enable $u" >&2
+ done
+ done
+
+# Show drift between curated services and actually-enabled services
+services-drift:
+ #!/bin/sh
+ echo "=== Service drift ==="
+ tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
+ cat systemd-units/*.txt 2>/dev/null \
+ | grep -v '^\s*#' | grep -v '^\s*$' | sort -u > "$tmp/curated"
+ systemctl list-unit-files --state=enabled --no-legend 2>/dev/null \
+ | awk '{print $1}' | sort -u > "$tmp/enabled"
+ comm -23 "$tmp/curated" "$tmp/enabled" | sed 's/^/ not-enabled: /'
+ comm -13 "$tmp/curated" "$tmp/enabled" | sed 's/^/ uncurated: /'
+
+
+# ═══════════════════════════════════════════════════════════════════
# Package management
# ═══════════════════════════════════════════════════════════════════
diff --git a/systemd-units/base.txt b/systemd-units/base.txt
new file mode 100644
index 0000000..bec3556
--- /dev/null
+++ b/systemd-units/base.txt
@@ -0,0 +1,13 @@
+# Systemd units to enable when the 'base' meta group is installed.
+# One unit per line, # comments OK.
+
+fstrim.timer
+systemd-timesyncd.service
+systemd-resolved.service
+reflector.timer
+paccache.timer
+pkgstats.timer
+acpid.service
+cpupower.service
+iwd.service
+tlp.service