feat: complete wayland desktop deployment (gnome/kde/sway/hyprland)

This commit is contained in:
2026-05-30 18:05:05 +02:00
parent 876e90ce2b
commit 9757ed3785
9 changed files with 355 additions and 163 deletions

View File

@@ -28,21 +28,41 @@
memory: "{{ [system_raw.memory | default(0) | int, 0] | max }}"
balloon: "{{ [system_raw.balloon | default(0) | int, 0] | max }}"
# --- Network ---
# Flat fields (bridge, ip, etc.) and interfaces[] are mutually exclusive.
# When interfaces[] is set, flat fields are populated from the first
# interface in the "Populate primary network fields" task below.
# When only flat fields are set, a synthetic interfaces[] entry is built.
# Flat fields (bridge, ip, etc.) and interfaces[] express the same primary NIC.
# When only flat fields are set, a synthetic interfaces[] entry is built below.
# When interfaces[] is set, the flat ip/prefix/gateway are backfilled from
# interfaces[0] so consumers reading the flat fields (e.g. the post-reboot
# reconnect block) still work.
network:
bridge: "{{ system_raw.network.bridge | default('') | string }}"
bridge: >-
{{
(system_raw.network.bridge | default('') | string)
if (system_raw.network.bridge | default('') | string | length) > 0
else (system_raw.network.interfaces[0].bridge | default('') | string
if (system_raw.network.interfaces | default([]) | length) > 0 else '')
}}
vlan: "{{ system_raw.network.vlan | default('') | string }}"
ip: "{{ system_raw.network.ip | default('') | string }}"
ip: >-
{{
(system_raw.network.ip | default('') | string)
if (system_raw.network.ip | default('') | string | length) > 0
else (system_raw.network.interfaces[0].ip | default('') | string
if (system_raw.network.interfaces | default([]) | length) > 0 else '')
}}
prefix: >-
{{
(system_raw.network.prefix | int | string)
if (system_raw.network.prefix | default('') | string | length) > 0
else ''
else (system_raw.network.interfaces[0].prefix | default('') | string
if (system_raw.network.interfaces | default([]) | length) > 0 else '')
}}
gateway: >-
{{
(system_raw.network.gateway | default('') | string)
if (system_raw.network.gateway | default('') | string | length) > 0
else (system_raw.network.interfaces[0].gateway | default('') | string
if (system_raw.network.interfaces | default([]) | length) > 0 else '')
}}
gateway: "{{ system_raw.network.gateway | default('') | string }}"
dns:
servers: "{{ system_raw.network.dns.servers | default([]) }}"
search: "{{ system_raw.network.dns.search | default([]) }}"
@@ -148,6 +168,9 @@
enabled: "{{ system_raw.features.desktop.enabled | bool }}"
environment: "{{ system_raw.features.desktop.environment | default('') | string | lower }}"
display_manager: "{{ system_raw.features.desktop.display_manager | default('') | string | lower }}"
autologin: "{{ system_raw.features.desktop.autologin | default(false) }}"
session: "{{ system_raw.features.desktop.session | default('') | string }}"
groups: "{{ system_raw.features.desktop.groups | default([]) }}"
secure_boot:
enabled: "{{ system_raw.features.secure_boot.enabled | bool }}"
method: "{{ system_raw.features.secure_boot.method | default('') | string | lower }}"
@@ -169,7 +192,12 @@
else (system_raw.features.firmware.microcode | bool)
}}
gpu:
enabled: "{{ system_raw.features.gpu.enabled | bool }}"
enabled: >-
{{
(system_raw.features.desktop.enabled | bool)
if (system_raw.features.gpu.enabled | string | lower) == 'auto'
else (system_raw.features.gpu.enabled | bool)
}}
nvidia_driver: "{{ system_raw.features.gpu.nvidia_driver | default('auto') | string | lower }}"
peripherals:
enabled: >-

View File

@@ -140,7 +140,7 @@
os in ["ubuntu", "ubuntu-lts"]
and (os_version | default('') | string | length) == 0
) or (
os in ["alpine", "archlinux", "opensuse", "void"]
os == "archlinux"
)
fail_msg: "Invalid os/version specified. Please check README.md for supported values."
quiet: true
@@ -252,6 +252,49 @@
peripherals.webcam in [auto|true|false]; hardware.profile must be a dict.
quiet: true
- name: Validate desktop environment
when: system_cfg.features.desktop.enabled | bool
ansible.builtin.assert:
that:
- system_cfg.features.desktop.environment in ["gnome", "kde", "sway", "hyprland"]
- >-
system_cfg.features.desktop.environment not in ["sway", "hyprland"]
or os_family_map[os] | default('') == "Archlinux"
- >-
system_cfg.features.desktop.display_manager | default('') | length == 0
or system_cfg.features.desktop.display_manager in ["gdm", "sddm", "greetd"]
- >-
system_cfg.features.desktop.display_manager | default('') != "greetd"
or system_cfg.features.desktop.environment in ["sway", "hyprland"]
- >-
system_cfg.features.desktop.environment != "gnome"
or system_cfg.features.desktop.display_manager | default('') in ["", "gdm"]
- >-
system_cfg.features.desktop.environment != "kde"
or system_cfg.features.desktop.display_manager | default('') in ["", "sddm"]
fail_msg: >-
Invalid desktop config: environment '{{ system_cfg.features.desktop.environment }}'
for os_family '{{ os_family_map[os] | default('Unknown') }}',
display_manager '{{ system_cfg.features.desktop.display_manager | default('') }}'.
gnome and kde are available on all families; sway and hyprland are Archlinux only.
display_manager must be empty (auto) or match the environment's native DM:
gnome->gdm, kde->sddm, sway/hyprland->greetd. Only that DM's package is
installed, so a mismatched override fails at enable time.
quiet: true
- name: Validate desktop autologin
when: system_cfg.features.desktop.enabled | bool
vars:
_autologin: "{{ system_cfg.features.desktop.autologin | default(false) }}"
ansible.builtin.assert:
that:
- _autologin is boolean and not _autologin or (_autologin is string and _autologin | length > 0 and _autologin in system_cfg.users)
fail_msg: >-
desktop.autologin must be false or a username string present in
system.users; got '{{ _autologin }}'. Bool true is not accepted - the
resolver matches the value against system.users by name.
quiet: true
- name: Validate virtual system sizing
when: system_cfg.type == "virtual"
ansible.builtin.assert:
@@ -262,7 +305,7 @@
- (system_cfg.disks[0].size | float) > 0
- (system_cfg.disks[0].size | float) >= 20
# Btrfs minimum disk: swap_size + 5.5 GiB overhead (subvolumes + metadata).
# Swap sizing: memory < 16 GiB max(memory_GiB, 2); memory >= 16 GiB memory/2.
# Swap sizing: memory < 16 GiB -> max(memory_GiB, 2); memory >= 16 GiB -> memory/2.
- >-
system_cfg.filesystem != "btrfs"
or (