diff --git a/ansible/roles/greetd/handlers/main.yml b/ansible/roles/greetd/handlers/main.yml new file mode 100644 index 0000000..c676711 --- /dev/null +++ b/ansible/roles/greetd/handlers/main.yml @@ -0,0 +1,4 @@ +--- +- name: restart greetd + command: systemctl restart greetd + become: yes diff --git a/ansible/roles/greetd/tasks/main.yml b/ansible/roles/greetd/tasks/main.yml new file mode 100644 index 0000000..4418183 --- /dev/null +++ b/ansible/roles/greetd/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Greetd - install packages + pacman: + name: + - "{{ display_manager_package }}" + - "{{ display_manager_greeter }}" + state: present + update_cache: yes + tags: [greetd, packages] + +- name: Greetd - configure tuigreet to launch Hyprland + template: + src: config.toml.j2 + dest: "{{ display_manager_config }}" + owner: root + group: root + mode: '0644' + notify: restart greetd + tags: [greetd, config] + +- name: Greetd - ensure enabled as display manager + file: + src: /usr/lib/systemd/system/greetd.service + dest: /etc/systemd/system/display-manager.service + state: link + force: yes + notify: restart greetd + tags: [greetd, service] diff --git a/ansible/roles/greetd/templates/config.toml.j2 b/ansible/roles/greetd/templates/config.toml.j2 new file mode 100644 index 0000000..8c8a45a --- /dev/null +++ b/ansible/roles/greetd/templates/config.toml.j2 @@ -0,0 +1,8 @@ +[terminal] +# The VT to run the greeter on +vt = 1 + +# Default session: tuigreet greeter +[default_session] +command = "tuigreet --time --remember --asterisks --cmd {{ hyprland_cmd | default('Hyprland') }}" +user = "greeter" diff --git a/ansible/roles/hyprland/tasks/main.yml b/ansible/roles/hyprland/tasks/main.yml index 280261f..6b69cea 100644 --- a/ansible/roles/hyprland/tasks/main.yml +++ b/ansible/roles/hyprland/tasks/main.yml @@ -44,7 +44,7 @@ notify: rebuild initramfs tags: [hyprland, nvidia] -- name: Hyprland - register session in SDDM +- name: Hyprland - register Wayland session desktop entry copy: dest: /usr/share/wayland-sessions/hyprland.desktop content: | diff --git a/ansible/vars/main.yml b/ansible/vars/main.yml index 4d958ef..df1b2a0 100644 --- a/ansible/vars/main.yml +++ b/ansible/vars/main.yml @@ -65,3 +65,11 @@ hyprland_packages: - egl-wayland - qt5-wayland - qt6-wayland + +# --------------------------------------------------------------------------- +# greetd role: display manager - minimal TUI greeter for Wayland +# Replaced SDDM (2026-05-20) - see docs/adr/0003-sddm-to-greetd.md +# --------------------------------------------------------------------------- +display_manager_package: greetd +display_manager_greeter: greetd-tuigreet +display_manager_config: /etc/greetd/config.toml diff --git a/ansible/workstation.yml b/ansible/workstation.yml index 4260714..0c1ac85 100644 --- a/ansible/workstation.yml +++ b/ansible/workstation.yml @@ -16,3 +16,5 @@ - maintenance - role: hyprland tags: [hyprland] + - role: greetd + tags: [greetd] diff --git a/docs/adr/0003-sddm-to-greetd.md b/docs/adr/0003-sddm-to-greetd.md new file mode 100644 index 0000000..9d013da --- /dev/null +++ b/docs/adr/0003-sddm-to-greetd.md @@ -0,0 +1,95 @@ +--- +description: >- + Replace SDDM (Qt-based graphical display manager) with greetd + tuigreet + for a minimal, Wayland-first login experience with zero heavy GUI dependencies. +status: accepted +date: 2026-05-20 +replaces: SDDM as display-manager.service +--- + +# 0003: SDDM to greetd Migration + +## Context + +The workstation uses Hyprland as the primary Wayland compositor. SDDM was +pulled in as the display manager with significant Qt dependencies (~50+ +transitive packages). For a single-user dev workstation running Hyprland, +this is unnecessary overhead — heavy, slow-booting, and over-engineered for +the use case. + +SDDM provides: graphical login prompt, session selection, PAM authentication. +All three can be achieved with far lighter tools. + +## Decision + +Migrate from SDDM to greetd + tuigreet. + +- **greetd**: minimal display manager daemon, designed for Wayland first-class. +- **tuigreet**: TUI greeter with time display, user remembering, session + discovery from `/usr/share/wayland-sessions/` and `/usr/share/xsessions/`. + +### What changed + +| Before | After | +|--------|-------| +| sddm.service (display-manager) | greetd.service (display-manager) | +| Qt5/Qt6 dependency chain | greetd + greetd-tuigreet (3 packages, 4.9MB) | +| /etc/sddm.conf | /etc/greetd/config.toml | +| Graphical login screen | Text-based TUI login screen | +| Heavy PAM surface | Standard PAM chain (system-local-login) | + +### Ansible changes + +- Added `greetd` role: installs packages, configures config.toml from template, + enables greetd as display-manager.service +- Hyprland task renamed: "register session in SDDM" -> "register Wayland session + desktop entry" (no functional change, just accurate naming) +- vars/main.yml: added `display_manager_package`, `display_manager_greeter`, + `display_manager_config` variables + +### Configuration + +```toml +[terminal] +vt = 1 +[default_session] +command = "tuigreet --time --remember --asterisks --cmd Hyprland" +user = "greeter" +``` + +### Rationale + +1. **Wayland-native**: greetd handles Wayland sessions cleanly without X + compatibility layers +2. **Minimal**: 3 packages vs Qt dependency chain; <5MB vs ~500MB +3. **Maintained**: Rust codebase, clean TOML config, Arch repos (no AUR) +4. **AI-agent friendly**: TOML config is trivially parseable/modifiable; + clean systemd service with structured journalctl output +5. **Simplicity principle**: maximizes work not done + +## Consequences + +### Positive + +- Faster boot (no Qt/Xorg init) +- Smaller attack surface +- Less disk usage +- No Qt dependencies to maintain +- Clean systemd service management + +### Negative + +- No graphical login (only a limitation if multi-user GUI switching is needed) +- SDDM themes not available (not a requirement for this workstation) +- Tuigreet has fewer visual customization options + +### Migration path back + +```bash +sudo systemctl disable greetd +sudo systemctl enable sddm +sudo ln -sf /usr/lib/systemd/system/sddm.service /etc/systemd/system/display-manager.service +``` + +Reversible with zero data loss — the hyprland.desktop session entry is +unchanged and works with both DMs. diff --git a/docs/tech/setup.md b/docs/tech/setup.md index 3bf95c8..4e3b976 100644 --- a/docs/tech/setup.md +++ b/docs/tech/setup.md @@ -5,7 +5,7 @@ tags: - setup - bootstrap - ansible -last_updated: '2026-05-18' +last_updated: '2026-05-20' --- # Workstation Setup Guide