Reorganize desktop roles: extract common bootstrap and host-specific layers

- Add profile_desktop_common with shared desktop bootstrap (emptty, PAM,
  dotfiles, templates, GPG, Maildir, Flatpak, st, external tools)
- Add profile_desktop_host with host-specific tasks (NVIDIA/PRIME on nymph)
- Reduce profile_desktop_i3 to i3/X11-only tasks
- Create profile_desktop_hyprland for Hyprland Wayland session
- Add dual-session support (i3 + Hyprland) on nymph with session choice
- Create shared Hyprland/Waybar dotfiles under dotfiles/desktop/
- Fix Waybar: bottom position, no persistent workspaces, sort by number
- Rename host_dotfiles to host_i3_dotfiles for clarity
- Make emptty restart manual by default to avoid session drops
This commit is contained in:
Fabio Scotto di Santolo
2026-03-30 12:43:41 +02:00
parent 56d634c64e
commit 0a80706ea2
34 changed files with 1342 additions and 1013 deletions

View File

@@ -2,36 +2,57 @@
desktop_manage_icloud_keyring: false
desktop_protonmail_bridge_cert_path: ~/.var/app/ch.protonmail.protonmail-bridge/config/protonmail/bridge-v3/cert.pem
desktop_x11_packages:
- arandr
- autorandr
desktop_sessions_enabled:
- i3
desktop_default_session: i3
desktop_default_session_env: xorg
desktop_restart_emptty_automatically: false
desktop_emptty_session_error_logging: disabled
desktop_common_packages:
- brightnessctl
- dex
- dunst
- emptty
- network-manager-applet
- rofi
- udiskie
- xfce-polkit
- xdg-desktop-portal
- xdg-desktop-portal-gtk
desktop_i3_packages:
- arandr
- autorandr
- feh
- i3
- i3blocks
- i3blocks-blocklets
- i3lock-color
- i3status
- network-manager-applet
- rofi
- scrot
- setxkbmap
- udiskie
- volumeicon
- xclip
- xfce-polkit
- xfce4-clipman-plugin
- xfce4-screenshooter
- xkbutils
- xdg-desktop-portal
- xdg-desktop-portal-gtk
- xorg-fonts
- xorg-minimal
- xss-lock
desktop_hyprland_packages:
- grim
- hypridle
- hyprland
- hyprlock
- hyprpaper
- slurp
- Waybar
- wl-clipboard
- xdg-desktop-portal-hyprland
profile_packages:
- alacritty
- bluez
@@ -68,19 +89,11 @@ profile_packages:
- yaru
- yaru-plus
desktop_dotfiles:
desktop_common_dotfiles:
- name: XDG autostart entries
src: .config/autostart/
dest: .config/autostart/
mode: preserve
- name: i3 config
src: .config/i3/
dest: .config/i3/
mode: preserve
- name: i3blocks config
src: .config/i3blocks/
dest: .config/i3blocks/
mode: preserve
- name: dunst config
src: .config/dunst/
dest: .config/dunst/
@@ -113,10 +126,6 @@ desktop_dotfiles:
src: .config/yt-dlp/
dest: .config/yt-dlp/
mode: preserve
- name: .xinitrc
src: .xinitrc
dest: .xinitrc
mode: "0644"
- name: .gitignore_global
src: .gitignore_global
dest: .gitignore_global
@@ -129,6 +138,50 @@ desktop_dotfiles:
src: .emacs.d/
dest: .emacs.d/
mode: preserve
- name: GTK theme setup script
src: .local/bin/setup-gtk-theme
dest: .local/bin/setup-gtk-theme
mode: "0755"
- name: Lock session script
src: .local/bin/lock-session
dest: .local/bin/lock-session
mode: "0755"
- name: Powermenu script
src: .local/bin/powermenu
dest: .local/bin/powermenu
mode: "0755"
desktop_i3_dotfiles:
- name: i3 config
src: .config/i3/
dest: .config/i3/
mode: preserve
- name: i3blocks config
src: .config/i3blocks/
dest: .config/i3blocks/
mode: preserve
- name: .xinitrc
src: .xinitrc
dest: .xinitrc
mode: "0644"
desktop_hyprland_dotfiles:
- name: Hyprland config
src: .config/hypr/
dest: .config/hypr/
mode: preserve
- name: Waybar config
src: .config/waybar/
dest: .config/waybar/
mode: preserve
- name: Hyprland session wrapper
src: .local/bin/start-hyprland-session
dest: .local/bin/start-hyprland-session
mode: "0755"
- name: Wayland screenshot script
src: .local/bin/screenshot-wayland
dest: .local/bin/screenshot-wayland
mode: "0755"
desktop_flatpak_packages:
- be.alexandervanhee.gradia

View File

@@ -1,6 +1,12 @@
---
hostname: ikaros
desktop_sessions_enabled:
- i3
desktop_default_session: i3
desktop_default_session_env: xorg
host_packages:
- mesa-dri
- vulkan-loader
@@ -8,7 +14,7 @@ host_packages:
- mesa-vaapi
- xf86-video-amdgpu
host_dotfiles:
host_i3_dotfiles:
- src: .config/autorandr/
dest: .config/autorandr/
mode: preserve

View File

@@ -1,13 +1,17 @@
---
hostname: nymph
desktop_sessions_enabled:
- i3
- hyprland
desktop_prompt_for_session: true
desktop_emptty_session_error_logging: rotate
host_xbps_repositories:
- name: hyprland-void
url: "https://raw.githubusercontent.com/Makrennel/hyprland-void/repository-x86_64-glibc"
host_emptty_wayland_sessions:
- Hyprland.desktop
host_packages:
- nvidia
- mesa-dri
@@ -16,22 +20,16 @@ host_packages:
- intel-video-accel
- tlp
- tlp-rdw
- hyprland
- hyprpaper
- xdg-desktop-portal-hyprland
- Waybar
- wlogout
host_enabled_services:
- tlp
host_dotfiles:
host_i3_dotfiles:
- src: .config/autorandr/
dest: .config/autorandr/
mode: preserve
- src: .config/hypr/
dest: .config/hypr/
mode: preserve
- src: .config/waybar/
dest: .config/waybar/
mode: preserve
host_hyprland_dotfiles:
- src: .config/hypr/host.conf
dest: .config/hypr/host.conf
mode: "0644"

View File

@@ -86,12 +86,24 @@
ansible.builtin.apt:
name: >-
{{
(common_packages | default([]))
(
(common_packages | default([]))
+ (ubuntu_packages_base | default([]))
+ (ubuntu_docker_packages | default([]))
+ (profile_packages | default([]))
+ (desktop_x11_packages | default([]))
+ (desktop_common_packages | default([]))
+ (
(desktop_i3_packages | default([]))
if 'i3' in (desktop_sessions_enabled | default([]))
else []
)
+ (
(desktop_hyprland_packages | default([]))
if 'hyprland' in (desktop_sessions_enabled | default([]))
else []
)
+ (host_packages | default([]))
) | unique
}}
state: present

View File

@@ -51,11 +51,23 @@
community.general.xbps:
name: >-
{{
(common_packages | default([]))
(
(common_packages | default([]))
+ (void_packages_base | default([]))
+ (profile_packages | default([]))
+ (desktop_x11_packages | default([]))
+ (desktop_common_packages | default([]))
+ (
(desktop_i3_packages | default([]))
if 'i3' in (desktop_sessions_enabled | default([]))
else []
)
+ (
(desktop_hyprland_packages | default([]))
if 'hyprland' in (desktop_sessions_enabled | default([]))
else []
)
+ (host_packages | default([]))
) | unique
}}
state: present
update_cache: false

View File

@@ -0,0 +1,19 @@
---
- name: Restart emptty service
listen: Restart emptty
ansible.builtin.command: sv restart emptty
changed_when: true
when:
- not ansible_check_mode
- desktop_restart_emptty_automatically | default(false)
- name: Report manual emptty restart requirement
listen: Restart emptty
ansible.builtin.debug:
msg: >-
Emptty configuration changed but automatic restart is disabled.
Restart it manually from SSH or another TTY with `sudo sv restart emptty`
to avoid dropping the active graphical session.
when:
- not ansible_check_mode
- not (desktop_restart_emptty_automatically | default(false))

View File

@@ -0,0 +1,509 @@
---
- name: Configure elogind to suspend on lid close
tags: [packages]
ansible.builtin.lineinfile:
path: /etc/elogind/logind.conf
regexp: '^#?HandleLidSwitch='
line: 'HandleLidSwitch=suspend'
state: present
- name: Ensure common config directories exist
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
loop:
- "{{ user_home }}/.config"
- "{{ user_home }}/.config/autostart"
- "{{ user_home }}/.config/dunst"
- "{{ user_home }}/.config/alacritty"
- "{{ user_home }}/.config/Thunar"
- "{{ user_home }}/.config/rofi"
- name: Ensure user local bin directory exists
tags: [dotfiles, dotfiles:desktop, dotfiles:host]
ansible.builtin.file:
path: "{{ user_home }}/.local/bin"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
- name: Enable gnome-keyring PAM auth hook
tags: [packages, gnome]
ansible.builtin.lineinfile:
path: /etc/pam.d/login
insertafter: '^auth\s+include\s+system-local-login$'
line: "auth optional pam_gnome_keyring.so"
state: present
- name: Enable gnome-keyring PAM session hook
tags: [packages, gnome]
ansible.builtin.lineinfile:
path: /etc/pam.d/login
insertafter: '^session\s+include\s+system-local-login$'
line: "session optional pam_gnome_keyring.so auto_start"
state: present
- name: Enable gnome-keyring PAM password hook
tags: [packages, gnome]
ansible.builtin.lineinfile:
path: /etc/pam.d/login
insertafter: '^password\s+include\s+system-local-login$'
line: "password optional pam_gnome_keyring.so use_authtok"
state: present
- name: Ensure emptty log directory exists
tags: [packages, services, emptty]
ansible.builtin.file:
path: /var/log/emptty
state: directory
owner: root
group: root
mode: "0755"
- name: Ensure emptty session directories exist
tags: [packages, services, emptty]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
loop:
- /etc/emptty/xsessions
- /etc/emptty/wayland-sessions
- name: Configure emptty
tags: [packages, services, emptty]
ansible.builtin.template:
src: emptty-conf.j2
dest: /etc/emptty/conf
owner: root
group: root
mode: "0644"
notify: Restart emptty
- name: Copy common desktop dotfiles
tags: [dotfiles, dotfiles:desktop]
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_common_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
- name: Render desktop templates with private values
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop:
- src: desktop/.gitconfig.j2
dest: .gitconfig
mode: "0644"
- src: desktop/.mbsyncrc.j2
dest: .mbsyncrc
mode: "0600"
- src: desktop/.msmtprc.j2
dest: .msmtprc
mode: "0600"
- src: desktop/email.el.j2
dest: .emacs.d/lisp/misc/email.el
mode: "0644"
loop_control:
label: "{{ item.dest }}"
- name: Refresh user font cache
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.command: fc-cache -f
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
changed_when: false
- name: Ensure .gnupg directory exists
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ user_home }}/.gnupg"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0700"
- name: Copy gpg-agent.conf
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/desktop/.gnupg/gpg-agent.conf"
dest: "{{ user_home }}/.gnupg/gpg-agent.conf"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0600"
- name: Ensure local user directories exist
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop:
- path: "{{ user_home }}/.local"
mode: "0755"
- path: "{{ user_home }}/.local/share"
mode: "0755"
- path: "{{ user_home }}/.local/share/keyrings"
mode: "0700"
- path: "{{ user_home }}/.local/src"
mode: "0755"
- name: Ensure maildir directories exist
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0700"
loop:
- "{{ user_home }}/Maildir"
- "{{ user_home }}/Maildir/iCloudAccount"
- "{{ user_home }}/Maildir/ProtonMailAccount"
- name: Bootstrap iCloud keyring secret from Ansible vault
tags: [dotfiles, dotfiles:desktop, gnome]
when: desktop_manage_icloud_keyring | default(false)
block:
- name: Store iCloud mail password in GNOME Keyring
ansible.builtin.getent:
database: passwd
key: "{{ username }}"
- name: Set desktop user runtime UID
ansible.builtin.set_fact:
desktop_user_uid: "{{ ansible_facts.getent_passwd[username][1] }}"
- name: Check whether desktop user DBus session address file exists
ansible.builtin.stat:
path: "{{ user_home }}/.dbus-session-bus-address"
register: desktop_user_bus_address_file
- name: Read desktop user DBus session address
ansible.builtin.slurp:
src: "{{ user_home }}/.dbus-session-bus-address"
register: desktop_user_bus_address_raw
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address_file.stat.exists
- name: Set desktop user DBus session address
ansible.builtin.set_fact:
desktop_user_bus_address: >-
{{ desktop_user_bus_address_raw.content | b64decode | trim }}
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address_file.stat.exists
- name: Check whether GNOME Keyring default collection is available
ansible.builtin.command:
cmd: >-
gdbus call --session
--dest org.freedesktop.secrets
--object-path /org/freedesktop/secrets
--method org.freedesktop.Secret.Service.ReadAlias default
become: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
XDG_RUNTIME_DIR: "/run/user/{{ desktop_user_uid }}"
DBUS_SESSION_BUS_ADDRESS: "{{ desktop_user_bus_address }}"
register: icloud_keyring_default_alias
failed_when: false
changed_when: false
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address | default('') | length > 0
- name: Set GNOME Keyring default collection path
ansible.builtin.set_fact:
icloud_keyring_default_alias_path: >-
{{
(
icloud_keyring_default_alias.stdout
| default('')
| regex_findall("objectpath '([^']+)'")
| first
)
| default('')
}}
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address | default('') | length > 0
- icloud_keyring_default_alias.rc | default(1) == 0
- name: Store iCloud mail password in GNOME Keyring
ansible.builtin.command:
cmd: secret-tool store --label="iCloud Mail" icloud-mail icloud
stdin: "{{ vault_icloud_mail_password }}"
stdin_add_newline: false
become: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
XDG_RUNTIME_DIR: "/run/user/{{ desktop_user_uid }}"
DBUS_SESSION_BUS_ADDRESS: "{{ desktop_user_bus_address }}"
register: icloud_keyring_store
failed_when: false
changed_when: icloud_keyring_store.rc == 0
no_log: true
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address | default('') | length > 0
- icloud_keyring_default_alias.rc | default(1) == 0
- (icloud_keyring_default_alias_path | default('')) | length > 0
- (icloud_keyring_default_alias_path | default('')) != '/'
- name: Warn when iCloud keyring storage is skipped
ansible.builtin.debug:
msg: >-
Unable to store iCloud password in GNOME Keyring automatically.
{% if (desktop_user_bus_address | default('')) | length == 0 %}
No saved DBus session address was found in {{ user_home }}/.dbus-session-bus-address.
{% elif icloud_keyring_default_alias.rc | default(1) != 0 %}
The Secret Service default alias could not be queried for {{ username }}.
{% elif (icloud_keyring_default_alias_path | default('')) == '/' %}
The Secret Service default alias is unset, so the login keyring is not initialized.
{% endif %}
Ensure a graphical user session is active, the login keyring exists and is unlocked, then run:
secret-tool store --label="iCloud Mail" icloud-mail icloud
when:
- (vault_icloud_mail_password | default('')) | length > 0
- icloud_keyring_store.rc | default(1) != 0
- name: Clone st repository
tags: [packages]
ansible.builtin.git:
repo: https://codeberg.org/fscotto/st
dest: "{{ user_home }}/.local/src/st"
update: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
register: st_repo
- name: Check whether st binary is installed
tags: [packages]
ansible.builtin.stat:
path: /usr/local/bin/st
register: st_binary
- name: Build and install st
tags: [packages]
ansible.builtin.command:
cmd: make clean install
chdir: "{{ user_home }}/.local/src/st"
when: st_repo.changed or not st_binary.stat.exists
- name: Clean st build artifacts
tags: [packages]
ansible.builtin.command:
cmd: make clean
chdir: "{{ user_home }}/.local/src/st"
when: st_repo.changed or not st_binary.stat.exists
- name: Ensure flathub remote is configured
tags: [packages]
community.general.flatpak_remote:
name: "{{ desktop_flatpak_remote_name | default('flathub') }}"
state: present
flatpakrepo_url: "{{ desktop_flatpak_remote_url | default('https://dl.flathub.org/repo/flathub.flatpakrepo') }}"
when: (desktop_flatpak_packages | default([])) | length > 0
- name: Install desktop flatpak applications
tags: [packages]
community.general.flatpak:
name: "{{ desktop_flatpak_packages }}"
state: present
remote: "{{ desktop_flatpak_remote_name | default('flathub') }}"
method: system
when: (desktop_flatpak_packages | default([])) | length > 0
- name: Install Flatpak extensions
tags: [packages]
community.general.flatpak:
name: "{{ item }}"
state: present
remote: "{{ desktop_flatpak_remote_name | default('flathub') }}"
method: system
loop: "{{ desktop_flatpak_extensions | default([]) }}"
when:
- (desktop_flatpak_packages | default([])) | length > 0
- (desktop_flatpak_extensions | default([])) | length > 0
- item | length > 0
- name: Set desktop external tool release metadata
tags: [packages]
ansible.builtin.set_fact:
desktop_tools_tmp_dir: /tmp/desktop-tools
gitmux_version: v0.11.5
bw_version: 1.22.1
opencode_asset_name: >-
{{
'opencode-linux-x64-baseline.tar.gz' if ansible_facts['architecture'] == 'x86_64'
else 'opencode-linux-arm64.tar.gz' if ansible_facts['architecture'] in ['aarch64', 'arm64']
else ''
}}
gitmux_arch: >-
{{
'amd64' if ansible_facts['architecture'] == 'x86_64'
else 'arm64' if ansible_facts['architecture'] in ['aarch64', 'arm64']
else ''
}}
- name: Ensure architecture is supported for OpenCode binary
tags: [packages]
ansible.builtin.fail:
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for OpenCode release binary"
when: opencode_asset_name == ''
- name: Ensure architecture is supported for gitmux binary
tags: [packages]
ansible.builtin.fail:
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for gitmux release binary"
when: gitmux_arch == ''
- name: Ensure architecture is supported for bw binary
tags: [packages]
ansible.builtin.fail:
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for bw release binary"
when: ansible_facts['architecture'] != 'x86_64'
- name: Ensure temporary directory exists for external tools
tags: [packages]
ansible.builtin.file:
path: "{{ desktop_tools_tmp_dir }}"
state: directory
mode: "0755"
- name: Fetch latest OpenCode release metadata
tags: [packages]
ansible.builtin.uri:
url: https://api.github.com/repos/anomalyco/opencode/releases/latest
headers:
Accept: application/vnd.github+json
return_content: true
register: opencode_latest_release
changed_when: false
- name: Set OpenCode release asset metadata
tags: [packages]
ansible.builtin.set_fact:
opencode_version: "{{ opencode_latest_release.json.tag_name }}"
opencode_asset: >-
{{
opencode_latest_release.json.assets
| selectattr('name', 'equalto', opencode_asset_name)
| first
| default({})
}}
- name: Ensure latest OpenCode asset metadata is available
tags: [packages]
ansible.builtin.fail:
msg: "Could not find OpenCode asset {{ opencode_asset_name }} in release {{ opencode_version }}"
when: opencode_asset == {}
- name: Download OpenCode release archive
tags: [packages]
ansible.builtin.get_url:
url: "{{ opencode_asset.browser_download_url }}"
dest: "{{ desktop_tools_tmp_dir }}/{{ opencode_asset.name }}"
checksum: "{{ opencode_asset.digest | default(omit) }}"
mode: "0644"
- name: Extract OpenCode release archive
tags: [packages]
ansible.builtin.unarchive:
src: "{{ desktop_tools_tmp_dir }}/{{ opencode_asset.name }}"
dest: "{{ desktop_tools_tmp_dir }}"
remote_src: true
- name: Install OpenCode binary
tags: [packages]
ansible.builtin.copy:
src: "{{ desktop_tools_tmp_dir }}/opencode"
dest: /usr/local/bin/opencode
remote_src: true
owner: root
group: root
mode: "0755"
- name: Set gitmux asset metadata
tags: [packages]
ansible.builtin.set_fact:
gitmux_asset: "gitmux_{{ gitmux_version }}_linux_{{ gitmux_arch }}.tar.gz"
- name: Download gitmux release archive
tags: [packages]
ansible.builtin.get_url:
url: "https://github.com/arl/gitmux/releases/download/{{ gitmux_version }}/{{ gitmux_asset }}"
dest: "{{ desktop_tools_tmp_dir }}/{{ gitmux_asset }}"
checksum: "sha256:https://github.com/arl/gitmux/releases/download/{{ gitmux_version }}/checksums.txt"
mode: "0644"
- name: Extract gitmux release archive
tags: [packages]
ansible.builtin.unarchive:
src: "{{ desktop_tools_tmp_dir }}/{{ gitmux_asset }}"
dest: "{{ desktop_tools_tmp_dir }}"
remote_src: true
- name: Install gitmux binary
tags: [packages]
ansible.builtin.copy:
src: "{{ desktop_tools_tmp_dir }}/gitmux"
dest: /usr/local/bin/gitmux
remote_src: true
owner: root
group: root
mode: "0755"
- name: Set bw asset metadata
tags: [packages]
ansible.builtin.set_fact:
bw_asset: "bw-linux-{{ bw_version }}.zip"
- name: Download bw release archive
tags: [packages]
ansible.builtin.get_url:
url: "https://github.com/bitwarden/cli/releases/download/v{{ bw_version }}/{{ bw_asset }}"
dest: "{{ desktop_tools_tmp_dir }}/{{ bw_asset }}"
checksum: "sha256:https://github.com/bitwarden/cli/releases/download/v{{ bw_version }}/bw-linux-sha256-{{ bw_version }}.txt"
mode: "0644"
- name: Extract bw release archive
tags: [packages]
ansible.builtin.unarchive:
src: "{{ desktop_tools_tmp_dir }}/{{ bw_asset }}"
dest: "{{ desktop_tools_tmp_dir }}"
remote_src: true
- name: Install bw binary
tags: [packages]
ansible.builtin.copy:
src: "{{ desktop_tools_tmp_dir }}/bw"
dest: /usr/local/bin/bw
remote_src: true
owner: root
group: root
mode: "0755"

View File

@@ -0,0 +1,18 @@
TTY_NUMBER=7
SWITCH_TTY=true
DEFAULT_ENV={{ desktop_default_session_env | default('xorg') }}
{% if not (desktop_prompt_for_session | default(false)) and (desktop_default_session | default('')) | length > 0 %}
DEFAULT_SESSION={{ desktop_default_session | default('') }}
{% if (desktop_default_session_env | default('')) | length > 0 %}
DEFAULT_SESSION_ENV={{ desktop_default_session_env | default('') }}
{% endif %}
{% endif %}
DBUS_LAUNCH=false
XINITRC_LAUNCH=true
XORG_SESSIONS_PATH=/etc/emptty/xsessions
WAYLAND_SESSIONS_PATH=/etc/emptty/wayland-sessions
VERTICAL_SELECTION=true
IDENTIFY_ENVS=true
SELECT_LAST_USER=global
LOGGING=rotate
SESSION_ERROR_LOGGING={{ desktop_emptty_session_error_logging | default('disabled') }}

View File

@@ -0,0 +1,35 @@
---
- name: Include nymph desktop host tasks
tags: [packages, nvidia, dotfiles, dotfiles:host]
ansible.builtin.include_tasks: nymph.yml
when: hostname == 'nymph'
- name: Copy host-specific i3 dotfiles
tags: [dotfiles, dotfiles:desktop, dotfiles:host, i3]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/{{ hostname }}/{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ host_i3_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
when:
- "'i3' in (desktop_sessions_enabled | default([]))"
- (host_i3_dotfiles | default([])) | length > 0
- name: Copy host-specific Hyprland dotfiles
tags: [dotfiles, dotfiles:desktop, dotfiles:host, hyprland]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/{{ hostname }}/{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ host_hyprland_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
when:
- "'hyprland' in (desktop_sessions_enabled | default([]))"
- (host_hyprland_dotfiles | default([])) | length > 0

View File

@@ -0,0 +1,41 @@
---
- name: Configure GRUB kernel parameters for NVIDIA hybrid graphics
tags: [packages, nvidia]
ansible.builtin.lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX='
line: 'GRUB_CMDLINE_LINUX="rd.luks.uuid=1e15d159-5d05-4a1f-9639-ac200dff9f9c rootflags=subvol=@ apparmor=1 security=apparmor nouveau.modeset=0 nvidia-drm.modeset=1"'
state: present
- name: Regenerate GRUB configuration
tags: [packages, nvidia]
ansible.builtin.command: grub-mkconfig -o /boot/grub/grub.cfg
changed_when: true
- name: Configure NVIDIA power management for hybrid graphics
tags: [packages, nvidia]
ansible.builtin.copy:
dest: /etc/modprobe.d/nvidia-power-management.conf
content: |
options nvidia "NVreg_DynamicPowerManagement=0x02"
owner: root
group: root
mode: "0644"
- name: Install prime-run wrapper script for NVIDIA PRIME offload
tags: [nvidia, dotfiles, dotfiles:host]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/nymph/.local/bin/prime-run"
dest: "{{ user_home }}/.local/bin/prime-run"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
force: false
- name: Wrap alacritty with prime-run for NVIDIA PRIME offload
tags: [nvidia, dotfiles, dotfiles:desktop, dotfiles:host]
ansible.builtin.lineinfile:
path: "{{ user_home }}/.config/i3/config"
regexp: '^bindsym \$mod\+Return exec --no-startup-id /usr/bin/alacritty'
line: 'bindsym $mod+Return exec --no-startup-id ~/.local/bin/prime-run /usr/bin/alacritty'
when: "'i3' in (desktop_sessions_enabled | default([]))"

View File

@@ -0,0 +1,36 @@
---
- name: Ensure Hyprland 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/hypr"
- "{{ user_home }}/.config/waybar"
when: "'hyprland' in (desktop_sessions_enabled | default([]))"
- name: Install Hyprland emptty session entry
tags: [packages, services, emptty, hyprland]
ansible.builtin.template:
src: Hyprland.desktop.j2
dest: /etc/emptty/wayland-sessions/Hyprland.desktop
owner: root
group: root
mode: "0644"
when: "'hyprland' in (desktop_sessions_enabled | default([]))"
- name: Copy Hyprland desktop dotfiles
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 }}"
when: "'hyprland' in (desktop_sessions_enabled | default([]))"

View File

@@ -1,7 +1,7 @@
[Desktop Entry]
Name=Hyprland
Comment=Hyprland Wayland compositor
Exec=Hyprland
Exec={{ user_home }}/.local/bin/start-hyprland-session
TryExec=Hyprland
Type=Application
DesktopNames=Hyprland

View File

@@ -1,5 +0,0 @@
---
- name: Restart emptty
ansible.builtin.command: sv restart emptty
changed_when: true
when: not ansible_check_mode

View File

@@ -1,14 +1,6 @@
---
- name: Configure elogind to suspend on lid close
tags: [packages]
ansible.builtin.lineinfile:
path: /etc/elogind/logind.conf
regexp: '^#?HandleLidSwitch='
line: 'HandleLidSwitch=suspend'
state: present
- name: Ensure config directories exist
tags: [dotfiles, dotfiles:desktop]
- name: Ensure i3 config directories exist
tags: [dotfiles, dotfiles:desktop, i3]
ansible.builtin.file:
path: "{{ item }}"
state: directory
@@ -16,577 +8,29 @@
group: "{{ user_group }}"
mode: "0755"
loop:
- "{{ user_home }}/.config"
- "{{ user_home }}/.config/autostart"
- "{{ user_home }}/.config/i3"
- "{{ user_home }}/.config/i3blocks"
- "{{ user_home }}/.config/dunst"
- "{{ user_home }}/.config/alacritty"
- "{{ user_home }}/.config/Thunar"
- "{{ user_home }}/.config/rofi"
- name: Configure GRUB kernel parameters for NVIDIA hybrid graphics
tags: [packages, nvidia]
ansible.builtin.lineinfile:
path: /etc/default/grub
regexp: '^GRUB_CMDLINE_LINUX='
line: 'GRUB_CMDLINE_LINUX="rd.luks.uuid=1e15d159-5d05-4a1f-9639-ac200dff9f9c rootflags=subvol=@ apparmor=1 security=apparmor nouveau.modeset=0 nvidia-drm.modeset=1"'
state: present
when: ansible_facts['hostname'] == 'nymph'
- name: Regenerate GRUB configuration
tags: [packages, nvidia]
ansible.builtin.command: grub-mkconfig -o /boot/grub/grub.cfg
changed_when: true
when: ansible_facts['hostname'] == 'nymph'
- name: Configure NVIDIA power management for hybrid graphics
tags: [packages, nvidia]
ansible.builtin.copy:
dest: /etc/modprobe.d/nvidia-power-management.conf
content: |
options nvidia "NVreg_DynamicPowerManagement=0x02"
owner: root
group: root
mode: "0644"
when: ansible_facts['hostname'] == 'nymph'
- name: Ensure user local bin directory exists
tags: [nvidia, dotfiles, dotfiles:host]
ansible.builtin.file:
path: "{{ user_home }}/.local/bin"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
when: ansible_facts['hostname'] == 'nymph'
- name: Install prime-run wrapper script for NVIDIA PRIME offload
tags: [nvidia, dotfiles, dotfiles:host]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/nymph/.local/bin/prime-run"
dest: "{{ user_home }}/.local/bin/prime-run"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
force: false
when: ansible_facts['hostname'] == 'nymph'
- name: Enable gnome-keyring PAM auth hook
tags: [packages, gnome]
ansible.builtin.lineinfile:
path: /etc/pam.d/login
insertafter: '^auth\s+include\s+system-local-login$'
line: "auth optional pam_gnome_keyring.so"
state: present
- name: Enable gnome-keyring PAM session hook
tags: [packages, gnome]
ansible.builtin.lineinfile:
path: /etc/pam.d/login
insertafter: '^session\s+include\s+system-local-login$'
line: "session optional pam_gnome_keyring.so auto_start"
state: present
- name: Enable gnome-keyring PAM password hook
tags: [packages, gnome]
ansible.builtin.lineinfile:
path: /etc/pam.d/login
insertafter: '^password\s+include\s+system-local-login$'
line: "password optional pam_gnome_keyring.so use_authtok"
state: present
- name: Ensure emptty log directory exists
tags: [packages, services, emptty]
ansible.builtin.file:
path: /var/log/emptty
state: directory
owner: root
group: root
mode: "0755"
- name: Ensure emptty session directories exist
tags: [packages, services, emptty]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
loop:
- /etc/emptty/xsessions
- /etc/emptty/wayland-sessions
when: "'i3' in (desktop_sessions_enabled | default([]))"
- name: Install allowed emptty X11 sessions
tags: [packages, services, emptty]
tags: [packages, services, emptty, i3]
ansible.builtin.copy:
src: i3.desktop
dest: /etc/emptty/xsessions/i3.desktop
owner: root
group: root
mode: "0644"
when: "'i3' in (desktop_sessions_enabled | default([]))"
- name: Install host-specific Wayland sessions for emptty
tags: [packages, services, emptty, hyprland]
ansible.builtin.copy:
src: "{{ item }}"
dest: "/etc/emptty/wayland-sessions/{{ item }}"
owner: root
group: root
mode: "0644"
loop: "{{ host_emptty_wayland_sessions | default([]) }}"
loop_control:
label: "{{ item }}"
when: (host_emptty_wayland_sessions | default([])) | length > 0
- name: Configure emptty
tags: [packages, services, emptty]
ansible.builtin.template:
src: emptty-conf.j2
dest: /etc/emptty/conf
owner: root
group: root
mode: "0644"
notify: Restart emptty
- name: Copy desktop dotfiles
tags: [dotfiles, dotfiles:desktop]
- name: Copy i3 desktop dotfiles
tags: [dotfiles, dotfiles:desktop, i3]
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_dotfiles | default([]) }}"
loop: "{{ desktop_i3_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
- name: Wrap alacritty with prime-run for NVIDIA PRIME offload
tags: [nvidia, dotfiles, dotfiles:desktop, dotfiles:host]
ansible.builtin.lineinfile:
path: "{{ user_home }}/.config/i3/config"
regexp: '^bindsym \$mod\+Return exec --no-startup-id /usr/bin/alacritty'
line: 'bindsym $mod+Return exec --no-startup-id ~/.local/bin/prime-run /usr/bin/alacritty'
when: ansible_facts['hostname'] == 'nymph'
- name: Copy host-specific dotfiles
tags: [dotfiles, dotfiles:desktop, dotfiles:host]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/{{ hostname }}/{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ host_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
when: host_dotfiles is defined and host_dotfiles | length > 0
- name: Render desktop templates with private values
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop:
- src: desktop/.gitconfig.j2
dest: .gitconfig
mode: "0644"
- src: desktop/.mbsyncrc.j2
dest: .mbsyncrc
mode: "0600"
- src: desktop/.msmtprc.j2
dest: .msmtprc
mode: "0600"
- src: desktop/email.el.j2
dest: .emacs.d/lisp/misc/email.el
mode: "0644"
loop_control:
label: "{{ item.dest }}"
- name: Refresh user font cache
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.command: fc-cache -f
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
changed_when: false
- name: Ensure .gnupg directory exists
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ user_home }}/.gnupg"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0700"
- name: Copy gpg-agent.conf
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/desktop/.gnupg/gpg-agent.conf"
dest: "{{ user_home }}/.gnupg/gpg-agent.conf"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0600"
- name: Ensure local user directories exist
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop:
- path: "{{ user_home }}/.local"
mode: "0755"
- path: "{{ user_home }}/.local/share"
mode: "0755"
- path: "{{ user_home }}/.local/share/keyrings"
mode: "0700"
- path: "{{ user_home }}/.local/src"
mode: "0755"
- name: Ensure maildir directories exist
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0700"
loop:
- "{{ user_home }}/Maildir"
- "{{ user_home }}/Maildir/iCloudAccount"
- "{{ user_home }}/Maildir/ProtonMailAccount"
- name: Bootstrap iCloud keyring secret from Ansible vault
tags: [dotfiles, dotfiles:desktop, gnome]
when: desktop_manage_icloud_keyring | default(false)
block:
- name: Store iCloud mail password in GNOME Keyring
ansible.builtin.getent:
database: passwd
key: "{{ username }}"
- name: Set desktop user runtime UID
ansible.builtin.set_fact:
desktop_user_uid: "{{ ansible_facts.getent_passwd[username][1] }}"
- name: Check whether desktop user DBus session address file exists
ansible.builtin.stat:
path: "{{ user_home }}/.dbus-session-bus-address"
register: desktop_user_bus_address_file
- name: Read desktop user DBus session address
ansible.builtin.slurp:
src: "{{ user_home }}/.dbus-session-bus-address"
register: desktop_user_bus_address_raw
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address_file.stat.exists
- name: Set desktop user DBus session address
ansible.builtin.set_fact:
desktop_user_bus_address: >-
{{ desktop_user_bus_address_raw.content | b64decode | trim }}
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address_file.stat.exists
- name: Check whether GNOME Keyring default collection is available
ansible.builtin.command:
cmd: >-
gdbus call --session
--dest org.freedesktop.secrets
--object-path /org/freedesktop/secrets
--method org.freedesktop.Secret.Service.ReadAlias default
become: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
XDG_RUNTIME_DIR: "/run/user/{{ desktop_user_uid }}"
DBUS_SESSION_BUS_ADDRESS: "{{ desktop_user_bus_address }}"
register: icloud_keyring_default_alias
failed_when: false
changed_when: false
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address | default('') | length > 0
- name: Set GNOME Keyring default collection path
ansible.builtin.set_fact:
icloud_keyring_default_alias_path: >-
{{
(
icloud_keyring_default_alias.stdout
| default('')
| regex_findall("objectpath '([^']+)'")
| first
)
| default('')
}}
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address | default('') | length > 0
- icloud_keyring_default_alias.rc | default(1) == 0
- name: Store iCloud mail password in GNOME Keyring
ansible.builtin.command:
cmd: secret-tool store --label="iCloud Mail" icloud-mail icloud
stdin: "{{ vault_icloud_mail_password }}"
stdin_add_newline: false
become: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
XDG_RUNTIME_DIR: "/run/user/{{ desktop_user_uid }}"
DBUS_SESSION_BUS_ADDRESS: "{{ desktop_user_bus_address }}"
register: icloud_keyring_store
failed_when: false
changed_when: icloud_keyring_store.rc == 0
no_log: true
when:
- (vault_icloud_mail_password | default('')) | length > 0
- desktop_user_bus_address | default('') | length > 0
- icloud_keyring_default_alias.rc | default(1) == 0
- (icloud_keyring_default_alias_path | default('')) | length > 0
- (icloud_keyring_default_alias_path | default('')) != '/'
- name: Warn when iCloud keyring storage is skipped
ansible.builtin.debug:
msg: >-
Unable to store iCloud password in GNOME Keyring automatically.
{% if (desktop_user_bus_address | default('')) | length == 0 %}
No saved DBus session address was found in {{ user_home }}/.dbus-session-bus-address.
{% elif icloud_keyring_default_alias.rc | default(1) != 0 %}
The Secret Service default alias could not be queried for {{ username }}.
{% elif (icloud_keyring_default_alias_path | default('')) == '/' %}
The Secret Service default alias is unset, so the login keyring is not initialized.
{% endif %}
Ensure a graphical user session is active, the login keyring exists and is unlocked, then run:
secret-tool store --label="iCloud Mail" icloud-mail icloud
when:
- (vault_icloud_mail_password | default('')) | length > 0
- icloud_keyring_store.rc | default(1) != 0
- name: Clone st repository
tags: [packages]
ansible.builtin.git:
repo: https://codeberg.org/fscotto/st
dest: "{{ user_home }}/.local/src/st"
update: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
register: st_repo
- name: Check whether st binary is installed
tags: [packages]
ansible.builtin.stat:
path: /usr/local/bin/st
register: st_binary
- name: Build and install st
tags: [packages]
ansible.builtin.command:
cmd: make clean install
chdir: "{{ user_home }}/.local/src/st"
when: st_repo.changed or not st_binary.stat.exists
- name: Clean st build artifacts
tags: [packages]
ansible.builtin.command:
cmd: make clean
chdir: "{{ user_home }}/.local/src/st"
when: st_repo.changed or not st_binary.stat.exists
- name: Ensure flathub remote is configured
tags: [packages]
community.general.flatpak_remote:
name: "{{ desktop_flatpak_remote_name | default('flathub') }}"
state: present
flatpakrepo_url: "{{ desktop_flatpak_remote_url | default('https://dl.flathub.org/repo/flathub.flatpakrepo') }}"
when: (desktop_flatpak_packages | default([])) | length > 0
- name: Install desktop flatpak applications
tags: [packages]
community.general.flatpak:
name: "{{ desktop_flatpak_packages }}"
state: present
remote: "{{ desktop_flatpak_remote_name | default('flathub') }}"
method: system
when: (desktop_flatpak_packages | default([])) | length > 0
- name: Install Flatpak extensions
tags: [packages]
community.general.flatpak:
name: "{{ item }}"
state: present
remote: "{{ desktop_flatpak_remote_name | default('flathub') }}"
method: system
loop: "{{ desktop_flatpak_extensions | default([]) }}"
when:
- (desktop_flatpak_packages | default([])) | length > 0
- (desktop_flatpak_extensions | default([])) | length > 0
- item | length > 0
- name: Set desktop external tool release metadata
tags: [packages]
ansible.builtin.set_fact:
desktop_tools_tmp_dir: /tmp/desktop-tools
gitmux_version: v0.11.5
bw_version: 1.22.1
opencode_asset_name: >-
{{
'opencode-linux-x64-baseline.tar.gz' if ansible_facts['architecture'] == 'x86_64'
else 'opencode-linux-arm64.tar.gz' if ansible_facts['architecture'] in ['aarch64', 'arm64']
else ''
}}
gitmux_arch: >-
{{
'amd64' if ansible_facts['architecture'] == 'x86_64'
else 'arm64' if ansible_facts['architecture'] in ['aarch64', 'arm64']
else ''
}}
- name: Ensure architecture is supported for OpenCode binary
tags: [packages]
ansible.builtin.fail:
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for OpenCode release binary"
when: opencode_asset_name == ''
- name: Ensure architecture is supported for gitmux binary
tags: [packages]
ansible.builtin.fail:
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for gitmux release binary"
when: gitmux_arch == ''
- name: Ensure architecture is supported for bw binary
tags: [packages]
ansible.builtin.fail:
msg: "Unsupported architecture {{ ansible_facts['architecture'] }} for bw release binary"
when: ansible_facts['architecture'] != 'x86_64'
- name: Ensure temporary directory exists for external tools
tags: [packages]
ansible.builtin.file:
path: "{{ desktop_tools_tmp_dir }}"
state: directory
mode: "0755"
- name: Fetch latest OpenCode release metadata
tags: [packages]
ansible.builtin.uri:
url: https://api.github.com/repos/anomalyco/opencode/releases/latest
headers:
Accept: application/vnd.github+json
return_content: true
register: opencode_latest_release
changed_when: false
- name: Set OpenCode release asset metadata
tags: [packages]
ansible.builtin.set_fact:
opencode_version: "{{ opencode_latest_release.json.tag_name }}"
opencode_asset: >-
{{
opencode_latest_release.json.assets
| selectattr('name', 'equalto', opencode_asset_name)
| first
| default({})
}}
- name: Ensure latest OpenCode asset metadata is available
tags: [packages]
ansible.builtin.fail:
msg: "Could not find OpenCode asset {{ opencode_asset_name }} in release {{ opencode_version }}"
when: opencode_asset == {}
- name: Download OpenCode release archive
tags: [packages]
ansible.builtin.get_url:
url: "{{ opencode_asset.browser_download_url }}"
dest: "{{ desktop_tools_tmp_dir }}/{{ opencode_asset.name }}"
checksum: "{{ opencode_asset.digest | default(omit) }}"
mode: "0644"
- name: Extract OpenCode release archive
tags: [packages]
ansible.builtin.unarchive:
src: "{{ desktop_tools_tmp_dir }}/{{ opencode_asset.name }}"
dest: "{{ desktop_tools_tmp_dir }}"
remote_src: true
- name: Install OpenCode binary
tags: [packages]
ansible.builtin.copy:
src: "{{ desktop_tools_tmp_dir }}/opencode"
dest: /usr/local/bin/opencode
remote_src: true
owner: root
group: root
mode: "0755"
- name: Set gitmux asset metadata
tags: [packages]
ansible.builtin.set_fact:
gitmux_asset: "gitmux_{{ gitmux_version }}_linux_{{ gitmux_arch }}.tar.gz"
- name: Download gitmux release archive
tags: [packages]
ansible.builtin.get_url:
url: "https://github.com/arl/gitmux/releases/download/{{ gitmux_version }}/{{ gitmux_asset }}"
dest: "{{ desktop_tools_tmp_dir }}/{{ gitmux_asset }}"
checksum: "sha256:https://github.com/arl/gitmux/releases/download/{{ gitmux_version }}/checksums.txt"
mode: "0644"
- name: Extract gitmux release archive
tags: [packages]
ansible.builtin.unarchive:
src: "{{ desktop_tools_tmp_dir }}/{{ gitmux_asset }}"
dest: "{{ desktop_tools_tmp_dir }}"
remote_src: true
- name: Install gitmux binary
tags: [packages]
ansible.builtin.copy:
src: "{{ desktop_tools_tmp_dir }}/gitmux"
dest: /usr/local/bin/gitmux
remote_src: true
owner: root
group: root
mode: "0755"
- name: Set bw asset metadata
tags: [packages]
ansible.builtin.set_fact:
bw_asset: "bw-linux-{{ bw_version }}.zip"
- name: Download bw release archive
tags: [packages]
ansible.builtin.get_url:
url: "https://github.com/bitwarden/cli/releases/download/v{{ bw_version }}/{{ bw_asset }}"
dest: "{{ desktop_tools_tmp_dir }}/{{ bw_asset }}"
checksum: "sha256:https://github.com/bitwarden/cli/releases/download/v{{ bw_version }}/bw-linux-sha256-{{ bw_version }}.txt"
mode: "0644"
- name: Extract bw release archive
tags: [packages]
ansible.builtin.unarchive:
src: "{{ desktop_tools_tmp_dir }}/{{ bw_asset }}"
dest: "{{ desktop_tools_tmp_dir }}"
remote_src: true
- name: Install bw binary
tags: [packages]
ansible.builtin.copy:
src: "{{ desktop_tools_tmp_dir }}/bw"
dest: /usr/local/bin/bw
remote_src: true
owner: root
group: root
mode: "0755"
when: "'i3' in (desktop_sessions_enabled | default([]))"

View File

@@ -1,12 +0,0 @@
TTY_NUMBER=7
SWITCH_TTY=true
DEFAULT_ENV=xorg
DBUS_LAUNCH=false
XINITRC_LAUNCH=true
XORG_SESSIONS_PATH=/etc/emptty/xsessions
WAYLAND_SESSIONS_PATH=/etc/emptty/wayland-sessions
VERTICAL_SELECTION=true
IDENTIFY_ENVS=true
SELECT_LAST_USER=global
LOGGING=rotate
SESSION_ERROR_LOGGING=disabled

View File

@@ -17,7 +17,10 @@
roles:
- packages_void
- services_runit
- profile_desktop_common
- profile_desktop_i3
- profile_desktop_hyprland
- profile_desktop_host
- hosts: ubuntu_workstation
become: true