From f33f3fe43332ad4d9ee4bab1c7a7fc468a16879c Mon Sep 17 00:00:00 2001 From: Fabio Scotto di Santolo Date: Sat, 11 Jul 2026 22:04:22 +0200 Subject: [PATCH] Switch to Linux Mint and FreeBSD --- AGENTS.md | 12 +- README.md | 206 ++++++++++++------ .../examples/platform-test-hosts.yml | 34 +++ .../inventory/group_vars/desktop_cinnamon.yml | 22 ++ .../inventory/group_vars/desktop_hyprland.yml | 3 + ansible/inventory/group_vars/desktop_sway.yml | 2 + .../group_vars/graphical_desktop.yml | 3 + .../inventory/group_vars/platform_freebsd.yml | 95 ++++++++ .../inventory/group_vars/platform_mint.yml | 65 ++++++ .../inventory/group_vars/platform_void.yml | 5 + ansible/inventory/group_vars/role_lab.yml | 11 + .../group_vars/role_personal_workstation.yml | 24 ++ ansible/inventory/host_vars/ikaros.yml | 7 - ansible/inventory/host_vars/nymph.yml | 6 - ansible/inventory/hosts.yml | 41 ++++ ansible/roles/packages_freebsd/tasks/main.yml | 29 +++ ansible/roles/packages_mint/tasks/main.yml | 80 +++++++ .../profile_desktop_cinnamon/tasks/main.yml | 27 +++ .../files/hyprland-portals.conf | 4 + .../tasks/main.yml | 58 +++++ .../templates/start-hyprland-session.j2 | 24 ++ ansible/roles/profile_lab/tasks/main.yml | 12 + .../tasks/main.yml | 24 ++ ansible/roles/services_freebsd/tasks/main.yml | 20 ++ ansible/roles/services_systemd/tasks/main.yml | 1 - ansible/site.yml | 76 ++++++- 26 files changed, 804 insertions(+), 87 deletions(-) create mode 100644 ansible/inventory/examples/platform-test-hosts.yml create mode 100644 ansible/inventory/group_vars/desktop_cinnamon.yml create mode 100644 ansible/inventory/group_vars/desktop_hyprland.yml create mode 100644 ansible/inventory/group_vars/desktop_sway.yml create mode 100644 ansible/inventory/group_vars/graphical_desktop.yml create mode 100644 ansible/inventory/group_vars/platform_freebsd.yml create mode 100644 ansible/inventory/group_vars/platform_mint.yml create mode 100644 ansible/inventory/group_vars/platform_void.yml create mode 100644 ansible/inventory/group_vars/role_lab.yml create mode 100644 ansible/inventory/group_vars/role_personal_workstation.yml create mode 100644 ansible/roles/packages_freebsd/tasks/main.yml create mode 100644 ansible/roles/packages_mint/tasks/main.yml create mode 100644 ansible/roles/profile_desktop_cinnamon/tasks/main.yml create mode 100644 ansible/roles/profile_desktop_hyprland_freebsd/files/hyprland-portals.conf create mode 100644 ansible/roles/profile_desktop_hyprland_freebsd/tasks/main.yml create mode 100644 ansible/roles/profile_desktop_hyprland_freebsd/templates/start-hyprland-session.j2 create mode 100644 ansible/roles/profile_lab/tasks/main.yml create mode 100644 ansible/roles/profile_personal_workstation/tasks/main.yml create mode 100644 ansible/roles/services_freebsd/tasks/main.yml diff --git a/AGENTS.md b/AGENTS.md index b7d813a..082ccb9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # AGENTS.md -Ansible-driven personal infrastructure repo for Void desktops, Linux workstations, WSL, and an Ubuntu server. +Ansible-driven personal infrastructure repo for Void desktops, Linux Mint and FreeBSD transition targets, Linux workstations, WSL, and an Ubuntu server. ## Source Of Truth - Main orchestration: `ansible/site.yml` @@ -11,14 +11,16 @@ 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` +- Current Void desktops: `ikaros`, `nymph` via `platform_void + graphical_desktop` +- Target model: `ikaros = platform_mint + role_personal_workstation + desktop_cinnamon`; `nymph = platform_freebsd + role_lab + desktop_hyprland` - Native Linux workstation: `deadalus-fedora` - WSL dev: `deadalus-wsl` - Ubuntu server: `prometheus` - Hosts intentionally belong to multiple groups; trust `ansible/site.yml` over hostname assumptions. +- Inventory axes are independent: `platform_*`, `role_*`, and `desktop_*`. Legacy `void` and `desktop` remain compatibility parents. ## Working Rules -- Preserve layering `all -> OS -> profile -> host`. +- Preserve layering `all -> platform -> role -> desktop -> host`. - Keep `ansible/site.yml` small; orchestration belongs there, implementation belongs in roles. - Prefer minimal, targeted edits. Preserve idempotency and existing ordering. - All hosts use `ansible_connection: local`. @@ -34,6 +36,7 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation - `ansible-lint ansible/roles` - `yamllint ansible/` - Host-focused dry runs: + - Current Void preservation: `ansible-playbook ansible/site.yml --limit ikaros,nymph --check --diff` - Void desktop work: `ansible-playbook ansible/site.yml --limit ikaros --check --diff` or `--limit nymph --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` @@ -52,6 +55,7 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation - Use `no_log: true` for secret-bearing task inputs or outputs. ## Desktop Notes +- `desktop_profile` names independently selectable desktop groups such as `desktop_hyprland`, `desktop_sway`, and `desktop_cinnamon`. Keep platform-specific session bootstrap in platform-specific roles. - `desktop_environment` selects the mutually exclusive `minimal` (default), `xfce`, or `kde` desktop mode. `profile_desktop_common` owns shared bootstrap; the minimal mode uses `profile_desktop_sway` and `profile_desktop_hyprland`, `profile_desktop_xfce` owns the reproducible XFCE setup, and `profile_desktop_kde` owns KDE-specific defaults and cleanup. `desktop_sessions_enabled` and `desktop_default_session` apply only to the minimal mode. - `.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`. @@ -60,10 +64,12 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation - Critical session entrypoints: - `dotfiles/desktop/.config/sway/config` plus `host.conf` and `session-env` deployed via `host_sway_dotfiles` (sway / Wayland) - `dotfiles/desktop/.config/hypr/hyprland.conf` plus `host.conf` and `session-env` deployed via `host_hyprland_dotfiles` (Hyprland / Wayland) +- FreeBSD Hyprland must reuse common Hyprland dotfiles and keep FreeBSD-specific package, rc, DBus, seat, portal, and launcher behavior in `profile_desktop_hyprland_freebsd` or FreeBSD platform vars. - Do not switch or restart a display manager during a playbook run from an active graphical session. Changing among `emptty`, LightDM, and SDDM requires an explicit run from another TTY/SSH session with `desktop_allow_display_manager_switch=true`. Apply managed XFCE XML while logged out of XFCE so `xfconfd` cannot overwrite it from its in-memory state. - `nymph` is a Void laptop with NVIDIA Optimus, running sway (Wayland) and Hyprland (Wayland); host-specific tasks in `profile_desktop_host/tasks/nymph.yml` handle GRUB NVIDIA cmdline params, `prime-run` wrapper, and the WirePlumber camera priority config. Multi-monitor on sway is driven by `kanshi` (config deployed via `host_sway_dotfiles`), and on Hyprland by host-specific Hyprland monitor/workspace rules. ## Void Package And Dotfile Bucket Rules +`platform_void` is the reusable Void platform selection. The legacy `void` group remains a compatibility parent so existing `group_vars/void.yml` and `when: "'void' in group_names"` checks keep working during the transition. The Void desktop package lists in `ansible/inventory/group_vars/void.yml` are kept disjoint by role: - `void_packages_base` — system runtime only (init/services, kernel, audio core, networking, filesystem, firewall, hardware daemons, runit logging). - `desktop_common_packages` — GUI infrastructure shared by all desktop modes. diff --git a/README.md b/README.md index 66f1961..3c9269b 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,44 @@ Il repository è diviso in due componenti principali: # Macchine gestite -Il repository modella attualmente tre tipologie di profilo, con i filoni workstation Linux nativa e WSL. +Il repository modella attualmente tre tipologie di profilo, con i filoni workstation Linux nativa e WSL. +La nuova direzione del repository separa tre assi indipendenti: + +```text +common user environment ++ host-specific platform ++ role-specific software ++ independently selectable desktop ++ host hardware overrides +``` + +Matrice target: + +| Host | Platform | Role | Desktop | +| -------------- | ---------- | -------------------- | --------------------------------- | +| ikaros | Linux Mint | Personal workstation | Cinnamon | +| nymph | FreeBSD | Lab | Hyprland | +| void-reference | Void Linux | Lab/reference | Current preserved desktop profile | + +Regola operativa: + +```text +ikaros must be boring +nymph is allowed to break +``` + +Durante il refactoring strutturale iniziale `ikaros` e `nymph` restano in +`platform_void` per preservare il comportamento esistente. I gruppi legacy +`void` e `desktop` restano alias di compatibilita mentre i nuovi assi sono +`platform_*`, `role_*` e `desktop_*`. + +Prima di una migrazione reale degli host e consigliato creare uno snapshot +logico, per esempio: + +```bash +git switch -c refactor/platform-role-desktop +git tag void-desktop-before-platform-refactor +``` Nota sullo stato attuale del playbook principale: @@ -210,32 +247,42 @@ ansible-playbook ansible/site.yml --limit ikaros --tags emacs ansible-playbook ansible/site.yml --limit nymph --tags emacs ``` -La configurazione finale di una macchina è ottenuta combinando più livelli. - -```text -common configuration -+ OS configuration -+ profile configuration -+ host overrides -``` - -Esempio per `ikaros`: - -```text -common + void + desktop + ikaros -``` - -Esempio per `nymph`: - -```text -common + void + desktop + nymph -``` +La configurazione finale di una macchina è ottenuta combinando più livelli. + +```text +common configuration ++ platform configuration ++ role configuration ++ desktop configuration ++ host overrides +``` + +Esempio corrente per `ikaros` nella fase conservativa: + +```text +common + platform_void + graphical_desktop + role_personal_workstation + desktop_hyprland/desktop_sway + ikaros +``` + +Esempio corrente per `nymph` nella fase conservativa: + +```text +common + platform_void + graphical_desktop + role_lab + desktop_hyprland/desktop_sway + nymph +``` + +Esempi target, da attivare con un cambio inventory separato: + +```text +ikaros -> platform_mint + role_personal_workstation + desktop_cinnamon +nymph -> platform_freebsd + role_lab + desktop_hyprland +``` Questo approccio consente di: -- mantenere configurazioni condivise -- applicare override specifici per host -- evitare duplicazioni +- mantenere configurazioni condivise +- applicare override specifici per host +- evitare duplicazioni +- riutilizzare il profilo Void corrente su un host futuro assegnandolo a + `platform_void + graphical_desktop + role_lab + desktop_hyprland` --- @@ -243,19 +290,26 @@ Questo approccio consente di: I principali ruoli attualmente presenti sono: -| Role | Descrizione | -| ------------------------- | ----------------------------------- | -| base | configurazione base comune | -| packages_void | installazione pacchetti su Void | -| packages_ubuntu | installazione pacchetti su Ubuntu | -| packages_fedora | installazione pacchetti su Fedora | -| services_runit | gestione servizi runit | -| services_systemd | gestione servizi systemd | -| profile_desktop_common | bootstrap desktop Void condiviso | -| profile_desktop_sway | sessione desktop sway / SwayFX (Wayland) | -| profile_desktop_hyprland | sessione desktop Hyprland (Wayland) | -| profile_desktop_host | override desktop specifici per host | -| profile_workstation_dev_common | configurazione dev workstation condivisa | +| Role | Descrizione | +| ------------------------- | ----------------------------------- | +| base | configurazione base comune | +| packages_void | installazione pacchetti su Void | +| packages_mint | installazione pacchetti su Linux Mint via APT | +| packages_freebsd | installazione pacchetti su FreeBSD via pkg | +| packages_ubuntu | installazione pacchetti su Ubuntu | +| packages_fedora | installazione pacchetti su Fedora | +| services_runit | gestione servizi runit | +| services_systemd | gestione servizi systemd | +| services_freebsd | gestione servizi FreeBSD rc.conf/rc.d | +| profile_desktop_common | bootstrap desktop Void condiviso | +| profile_desktop_sway | sessione desktop sway / SwayFX (Wayland) | +| profile_desktop_hyprland | sessione desktop Hyprland (Wayland) | +| profile_desktop_hyprland_freebsd | adattamenti FreeBSD per Hyprland | +| profile_desktop_cinnamon | impostazioni Cinnamon circoscritte | +| profile_desktop_host | override desktop specifici per host | +| profile_personal_workstation | layer stabile per workstation personale | +| profile_lab | layer sperimentale/lab | +| profile_workstation_dev_common | configurazione dev workstation condivisa | | profile_workstation_gnome | configurazione host workstation GNOME | | profile_workstation_dev_wsl | configurazione WSL Ubuntu per sviluppo | | profile_server | configurazione server | @@ -266,20 +320,28 @@ I principali ruoli attualmente presenti sono: # Stato attuale del playbook principale -Il playbook `ansible/site.yml` e attualmente composto da sei blocchi: - -```text -all -> dotfiles_common -void -> packages_void + services_runit + profile_desktop_common + profile_desktop_sway + profile_desktop_hyprland + profile_desktop_host -workstation_dev_fedora -> packages_fedora + services_systemd + profile_workstation_dev_common -workstation_host_linux -> profile_workstation_gnome -workstation_dev_wsl -> packages_ubuntu + services_systemd + profile_workstation_dev_common + profile_workstation_dev_wsl -ubuntu_server -> packages_ubuntu + services_systemd + profile_server +Il playbook `ansible/site.yml` e attualmente composto da blocchi per asse: + +```text +all -> dotfiles_common +platform_void -> packages_void + services_runit +platform_void & graphical_desktop -> profile_desktop_common + profile_desktop_sway + profile_desktop_hyprland + profile_desktop_kde + profile_desktop_xfce + profile_desktop_host +platform_mint -> packages_mint + services_systemd +platform_mint & role_personal_workstation -> profile_personal_workstation +platform_mint & desktop_cinnamon -> profile_desktop_cinnamon +platform_freebsd -> packages_freebsd + services_freebsd +platform_freebsd & role_lab -> profile_lab +platform_freebsd & desktop_hyprland -> profile_desktop_hyprland_freebsd +workstation_dev_fedora -> packages_fedora + services_systemd + profile_workstation_dev_common +workstation_host_linux -> profile_workstation_gnome +workstation_dev_wsl -> packages_ubuntu + services_systemd + profile_workstation_dev_common + profile_workstation_dev_wsl +ubuntu_server -> packages_ubuntu + services_systemd + profile_server ``` Questo significa che, allo stato attuale: -- i desktop Void (`ikaros`, `nymph`) restano il target operativo piu completo +- i desktop Void (`ikaros`, `nymph`) restano il target operativo piu completo tramite `platform_void + graphical_desktop` +- Linux Mint/Cinnamon e FreeBSD/Hyprland sono scaffolding selezionabile tramite gruppi, ma non ricevono host reali nel refactoring strutturale iniziale - la workstation Fedora (`deadalus-fedora`) usa il principio di composizione a gruppi con il ramo Fedora dedicato e con `gsettings` host-specifici dichiarati in inventory - il ramo WSL (`deadalus-wsl`) e predisposto con play dev dedicato - il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall @@ -350,11 +412,13 @@ Eseguire il playbook principale: ansible-playbook ansible/site.yml ``` -Allo stato attuale questo comando: - -- distribuisce i dotfiles comuni a tutti gli host -- per gli host Void applica bootstrap desktop condiviso, sessioni sway/Hyprland e override specifici per host -- per `workstation_dev_fedora` applica pacchetti Fedora, servizi systemd e profilo dev comune +Allo stato attuale questo comando: + +- distribuisce i dotfiles comuni a tutti gli host +- per `platform_void` applica pacchetti Void e servizi runit +- per `platform_void + graphical_desktop` applica bootstrap desktop condiviso, sessioni sway/Hyprland e override specifici per host +- per `platform_mint` e `platform_freebsd` applica solo host presenti esplicitamente in quei gruppi; nell'inventory principale iniziale questi gruppi sono vuoti +- per `workstation_dev_fedora` applica pacchetti Fedora, servizi systemd e profilo dev comune - per `workstation_host_linux` applica il layer host Linux GNOME - per `workstation_dev_wsl` applica pacchetti Ubuntu, servizi systemd, profilo dev comune e tweak WSL dedicati - per gli host `ubuntu_server` applica pacchetti Ubuntu, servizi systemd, profilo server, UFW, dotfiles e template dedicati @@ -362,12 +426,13 @@ Allo stato attuale questo comando: - carica `secrets/vault.yml` solo se presente - carica `secrets/vault.local.yml` solo se presente, dopo `vault.yml`, cosi gli override locali hanno precedenza -Per validare prima di applicare: - -```bash -ansible-playbook ansible/site.yml --syntax-check -ansible-playbook ansible/site.yml --limit ikaros --check --diff -ansible-playbook ansible/site.yml --limit nymph --check --diff +Per validare prima di applicare: + +```bash +ansible-playbook ansible/site.yml --syntax-check +ansible-playbook ansible/site.yml --limit ikaros,nymph --check --diff +ansible-playbook ansible/site.yml --limit ikaros --check --diff +ansible-playbook ansible/site.yml --limit nymph --check --diff ansible-playbook ansible/site.yml --limit deadalus-fedora --check --diff ansible-playbook ansible/site.yml --limit deadalus-wsl --check --diff ansible-playbook ansible/site.yml --limit prometheus --check --diff @@ -423,7 +488,8 @@ Allo stato attuale `ansible/site.yml` espone questi tag: | `display-manager` | selezione protetta tra `emptty`, LightDM e SDDM | desktop Void | | `kde` | profilo KDE Plasma e relativa pulizia | desktop Void | | `xfce` | profilo XFCE, LightDM e relativa pulizia | desktop Void | -| `gnome` | configurazione host GNOME | workstation host Linux, parte desktop | +| `cinnamon` | impostazioni Cinnamon circoscritte | Linux Mint desktop | +| `gnome` | configurazione host GNOME | workstation host Linux, parte desktop | | `sway` | sessione/configurazione sway / SwayFX (Wayland) | desktop Void | | `hyprland` | sessione/configurazione Hyprland (Wayland) | desktop Void | | `npm` | installazione pacchetti npm globali | desktop Void, workstation Linux, WSL | @@ -456,9 +522,25 @@ ansible-galaxy collection install -r ansible/collections/requirements.yml ansible-playbook ansible/site.yml ``` -Dopo l'esecuzione del playbook la macchina verra configurata secondo il profilo definito e i ruoli attualmente orchestrati. - -Per il flusso mail desktop esiste inoltre uno script dedicato: +Dopo l'esecuzione del playbook la macchina verra configurata secondo il profilo definito e i ruoli attualmente orchestrati. + +Per aggiungere un nuovo host Void che riusa il profilo desktop preservato: + +1. aggiungere l'host a `platform_void`; +2. aggiungerlo a `graphical_desktop`; +3. scegliere il ruolo, per esempio `role_lab`; +4. scegliere il desktop, per esempio `desktop_hyprland`; +5. lasciare eventuali dettagli hardware in `host_vars/.yml`. + +I gruppi legacy `void` e `desktop` sono parent di compatibilita, quindi un host +in `platform_void` e `graphical_desktop` continua a ricevere anche le variabili +Void e desktop esistenti. + +Per prove in VM sono disponibili gruppi di esempio in +`ansible/inventory/examples/platform-test-hosts.yml`, da passare esplicitamente +con `-i` insieme all'inventory principale. + +Per il flusso mail desktop esiste inoltre uno script dedicato: ```bash scripts/bootstrap_mail.sh diff --git a/ansible/inventory/examples/platform-test-hosts.yml b/ansible/inventory/examples/platform-test-hosts.yml new file mode 100644 index 0000000..fdb61df --- /dev/null +++ b/ansible/inventory/examples/platform-test-hosts.yml @@ -0,0 +1,34 @@ +--- +# Optional inventory overlay for VM tests. It is not loaded by ansible.cfg. +all: + children: + platform_mint: + hosts: + minttest: + ansible_connection: local + + platform_freebsd: + hosts: + freebsdtest: + ansible_connection: local + + graphical_desktop: + hosts: + minttest: + freebsdtest: + + role_personal_workstation: + hosts: + minttest: + + role_lab: + hosts: + freebsdtest: + + desktop_cinnamon: + hosts: + minttest: + + desktop_hyprland: + hosts: + freebsdtest: diff --git a/ansible/inventory/group_vars/desktop_cinnamon.yml b/ansible/inventory/group_vars/desktop_cinnamon.yml new file mode 100644 index 0000000..6feacc3 --- /dev/null +++ b/ansible/inventory/group_vars/desktop_cinnamon.yml @@ -0,0 +1,22 @@ +--- +desktop_profile: cinnamon +desktop_default_session: cinnamon + +cinnamon_theme_gtk: Mint-Y-Dark-Aqua +cinnamon_theme_icons: Mint-Y-Aqua +cinnamon_font_ui: Sans 10 +cinnamon_font_monospace: Monospace 10 + +cinnamon_dconf_settings: + - key: /org/cinnamon/desktop/interface/gtk-theme + value: "'{{ cinnamon_theme_gtk }}'" + - key: /org/cinnamon/desktop/interface/icon-theme + value: "'{{ cinnamon_theme_icons }}'" + - key: /org/cinnamon/desktop/interface/font-name + value: "'{{ cinnamon_font_ui }}'" + - key: /org/cinnamon/desktop/interface/monospace-font-name + value: "'{{ cinnamon_font_monospace }}'" + - key: /org/cinnamon/desktop/interface/clock-use-24h + value: "true" + - key: /org/cinnamon/desktop/wm/preferences/button-layout + value: "'menu:minimize,maximize,close'" diff --git a/ansible/inventory/group_vars/desktop_hyprland.yml b/ansible/inventory/group_vars/desktop_hyprland.yml new file mode 100644 index 0000000..6fd1bb5 --- /dev/null +++ b/ansible/inventory/group_vars/desktop_hyprland.yml @@ -0,0 +1,3 @@ +--- +desktop_profile: hyprland +desktop_default_session: hyprland diff --git a/ansible/inventory/group_vars/desktop_sway.yml b/ansible/inventory/group_vars/desktop_sway.yml new file mode 100644 index 0000000..ea77d69 --- /dev/null +++ b/ansible/inventory/group_vars/desktop_sway.yml @@ -0,0 +1,2 @@ +--- +desktop_profile: sway diff --git a/ansible/inventory/group_vars/graphical_desktop.yml b/ansible/inventory/group_vars/graphical_desktop.yml new file mode 100644 index 0000000..828cdc5 --- /dev/null +++ b/ansible/inventory/group_vars/graphical_desktop.yml @@ -0,0 +1,3 @@ +--- +host_capabilities: + - graphical_desktop diff --git a/ansible/inventory/group_vars/platform_freebsd.yml b/ansible/inventory/group_vars/platform_freebsd.yml new file mode 100644 index 0000000..e167fd0 --- /dev/null +++ b/ansible/inventory/group_vars/platform_freebsd.yml @@ -0,0 +1,95 @@ +--- +platform_profile: freebsd +platform_family: freebsd +platform_package_manager: pkg +platform_service_manager: rc +ansible_python_interpreter: /usr/local/bin/python3 + +effective_user_group: "{{ user_group }}" +effective_user_home: "/home/{{ effective_username }}" +user_home: "/home/{{ username }}" + +freebsd_packages_base: + - bash + - bash-completion + - bat + - curl + - fzf + - git + - jq + - python3 + - ripgrep + - rsync + - tmux + - tree + - unzip + - vim + - wget + - zip + - zoxide + +freebsd_development_packages: + - clang + - cmake + - gdb + - go + - gmake + - node + - npm + - pkgconf + - py311-pip + - rust + - shellcheck + +freebsd_desktop_common_packages: + - dbus + - dconf + - firefox + - fontconfig + - gnome-keyring + - libsecret + - mpv + - pinentry-gnome + - pipewire + - polkit + - thunderbird + - wireplumber + - xdg-desktop-portal + +freebsd_hyprland_packages: + - alacritty + - cliphist + - dunst + - foot + - grim + - hypridle + - hyprland + - hyprlock + - hyprpaper + - rofi-wayland + - seatd + - slurp + - waybar + - wl-clipboard + - xdg-desktop-portal-gtk + - xdg-desktop-portal-hyprland + - xwayland + +freebsd_lab_packages: + - lldb + - llvm + - podman + - qemu + - smartmontools + +freebsd_rc_conf: + - name: dbus_enable + value: "YES" + - name: seatd_enable + value: "YES" + +freebsd_enabled_services: + - dbus + - seatd + +freebsd_xdg_config_dir: /usr/local/etc/xdg diff --git a/ansible/inventory/group_vars/platform_mint.yml b/ansible/inventory/group_vars/platform_mint.yml new file mode 100644 index 0000000..80afea6 --- /dev/null +++ b/ansible/inventory/group_vars/platform_mint.yml @@ -0,0 +1,65 @@ +--- +platform_profile: mint +platform_family: debian +platform_package_manager: apt +platform_service_manager: systemd + +mint_manage_flatpak: true +mint_flatpak_remote_name: flathub +mint_flatpak_remote_url: https://dl.flathub.org/repo/flathub.flatpakrepo + +mint_packages_base: + - ca-certificates + - curl + - flatpak + - gpg + - htop + - make + - python3-pip + - ripgrep + - rsync + - shellcheck + +mint_development_packages: + - build-essential + - clang + - clang-tools + - cmake + - gdb + - golang + - nodejs + - npm + - pkg-config + - python3-venv + +mint_desktop_common_packages: + - dconf-cli + - deja-dup + - emacs + - firefox + - fonts-liberation + - fonts-noto-color-emoji + - gnome-keyring + - libsecret-tools + - mpv + - pinentry-gnome3 + - rclone + - thunderbird + - xdg-user-dirs + +mint_cinnamon_packages: + - cinnamon + - cinnamon-control-center + - cinnamon-screensaver + - lightdm + - slick-greeter + - xdg-desktop-portal + - xdg-desktop-portal-gtk + +mint_personal_workstation_packages: + - libreoffice + - meld + - pdfarranger + - vim + +mint_flatpak_packages: [] diff --git a/ansible/inventory/group_vars/platform_void.yml b/ansible/inventory/group_vars/platform_void.yml new file mode 100644 index 0000000..8be723a --- /dev/null +++ b/ansible/inventory/group_vars/platform_void.yml @@ -0,0 +1,5 @@ +--- +platform_profile: void +platform_family: void +platform_package_manager: xbps +platform_service_manager: runit diff --git a/ansible/inventory/group_vars/role_lab.yml b/ansible/inventory/group_vars/role_lab.yml new file mode 100644 index 0000000..c848bf4 --- /dev/null +++ b/ansible/inventory/group_vars/role_lab.yml @@ -0,0 +1,11 @@ +--- +machine_role: lab +role_profile: lab +role_stability: experimental +experimental_profile: true + +lab_workspace_directories: + - path: "{{ user_home }}/Lab" + mode: "0755" + - path: "{{ user_home }}/Scratch" + mode: "0755" diff --git a/ansible/inventory/group_vars/role_personal_workstation.yml b/ansible/inventory/group_vars/role_personal_workstation.yml new file mode 100644 index 0000000..b1e30bf --- /dev/null +++ b/ansible/inventory/group_vars/role_personal_workstation.yml @@ -0,0 +1,24 @@ +--- +machine_role: personal_workstation +role_profile: personal_workstation +role_stability: stable + +personal_workstation_directories: + - path: "{{ user_home }}/Documents" + mode: "0755" + - path: "{{ user_home }}/Downloads" + mode: "0755" + - path: "{{ user_home }}/Org" + mode: "0755" + - path: "{{ user_home }}/Remotes" + mode: "0755" + +personal_workstation_dotfiles: + - src: .gitignore_global + dest: .gitignore_global + mode: "0644" + - src: .themes.gitignore + dest: .themes.gitignore + mode: "0644" + +personal_workstation_flatpak_packages: [] diff --git a/ansible/inventory/host_vars/ikaros.yml b/ansible/inventory/host_vars/ikaros.yml index dfb2bb3..f119efa 100644 --- a/ansible/inventory/host_vars/ikaros.yml +++ b/ansible/inventory/host_vars/ikaros.yml @@ -1,13 +1,6 @@ --- hostname: ikaros -desktop_sessions_enabled: - - sway - - hyprland - -desktop_default_session: hyprland -desktop_default_session_env: wayland - host_packages: - openssh - mesa-dri diff --git a/ansible/inventory/host_vars/nymph.yml b/ansible/inventory/host_vars/nymph.yml index 40a4cc7..fd624b2 100644 --- a/ansible/inventory/host_vars/nymph.yml +++ b/ansible/inventory/host_vars/nymph.yml @@ -1,12 +1,6 @@ --- hostname: nymph -desktop_sessions_enabled: - - sway - - hyprland - -desktop_default_session: hyprland -desktop_default_session_env: wayland desktop_emptty_session_error_logging: rotate host_packages: diff --git a/ansible/inventory/hosts.yml b/ansible/inventory/hosts.yml index f5e0ba1..855e6d3 100644 --- a/ansible/inventory/hosts.yml +++ b/ansible/inventory/hosts.yml @@ -1,7 +1,24 @@ --- all: children: + platform_void: + hosts: + ikaros: + ansible_connection: local + nymph: + ansible_connection: local + + platform_mint: + hosts: {} + + platform_freebsd: + hosts: {} + void: + children: + platform_void: + + graphical_desktop: hosts: ikaros: ansible_connection: local @@ -9,12 +26,36 @@ all: ansible_connection: local desktop: + children: + graphical_desktop: + + role_personal_workstation: + hosts: + ikaros: + ansible_connection: local + + role_lab: + hosts: + nymph: + ansible_connection: local + + desktop_sway: hosts: ikaros: ansible_connection: local nymph: ansible_connection: local + desktop_hyprland: + hosts: + ikaros: + ansible_connection: local + nymph: + ansible_connection: local + + desktop_cinnamon: + hosts: {} + ubuntu: children: workstation_dev_wsl: diff --git a/ansible/roles/packages_freebsd/tasks/main.yml b/ansible/roles/packages_freebsd/tasks/main.yml new file mode 100644 index 0000000..627dc20 --- /dev/null +++ b/ansible/roles/packages_freebsd/tasks/main.yml @@ -0,0 +1,29 @@ +--- +- name: Install packages on FreeBSD + tags: [packages] + community.general.pkgng: + name: >- + {{ + ( + (freebsd_packages_base | default([])) + + (freebsd_development_packages | default([])) + + ( + (freebsd_desktop_common_packages | default([])) + if 'graphical_desktop' in group_names + else [] + ) + + ( + (freebsd_hyprland_packages | default([])) + if 'desktop_hyprland' in group_names + else [] + ) + + ( + (freebsd_lab_packages | default([])) + if 'role_lab' in group_names + else [] + ) + + (host_packages | default([])) + ) + | unique + }} + state: present diff --git a/ansible/roles/packages_mint/tasks/main.yml b/ansible/roles/packages_mint/tasks/main.yml new file mode 100644 index 0000000..2486129 --- /dev/null +++ b/ansible/roles/packages_mint/tasks/main.yml @@ -0,0 +1,80 @@ +--- +- name: Refresh apt package cache on Linux Mint + tags: [packages] + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + +- name: Install packages on Linux Mint + tags: [packages] + ansible.builtin.apt: + name: >- + {{ + ( + (common_packages | default([])) + + (mint_packages_base | default([])) + + (mint_development_packages | default([])) + + ( + (mint_desktop_common_packages | default([])) + if 'graphical_desktop' in group_names + else [] + ) + + ( + (mint_cinnamon_packages | default([])) + if 'desktop_cinnamon' in group_names + else [] + ) + + ( + (mint_personal_workstation_packages | default([])) + if 'role_personal_workstation' in group_names + else [] + ) + + (host_packages | default([])) + ) + | unique + }} + state: present + +- name: Ensure Flathub remote is configured on Linux Mint + tags: [packages] + community.general.flatpak_remote: + name: "{{ mint_flatpak_remote_name | default('flathub') }}" + state: present + flatpakrepo_url: "{{ mint_flatpak_remote_url | default('https://dl.flathub.org/repo/flathub.flatpakrepo') }}" + when: + - mint_manage_flatpak | default(true) + - >- + ( + (mint_flatpak_packages | default([])) + + (personal_workstation_flatpak_packages | default([])) + ) | length > 0 + +- name: Install Linux Mint Flatpak applications + tags: [packages] + community.general.flatpak: + name: >- + {{ + ( + (mint_flatpak_packages | default([])) + + ( + (personal_workstation_flatpak_packages | default([])) + if 'role_personal_workstation' in group_names + else [] + ) + ) + | unique + }} + state: present + remote: "{{ mint_flatpak_remote_name | default('flathub') }}" + method: system + when: + - mint_manage_flatpak | default(true) + - >- + ( + (mint_flatpak_packages | default([])) + + ( + (personal_workstation_flatpak_packages | default([])) + if 'role_personal_workstation' in group_names + else [] + ) + ) | length > 0 diff --git a/ansible/roles/profile_desktop_cinnamon/tasks/main.yml b/ansible/roles/profile_desktop_cinnamon/tasks/main.yml new file mode 100644 index 0000000..affe04b --- /dev/null +++ b/ansible/roles/profile_desktop_cinnamon/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Ensure Cinnamon user config directories exist + tags: [dotfiles, dotfiles:desktop, cinnamon] + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "0755" + loop: + - "{{ user_home }}/.config" + - "{{ user_home }}/.local" + - "{{ user_home }}/.local/share" + +- name: Apply Cinnamon dconf settings + tags: [cinnamon] + community.general.dconf: + key: "{{ item.key }}" + value: "{{ item.value }}" + state: present + become: true + become_user: "{{ username }}" + environment: + HOME: "{{ user_home }}" + loop: "{{ cinnamon_dconf_settings | default([]) }}" + loop_control: + label: "{{ item.key }}" diff --git a/ansible/roles/profile_desktop_hyprland_freebsd/files/hyprland-portals.conf b/ansible/roles/profile_desktop_hyprland_freebsd/files/hyprland-portals.conf new file mode 100644 index 0000000..9ba090c --- /dev/null +++ b/ansible/roles/profile_desktop_hyprland_freebsd/files/hyprland-portals.conf @@ -0,0 +1,4 @@ +[preferred] +default=gtk +org.freedesktop.impl.portal.Screenshot=hyprland +org.freedesktop.impl.portal.ScreenCast=hyprland diff --git a/ansible/roles/profile_desktop_hyprland_freebsd/tasks/main.yml b/ansible/roles/profile_desktop_hyprland_freebsd/tasks/main.yml new file mode 100644 index 0000000..842dc31 --- /dev/null +++ b/ansible/roles/profile_desktop_hyprland_freebsd/tasks/main.yml @@ -0,0 +1,58 @@ +--- +- name: Ensure FreeBSD Hyprland user config directories exist + tags: [dotfiles, dotfiles:desktop, hyprland] + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "0755" + loop: + - "{{ user_home }}/.config" + - "{{ user_home }}/.config/alacritty" + - "{{ user_home }}/.config/dunst" + - "{{ user_home }}/.config/foot" + - "{{ user_home }}/.config/hypr" + - "{{ user_home }}/.config/rofi" + - "{{ user_home }}/.config/waybar" + - "{{ user_home }}/.local" + - "{{ user_home }}/.local/bin" + +- name: Copy common Hyprland desktop dotfiles on FreeBSD + tags: [dotfiles, dotfiles:desktop, hyprland] + ansible.builtin.copy: + src: "{{ playbook_dir }}/../dotfiles/desktop/{{ item.src }}" + dest: "{{ user_home }}/{{ item.dest }}" + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "{{ item.mode }}" + loop: "{{ desktop_hyprland_dotfiles | default([]) }}" + loop_control: + label: "{{ item.dest }}" + +- name: Render FreeBSD Hyprland session launcher + tags: [packages, services, hyprland] + ansible.builtin.template: + src: start-hyprland-session.j2 + dest: /usr/local/bin/start-hyprland-session + owner: root + group: wheel + mode: "0755" + +- name: Ensure FreeBSD xdg-desktop-portal config directory exists + tags: [packages, services, hyprland, portal] + ansible.builtin.file: + path: "{{ freebsd_xdg_config_dir | default('/usr/local/etc/xdg') }}/xdg-desktop-portal" + state: directory + owner: root + group: wheel + mode: "0755" + +- name: Configure xdg-desktop-portal backend preferences for FreeBSD Hyprland + tags: [packages, services, hyprland, portal] + ansible.builtin.copy: + src: hyprland-portals.conf + dest: "{{ freebsd_xdg_config_dir | default('/usr/local/etc/xdg') }}/xdg-desktop-portal/hyprland-portals.conf" + owner: root + group: wheel + mode: "0644" diff --git a/ansible/roles/profile_desktop_hyprland_freebsd/templates/start-hyprland-session.j2 b/ansible/roles/profile_desktop_hyprland_freebsd/templates/start-hyprland-session.j2 new file mode 100644 index 0000000..7653ad0 --- /dev/null +++ b/ansible/roles/profile_desktop_hyprland_freebsd/templates/start-hyprland-session.j2 @@ -0,0 +1,24 @@ +#!/bin/sh + +[ -r /etc/profile ] && . /etc/profile +[ -r "$HOME/.profile" ] && . "$HOME/.profile" + +export XDG_CURRENT_DESKTOP=Hyprland +export XDG_SESSION_DESKTOP=Hyprland +export XDG_SESSION_TYPE=wayland + +export MOZ_ENABLE_WAYLAND=1 +export QT_QPA_PLATFORM='wayland;xcb' +export _JAVA_AWT_WM_NONREPARENTING=1 +export SDL_VIDEODRIVER=wayland +export GDK_BACKEND='wayland,x11' + +export SSH_AUTH_SOCK="$HOME/.local/state/ssh-agent/socket" + +[ -r "$HOME/.config/hypr/session-env" ] && . "$HOME/.config/hypr/session-env" + +if command -v dbus-run-session >/dev/null 2>&1; then + exec dbus-run-session Hyprland +fi + +exec Hyprland diff --git a/ansible/roles/profile_lab/tasks/main.yml b/ansible/roles/profile_lab/tasks/main.yml new file mode 100644 index 0000000..074f3d3 --- /dev/null +++ b/ansible/roles/profile_lab/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Ensure lab workspace directories exist + tags: [dotfiles] + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "{{ item.mode }}" + loop: "{{ lab_workspace_directories | default([]) }}" + loop_control: + label: "{{ item.path }}" diff --git a/ansible/roles/profile_personal_workstation/tasks/main.yml b/ansible/roles/profile_personal_workstation/tasks/main.yml new file mode 100644 index 0000000..f7b00c5 --- /dev/null +++ b/ansible/roles/profile_personal_workstation/tasks/main.yml @@ -0,0 +1,24 @@ +--- +- name: Ensure personal workstation directories exist + tags: [dotfiles, dotfiles:workstation] + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "{{ item.mode }}" + loop: "{{ personal_workstation_directories | default([]) }}" + loop_control: + label: "{{ item.path }}" + +- name: Copy personal workstation dotfiles + tags: [dotfiles, dotfiles:workstation] + ansible.builtin.copy: + src: "{{ playbook_dir }}/../dotfiles/workstation/{{ item.src }}" + dest: "{{ user_home }}/{{ item.dest }}" + owner: "{{ username }}" + group: "{{ user_group }}" + mode: "{{ item.mode }}" + loop: "{{ personal_workstation_dotfiles | default([]) }}" + loop_control: + label: "{{ item.dest }}" diff --git a/ansible/roles/services_freebsd/tasks/main.yml b/ansible/roles/services_freebsd/tasks/main.yml new file mode 100644 index 0000000..36b5aef --- /dev/null +++ b/ansible/roles/services_freebsd/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Configure FreeBSD rc.conf values + tags: [services, packages] + community.general.sysrc: + name: "{{ item.name }}" + value: "{{ item.value }}" + state: present + loop: "{{ freebsd_rc_conf | default([]) }}" + loop_control: + label: "{{ item.name }}" + +- name: Enable FreeBSD rc services + tags: [services, packages] + ansible.builtin.service: + name: "{{ item }}" + enabled: true + state: started + loop: "{{ freebsd_enabled_services | default([]) + host_enabled_services | default([]) }}" + loop_control: + label: "{{ item }}" diff --git a/ansible/roles/services_systemd/tasks/main.yml b/ansible/roles/services_systemd/tasks/main.yml index 51ba75b..43a3482 100644 --- a/ansible/roles/services_systemd/tasks/main.yml +++ b/ansible/roles/services_systemd/tasks/main.yml @@ -18,4 +18,3 @@ loop: "{{ host_enabled_services | default([]) }}" loop_control: label: "{{ item }}" - diff --git a/ansible/site.yml b/ansible/site.yml index a6ddef3..160c9e8 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -1,28 +1,40 @@ --- -- hosts: all +- name: Configure common user environment + hosts: all become: true pre_tasks: - name: Load local vault variables when available tags: [always] ansible.builtin.include_vars: file: "{{ playbook_dir }}/../secrets/vault.yml" - when: lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.yml', errors='ignore', wantlist=True) | length > 0 + when: >- + lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.yml', + errors='ignore', wantlist=True) | length > 0 - name: Load machine-local vault variables when available tags: [always] ansible.builtin.include_vars: file: "{{ playbook_dir }}/../secrets/vault.local.yml" - when: lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.local.yml', errors='ignore', wantlist=True) | length > 0 + when: >- + lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.local.yml', + errors='ignore', wantlist=True) | length > 0 roles: - dotfiles_common -- hosts: void +- name: Configure Void platform + hosts: platform_void become: true roles: - packages_void - services_runit + +- name: Configure Void graphical desktop + hosts: platform_void:&graphical_desktop + become: true + + roles: - profile_desktop_common - profile_desktop_sway - profile_desktop_hyprland @@ -30,7 +42,52 @@ - profile_desktop_xfce - profile_desktop_host -- hosts: workstation_dev_fedora +- name: Configure Linux Mint platform + hosts: platform_mint + become: true + + roles: + - packages_mint + - services_systemd + +- name: Configure personal workstation role on Linux Mint + hosts: platform_mint:&role_personal_workstation + become: true + + roles: + - profile_personal_workstation + +- name: Configure Cinnamon desktop on Linux Mint + hosts: platform_mint:&desktop_cinnamon + become: true + + roles: + - profile_desktop_cinnamon + +- name: Configure FreeBSD platform + hosts: platform_freebsd + become: true + + roles: + - packages_freebsd + - services_freebsd + +- name: Configure lab role on FreeBSD + hosts: platform_freebsd:&role_lab + become: true + + roles: + - profile_lab + +- name: Configure Hyprland desktop on FreeBSD + hosts: platform_freebsd:&desktop_hyprland + become: true + + roles: + - profile_desktop_hyprland_freebsd + +- name: Configure Fedora workstation development layer + hosts: workstation_dev_fedora become: true roles: @@ -38,13 +95,15 @@ - services_systemd - profile_workstation_dev_common -- hosts: workstation_host_linux +- name: Configure native Linux workstation host layer + hosts: workstation_host_linux become: true roles: - profile_workstation_gnome -- hosts: workstation_dev_wsl +- name: Configure WSL workstation development layer + hosts: workstation_dev_wsl become: true roles: @@ -53,7 +112,8 @@ - profile_workstation_dev_common - profile_workstation_dev_wsl -- hosts: ubuntu_server +- name: Configure Ubuntu server + hosts: ubuntu_server become: true roles: