Remove deadalus-win and deadalus-ubuntu profiles

Rimuove completamente i due host non più in uso dal playbook:
- inventory: gruppi ubuntu_workstation, workstation_dev_ubuntu,
  workstation_host_windows e relative entry host
- host_vars deadalus-ubuntu/deadalus-win e group_vars windows
- play workstation_dev_ubuntu e workstation_host_windows in site.yml
- ruolo profile_workstation_host_windows e bootstrap PowerShell
- var PSRP nel vault.yml.example, pacchetti python pypsrp/pyspnego WSL
- collection ansible.windows/community.windows
- riferimenti nella documentazione (README/AGENTS/CLAUDE)

Workstation Linux nativa: resta solo deadalus-fedora.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Fabio Scotto di Santolo
2026-06-21 16:30:30 +02:00
parent 0fb8f23ae2
commit a135edaa3f
14 changed files with 33 additions and 1145 deletions

View File

@@ -1,6 +1,6 @@
# AGENTS.md # 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 desktops, Linux workstations, WSL, and an Ubuntu server.
## Source Of Truth ## Source Of Truth
- Main orchestration: `ansible/site.yml` - Main orchestration: `ansible/site.yml`
@@ -12,8 +12,8 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
## Topology ## Topology
- Void desktops: `ikaros`, `nymph` - Void desktops: `ikaros`, `nymph`
- Native Linux workstations: `deadalus-ubuntu`, `deadalus-fedora` - Native Linux workstation: `deadalus-fedora`
- Windows host + WSL dev: `deadalus-win`, `deadalus-wsl` - WSL dev: `deadalus-wsl`
- Ubuntu server: `prometheus` - Ubuntu server: `prometheus`
- Hosts intentionally belong to multiple groups; trust `ansible/site.yml` over hostname assumptions. - Hosts intentionally belong to multiple groups; trust `ansible/site.yml` over hostname assumptions.
@@ -21,7 +21,7 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
- Preserve layering `all -> OS -> profile -> host`. - Preserve layering `all -> OS -> profile -> host`.
- Keep `ansible/site.yml` small; orchestration belongs there, implementation belongs in roles. - Keep `ansible/site.yml` small; orchestration belongs there, implementation belongs in roles.
- Prefer minimal, targeted edits. Preserve idempotency and existing ordering. - Prefer minimal, targeted edits. Preserve idempotency and existing ordering.
- Most hosts use `ansible_connection: local`; Windows host is the exception. - All hosts use `ansible_connection: local`.
- Treat `secrets/` as sensitive. Never print secret values. - Treat `secrets/` as sensitive. Never print secret values.
- Tmux plugins are bootstrapped by TPM on the host; the repo only keeps tmux config and custom helper scripts. - Tmux plugins are bootstrapped by TPM on the host; the repo only keeps tmux config and custom helper scripts.
- Read the relevant role tasks, templates, vars, and deployed dotfiles before editing. - Read the relevant role tasks, templates, vars, and deployed dotfiles before editing.
@@ -35,14 +35,12 @@ Ansible-driven personal infrastructure repo for Void desktops, Linux workstation
- `yamllint ansible/` - `yamllint ansible/`
- Host-focused dry runs: - 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` or `--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` - Fedora workstation: `ansible-playbook ansible/site.yml --limit deadalus-fedora --check --diff`
- WSL dev: `ansible-playbook ansible/site.yml --limit deadalus-wsl --check --diff` - WSL dev: `ansible-playbook ansible/site.yml --limit deadalus-wsl --check --diff`
- Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff` - Server: `ansible-playbook ansible/site.yml --limit prometheus --check --diff`
- Focused checks: - Focused checks:
- Emacs dotfiles only: `ansible-playbook ansible/site.yml --limit ikaros --tags emacs --check --diff` or `--limit nymph --tags emacs --check --diff` - Emacs dotfiles only: `ansible-playbook ansible/site.yml --limit ikaros --tags emacs --check --diff` or `--limit nymph --tags emacs --check --diff`
- Mail bootstrap: `sh -n scripts/bootstrap_mail.sh` and `shellcheck scripts/bootstrap_mail.sh` - 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` - Server compose render: `docker compose -f /opt/docker/server/docker-compose.yml config`
## Conventions ## Conventions
@@ -74,12 +72,9 @@ The four Void desktop package lists in `ansible/inventory/group_vars/void.yml` a
`profile_packages` in the same file is cross-distro and is overridden by `group_vars/server.yml` and the workstation group vars; do not move desktop-specific Void entries through it. `profile_packages` in the same file is cross-distro and is overridden by `group_vars/server.yml` and the workstation group vars; do not move desktop-specific Void entries through it.
The dotfile vars follow the same split: `desktop_common_dotfiles` (in `group_vars/desktop.yml`) carries WM-agnostic GUI config and user scripts (Thunar, mimeapps, GTK theme setup, Udiskie, fontconfig, WirePlumber, mpv, …); `desktop_void_dotfiles` (in `group_vars/void.yml`) is reserved for files that need Void runtime (turnstile services, bash runit/dbus/ssh-agent fragments, `update-turnstile-env`). The dotfile vars follow the same split: `desktop_common_dotfiles` (in `group_vars/desktop.yml`) carries WM-agnostic GUI config and user scripts (Thunar, mimeapps, GTK theme setup, Udiskie, fontconfig, WirePlumber, mpv, …); `desktop_void_dotfiles` (in `group_vars/void.yml`) is reserved for files that need Void runtime (turnstile services, bash runit/dbus/ssh-agent fragments, `update-turnstile-env`).
## Workstation / Windows Notes ## Workstation Notes
- Native Linux workstation hosts can combine `workstation_host_linux` with an OS-specific dev group. - Native Linux workstation hosts can combine `workstation_host_linux` with an OS-specific dev group.
- `deadalus-fedora` keeps GNOME managed settings in `ansible/inventory/host_vars/deadalus-fedora.yml`. - `deadalus-fedora` keeps GNOME managed settings in `ansible/inventory/host_vars/deadalus-fedora.yml`.
- Ubuntu workstation follow-up work is still open around YubiKey/GPG/SSH-FIDO2 package verification, GPG signing setup on the YubiKey, and evaluating `ed25519-sk` SSH key generation.
- `workstation_host_windows` runs with `gather_facts: false` and validates PSRP settings plus `windows_package_backend` before role execution.
- Windows taskbar pins are driven by `windows_taskbar_pins` in `ansible/inventory/group_vars/workstation_host_windows.yml`; validate identifiers from a real Windows session before changing them.
## Coding Agent Notes ## Coding Agent Notes
- Shared agent packages live in `ai_agents_npm_packages` in `ansible/inventory/group_vars/all.yml`. - Shared agent packages live in `ai_agents_npm_packages` in `ansible/inventory/group_vars/all.yml`.
@@ -92,7 +87,7 @@ The dotfile vars follow the same split: `desktop_common_dotfiles` (in `group_var
- Install local tooling with: - Install local tooling with:
- `python3 -m pip install ansible ansible-lint yamllint shellcheck-py` - `python3 -m pip install ansible ansible-lint yamllint shellcheck-py`
- `ansible-galaxy collection install -r ansible/collections/requirements.yml` - `ansible-galaxy collection install -r ansible/collections/requirements.yml`
- Required collections currently include `ansible.posix`, `ansible.windows`, `community.general`, and `community.windows`. - Required collections currently include `ansible.posix` and `community.general`.
- `.yamllint` treats `line-length` as a warning at 120 chars and disables `document-start` and `comments-indentation`. - `.yamllint` treats `line-length` as a warning at 120 chars and disables `document-start` and `comments-indentation`.
## When Updating Docs ## When Updating Docs

View File

@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## What this repo is ## What this repo is
Ansible-driven personal infrastructure as code for Void Linux desktops (`ikaros`, `nymph`), Linux/Windows workstations (`deadalus-*`), and an Ubuntu server (`prometheus`). See `AGENTS.md` for topology and `README.md` for full profile descriptions. Ansible-driven personal infrastructure as code for Void Linux desktops (`ikaros`, `nymph`), Linux workstations (`deadalus-fedora`, `deadalus-wsl`), and an Ubuntu server (`prometheus`). See `AGENTS.md` for topology and `README.md` for full profile descriptions.
## Validation commands ## Validation commands
@@ -15,7 +15,6 @@ ansible-playbook ansible/site.yml --syntax-check
# Dry-run per host # Dry-run per host
ansible-playbook ansible/site.yml --limit ikaros --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 nymph --check --diff
ansible-playbook ansible/site.yml --limit deadalus-ubuntu --check --diff
ansible-playbook ansible/site.yml --limit deadalus-fedora --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 deadalus-wsl --check --diff
ansible-playbook ansible/site.yml --limit prometheus --check --diff ansible-playbook ansible/site.yml --limit prometheus --check --diff
@@ -34,7 +33,7 @@ sh -n scripts/bootstrap_mail.sh && shellcheck scripts/bootstrap_mail.sh
## Architecture ## Architecture
Configuration is composed in layers: `all → OS → profile → host`. Most hosts use `ansible_connection: local`; `deadalus-win` is the PSRP/Windows exception. Configuration is composed in layers: `all → OS → profile → host`. All hosts use `ansible_connection: local`.
`ansible/site.yml` is the sole orchestration entry point — keep it thin. Implementation belongs in roles under `ansible/roles/`. `ansible/site.yml` is the sole orchestration entry point — keep it thin. Implementation belongs in roles under `ansible/roles/`.

View File

@@ -55,13 +55,13 @@ Il repository è diviso in due componenti principali:
# Macchine gestite # Macchine gestite
Il repository modella attualmente tre tipologie di profilo e prepara due filoni workstation: Linux nativa e Windows + WSL. Il repository modella attualmente tre tipologie di profilo, con i filoni workstation Linux nativa e WSL.
Nota sullo stato attuale del playbook principale: Nota sullo stato attuale del playbook principale:
- `ansible/site.yml` applica oggi in automatico il profilo desktop su host Void Linux - `ansible/site.yml` applica oggi in automatico il profilo desktop su host Void Linux
- `ansible/site.yml` applica la workstation Linux nativa separando il layer dev comune dal layer host GNOME - `ansible/site.yml` applica la workstation Linux nativa separando il layer dev comune dal layer host GNOME
- `ansible/site.yml` applica anche il ramo `workstation_host_windows` + `workstation_dev_wsl` per il modello Windows 11 + WSL - `ansible/site.yml` applica anche il ramo `workstation_dev_wsl` per il modello dev in WSL
- `ansible/site.yml` applica anche il profilo `ubuntu_server` con baseline apt, systemd, dotfiles server e firewall UFW - `ansible/site.yml` applica anche il profilo `ubuntu_server` con baseline apt, systemd, dotfiles server e firewall UFW
## Desktop ## Desktop
@@ -107,9 +107,8 @@ Lo stato attuale del profilo desktop include, tra le altre cose:
Sistemi operativi supportati: Sistemi operativi supportati:
- Ubuntu LTS nativa
- Fedora Workstation nativa - Fedora Workstation nativa
- Windows 11 host + Ubuntu WSL - Ubuntu WSL
Desktop environment host Linux: Desktop environment host Linux:
@@ -117,9 +116,8 @@ Desktop environment host Linux:
Macchine attuali: Macchine attuali:
- `deadalus-ubuntu` come workstation Ubuntu nativa
- `deadalus-fedora` come workstation Fedora nativa - `deadalus-fedora` come workstation Fedora nativa
- supporto attivo per host Windows 11 + WSL tramite `deadalus-win` e `deadalus-wsl` - `deadalus-wsl` come ambiente dev Ubuntu in WSL
Questo profilo è pensato per sviluppo e lavoro, con separazione tra layer host e layer dev. Questo profilo è pensato per sviluppo e lavoro, con separazione tra layer host e layer dev.
@@ -127,13 +125,12 @@ Nel modello Ansible usato qui, un singolo inventory host puo appartenere intenzi
Il profilo workstation e agganciato al playbook principale e ora distingue: Il profilo workstation e agganciato al playbook principale e ora distingue:
- layer dev Ubuntu condiviso tra workstation Linux nativa e Ubuntu in WSL - layer dev Ubuntu condiviso tra WSL e server
- layer dev Fedora nativo parallelo a Ubuntu - layer dev Fedora nativo
- layer host Linux GNOME - layer host Linux GNOME
- layer host Windows 11 con bootstrap WSL, remoting `PSRP` su `HTTPS/5986`, gestione app via `winget` con backend configurabile e VS Code lato Windows
- layer WSL dedicato per sviluppo con `systemd` - layer WSL dedicato per sviluppo con `systemd`
Per esempio, lo stesso host Linux puo stare in `workstation_host_linux` e in `workstation_dev_fedora` oppure `workstation_dev_ubuntu`, a seconda del layering che vuoi comporre. Per esempio, lo stesso host Linux puo stare in `workstation_host_linux` e in `workstation_dev_fedora`, a seconda del layering che vuoi comporre.
Lo stato attuale del profilo workstation include: Lo stato attuale del profilo workstation include:
@@ -141,42 +138,18 @@ Lo stato attuale del profilo workstation include:
- installazione pacchetti base Fedora via dnf per il ramo workstation nativo - installazione pacchetti base Fedora via dnf per il ramo workstation nativo
- installazione e configurazione di Docker dal repository ufficiale - installazione e configurazione di Docker dal repository ufficiale
- gestione dei dotfiles workstation e rendering dei template dev condivisi - gestione dei dotfiles workstation e rendering dei template dev condivisi
- installazione di Google Chrome su Ubuntu e Fedora, `VS Code` su Fedora via repository RPM Microsoft, `IntelliJ IDEA Ultimate` su Fedora via COPR RPM, e applicazioni workstation residue su Fedora via Flatpak - installazione di Google Chrome su Fedora, `VS Code` su Fedora via repository RPM Microsoft, `IntelliJ IDEA Ultimate` su Fedora via COPR RPM, e applicazioni workstation residue su Fedora via Flatpak
- installazione di applicazioni workstation su Ubuntu nativa via Snap, oltre alle estensioni GNOME sul solo host Linux nativo - estensioni GNOME sul solo host Linux nativo
- configurazione del ramo Windows 11 host con app installate dal playbook via `winget`, con backend predefinito `winget_psrp`, tema scuro, pin della taskbar gestiti via policy locale e profilo predefinito di Windows Terminal impostato su `Ubuntu`
- preparazione del ramo WSL Ubuntu con `systemd` per il toolchain di sviluppo - preparazione del ramo WSL Ubuntu con `systemd` per il toolchain di sviluppo
- attivazione del firewall UFW su Ubuntu nativa e `firewalld` su Fedora nativa - attivazione del firewall `firewalld` su Fedora nativa
- gestione di `gsettings` GNOME host-specifici su `deadalus-fedora`, inclusi shell, Files/Nautilus, file chooser GTK e GNOME Text Editor, allineati allo stato reale della macchina - gestione di `gsettings` GNOME host-specifici su `deadalus-fedora`, inclusi shell, Files/Nautilus, file chooser GTK e GNOME Text Editor, allineati allo stato reale della macchina
Workflow Windows + WSL previsto: Workflow WSL previsto:
Prima di eseguire il bootstrap Windows, apri PowerShell come amministratore e verifica la policy di esecuzione: 1. avviare Ubuntu WSL almeno una volta e completare la creazione dell'utente Linux
2. installare Ansible dentro WSL Ubuntu
```powershell 3. lanciare il playbook da WSL su `deadalus-wsl` per configurare l'ambiente dev locale
Get-ExecutionPolicy -List 4. usare VS Code con le estensioni Remote (`WSL`, `SSH`, `Dev Containers`) dal lato Windows
```
Se necessario, abilita l'esecuzione degli script per l'utente corrente:
```powershell
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
```
Se Windows ha bloccato il file di bootstrap, sbloccalo esplicitamente:
```powershell
Unblock-File .\scripts\bootstrap_windows_workstation.ps1
```
1. eseguire `scripts/bootstrap_windows_workstation.ps1` su Windows come amministratore
2. riavviare Windows se richiesto dalle feature WSL
3. avviare Ubuntu WSL almeno una volta e completare la creazione dell'utente Linux
4. installare Ansible dentro WSL Ubuntu
5. lanciare il playbook da WSL su `deadalus-wsl` per configurare l'ambiente dev locale
6. lanciare da WSL anche il playbook su `deadalus-win` via `psrp` per configurare l'host Windows; per default il backend pacchetti Windows e `winget_psrp`
7. usare VS Code con le estensioni Remote (`WSL`, `SSH`, `Dev Containers`) dal lato Windows
Per il remoting Windows il repository usa di default `PSRP` con `Negotiate` su `HTTPS/5986`. L'utente di default puo essere un `MicrosoftAccount\...`, con host, utente e password forniti via vault o extra vars. Il backend pacchetti Windows e configurabile con `windows_package_backend` oppure `vault_windows_package_backend`; il default e `winget_psrp`.
--- ---
@@ -281,7 +254,6 @@ I principali ruoli attualmente presenti sono:
| profile_workstation_dev_common | configurazione dev workstation condivisa | | profile_workstation_dev_common | configurazione dev workstation condivisa |
| profile_workstation_gnome | configurazione host workstation GNOME | | profile_workstation_gnome | configurazione host workstation GNOME |
| profile_workstation_dev_wsl | configurazione WSL Ubuntu per sviluppo | | profile_workstation_dev_wsl | configurazione WSL Ubuntu per sviluppo |
| profile_workstation_host_windows | configurazione host Windows 11 workstation |
| profile_server | configurazione server | | profile_server | configurazione server |
| dotfiles_common | distribuzione dotfiles comuni | | dotfiles_common | distribuzione dotfiles comuni |
| dotfiles | distribuzione configurazioni utente | | dotfiles | distribuzione configurazioni utente |
@@ -290,25 +262,22 @@ I principali ruoli attualmente presenti sono:
# Stato attuale del playbook principale # Stato attuale del playbook principale
Il playbook `ansible/site.yml` e attualmente composto da sette blocchi: Il playbook `ansible/site.yml` e attualmente composto da sei blocchi:
```text ```text
all:!workstation_host_windows -> dotfiles_common all -> dotfiles_common
void -> packages_void + services_runit + profile_desktop_common + profile_desktop_i3 + profile_desktop_sway + profile_desktop_hyprland + profile_desktop_host void -> packages_void + services_runit + profile_desktop_common + profile_desktop_i3 + profile_desktop_sway + profile_desktop_hyprland + profile_desktop_host
workstation_dev_ubuntu -> packages_ubuntu + services_systemd + profile_workstation_dev_common
workstation_dev_fedora -> packages_fedora + services_systemd + profile_workstation_dev_common workstation_dev_fedora -> packages_fedora + services_systemd + profile_workstation_dev_common
workstation_host_linux -> profile_workstation_gnome workstation_host_linux -> profile_workstation_gnome
workstation_dev_wsl -> packages_ubuntu + services_systemd + profile_workstation_dev_common + profile_workstation_dev_wsl workstation_dev_wsl -> packages_ubuntu + services_systemd + profile_workstation_dev_common + profile_workstation_dev_wsl
workstation_host_windows -> profile_workstation_host_windows
ubuntu_server -> packages_ubuntu + services_systemd + profile_server ubuntu_server -> packages_ubuntu + services_systemd + profile_server
``` ```
Questo significa che, allo stato attuale: 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
- la workstation Ubuntu (`deadalus-ubuntu`) e gestita separando ambiente dev e layer host GNOME - 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
- la workstation Fedora (`deadalus-fedora`) usa lo stesso 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 ramo Windows + WSL e predisposto con bootstrap PowerShell e play Windows/WSL dedicati
- il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall - il server Ubuntu (`prometheus`) e gestito con pacchetti, servizi, dotfiles server e firewall
- lo stack container server include `navidrome`, `postgres`, `gitea`, `nginx-proxy-manager` e `syncthing`, con GUI Syncthing raggiungibile tramite la rete Docker `web` - lo stack container server include `navidrome`, `postgres`, `gitea`, `nginx-proxy-manager` e `syncthing`, con GUI Syncthing raggiungibile tramite la rete Docker `web`
@@ -366,7 +335,6 @@ Gestione segreti:
- `secrets/vault.yml.example` funge da template/esempio - `secrets/vault.yml.example` funge da template/esempio
- se `secrets/vault.yml` non e presente, il playbook continua comunque senza caricare variabili locali opzionali - se `secrets/vault.yml` non e presente, il playbook continua comunque senza caricare variabili locali opzionali
- se `secrets/.vault_pass.gpg` esiste viene usato automaticamente per sbloccare i vault tramite `gpg`; in alternativa resta supportato `secrets/.vault_pass` come fallback legacy locale; se nessuno dei due file esiste Ansible richiede la password in modo interattivo - se `secrets/.vault_pass.gpg` esiste viene usato automaticamente per sbloccare i vault tramite `gpg`; in alternativa resta supportato `secrets/.vault_pass` come fallback legacy locale; se nessuno dei due file esiste Ansible richiede la password in modo interattivo
- per il ramo Windows puoi anche definire `vault_windows_package_backend`, con valori supportati `winget_psrp` e `winget_wsl_local`; il default e `winget_psrp`
--- ---
@@ -382,11 +350,9 @@ Allo stato attuale questo comando:
- distribuisce i dotfiles comuni a tutti gli host - distribuisce i dotfiles comuni a tutti gli host
- per gli host Void applica bootstrap desktop condiviso, sessione i3 e override specifici per host - per gli host Void applica bootstrap desktop condiviso, sessione i3 e override specifici per host
- per `workstation_dev_ubuntu` applica pacchetti Ubuntu, servizi systemd e profilo dev comune
- per `workstation_dev_fedora` applica pacchetti Fedora, servizi systemd e profilo dev comune - 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_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 `workstation_dev_wsl` applica pacchetti Ubuntu, servizi systemd, profilo dev comune e tweak WSL dedicati
- per `workstation_host_windows` applica il layer host Windows 11 via PSRP, con installazione pacchetti Windows eseguita di default tramite `winget_psrp`
- per gli host `ubuntu_server` applica pacchetti Ubuntu, servizi systemd, profilo server, UFW, dotfiles e template dedicati - per gli host `ubuntu_server` applica pacchetti Ubuntu, servizi systemd, profilo server, UFW, dotfiles e template dedicati
- non riavvia automaticamente `emptty`; le modifiche al display manager vanno applicate manualmente da SSH o da una TTY separata - non riavvia automaticamente `emptty`; le modifiche al display manager vanno applicate manualmente da SSH o da una TTY separata
- carica `secrets/vault.yml` solo se presente - carica `secrets/vault.yml` solo se presente
@@ -398,7 +364,6 @@ Per validare prima di applicare:
ansible-playbook ansible/site.yml --syntax-check ansible-playbook ansible/site.yml --syntax-check
ansible-playbook ansible/site.yml --limit ikaros --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 nymph --check --diff
ansible-playbook ansible/site.yml --limit deadalus-ubuntu --check --diff
ansible-playbook ansible/site.yml --limit deadalus-fedora --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 deadalus-wsl --check --diff
ansible-playbook ansible/site.yml --limit prometheus --check --diff ansible-playbook ansible/site.yml --limit prometheus --check --diff
@@ -435,7 +400,7 @@ Allo stato attuale `ansible/site.yml` espone questi tag:
| Tag | Scopo | Ambito principale | | Tag | Scopo | Ambito principale |
| --- | --- | --- | | --- | --- | --- |
| `always` | pre-task sempre eseguiti, inclusi caricamento vault e validazioni preliminari | common, Windows | | `always` | pre-task sempre eseguiti, inclusi caricamento vault e validazioni preliminari | common |
| `dotfiles` | distribuzione/configurazione dotfiles | tutti i profili | | `dotfiles` | distribuzione/configurazione dotfiles | tutti i profili |
| `dotfiles:common` | dotfiles comuni condivisi | common, workstation, server | | `dotfiles:common` | dotfiles comuni condivisi | common, workstation, server |
| `dotfiles:desktop` | dotfiles desktop | desktop Void | | `dotfiles:desktop` | dotfiles desktop | desktop Void |
@@ -450,9 +415,9 @@ Allo stato attuale `ansible/site.yml` espone questi tag:
| `npm` | installazione pacchetti npm globali | desktop Void, workstation Linux, WSL | | `npm` | installazione pacchetti npm globali | desktop Void, workstation Linux, WSL |
| `nvidia` | componenti NVIDIA desktop | desktop Void | | `nvidia` | componenti NVIDIA desktop | desktop Void |
| `packages` | installazione e aggiornamento pacchetti | tutti i profili | | `packages` | installazione e aggiornamento pacchetti | tutti i profili |
| `services` | gestione servizi runit/systemd/Windows | tutti i profili | | `services` | gestione servizi runit/systemd | tutti i profili |
| `vscode` | installazione/configurazione VS Code | Fedora, host Linux, Windows | | `vscode` | installazione/configurazione VS Code | Fedora, host Linux |
| `wsl` | bootstrap e configurazione WSL | WSL, Windows | | `wsl` | bootstrap e configurazione WSL | WSL |
Esempi pratici: Esempi pratici:

View File

@@ -1,6 +1,4 @@
--- ---
collections: collections:
- name: ansible.posix - name: ansible.posix
- name: ansible.windows
- name: community.general - name: community.general
- name: community.windows

View File

@@ -19,9 +19,7 @@ workstation_removed_snap_packages: []
workstation_snap_packages: workstation_snap_packages:
- name: glab - name: glab
classic: true classic: true
workstation_dev_wsl_python_packages: workstation_dev_wsl_python_packages: []
- pypsrp
- pyspnego
workstation_wsl_systemd_enabled: true workstation_wsl_systemd_enabled: true
workstation_dev_wsl_dotfiles: workstation_dev_wsl_dotfiles:
- src: .gnupg/gpg-agent.conf - src: .gnupg/gpg-agent.conf

View File

@@ -1,71 +0,0 @@
---
ansible_connection: psrp
ansible_psrp_auth: negotiate
ansible_psrp_cert_validation: ignore
ansible_psrp_protocol: https
ansible_port: 5986
ansible_shell_type: powershell
windows_enable_dark_theme: true
windows_hide_taskbar_search: true
windows_hide_taskbar_widgets: true
windows_terminal_default_profile_name: Ubuntu
windows_taskbar_layout_directory: 'C:\ProgramData\Infra\Windows'
windows_taskbar_layout_path: '{{ windows_taskbar_layout_directory }}\taskbar-layout.xml'
windows_taskbar_reapply_every_logon: false
windows_taskbar_pins:
- type: desktop_application_id
id: Chrome
- type: desktop_application_id
id: Microsoft.Windows.Explorer
- type: app_user_model_id
id: Microsoft.OutlookForWindows_8wekyb3d8bbwe!Microsoft.OutlookforWindows
- type: app_user_model_id
id: MSTeams_8wekyb3d8bbwe!MSTeams
- type: app_user_model_id
id: 5319275A.WhatsAppDesktop_cv1g1gvanyjgm!App
- type: desktop_application_id
id: Telegram.TelegramDesktop
- type: desktop_application_id
id: Microsoft.VisualStudioCode
- type: desktop_application_link_path
path: '%APPDATA%\Microsoft\Windows\Start Menu\Programs\JetBrains Toolbox\IntelliJ IDEA Ultimate.lnk'
- type: desktop_application_id
id: com.squirrel.Postman.Postman
- type: app_user_model_id
id: Microsoft.WindowsTerminal_8wekyb3d8bbwe!App
- type: desktop_application_link_path
path: '%APPDATA%\Microsoft\Windows\Start Menu\Programs\DBeaver Community\DBeaver.lnk'
windows_winget_packages:
- id: 7zip.7zip
name: 7-Zip
- id: Adobe.Acrobat.Reader.64-bit
name: Adobe Acrobat Reader
- id: DBeaver.DBeaver.Community
name: DBeaver Community
- id: Google.Chrome
name: Google Chrome
- id: JetBrains.IntelliJIDEA.Ultimate
name: IntelliJ IDEA Ultimate
- id: Logitech.OptionsPlus
name: Logitech Options+
- id: Microsoft.VisualStudioCode
name: Visual Studio Code
- id: Microsoft.WindowsTerminal
name: Windows Terminal
- id: Postman.Postman
name: Postman
- id: Telegram.TelegramDesktop
name: Telegram Desktop
- id: 9NKSQGP7F2NH
name: WhatsApp
source: msstore
windows_vscode_extensions:
- ms-vscode-remote.remote-containers
- ms-vscode-remote.remote-ssh
- ms-vscode-remote.remote-wsl
windows_wsl_distribution_name: Ubuntu

View File

@@ -1,319 +0,0 @@
---
hostname: deadalus-ubuntu
host_packages: []
host_enabled_services: []
workstation_host_vscode_extensions:
- ms-vscode-remote.remote-containers
- ms-vscode-remote.remote-ssh
- ms-azuretools.vscode-docker
- redhat.vscode-yaml
- redhat.ansible
workstation_gnome_managed_settings:
- schema: org.gnome.shell
key: favorite-apps
value: "['google-chrome.desktop', 'org.gnome.Nautilus.desktop', 'spotify_spotify.desktop', 'thunderbird_thunderbird.desktop', 'telegram-desktop_telegram-desktop.desktop', 'code_code.desktop', 'intellij-idea-ultimate_intellij-idea-ultimate.desktop', 'dbeaver-ce_dbeaver-ce.desktop', 'postman_postman.desktop', 'org.gnome.Ptyxis.desktop']"
- schema: org.gnome.shell
key: app-picker-layout
value: "[{'Utilities': <{'position': <0>}>, 'System': <{'position': <1>}>, 'a3b499f3-e2cc-40ac-9145-7db9c827dff2': <{'position': <2>}>, 'org.gnome.Calculator.desktop': <{'position': <3>}>, 'com.mattjakeman.ExtensionManager.desktop': <{'position': <4>}>, 'org.gnome.clocks.desktop': <{'position': <5>}>, 'htop.desktop': <{'position': <6>}>, 'org.gnome.Characters.desktop': <{'position': <7>}>, 'gnome-language-selector.desktop': <{'position': <8>}>, 'org.gnome.Meld.desktop': <{'position': <9>}>, 'net.nokyan.Resources.desktop': <{'position': <10>}>, 'org.gnome.TextEditor.desktop': <{'position': <11>}>, 'org.gnome.tweaks.desktop': <{'position': <12>}>, 'vim.desktop': <{'position': <13>}>, 'snap-store_snap-store.desktop': <{'position': <14>}>, 'org.gnome.Yelp.desktop': <{'position': <15>}>}]"
- schema: org.gnome.desktop.app-folders
key: folder-children
value: "['System', 'Utilities', 'YaST', 'Pardus', 'a3b499f3-e2cc-40ac-9145-7db9c827dff2']"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/System/
key: name
value: "'X-GNOME-Shell-System.directory'"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/System/
key: translate
value: "true"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/System/
key: categories
value: "@as []"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/System/
key: apps
value: "['nm-connection-editor.desktop', 'org.gnome.baobab.desktop', 'org.gnome.DiskUtility.desktop', 'im-config.desktop', 'org.gnome.Logs.desktop', 'org.gnome.Sysprof.desktop', 'gufw.desktop', 'firmware-updater_firmware-updater.desktop', 'org.gnome.Settings.desktop', 'update-manager.desktop', 'desktop-security-center_desktop-security-center.desktop']"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Utilities/
key: name
value: "'X-GNOME-Shell-Utilities.directory'"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Utilities/
key: translate
value: "true"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Utilities/
key: categories
value: "@as []"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Utilities/
key: apps
value: "['org.gnome.Papers.desktop', 'org.gnome.font-viewer.desktop', 'org.gnome.Loupe.desktop', 'org.gnome.seahorse.Application.desktop']"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/YaST/
key: name
value: "'suse-yast.directory'"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/YaST/
key: translate
value: "true"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/YaST/
key: categories
value: "['X-SuSE-YaST']"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/YaST/
key: apps
value: "@as []"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Pardus/
key: name
value: "'X-Pardus-Apps.directory'"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Pardus/
key: translate
value: "true"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Pardus/
key: categories
value: "['X-Pardus-Apps']"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/Pardus/
key: apps
value: "@as []"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/a3b499f3-e2cc-40ac-9145-7db9c827dff2/
key: name
value: "'Office'"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/a3b499f3-e2cc-40ac-9145-7db9c827dff2/
key: translate
value: "false"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/a3b499f3-e2cc-40ac-9145-7db9c827dff2/
key: categories
value: "@as []"
- schema: org.gnome.desktop.app-folders.folder
path: /org/gnome/desktop/app-folders/folders/a3b499f3-e2cc-40ac-9145-7db9c827dff2/
key: apps
value: "['libreoffice-calc.desktop', 'libreoffice-base.desktop', 'libreoffice-draw.desktop', 'libreoffice-impress.desktop', 'libreoffice-math.desktop', 'libreoffice-writer.desktop', 'xournalpp_xournalpp.desktop', 'libreoffice-startcenter.desktop', 'pdfarranger_pdfarranger.desktop']"
- schema: org.gnome.desktop.input-sources
key: sources
value: "[('xkb', 'us')]"
- schema: org.gnome.desktop.interface
key: accent-color
value: "'orange'"
- schema: org.gnome.desktop.interface
key: clock-format
value: "'24h'"
- schema: org.gnome.desktop.interface
key: clock-show-date
value: "true"
- schema: org.gnome.desktop.interface
key: color-scheme
value: "'prefer-dark'"
- schema: org.gnome.desktop.interface
key: cursor-theme
value: "'Adwaita'"
- schema: org.gnome.desktop.interface
key: document-font-name
value: "'Adwaita Sans 12'"
- schema: org.gnome.desktop.interface
key: font-name
value: "'Adwaita Sans 11'"
- schema: org.gnome.desktop.interface
key: gtk-theme
value: "'Yaru-dark'"
- schema: org.gnome.desktop.interface
key: icon-theme
value: "'Yaru-dark'"
- schema: org.gnome.desktop.interface
key: monospace-font-name
value: "'Ubuntu Sans Mono 11'"
- schema: org.gnome.desktop.interface
key: show-battery-percentage
value: "false"
- schema: org.gnome.desktop.interface
key: text-scaling-factor
value: "1.0"
- schema: org.gnome.desktop.privacy
key: report-technical-problems
value: "false"
- schema: org.gnome.desktop.wm.preferences
key: button-layout
value: "'appmenu:close'"
- schema: org.gnome.desktop.wm.preferences
key: focus-mode
value: "'click'"
- schema: org.gnome.desktop.wm.preferences
key: focus-new-windows
value: "'smart'"
- schema: org.gnome.desktop.wm.preferences
key: num-workspaces
value: "4"
- schema: org.gnome.nautilus.preferences
key: click-policy
value: "'double'"
- schema: org.gnome.nautilus.preferences
key: date-time-format
value: "'simple'"
- schema: org.gnome.nautilus.preferences
key: default-folder-viewer
value: "'icon-view'"
- schema: org.gnome.nautilus.preferences
key: default-sort-order
value: "'name'"
- schema: org.gnome.nautilus.preferences
key: recursive-search
value: "'local-only'"
- schema: org.gnome.nautilus.preferences
key: show-create-link
value: "true"
- schema: org.gnome.nautilus.preferences
key: show-delete-permanently
value: "true"
- schema: org.gnome.nautilus.preferences
key: show-directory-item-counts
value: "'local-only'"
- schema: org.gnome.nautilus.preferences
key: show-hidden-files
value: "false"
- schema: org.gnome.nautilus.preferences
key: show-image-thumbnails
value: "'local-only'"
- schema: org.gnome.nautilus.preferences
key: thumbnail-limit
value: "uint64 50"
- schema: org.gnome.nautilus.icon-view
key: captions
value: "['none', 'none', 'none']"
- schema: org.gnome.nautilus.icon-view
key: default-zoom-level
value: "'medium'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: clock-format
value: "'24h'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: date-format
value: "'regular'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: location-mode
value: "'path-bar'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: show-hidden
value: "false"
- schema: org.gtk.gtk4.Settings.FileChooser
key: show-size-column
value: "true"
- schema: org.gtk.gtk4.Settings.FileChooser
key: show-type-column
value: "true"
- schema: org.gtk.gtk4.Settings.FileChooser
key: sort-column
value: "'name'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: sort-directories-first
value: "true"
- schema: org.gtk.gtk4.Settings.FileChooser
key: sort-order
value: "'ascending'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: startup-mode
value: "'recent'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: type-format
value: "'category'"
- schema: org.gtk.gtk4.Settings.FileChooser
key: view-type
value: "'list'"
- schema: org.gnome.settings-daemon.plugins.color
key: night-light-schedule-automatic
value: "false"
- schema: org.gnome.settings-daemon.plugins.power
key: sleep-inactive-ac-timeout
value: "3600"
- schema: org.gnome.settings-daemon.plugins.power
key: sleep-inactive-ac-type
value: "'nothing'"
- schema: org.gnome.system.location
key: enabled
value: "false"
- schema: org.gnome.TextEditor
key: auto-indent
value: "true"
- schema: org.gnome.TextEditor
key: auto-save-delay
value: "uint32 3"
- schema: org.gnome.TextEditor
key: custom-font
value: "'Monospace 11'"
- schema: org.gnome.TextEditor
key: discover-settings
value: "true"
- schema: org.gnome.TextEditor
key: draw-spaces
value: "@as []"
- schema: org.gnome.TextEditor
key: enable-snippets
value: "false"
- schema: org.gnome.TextEditor
key: highlight-current-line
value: "false"
- schema: org.gnome.TextEditor
key: highlight-matching-brackets
value: "true"
- schema: org.gnome.TextEditor
key: indent-style
value: "'tab'"
- schema: org.gnome.TextEditor
key: indent-width
value: "-1"
- schema: org.gnome.TextEditor
key: keybindings
value: "'default'"
- schema: org.gnome.TextEditor
key: line-height
value: "1.2"
- schema: org.gnome.TextEditor
key: recolor-window
value: "true"
- schema: org.gnome.TextEditor
key: restore-session
value: "true"
- schema: org.gnome.TextEditor
key: right-margin-position
value: "uint32 80"
- schema: org.gnome.TextEditor
key: show-grid
value: "false"
- schema: org.gnome.TextEditor
key: show-line-numbers
value: "false"
- schema: org.gnome.TextEditor
key: show-map
value: "false"
- schema: org.gnome.TextEditor
key: show-right-margin
value: "false"
- schema: org.gnome.TextEditor
key: spellcheck
value: "true"
- schema: org.gnome.TextEditor
key: style-scheme
value: "'Adwaita'"
- schema: org.gnome.TextEditor
key: style-variant
value: "'follow'"
- schema: org.gnome.TextEditor
key: tab-width
value: "uint32 8"
- schema: org.gnome.TextEditor
key: use-system-font
value: "true"
- schema: org.gnome.TextEditor
key: wrap-text
value: "true"

View File

@@ -1,2 +0,0 @@
---
hostname: deadalus-win

View File

@@ -17,7 +17,6 @@ all:
ubuntu: ubuntu:
children: children:
ubuntu_workstation:
workstation_dev_wsl: workstation_dev_wsl:
ubuntu_server: ubuntu_server:
@@ -33,11 +32,9 @@ all:
workstation_host: workstation_host:
children: children:
workstation_host_linux: workstation_host_linux:
workstation_host_windows:
workstation_dev: workstation_dev:
children: children:
workstation_dev_ubuntu:
workstation_dev_fedora: workstation_dev_fedora:
workstation_dev_wsl: workstation_dev_wsl:
@@ -45,11 +42,6 @@ all:
children: children:
ubuntu_server: ubuntu_server:
ubuntu_workstation:
hosts:
deadalus-ubuntu:
ansible_connection: local
fedora_workstation: fedora_workstation:
hosts: hosts:
deadalus-fedora: deadalus-fedora:
@@ -57,25 +49,14 @@ all:
workstation_host_linux: workstation_host_linux:
hosts: hosts:
deadalus-ubuntu:
ansible_connection: local
deadalus-fedora: deadalus-fedora:
ansible_connection: local ansible_connection: local
workstation_dev_ubuntu:
hosts:
deadalus-ubuntu:
ansible_connection: local
workstation_dev_fedora: workstation_dev_fedora:
hosts: hosts:
deadalus-fedora: deadalus-fedora:
ansible_connection: local ansible_connection: local
workstation_host_windows:
hosts:
deadalus-win:
workstation_dev_wsl: workstation_dev_wsl:
hosts: hosts:
deadalus-wsl: deadalus-wsl:

View File

@@ -1,411 +0,0 @@
---
- name: Enable required Windows features for WSL
tags: [packages, services, wsl]
ansible.windows.win_optional_feature:
name:
- Microsoft-Windows-Subsystem-Linux
- VirtualMachinePlatform
state: present
include_parent: true
- name: Gather Windows host version details
tags: [packages]
ansible.windows.win_powershell:
script: |
$os = Get-ComputerInfo
$buildNumber = [int]$os.OsBuildNumber
$Ansible.Result = @{
product_name = $os.WindowsProductName
build_number = $buildNumber
is_windows_11 = $buildNumber -ge 22000
}
$Ansible.Changed = $false
register: windows_host_version_state
- name: Fail when Windows host is not Windows 11
tags: [packages]
ansible.builtin.fail:
msg: >-
workstation_host_windows is supported only on Windows 11. Detected {{ windows_host_version_state.result.product_name }}
build {{ windows_host_version_state.result.build_number }}.
when: not (windows_host_version_state.result.is_windows_11 | default(false))
- name: Enable dark mode for Windows apps
tags: [packages]
ansible.windows.win_regedit:
path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
name: AppsUseLightTheme
data: 0
type: dword
register: windows_apps_dark_mode_state
when: windows_enable_dark_theme | default(false)
- name: Enable dark mode for Windows system surfaces
tags: [packages]
ansible.windows.win_regedit:
path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
name: SystemUsesLightTheme
data: 0
type: dword
register: windows_system_dark_mode_state
when: windows_enable_dark_theme | default(false)
- name: Hide Windows taskbar search box
tags: [packages]
ansible.windows.win_regedit:
path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Search
name: SearchboxTaskbarMode
data: 0
type: dword
register: windows_taskbar_search_state
when: windows_hide_taskbar_search | default(false)
- name: Hide Windows 11 taskbar widgets
tags: [packages]
ansible.windows.win_regedit:
path: HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
name: TaskbarDa
data: 0
type: dword
register: windows_11_widgets_state
when: windows_hide_taskbar_widgets | default(false)
- name: Disable Windows 11 widgets via policy
tags: [packages]
ansible.windows.win_regedit:
path: HKLM:\SOFTWARE\Policies\Microsoft\Dsh
name: AllowNewsAndInterests
data: 0
type: dword
register: windows_11_widgets_policy_state
when: windows_hide_taskbar_widgets | default(false)
- name: Note when Windows shell settings may require sign out
tags: [packages]
ansible.builtin.debug:
msg: >-
Windows shell appearance settings changed. Sign out and back in, or restart explorer.exe,
if taskbar or theme updates do not appear immediately. Windows 11 widget policy changes can require
signing out before the widget button disappears from the taskbar.
changed_when: false
when: >-
(windows_apps_dark_mode_state is changed)
or (windows_system_dark_mode_state is changed)
or (windows_taskbar_search_state is changed)
or (windows_11_widgets_state is changed)
or (windows_11_widgets_policy_state is changed)
- name: Ensure winget is executable on Windows host through PSRP
tags: [packages]
when: windows_package_backend == 'winget_psrp'
ansible.windows.win_powershell:
script: |
$winget = Get-Command winget.exe -ErrorAction SilentlyContinue
if ($null -eq $winget) {
throw 'winget.exe is not available on the Windows host. Install App Installer or rerun the bootstrap script.'
}
& $winget.Source --info *> $null
if ($LASTEXITCODE -ne 0) {
throw 'winget.exe is not executable through the current PSRP session. Set windows_package_backend to winget_wsl_local on WSL-managed hosts.'
}
$Ansible.Changed = $false
- name: Ensure winget is executable through local Windows PowerShell from WSL
tags: [packages]
when: windows_package_backend == 'winget_wsl_local'
block:
- name: Ensure winget_wsl_local backend is running inside WSL
ansible.builtin.assert:
that:
- lookup('ansible.builtin.env', 'WSL_DISTRO_NAME') | length > 0
fail_msg: >-
winget_wsl_local requires running the playbook from inside the
target machine's WSL environment.
- name: Get local Windows host name through WSL interop
ansible.builtin.shell: |
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command '$env:COMPUTERNAME'
args:
executable: /bin/bash
delegate_to: localhost
register: local_windows_host_name_state
changed_when: false
- name: Get local Windows host IP addresses through WSL interop
ansible.builtin.shell: |
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command '
Get-NetIPAddress -AddressFamily IPv4, IPv6 -ErrorAction SilentlyContinue |
Where-Object {
$_.IPAddress -notin @("127.0.0.1", "::1") -and
$_.IPAddress -notlike "169.254.*" -and
$_.IPAddress -notlike "fe80:*"
} |
Select-Object -ExpandProperty IPAddress
'
args:
executable: /bin/bash
delegate_to: localhost
register: local_windows_host_ip_state
changed_when: false
- name: Ensure winget_wsl_local backend targets the local Windows host
ansible.builtin.assert:
that:
- >-
(ansible_host | lower) in ['localhost', '127.0.0.1', '::1']
or (local_windows_host_name_state.stdout | trim | upper)
== ((ansible_host | regex_replace('\\..*$', '')) | upper)
or (ansible_host | lower)
in (local_windows_host_ip_state.stdout_lines | map('trim') | map('lower') | list)
fail_msg: >-
winget_wsl_local can only target the local Windows host reached
through WSL interop. Local Windows host '{{ local_windows_host_name_state.stdout | trim }}'
with addresses {{ local_windows_host_ip_state.stdout_lines | map('trim') | list }}
does not match ansible_host '{{ ansible_host }}'.
- name: Ensure winget is executable through local Windows PowerShell
ansible.builtin.shell: |
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command '
$ErrorActionPreference = "Stop"
$winget = Get-Command winget.exe -ErrorAction SilentlyContinue
if ($null -eq $winget) {
throw "winget.exe is not available on the local Windows host. Install App Installer or rerun the bootstrap script."
}
& $winget.Source --info *> $null
if ($LASTEXITCODE -ne 0) {
throw "winget.exe is not executable through local Windows PowerShell interop."
}
'
args:
executable: /bin/bash
delegate_to: localhost
changed_when: false
- name: Ensure WSL 2 is the default backend
tags: [packages, services, wsl]
ansible.windows.win_powershell:
script: |
$status = & wsl --status 2>$null
if ($LASTEXITCODE -eq 0 -and $status -match 'Default Version:\s*2') {
$Ansible.Changed = $false
return
}
& wsl --set-default-version 2
if ($LASTEXITCODE -ne 0) {
throw 'Failed to set WSL default version to 2.'
}
$Ansible.Changed = $true
- name: Install Windows workstation applications with winget through PSRP
tags: [packages]
when: windows_package_backend == 'winget_psrp'
ansible.windows.win_powershell:
script: |
$packageId = '{{ item.id }}'
$packageName = '{{ item.name | default(item.id) }}'
$packageSource = '{{ item.source | default('') }}'
$listArgs = @(
'list'
'--id', $packageId
'--exact'
'--accept-source-agreements'
'--disable-interactivity'
)
$installArgs = @(
'install'
'--id', $packageId
'--exact'
'--silent'
'--accept-package-agreements'
'--accept-source-agreements'
'--disable-interactivity'
)
if (-not [string]::IsNullOrWhiteSpace($packageSource)) {
$listArgs += @('--source', $packageSource)
$installArgs += @('--source', $packageSource)
}
$installed = & winget @listArgs 2>$null
if ($LASTEXITCODE -eq 0 -and $installed -match [regex]::Escape($packageId)) {
$Ansible.Changed = $false
return
}
& winget @installArgs
if ($LASTEXITCODE -ne 0) {
throw "Failed to install $packageName with winget"
}
$Ansible.Changed = $true
loop: "{{ windows_winget_packages | default([]) }}"
loop_control:
label: "{{ item.id }}"
- name: Install Windows workstation applications with winget through WSL local backend
tags: [packages]
when: windows_package_backend == 'winget_wsl_local'
ansible.builtin.shell: |
powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command '
$ErrorActionPreference = "Stop"
$packageId = "{{ item.id }}"
$packageName = "{{ item.name | default(item.id) }}"
$packageSource = "{{ item.source | default('') }}"
$winget = Get-Command winget.exe -ErrorAction Stop
$listArgs = @(
"list"
"--id", $packageId
"--exact"
"--accept-source-agreements"
"--disable-interactivity"
)
$installArgs = @(
"install"
"--id", $packageId
"--exact"
"--silent"
"--accept-package-agreements"
"--accept-source-agreements"
"--disable-interactivity"
)
if (-not [string]::IsNullOrWhiteSpace($packageSource)) {
$listArgs += @("--source", $packageSource)
$installArgs += @("--source", $packageSource)
}
$installed = & $winget.Source @listArgs 2>$null
if ($LASTEXITCODE -eq 0 -and $installed -match [regex]::Escape($packageId)) {
[Console]::Out.WriteLine("changed=false")
exit 0
}
& $winget.Source @installArgs
if ($LASTEXITCODE -ne 0) {
throw "Failed to install $packageName with winget"
}
[Console]::Out.WriteLine("changed=true")
'
args:
executable: /bin/bash
delegate_to: localhost
register: windows_wsl_local_winget_install_state
changed_when: "'changed=true' in windows_wsl_local_winget_install_state.stdout"
loop: "{{ windows_winget_packages | default([]) }}"
loop_control:
label: "{{ item.id }}"
- name: Configure Windows taskbar pin layout
tags: [packages]
when: (windows_taskbar_pins | default([])) | length > 0
block:
- name: Ensure Windows taskbar layout directory exists
ansible.windows.win_file:
path: "{{ windows_taskbar_layout_directory }}"
state: directory
- name: Render Windows taskbar layout policy file
ansible.windows.win_template:
src: taskbar-layout.xml.j2
dest: "{{ windows_taskbar_layout_path }}"
register: windows_taskbar_layout_file_state
- name: Enable Windows taskbar layout policy
ansible.windows.win_regedit:
path: HKCU:\Software\Policies\Microsoft\Windows\Explorer
name: LockedStartLayout
data: 1
type: dword
register: windows_taskbar_layout_policy_state
- name: Set Windows taskbar layout policy file path
ansible.windows.win_regedit:
path: HKCU:\Software\Policies\Microsoft\Windows\Explorer
name: StartLayoutFile
data: "{{ windows_taskbar_layout_path }}"
type: expandstring
register: windows_taskbar_layout_policy_path_state
- name: Set Windows taskbar layout policy refresh behavior
ansible.windows.win_regedit:
path: HKCU:\Software\Policies\Microsoft\Windows\Explorer
name: ReapplyStartLayoutEveryLogon
data: "{{ (windows_taskbar_reapply_every_logon | default(false)) | ternary(1, 0) }}"
type: dword
register: windows_taskbar_layout_policy_reapply_state
- name: Note when Windows taskbar pin layout may require sign out
ansible.builtin.debug:
msg: >-
Windows taskbar pin policy changed. Sign out and back in if the updated pin order does not appear immediately.
changed_when: false
when: >-
(windows_taskbar_layout_file_state is changed)
or (windows_taskbar_layout_policy_state is changed)
or (windows_taskbar_layout_policy_path_state is changed)
or (windows_taskbar_layout_policy_reapply_state is changed)
- name: Install VS Code WSL extensions on Windows host
tags: [packages, vscode]
ansible.windows.win_powershell:
script: |
$extensionId = '{{ item }}'
$code = Get-Command code.cmd -ErrorAction SilentlyContinue
if ($null -eq $code) {
throw 'code.cmd is not available. Ensure Visual Studio Code is installed before managing extensions.'
}
$installedExtensions = & $code.Source --list-extensions
if ($installedExtensions -contains $extensionId) {
$Ansible.Changed = $false
return
}
& $code.Source --install-extension $extensionId --force
if ($LASTEXITCODE -ne 0) {
throw "Failed to install VS Code extension $extensionId"
}
$Ansible.Changed = $true
loop: "{{ windows_vscode_extensions | default([]) }}"
loop_control:
label: "{{ item }}"
- name: Set Windows Terminal default profile to Ubuntu
tags: [packages, wsl]
ansible.windows.win_powershell:
script: |
$terminalSettingsPath = Join-Path $env:LOCALAPPDATA 'Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json'
if (-not (Test-Path $terminalSettingsPath)) {
throw 'Windows Terminal settings.json was not found. Launch Windows Terminal once before applying the default profile configuration.'
}
$settings = Get-Content -Path $terminalSettingsPath -Raw | ConvertFrom-Json
if ($null -eq $settings.profiles -or $null -eq $settings.profiles.list) {
throw 'Windows Terminal settings.json does not contain a profiles.list section.'
}
$targetProfile = $settings.profiles.list |
Where-Object {
$_.name -eq '{{ windows_terminal_default_profile_name }}' -and -not ($_.PSObject.Properties.Name -contains 'hidden' -and $_.hidden)
} |
Select-Object -First 1
if ($null -eq $targetProfile) {
throw "Windows Terminal visible profile '{{ windows_terminal_default_profile_name }}' was not found. Ensure the Ubuntu WSL profile exists and is not hidden in Windows Terminal first."
}
if ($settings.defaultProfile -eq $targetProfile.guid) {
$Ansible.Changed = $false
return
}
$settings.defaultProfile = $targetProfile.guid
$settings | ConvertTo-Json -Depth 100 | Set-Content -Path $terminalSettingsPath -Encoding utf8
$Ansible.Changed = $true

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LayoutModificationTemplate
xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification"
xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout"
xmlns:start="http://schemas.microsoft.com/Start/2014/StartLayout"
xmlns:taskbar="http://schemas.microsoft.com/Start/2014/TaskbarLayout"
Version="1">
<CustomTaskbarLayoutCollection PinListPlacement="Replace">
<defaultlayout:TaskbarLayout>
<taskbar:TaskbarPinList>
{% for pin in windows_taskbar_pins %}
{% if pin.type == 'desktop_application_id' %}
<taskbar:DesktopApp DesktopApplicationID="{{ pin.id }}" />
{% elif pin.type == 'desktop_application_link_path' %}
<taskbar:DesktopApp DesktopApplicationLinkPath="{{ pin.path }}" />
{% elif pin.type == 'app_user_model_id' %}
<taskbar:UWA AppUserModelID="{{ pin.id }}" />
{% endif %}
{% endfor %}
</taskbar:TaskbarPinList>
</defaultlayout:TaskbarLayout>
</CustomTaskbarLayoutCollection>
</LayoutModificationTemplate>

View File

@@ -1,5 +1,5 @@
--- ---
- hosts: all:!workstation_host_windows - hosts: all
become: true become: true
pre_tasks: pre_tasks:
- name: Load local vault variables when available - name: Load local vault variables when available
@@ -29,14 +29,6 @@
- profile_desktop_hyprland - profile_desktop_hyprland
- profile_desktop_host - profile_desktop_host
- hosts: workstation_dev_ubuntu
become: true
roles:
- packages_ubuntu
- services_systemd
- profile_workstation_dev_common
- hosts: workstation_dev_fedora - hosts: workstation_dev_fedora
become: true become: true
@@ -60,53 +52,6 @@
- profile_workstation_dev_common - profile_workstation_dev_common
- profile_workstation_dev_wsl - profile_workstation_dev_wsl
- hosts: workstation_host_windows
gather_facts: false
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
- 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
- name: Resolve Windows PSRP connection settings
tags: [always]
ansible.builtin.set_fact:
ansible_host: "{{ windows_psrp_host | default(vault_windows_psrp_host | default('')) }}"
ansible_user: "{{ windows_psrp_user | default(vault_windows_psrp_user | default('')) }}"
ansible_password: "{{ windows_psrp_password | default(vault_windows_psrp_password | default('')) }}"
windows_package_backend: "{{ windows_package_backend | default(vault_windows_package_backend | default('winget_psrp')) }}"
- name: Ensure Windows PSRP connection settings are defined
tags: [always]
ansible.builtin.assert:
that:
- (ansible_host | default('') | length) > 0
- (ansible_user | default('') | length) > 0
fail_msg: >-
Define windows_psrp_host and windows_psrp_user via extra vars, secrets/vault.yml,
or secrets/vault.local.yml
before running the workstation_host_windows play.
- name: Ensure Windows package backend is supported
tags: [always]
ansible.builtin.assert:
that:
- windows_package_backend in ['winget_psrp', 'winget_wsl_local']
fail_msg: >-
Unsupported windows_package_backend '{{ windows_package_backend }}'.
Supported values are winget_psrp and winget_wsl_local.
roles:
- profile_workstation_host_windows
- hosts: ubuntu_server - hosts: ubuntu_server
become: true become: true

View File

@@ -1,163 +0,0 @@
#requires -RunAsAdministrator
param(
[string]$Distribution = 'Ubuntu',
[switch]$SkipUbuntuInstall
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Get-OrCreate-WinRMHttpsCertificate {
$dnsName = $env:COMPUTERNAME
$existingCertificate = Get-ChildItem -Path Cert:\LocalMachine\My |
Where-Object { $_.Subject -eq "CN=$dnsName" } |
Sort-Object NotAfter -Descending |
Select-Object -First 1
if ($null -ne $existingCertificate) {
return $existingCertificate
}
return New-SelfSignedCertificate `
-DnsName $dnsName `
-CertStoreLocation 'Cert:\LocalMachine\My' `
-FriendlyName 'WinRM HTTPS Listener' `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-HashAlgorithm SHA256 `
-NotAfter (Get-Date).AddYears(5)
}
function Ensure-WinRMHttpsListener {
param(
[Parameter(Mandatory = $true)]
[string]$CertificateThumbprint
)
$listener = Get-ChildItem -Path WSMan:\localhost\Listener |
Where-Object {
$_.Keys -match 'Transport=HTTPS'
} |
Select-Object -First 1
if ($null -eq $listener) {
try {
New-WSManInstance -ResourceURI winrm/config/Listener `
-SelectorSet @{ Transport = 'HTTPS'; Address = '*' } `
-ValueSet @{ Hostname = $env:COMPUTERNAME; CertificateThumbprint = $CertificateThumbprint } | Out-Null
return $true
}
catch {
$existingHttpsListener = Get-ChildItem -Path WSMan:\localhost\Listener |
Where-Object {
$_.Keys -match 'Transport=HTTPS'
} |
Select-Object -First 1
if ($null -ne $existingHttpsListener) {
return $false
}
throw
}
}
return $false
}
function Test-WinRMHttpsListener {
$listener = Get-ChildItem -Path WSMan:\localhost\Listener |
Where-Object {
$_.Keys -match 'Transport=HTTPS'
} |
Select-Object -First 1
return $null -ne $listener
}
function Ensure-LocalAccountTokenFilterPolicy {
$registryPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$propertyName = 'LocalAccountTokenFilterPolicy'
$currentValue = Get-ItemProperty -Path $registryPath -Name $propertyName -ErrorAction SilentlyContinue | Select-Object -ExpandProperty $propertyName -ErrorAction SilentlyContinue
if ($currentValue -ne 1) {
New-ItemProperty -Path $registryPath -Name $propertyName -Value 1 -PropertyType DWord -Force | Out-Null
return $true
}
return $false
}
function Ensure-CurrentUserInRemoteManagementGroup {
$groupName = 'Utenti gestione remota'
$currentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$members = @(Get-LocalGroupMember -Name $groupName -ErrorAction Stop | Select-Object -ExpandProperty Name)
if ($members -contains $currentUser) {
return @{ Changed = $false; User = $currentUser; Group = $groupName }
}
Add-LocalGroupMember -Group $groupName -Member $currentUser -ErrorAction Stop
return @{ Changed = $true; User = $currentUser; Group = $groupName }
}
function Enable-FeatureIfNeeded {
param(
[Parameter(Mandatory = $true)]
[string]$FeatureName
)
$feature = Get-WindowsOptionalFeature -Online -FeatureName $FeatureName
if ($feature.State -ne 'Enabled') {
Enable-WindowsOptionalFeature -Online -FeatureName $FeatureName -All -NoRestart | Out-Null
return $true
}
return $false
}
$rebootRequired = $false
$rebootRequired = (Enable-FeatureIfNeeded -FeatureName 'Microsoft-Windows-Subsystem-Linux') -or $rebootRequired
$rebootRequired = (Enable-FeatureIfNeeded -FeatureName 'VirtualMachinePlatform') -or $rebootRequired
wsl --set-default-version 2
$installedDistributions = @(wsl --list --quiet) | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' }
$installedUbuntuDistribution = $installedDistributions | Where-Object { $_ -like 'Ubuntu*' } | Select-Object -First 1
if (-not $SkipUbuntuInstall -and $null -eq $installedUbuntuDistribution) {
wsl --install --distribution $Distribution --no-launch
$rebootRequired = $true
}
Enable-PSRemoting -SkipNetworkProfileCheck -Force
Set-Service -Name WinRM -StartupType Automatic
$winrmCertificate = Get-OrCreate-WinRMHttpsCertificate
$httpsListenerChanged = Ensure-WinRMHttpsListener -CertificateThumbprint $winrmCertificate.Thumbprint
$rebootRequired = (Ensure-LocalAccountTokenFilterPolicy) -or $rebootRequired
$remoteManagementGroupState = Ensure-CurrentUserInRemoteManagementGroup
$httpsFirewallRule = Get-NetFirewallRule -DisplayName 'WinRM HTTPS (5986)' -ErrorAction SilentlyContinue
if ($null -eq $httpsFirewallRule) {
New-NetFirewallRule -DisplayName 'WinRM HTTPS (5986)' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5986 | Out-Null
}
if (-not (Test-WinRMHttpsListener)) {
throw 'WinRM HTTPS listener was not created successfully. Verify certificate creation and WSMan listener configuration.'
}
Write-Host ''
Write-Host 'Bootstrap completato.'
Write-Host 'Passi successivi:'
Write-Host '1. Riavvia Windows se richiesto dalle feature WSL.'
Write-Host '2. Avvia la distro Ubuntu almeno una volta e completa la creazione dell''utente Linux.'
Write-Host '3. Installa Ansible dentro WSL Ubuntu e lancia il playbook da li.'
Write-Host '4. Le applicazioni Windows saranno installate dal playbook Ansible; il backend predefinito e winget_psrp.'
Write-Host ''
Write-Host ('WSL distro Ubuntu rilevata: {0}' -f $(if ($null -ne $installedUbuntuDistribution) { $installedUbuntuDistribution } else { 'nessuna, verra installata ' + $Distribution }))
Write-Host ('PSRP transport consigliato: https://{0}:5986/wsman' -f $env:COMPUTERNAME)
Write-Host ('Certificato WinRM HTTPS: {0}' -f $winrmCertificate.Thumbprint)
Write-Host ('Utente aggiunto a Utenti gestione remota: {0}' -f $remoteManagementGroupState.User)
Write-Host ('Listener HTTPS creato in questo run: {0}' -f $(if ($httpsListenerChanged) { 'yes' } else { 'no' }))
Write-Host ('Riavvio consigliato: {0}' -f $(if ($rebootRequired) { 'yes' } else { 'no' }))

View File

@@ -8,10 +8,6 @@ vault_icloud_mail_password: "REPLACE_ME"
vault_git_work_email: "REPLACE_ME" vault_git_work_email: "REPLACE_ME"
vault_git_work_gpg: "REPLACE_ME" vault_git_work_gpg: "REPLACE_ME"
vault_openai_api_key: "REPLACE_ME" vault_openai_api_key: "REPLACE_ME"
vault_windows_psrp_host: "REPLACE_ME"
vault_windows_psrp_user: 'MicrosoftAccount\user@example.com'
vault_windows_psrp_password: "REPLACE_ME"
vault_windows_package_backend: "winget_psrp"
vault_navidrome_db_password: "REPLACE_ME" vault_navidrome_db_password: "REPLACE_ME"
vault_postgres_root_password: "REPLACE_ME" vault_postgres_root_password: "REPLACE_ME"
vault_ikaros_authorized_ssh_keys: vault_ikaros_authorized_ssh_keys: