diff --git a/AGENTS.md b/AGENTS.md index 670f6cf..48212e5 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md -Ansible-driven personal infrastructure repo for Void desktops, Linux workstations, Windows+WSL, and an Ubuntu server. +Ansible-driven personal infrastructure repo for Void/Arch desktops, Linux workstations, Windows+WSL, and an Ubuntu server. ## Source Of Truth - Main orchestration: `ansible/site.yml` @@ -11,7 +11,8 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation - Codex config is rendered from `dotfiles/common/.codex/config.toml.j2` so `model_instructions_file` points to the deployed `~/.config/ai/bootstrap.md`. ## Topology -- Void desktops: `ikaros`, `nymph` +- Void desktops: `ikaros` +- Arch desktops: `nymph` - Native Linux workstations: `deadalus-ubuntu`, `deadalus-fedora` - Windows host + WSL dev: `deadalus-win`, `deadalus-wsl` - Ubuntu server: `prometheus` @@ -34,14 +35,15 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation - `ansible-lint ansible/roles` - `yamllint ansible/` - Host-focused dry runs: - - Void desktop work: `ansible-playbook ansible/site.yml --limit ikaros --check --diff` or `--limit nymph --check --diff` + - Void desktop work: `ansible-playbook ansible/site.yml --limit ikaros --check --diff` + - Arch desktop work: `ansible-playbook ansible/site.yml --limit nymph --check --diff` - Ubuntu workstation: `ansible-playbook ansible/site.yml --limit deadalus-ubuntu --check --diff` - Fedora workstation: `ansible-playbook ansible/site.yml --limit deadalus-fedora --check --diff` - WSL dev: `ansible-playbook ansible/site.yml --limit deadalus-wsl --check --diff` - Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff` - Focused checks: - Emacs dotfiles only: `ansible-playbook ansible/site.yml --limit ikaros --tags emacs --check --diff` or `--limit nymph --tags emacs --check --diff` - - Sway/Noctalia bootstrap on nymph: `ansible-playbook ansible/site.yml --limit nymph --tags packages,dotfiles:desktop,sway --check --diff` + - Arch GNOME desktop bootstrap on nymph: `ansible-playbook ansible/site.yml --limit nymph --tags packages,services,gnome --check --diff` - Mail bootstrap: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh` - Windows bootstrap parse: `pwsh -NoProfile -Command "[void][System.Management.Automation.Language.Parser]::ParseFile('scripts/bootstrap_windows_workstation.ps1', [ref]$null, [ref]$null)"` - Server compose render: `docker compose -f /opt/docker/server/docker-compose.yml config` @@ -54,18 +56,20 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation - Put host-specific overrides in `host_vars`, not shared `group_vars`. - Use `no_log: true` for secret-bearing task inputs or outputs. -## Desktop Void Notes +## Desktop Notes - `profile_desktop_common` owns the shared desktop bootstrap. - `.emacs.d` is deployed by a dedicated `profile_desktop_common` task tagged `emacs`. - NTFS filesystem support is provided by `ntfs-3g` in `ansible/inventory/group_vars/void.yml`. -- User services are managed by `turnstile` and live under `dotfiles/desktop/.config/service/`. -- `ssh-agent` runs under `turnstile` with stable socket `~/.local/state/ssh-agent/socket`. +- Void user services are managed by `turnstile` and live under `dotfiles/desktop/.config/service/`. +- Arch user services are systemd user units under `dotfiles/desktop/.config/systemd/user/`. +- `ssh-agent` keeps the stable socket `~/.local/state/ssh-agent/socket`. - Critical session entrypoints: - `dotfiles/desktop/.xinitrc` - `dotfiles/desktop/.local/bin/start-sway-session` -- Do not auto-restart `emptty` during playbook runs on active desktop hosts; restart it manually from another TTY/SSH session if needed. -- `profile_desktop_sway` owns the Sway session, Noctalia config rendering, and official plugin linking. -- Noctalia shared config lives in `dotfiles/desktop/.config/noctalia/`; bar monitors and `screenOverrides` come from inventory (`noctalia_bar_monitors`, `noctalia_screen_overrides`). +- Do not auto-restart `emptty` during playbook runs on active Void desktop hosts; restart it manually from another TTY/SSH session if needed. +- `nymph` is an Arch GNOME/GDM desktop; do not route it through Void/i3/Sway/emptty tasks. +- `profile_desktop_sway` owns the Sway session, Noctalia config rendering, and official plugin linking when a Sway desktop is explicitly enabled. +- Noctalia shared config lives in `dotfiles/desktop/.config/noctalia/`; bar monitors and `screenOverrides` come from inventory (`noctalia_bar_monitors`, `noctalia_screen_overrides`) on Sway hosts. - On Sway hosts, `udiskie` is the backend for automount/LUKS but runs without tray; USB device UI is handled by `usb-drive-manager`. - Do not re-introduce `network-manager-applet` or `blueman` on Sway hosts without an explicit host-specific reason. diff --git a/ansible/inventory/group_vars/arch.yml b/ansible/inventory/group_vars/arch.yml new file mode 100644 index 0000000..a9fee0f --- /dev/null +++ b/ansible/inventory/group_vars/arch.yml @@ -0,0 +1,142 @@ +--- +arch_packages_base: + - 7zip + - archlinux-keyring + - avahi + - base-devel + - bluez + - clang + - cmake + - cups + - cups-filters + - cups-pk-helper + - fastfetch + - flatpak + - fuse3 + - gcc + - gdb + - git-delta + - github-cli + - gnome-keyring + - go + - gvfs + - gvfs-mtp + - gvfs-smb + - imagemagick + - isync + - libsecret + - libtool + - linux + - linux-headers + - lm_sensors + - man-db + - man-pages + - msmtp + - mu + - networkmanager + - nodejs + - npm + - pavucontrol + - pipewire + - pipewire-alsa + - pipewire-jack + - pipewire-pulse + - pkgconf + - plocate + - podman + - podman-compose + - rclone + - sane + - sane-airscan + - seahorse + - simple-scan + - speech-dispatcher + - syncthing + - system-config-printer + - tealdeer + - tmux + - tree-sitter-cli + - ufw + - wireplumber + - xdotool + - yt-dlp + +arch_desktop_common_packages: + - brightnessctl + - dex + - pinentry + - udiskie + - xdg-desktop-portal + - xdg-desktop-portal-gtk + - xdg-user-dirs + +arch_desktop_gnome_packages: + - gdm + - gnome-control-center + - gnome-session + - gnome-settings-daemon + - gnome-shell + - gnome-shell-extensions + - gnome-tweaks + - mutter + - nautilus + - xdg-desktop-portal-gnome + +arch_profile_packages: + - alacritty + - bridge-utils + - deluge + - dnsmasq + - edk2-ovmf + - emacs + - ffmpegthumbnailer + - firefox + - fontconfig + - freetype2 + - gufw + - libvterm + - libx11 + - libxft + - libvirt + - libreoffice-fresh + - meld + - mpv + - noto-fonts + - noto-fonts-emoji + - pdfarranger + - playerctl + - poppler + - poppler-glib + - qemu-desktop + - remmina + - ripgrep + - rsync + - ruff + - rustup + - texlive-basic + - texlive-binextra + - texlive-latex + - texlive-latexextra + - ttf-liberation + - ttf-nerd-fonts-symbols + - universal-ctags + - uv + - virt-manager + - xarchiver + - xournalpp + - zstd + +enabled_services: + - NetworkManager + - avahi-daemon + - bluetooth + - cups + - gdm + - libvirtd + - ufw + +desktop_systemd_user_services: + - ssh-agent.service + - emacs.service + - syncthing.service + - rclone-pcloud.service diff --git a/ansible/inventory/group_vars/desktop.yml b/ansible/inventory/group_vars/desktop.yml index a8fd79c..8677c83 100644 --- a/ansible/inventory/group_vars/desktop.yml +++ b/ansible/inventory/group_vars/desktop.yml @@ -6,113 +6,6 @@ desktop_sessions_enabled: desktop_default_session: i3 desktop_default_session_env: xorg -desktop_restart_emptty_automatically: false -desktop_emptty_session_error_logging: disabled - -desktop_common_packages: - - brightnessctl - - dex - - emptty - - pinentry-emacs - - pinentry-gtk - - turnstile - - udiskie - - xdg-desktop-portal - - xdg-desktop-portal-gtk - - xdg-user-dirs - -desktop_i3_packages: - - arandr - - autorandr - - feh - - i3 - - i3blocks - - i3blocks-blocklets - - i3lock-color - - i3status - - dunst - - network-manager-applet - - rofi - - scrot - - setxkbmap - - blueman - - volumeicon - - xclip - - xfce-polkit - - xfce4-clipman-plugin - - xfce4-screenshooter - - xkbutils - - xorg-fonts - - xorg-minimal - - xss-lock - -desktop_sway_packages: - - grim - - kanshi - - slurp - - swayfx - - wl-clipboard - - xdg-desktop-portal-wlr - -profile_packages: - - alacritty - - bluez - - bridge-utils - - ctags - - firefox - - deluge-gtk - - dnsmasq - - emacs-gtk3 - - poppler-glib - - poppler-utils - - exo - - fontconfig-devel - - freetype-devel - - gvfs-cdda - - gvfs-mtp - - gvfs-smb - - gufw - - libvirt - - libspa-bluetooth - - libreoffice - - liberation-fonts-ttf - - libvterm-devel - - libX11-devel - - libXft-devel - - meld - - mpv - - nerd-fonts-ttf - - nerd-fonts-symbols-ttf - - pdfarranger - - playerctl - - qemu - - qemu-firmware - - qemu-img - - qemu-tools - - remmina - - ripgrep - - rustup - - ristretto - - rsync - - shotwell - - ruff - - terminus-font - - texlive - - ty - - tumbler - - uv - - Thunar - - thunar-archive-plugin - - thunar-volman - - ffmpegthumbnailer - - virt-manager - - virt-manager-tools - - wireplumber - - xarchiver - - xournalpp - - yaru - - yaru-plus - - zstd desktop_source_tools: - name: st @@ -189,14 +82,42 @@ desktop_common_dotfiles: src: .config/udiskie/ dest: .config/udiskie/ mode: preserve - - name: Turnstile user services - src: .config/service/ - dest: .config/service/ - mode: preserve - - name: Bash profile fragments - src: .bashrc.d/ - dest: .bashrc.d/ - mode: preserve + - name: Bash cargo env fragment + src: .bashrc.d/08-cargo-env.sh + dest: .bashrc.d/08-cargo-env.sh + mode: "0644" + - name: Bash GPG TTY fragment + src: .bashrc.d/10-gpg-tty.sh + dest: .bashrc.d/10-gpg-tty.sh + mode: "0644" + - name: Bash man page colors fragment + src: .bashrc.d/12-manpages.sh + dest: .bashrc.d/12-manpages.sh + mode: "0644" + - name: Bash DBus session fragment + src: .bashrc.d/14-dbus-session.sh + dest: .bashrc.d/14-dbus-session.sh + mode: "0644" + - name: Bash SSH agent socket fragment + src: .bashrc.d/16-ssh-agent-socket.sh + dest: .bashrc.d/16-ssh-agent-socket.sh + mode: "0644" + - name: Bash editor fragment + src: .bashrc.d/20-editor-desktop.sh + dest: .bashrc.d/20-editor-desktop.sh + mode: "0644" + - name: Bash Emacs client fragment + src: .bashrc.d/25-emacs-client-desktop.sh + dest: .bashrc.d/25-emacs-client-desktop.sh + mode: "0644" + - name: Bash VM helper fragment + src: .bashrc.d/30-runvm.sh + dest: .bashrc.d/30-runvm.sh + mode: "0644" + - name: Bash Ansible playbook helper fragment + src: .bashrc.d/50-ap.sh + dest: .bashrc.d/50-ap.sh + mode: "0644" - name: .gitignore_global src: .gitignore_global dest: .gitignore_global @@ -221,10 +142,6 @@ desktop_common_dotfiles: src: .local/bin/setup-gtk-theme dest: .local/bin/setup-gtk-theme mode: "0755" - - name: Turnstile environment update script - src: .local/bin/update-turnstile-env - dest: .local/bin/update-turnstile-env - mode: "0755" - name: Udiskie password helper src: .local/bin/udiskie-password dest: .local/bin/udiskie-password @@ -238,6 +155,12 @@ desktop_common_dotfiles: dest: .ssh/config mode: "0600" +desktop_arch_dotfiles: + - name: systemd user services + src: .config/systemd/user/ + dest: .config/systemd/user/ + mode: preserve + desktop_emacs_dotfiles: - name: Emacs config src: .emacs.d/ diff --git a/ansible/inventory/group_vars/void.yml b/ansible/inventory/group_vars/void.yml index 931e18c..1a9e566 100644 --- a/ansible/inventory/group_vars/void.yml +++ b/ansible/inventory/group_vars/void.yml @@ -79,3 +79,125 @@ enabled_services: - ufw - virtlockd - virtlogd + +desktop_restart_emptty_automatically: false +desktop_emptty_session_error_logging: disabled + +desktop_void_dotfiles: + - name: Turnstile user services + src: .config/service/ + dest: .config/service/ + mode: preserve + - name: Bash runit desktop fragment + src: .bashrc.d/15-runit-desktop.sh + dest: .bashrc.d/15-runit-desktop.sh + mode: "0644" + - name: Turnstile environment update script + src: .local/bin/update-turnstile-env + dest: .local/bin/update-turnstile-env + mode: "0755" + +desktop_common_packages: + - brightnessctl + - dex + - emptty + - pinentry-emacs + - pinentry-gtk + - turnstile + - udiskie + - xdg-desktop-portal + - xdg-desktop-portal-gtk + - xdg-user-dirs + +desktop_i3_packages: + - arandr + - autorandr + - feh + - i3 + - i3blocks + - i3blocks-blocklets + - i3lock-color + - i3status + - dunst + - network-manager-applet + - rofi + - scrot + - setxkbmap + - blueman + - volumeicon + - xclip + - xfce-polkit + - xfce4-clipman-plugin + - xfce4-screenshooter + - xkbutils + - xorg-fonts + - xorg-minimal + - xss-lock + +desktop_sway_packages: + - grim + - kanshi + - slurp + - swayfx + - wl-clipboard + - xdg-desktop-portal-wlr + +profile_packages: + - alacritty + - bluez + - bridge-utils + - ctags + - firefox + - deluge-gtk + - dnsmasq + - emacs-gtk3 + - poppler-glib + - poppler-utils + - exo + - fontconfig-devel + - freetype-devel + - gvfs-cdda + - gvfs-mtp + - gvfs-smb + - gufw + - libvirt + - libspa-bluetooth + - libreoffice + - liberation-fonts-ttf + - libvterm-devel + - libX11-devel + - libXft-devel + - meld + - mpv + - nerd-fonts-ttf + - nerd-fonts-symbols-ttf + - pdfarranger + - playerctl + - qemu + - qemu-firmware + - qemu-img + - qemu-tools + - remmina + - ripgrep + - rustup + - ristretto + - rsync + - shotwell + - ruff + - terminus-font + - texlive + - ty + - tumbler + - uv + - Thunar + - thunar-archive-plugin + - thunar-volman + - ffmpegthumbnailer + - virt-manager + - virt-manager-tools + - wireplumber + - xarchiver + - xournalpp + - yaru + - yaru-plus + - zstd diff --git a/ansible/inventory/host_vars/nymph.yml b/ansible/inventory/host_vars/nymph.yml index 89455a9..81e98e7 100644 --- a/ansible/inventory/host_vars/nymph.yml +++ b/ansible/inventory/host_vars/nymph.yml @@ -2,55 +2,27 @@ hostname: nymph desktop_sessions_enabled: - - i3 + - gnome -desktop_default_session: i3 -desktop_default_session_env: xorg -desktop_emptty_session_error_logging: rotate +desktop_default_session: gnome +desktop_default_session_env: wayland -host_xbps_repositories: - - name: noctalia - url: https://universalrepo.r1xelelo.workers.dev/void +host_grub_cmdline_linux: >- + rd.luks.uuid=1e15d159-5d05-4a1f-9639-ac200dff9f9c rootflags=subvol=@ + apparmor=1 security=apparmor nouveau.modeset=0 nvidia-drm.modeset=1 host_packages: - - cliphist - - grimshot + - grub + - intel-media-driver + - libva-intel-driver + - mesa - nvidia - - linux-mainline-headers - - noctalia-shell + - nvidia-settings + - nvidia-utils - power-profiles-daemon - - mesa-dri - - vulkan-loader - - mesa-vulkan-intel - - intel-video-accel - - tlp - - tlp-rdw - upower + - vulkan-icd-loader + - vulkan-intel host_enabled_services: - - tlp - -host_sway_dotfiles: - - src: .config/sway/host.conf - dest: .config/sway/host.conf - mode: "0644" - - src: .config/sway/session-env - dest: .config/sway/session-env - mode: "0644" - - src: .config/kanshi/config - dest: .config/kanshi/config - mode: "0644" - -noctalia_bar_monitors: - - DP-1 - - eDP-1 - -noctalia_screen_overrides: - - name: DP-1 - enabled: false - - name: eDP-1 - enabled: false - -host_packages_absent: - - network-manager-applet - - blueman + - power-profiles-daemon diff --git a/ansible/inventory/hosts.yml b/ansible/inventory/hosts.yml index 253527b..cd34d45 100644 --- a/ansible/inventory/hosts.yml +++ b/ansible/inventory/hosts.yml @@ -5,8 +5,10 @@ all: hosts: ikaros: ansible_connection: local - nymph: - ansible_connection: local + + arch: + children: + arch_desktop: desktop: hosts: @@ -55,6 +57,11 @@ all: deadalus-fedora: ansible_connection: local + arch_desktop: + hosts: + nymph: + ansible_connection: local + workstation_host_linux: hosts: deadalus-ubuntu: diff --git a/ansible/roles/dotfiles_common/tasks/main.yml b/ansible/roles/dotfiles_common/tasks/main.yml index 824ef08..e63da3d 100644 --- a/ansible/roles/dotfiles_common/tasks/main.yml +++ b/ansible/roles/dotfiles_common/tasks/main.yml @@ -14,7 +14,7 @@ group: "{{ effective_user_group }}" mode: "0755" loop: "{{ xdg_user_directories | default([]) }}" - when: "'void' in group_names" + when: "'desktop' in group_names" - name: Extract templates kit to Templates directory tags: [dotfiles, dotfiles:common] @@ -23,7 +23,7 @@ dest: "{{ effective_user_home }}/Templates" owner: "{{ effective_username }}" group: "{{ effective_user_group }}" - when: "'void' in group_names" + when: "'desktop' in group_names" - name: Ensure SSH socket directory exists tags: [dotfiles, dotfiles:common] diff --git a/ansible/roles/packages_arch/tasks/main.yml b/ansible/roles/packages_arch/tasks/main.yml new file mode 100644 index 0000000..e67f25f --- /dev/null +++ b/ansible/roles/packages_arch/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Synchronize and upgrade Arch Linux packages + tags: [packages] + community.general.pacman: + update_cache: true + upgrade: true + +- name: Install packages on Arch Linux + tags: [packages] + community.general.pacman: + name: >- + {{ + ( + (common_packages | default([])) + + (arch_packages_base | default([])) + + (arch_desktop_common_packages | default([])) + + ( + (arch_desktop_gnome_packages | default([])) + if 'gnome' in (desktop_sessions_enabled | default([])) + else [] + ) + + (arch_profile_packages | default([])) + + (host_packages | default([])) + ) + | unique + }} + state: present diff --git a/ansible/roles/profile_desktop_common/handlers/main.yml b/ansible/roles/profile_desktop_common/handlers/main.yml index 106fc16..5cdbfbd 100644 --- a/ansible/roles/profile_desktop_common/handlers/main.yml +++ b/ansible/roles/profile_desktop_common/handlers/main.yml @@ -5,6 +5,7 @@ changed_when: true when: - not ansible_check_mode + - "'void' in group_names" - desktop_restart_emptty_automatically | default(false) - name: Report manual emptty restart requirement @@ -16,10 +17,22 @@ to avoid dropping the active graphical session. when: - not ansible_check_mode + - "'void' in group_names" - not (desktop_restart_emptty_automatically | default(false)) -- name: Reload SSH service +- name: Reload SSH service with runit listen: Reload SSH service ansible.builtin.command: sv reload sshd changed_when: true - when: not ansible_check_mode + when: + - not ansible_check_mode + - "'void' in group_names" + +- name: Reload SSH service with systemd + listen: Reload SSH service + ansible.builtin.systemd: + name: "{{ desktop_ssh_service_name | default('sshd') }}" + state: reloaded + when: + - not ansible_check_mode + - "'arch' in group_names" diff --git a/ansible/roles/profile_desktop_common/tasks/main.yml b/ansible/roles/profile_desktop_common/tasks/main.yml index 3758556..5108863 100644 --- a/ansible/roles/profile_desktop_common/tasks/main.yml +++ b/ansible/roles/profile_desktop_common/tasks/main.yml @@ -6,6 +6,7 @@ regexp: '^#?HandleLidSwitch=' line: 'HandleLidSwitch=suspend' state: present + when: "'void' in group_names" - name: Ensure common config directories exist tags: [dotfiles, dotfiles:desktop] @@ -22,6 +23,9 @@ - "{{ user_home }}/.config/alacritty" - "{{ user_home }}/.config/Thunar" - "{{ user_home }}/.config/rofi" + - "{{ user_home }}/.config/systemd" + - "{{ user_home }}/.config/systemd/user" + - "{{ user_home }}/.bashrc.d" - "{{ user_home }}/.tmux" - "{{ user_home }}/.tmux/bin" - "{{ user_home }}/.tmux/plugins" @@ -42,6 +46,7 @@ insertafter: '^auth\s+include\s+system-local-login$' line: "auth optional pam_gnome_keyring.so" state: present + when: "'void' in group_names" - name: Enable gnome-keyring PAM session hook tags: [packages, gnome] @@ -50,6 +55,7 @@ insertafter: '^session\s+include\s+system-local-login$' line: "session optional pam_gnome_keyring.so auto_start" state: present + when: "'void' in group_names" - name: Enable gnome-keyring PAM password hook tags: [packages, gnome] @@ -58,6 +64,7 @@ insertafter: '^password\s+include\s+system-local-login$' line: "password optional pam_gnome_keyring.so use_authtok" state: present + when: "'void' in group_names" - name: Check whether SSH host ed25519 key exists tags: [services] @@ -181,6 +188,7 @@ ansible.builtin.stat: path: /etc/sv/libvirtd register: libvirtd_service_dir + when: "'void' in group_names" - name: Enable libvirt daemon service tags: [packages, services] @@ -188,7 +196,9 @@ src: /etc/sv/libvirtd dest: /var/service/libvirtd state: link - when: libvirtd_service_dir.stat.exists + when: + - "'void' in group_names" + - libvirtd_service_dir.stat.exists - name: Check virtualization group availability tags: [packages] @@ -229,6 +239,7 @@ owner: root group: root mode: "0755" + when: "'void' in group_names" - name: Ensure emptty session directories exist tags: [packages, services, emptty] @@ -241,6 +252,7 @@ loop: - /etc/emptty/xsessions - /etc/emptty/wayland-sessions + when: "'void' in group_names" - name: Configure emptty tags: [packages, services, emptty] @@ -251,6 +263,7 @@ group: root mode: "0644" notify: Restart emptty + when: "'void' in group_names" - name: Copy common desktop dotfiles tags: [dotfiles, dotfiles:desktop] @@ -260,10 +273,41 @@ owner: "{{ username }}" group: "{{ user_group }}" mode: "{{ item.mode }}" - loop: "{{ desktop_common_dotfiles | default([]) }}" + loop: >- + {{ + (desktop_common_dotfiles | default([])) + + ((desktop_void_dotfiles | default([])) if 'void' in group_names else []) + + ((desktop_arch_dotfiles | default([])) if 'arch' in group_names else []) + }} loop_control: label: "{{ item.dest }}" +- name: Ensure systemd user enablement directory exists + tags: [services, dotfiles, dotfiles:desktop] + ansible.builtin.file: + path: "{{ user_home }}/.config/systemd/user/default.target.wants" + state: directory + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "0755" + when: + - "'arch' in group_names" + - (desktop_systemd_user_services | default([])) | length > 0 + +- name: Enable desktop systemd user services + tags: [services, dotfiles, dotfiles:desktop] + ansible.builtin.file: + src: "{{ user_home }}/.config/systemd/user/{{ item }}" + dest: "{{ user_home }}/.config/systemd/user/default.target.wants/{{ item }}" + state: link + owner: "{{ username }}" + group: "{{ user_group }}" + force: true + loop: "{{ desktop_systemd_user_services | default([]) }}" + loop_control: + label: "{{ item }}" + when: "'arch' in group_names" + - name: Copy Emacs desktop dotfiles tags: [dotfiles, dotfiles:desktop, emacs] ansible.builtin.copy: diff --git a/ansible/roles/profile_desktop_gnome/tasks/main.yml b/ansible/roles/profile_desktop_gnome/tasks/main.yml new file mode 100644 index 0000000..0c5ef5a --- /dev/null +++ b/ansible/roles/profile_desktop_gnome/tasks/main.yml @@ -0,0 +1,18 @@ +--- +- name: Ensure GNOME desktop session is enabled for this profile + tags: [gnome] + ansible.builtin.assert: + that: + - "'gnome' in (desktop_sessions_enabled | default([]))" + fail_msg: >- + profile_desktop_gnome requires desktop_sessions_enabled to include gnome. + +- name: Ensure systemd boots to the graphical target + tags: [services, gnome] + ansible.builtin.file: + src: /usr/lib/systemd/system/graphical.target + dest: /etc/systemd/system/default.target + state: link + force: true + owner: root + group: root diff --git a/ansible/roles/profile_desktop_host/tasks/nymph.yml b/ansible/roles/profile_desktop_host/tasks/nymph.yml index 21f8921..110fd9a 100644 --- a/ansible/roles/profile_desktop_host/tasks/nymph.yml +++ b/ansible/roles/profile_desktop_host/tasks/nymph.yml @@ -4,13 +4,18 @@ ansible.builtin.lineinfile: path: /etc/default/grub regexp: '^GRUB_CMDLINE_LINUX=' - line: 'GRUB_CMDLINE_LINUX="rd.luks.uuid=1e15d159-5d05-4a1f-9639-ac200dff9f9c rootflags=subvol=@ apparmor=1 security=apparmor nouveau.modeset=0 nvidia-drm.modeset=1"' + line: 'GRUB_CMDLINE_LINUX="{{ host_grub_cmdline_linux }}"' state: present + register: nymph_grub_cmdline + when: host_grub_cmdline_linux is defined - name: Regenerate GRUB configuration tags: [packages, nvidia] ansible.builtin.command: grub-mkconfig -o /boot/grub/grub.cfg changed_when: true + when: + - host_grub_cmdline_linux is defined + - nymph_grub_cmdline is changed - name: Configure NVIDIA power management for hybrid graphics tags: [packages, nvidia] diff --git a/ansible/site.yml b/ansible/site.yml index 3a754ae..fe108a5 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -28,6 +28,16 @@ - profile_desktop_sway - profile_desktop_host +- hosts: arch + become: true + + roles: + - packages_arch + - services_systemd + - profile_desktop_common + - profile_desktop_gnome + - profile_desktop_host + - hosts: workstation_dev_ubuntu become: true diff --git a/dotfiles/desktop/.bashrc.d/15-runit-desktop.sh b/dotfiles/desktop/.bashrc.d/15-runit-desktop.sh index 036a655..f019a87 100644 --- a/dotfiles/desktop/.bashrc.d/15-runit-desktop.sh +++ b/dotfiles/desktop/.bashrc.d/15-runit-desktop.sh @@ -1,2 +1 @@ export SVDIR="$HOME/.config/service" -export SSH_AUTH_SOCK="$HOME/.local/state/ssh-agent/socket" diff --git a/dotfiles/desktop/.bashrc.d/16-ssh-agent-socket.sh b/dotfiles/desktop/.bashrc.d/16-ssh-agent-socket.sh new file mode 100644 index 0000000..71e03e8 --- /dev/null +++ b/dotfiles/desktop/.bashrc.d/16-ssh-agent-socket.sh @@ -0,0 +1 @@ +export SSH_AUTH_SOCK="$HOME/.local/state/ssh-agent/socket" diff --git a/dotfiles/desktop/.bashrc.d/25-emacs-client-desktop.sh b/dotfiles/desktop/.bashrc.d/25-emacs-client-desktop.sh index 4427f00..1581fda 100644 --- a/dotfiles/desktop/.bashrc.d/25-emacs-client-desktop.sh +++ b/dotfiles/desktop/.bashrc.d/25-emacs-client-desktop.sh @@ -1,14 +1,14 @@ if command -v emacsclient >/dev/null 2>&1; then ec() { emacsclient -c -n "$@" || { - printf '%s\n' "Emacs server is not available. Log into a graphical session and ensure the turnstile-managed 'emacs' service is running." >&2 + printf '%s\n' "Emacs server is not available. Log into a graphical session and ensure the user 'emacs' service is running." >&2 return 1 } } et() { emacsclient -t "$@" || { - printf '%s\n' "Emacs server is not available. Ensure the turnstile-managed 'emacs' service is running in your graphical session." >&2 + printf '%s\n' "Emacs server is not available. Ensure the user 'emacs' service is running in your graphical session." >&2 return 1 } } diff --git a/dotfiles/desktop/.config/systemd/user/emacs.service b/dotfiles/desktop/.config/systemd/user/emacs.service new file mode 100644 index 0000000..d3bea5f --- /dev/null +++ b/dotfiles/desktop/.config/systemd/user/emacs.service @@ -0,0 +1,14 @@ +[Unit] +Description=Emacs daemon +After=ssh-agent.service +Wants=ssh-agent.service + +[Service] +Type=simple +Environment=SSH_AUTH_SOCK=%h/.local/state/ssh-agent/socket +WorkingDirectory=%h +ExecStart=/usr/bin/emacs --fg-daemon +Restart=on-failure + +[Install] +WantedBy=default.target diff --git a/dotfiles/desktop/.config/systemd/user/rclone-pcloud.service b/dotfiles/desktop/.config/systemd/user/rclone-pcloud.service new file mode 100644 index 0000000..b11cb56 --- /dev/null +++ b/dotfiles/desktop/.config/systemd/user/rclone-pcloud.service @@ -0,0 +1,12 @@ +[Unit] +Description=Mount pCloud remote with rclone + +[Service] +Type=simple +ExecStart=/bin/sh -lc 'mkdir -p "$HOME/.cache/rclone/pcloud" "$HOME/Remotes/pCloud"; mountpoint -q "$HOME/Remotes/pCloud" && exit 0; exec /usr/bin/rclone mount pcloud: "$HOME/Remotes/pCloud" --config "$HOME/.config/rclone/rclone.conf" --cache-dir "$HOME/.cache/rclone/pcloud" --vfs-cache-mode writes --dir-cache-time 10m --poll-interval 1m --log-level INFO' +ExecStop=/bin/sh -lc 'mountpoint -q "$HOME/Remotes/pCloud" && exec /usr/bin/fusermount3 -u "$HOME/Remotes/pCloud" || exit 0' +Restart=on-failure +RestartSec=10 + +[Install] +WantedBy=default.target diff --git a/dotfiles/desktop/.config/systemd/user/ssh-agent.service b/dotfiles/desktop/.config/systemd/user/ssh-agent.service new file mode 100644 index 0000000..6a78ee9 --- /dev/null +++ b/dotfiles/desktop/.config/systemd/user/ssh-agent.service @@ -0,0 +1,13 @@ +[Unit] +Description=SSH key agent + +[Service] +Type=simple +Environment=SSH_AUTH_SOCK=%h/.local/state/ssh-agent/socket +ExecStartPre=/usr/bin/mkdir -p %h/.local/state/ssh-agent +ExecStartPre=/usr/bin/rm -f %h/.local/state/ssh-agent/socket +ExecStart=/usr/bin/ssh-agent -D -a %h/.local/state/ssh-agent/socket +Restart=on-failure + +[Install] +WantedBy=default.target diff --git a/dotfiles/desktop/.config/systemd/user/syncthing.service b/dotfiles/desktop/.config/systemd/user/syncthing.service new file mode 100644 index 0000000..5fb7856 --- /dev/null +++ b/dotfiles/desktop/.config/systemd/user/syncthing.service @@ -0,0 +1,10 @@ +[Unit] +Description=Syncthing file synchronization + +[Service] +Type=simple +ExecStart=/usr/bin/syncthing serve --no-browser --no-restart --logfile=default +Restart=on-failure + +[Install] +WantedBy=default.target