245 lines
10 KiB
YAML
245 lines
10 KiB
YAML
---
|
|
- name: Resolve desktop facts
|
|
when: system_cfg.features.desktop.enabled | bool
|
|
vars:
|
|
_autologin: "{{ system_cfg.features.desktop.autologin | default(false) }}"
|
|
ansible.builtin.set_fact:
|
|
# KDE resolves to the plasmalogin unit on Arch/Fedora44+ (Plasma 6.6), else sddm.
|
|
_desktop_dm: >-
|
|
{{
|
|
('plasmalogin'
|
|
if system_cfg.features.desktop.display_manager == 'plasma-login-manager'
|
|
else system_cfg.features.desktop.display_manager)
|
|
if (system_cfg.features.desktop.display_manager | length > 0)
|
|
else (
|
|
('plasmalogin'
|
|
if (os == 'archlinux' or (os == 'fedora' and (os_version | int) >= 44))
|
|
else 'sddm')
|
|
if system_cfg.features.desktop.environment == 'kde'
|
|
else (configuration_desktop_dm_map[system_cfg.features.desktop.environment] | default(''))
|
|
)
|
|
}}
|
|
_desktop_session: "{{ system_cfg.features.desktop.session | default('') }}"
|
|
# Explicit session wins, else the per-environment command. Single source of
|
|
# truth for the greetd assert, the config gate, and the template.
|
|
_greetd_session: >-
|
|
{{
|
|
system_cfg.features.desktop.session
|
|
if (system_cfg.features.desktop.session | default('') | length > 0)
|
|
else (configuration_desktop_session_cmd_map[system_cfg.features.desktop.environment] | default(''))
|
|
}}
|
|
_desktop_autologin_user: >-
|
|
{{
|
|
_autologin
|
|
if (_autologin | string | lower not in ['', 'false'] and _autologin in system_cfg.users)
|
|
else ''
|
|
}}
|
|
|
|
- name: Enable systemd services
|
|
when: _configuration_platform.init_system == 'systemd'
|
|
vars:
|
|
configuration_systemd_services: >-
|
|
{{
|
|
['NetworkManager']
|
|
+ ([_configuration_platform.ssh_service] if system_cfg.features.ssh.enabled | bool else [])
|
|
+ (['logrotate', 'systemd-timesyncd'] if os == 'archlinux' else [])
|
|
+ (['bluetooth'] if system_cfg.features.desktop.enabled | bool else [])
|
|
}}
|
|
ansible.builtin.command: "{{ chroot_command }} systemctl enable {{ item }}"
|
|
loop: "{{ configuration_systemd_services }}"
|
|
register: configuration_enable_service_result
|
|
changed_when: configuration_enable_service_result.rc == 0
|
|
failed_when: >-
|
|
configuration_enable_service_result.rc != 0
|
|
and 'No such file or directory' not in (configuration_enable_service_result.stderr | default(''))
|
|
and 'does not exist' not in (configuration_enable_service_result.stderr | default(''))
|
|
|
|
- name: Enable display manager for selected desktop
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm | length > 0
|
|
- _desktop_dm != 'ly'
|
|
ansible.builtin.command: "{{ chroot_command }} systemctl enable {{ _desktop_dm }}"
|
|
register: configuration_enable_dm_result
|
|
changed_when: configuration_enable_dm_result.rc == 0
|
|
# Unlike optional services above, a missing/unenabled DM is fatal: chroot
|
|
# systemctl can exit 0 while only warning on stderr, so check both.
|
|
failed_when: >-
|
|
configuration_enable_dm_result.rc != 0
|
|
or 'No such file or directory' in (configuration_enable_dm_result.stderr | default(''))
|
|
or 'does not exist' in (configuration_enable_dm_result.stderr | default(''))
|
|
|
|
- name: Activate UFW firewall
|
|
when:
|
|
- system_cfg.features.firewall.backend == 'ufw'
|
|
- system_cfg.features.firewall.enabled | bool
|
|
ansible.builtin.command: "{{ chroot_command }} ufw --force enable"
|
|
register: _ufw_enable_result
|
|
changed_when: _ufw_enable_result.rc == 0
|
|
failed_when: false
|
|
- name: Enable ly on its tty
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm == 'ly'
|
|
vars:
|
|
_ly_tty: tty2
|
|
block:
|
|
- name: Enable ly display manager
|
|
ansible.builtin.command: "{{ chroot_command }} systemctl enable ly@{{ _ly_tty }}.service"
|
|
register: configuration_enable_ly_result
|
|
changed_when: configuration_enable_ly_result.rc == 0
|
|
failed_when: >-
|
|
configuration_enable_ly_result.rc != 0
|
|
or 'No such file or directory' in (configuration_enable_ly_result.stderr | default(''))
|
|
or 'does not exist' in (configuration_enable_ly_result.stderr | default(''))
|
|
|
|
# ly drives the VT itself; mask getty so logind never spawns a login on that tty.
|
|
- name: Mask getty on ly's tty
|
|
ansible.builtin.command: "{{ chroot_command }} systemctl mask getty@{{ _ly_tty }}.service"
|
|
register: configuration_mask_getty_result
|
|
changed_when: configuration_mask_getty_result.rc == 0
|
|
failed_when: >-
|
|
configuration_mask_getty_result.rc != 0
|
|
and 'No such file or directory' not in (configuration_mask_getty_result.stderr | default(''))
|
|
and 'does not exist' not in (configuration_mask_getty_result.stderr | default(''))
|
|
|
|
- name: Set default systemd target
|
|
when: _configuration_platform.init_system == 'systemd'
|
|
vars:
|
|
_default_target: "{{ 'graphical.target' if system_cfg.features.desktop.enabled | bool else 'multi-user.target' }}"
|
|
ansible.builtin.command: "{{ chroot_command }} systemctl set-default {{ _default_target }}"
|
|
register: _set_default_target_result
|
|
changed_when: _set_default_target_result.rc == 0
|
|
|
|
- name: Enable PipeWire user services globally
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
ansible.builtin.command: "{{ chroot_command }} systemctl --global enable {{ item }}"
|
|
loop: "{{ configuration_desktop_audio_units }}"
|
|
register: _desktop_audio_result
|
|
changed_when: _desktop_audio_result.rc == 0
|
|
failed_when: >-
|
|
_desktop_audio_result.rc != 0
|
|
and 'No such file or directory' not in (_desktop_audio_result.stderr | default(''))
|
|
and 'does not exist' not in (_desktop_audio_result.stderr | default(''))
|
|
|
|
- name: Assert greetd has a real session command to launch
|
|
when:
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm == 'greetd'
|
|
ansible.builtin.assert:
|
|
that:
|
|
- _greetd_session | length > 0
|
|
- not (_greetd_session | trim | regex_search('\\.desktop$'))
|
|
fail_msg: >-
|
|
greetd needs an executable session command, but the resolved command for desktop
|
|
environment '{{ system_cfg.features.desktop.environment }}' is
|
|
'{{ _greetd_session }}'. greetd suits wlroots compositors (sway, hyprland) that
|
|
launch from a plain command; kde/gnome ship a '.desktop' session and should use
|
|
their own display manager (sddm, gdm). Set features.desktop.session to an
|
|
executable, or pick a different display manager.
|
|
|
|
- name: Generate greetd configuration
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm == 'greetd'
|
|
- _greetd_session | length > 0
|
|
block:
|
|
- name: Ensure greetd config directory exists
|
|
ansible.builtin.file:
|
|
path: /mnt/etc/greetd
|
|
state: directory
|
|
mode: "0755"
|
|
|
|
- name: Write greetd config.toml
|
|
ansible.builtin.template:
|
|
src: greetd-config.toml.j2
|
|
dest: /mnt/etc/greetd/config.toml
|
|
mode: "0644"
|
|
|
|
- name: Configure GDM autologin
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm == 'gdm'
|
|
- _desktop_autologin_user | length > 0
|
|
vars:
|
|
# Debian gdm3 reads daemon.conf; RedHat/Arch gdm read custom.conf.
|
|
_gdm_dir: "/mnt/etc/{{ 'gdm3' if os_family == 'Debian' else 'gdm' }}"
|
|
_gdm_conf: "{{ 'daemon.conf' if os_family == 'Debian' else 'custom.conf' }}"
|
|
block:
|
|
- name: Ensure GDM config directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ _gdm_dir }}"
|
|
state: directory
|
|
mode: "0755"
|
|
|
|
- name: Write GDM autologin config
|
|
ansible.builtin.template:
|
|
src: gdm-custom.conf.j2
|
|
dest: "{{ _gdm_dir }}/{{ _gdm_conf }}"
|
|
mode: "0644"
|
|
|
|
# SDDM and plasma-login-manager share the [Autologin] format and the KDE Wayland
|
|
# session; only the config dir differs (sddm.conf.d vs plasmalogin.conf.d).
|
|
- name: Configure SDDM / plasma-login-manager autologin
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm in ['sddm', 'plasmalogin']
|
|
- _desktop_autologin_user | length > 0
|
|
vars:
|
|
_autologin_conf_dir: "/mnt/etc/{{ 'plasmalogin.conf.d' if _desktop_dm == 'plasmalogin' else 'sddm.conf.d' }}"
|
|
block:
|
|
- name: Ensure KDE login-manager config directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ _autologin_conf_dir }}"
|
|
state: directory
|
|
mode: "0755"
|
|
|
|
# Plasma 6 ships the Wayland session as plasma.desktop; Plasma 5 ships it as
|
|
# plasmawayland.desktop (plasma.desktop is the X11 session there). Pick the
|
|
# installed Wayland session so autologin never lands on X11.
|
|
- name: Discover installed KDE Wayland sessions
|
|
ansible.builtin.find:
|
|
paths: /mnt/usr/share/wayland-sessions
|
|
patterns: "plasma.desktop,plasmawayland.desktop"
|
|
register: _kde_wayland_sessions
|
|
|
|
- name: Resolve the KDE Wayland session file
|
|
ansible.builtin.set_fact:
|
|
_sddm_session: >-
|
|
{%- set names = _kde_wayland_sessions.files | map(attribute='path') | map('basename') | list -%}
|
|
{{ 'plasma.desktop' if 'plasma.desktop' in names else (names | first | default('')) }}
|
|
|
|
- name: Write KDE login-manager autologin drop-in
|
|
ansible.builtin.template:
|
|
src: sddm-autologin.conf.j2
|
|
dest: "{{ _autologin_conf_dir }}/10-autologin.conf"
|
|
mode: "0644"
|
|
|
|
# ly ships a flat (sectionless) config.ini; edit it in place to keep upstream
|
|
# defaults. Both keys are required: an unresolved session writes 'null', which
|
|
# disables autologin rather than leaving it half-configured.
|
|
- name: Configure ly autologin
|
|
when:
|
|
- _configuration_platform.init_system == 'systemd'
|
|
- system_cfg.features.desktop.enabled | bool
|
|
- _desktop_dm == 'ly'
|
|
- _desktop_autologin_user | length > 0
|
|
community.general.ini_file:
|
|
path: /mnt/etc/ly/config.ini
|
|
option: "{{ item.key }}"
|
|
value: "{{ item.value }}"
|
|
create: false
|
|
mode: "0644"
|
|
loop:
|
|
- key: auto_login_user
|
|
value: "{{ _desktop_autologin_user }}"
|
|
- key: auto_login_session
|
|
value: "{{ _greetd_session if (_greetd_session | length > 0) else 'null' }}"
|