Merge branch 'migrate-to-mint-bsd'

This commit is contained in:
Fabio Scotto di Santolo
2026-07-17 17:43:45 +02:00
51 changed files with 1457 additions and 354 deletions

View File

@@ -0,0 +1,34 @@
---
# Optional inventory overlay for VM tests. It is not loaded by ansible.cfg.
all:
children:
platform_mint:
hosts:
minttest:
ansible_connection: local
platform_freebsd:
hosts:
freebsdtest:
ansible_connection: local
graphical_desktop:
hosts:
minttest:
freebsdtest:
role_personal_workstation:
hosts:
minttest:
role_lab:
hosts:
freebsdtest:
desktop_cinnamon:
hosts:
minttest:
desktop_hyprland:
hosts:
freebsdtest:

View File

@@ -7,6 +7,7 @@ user_shell: /bin/bash
effective_username: "{{ username }}"
effective_user_group: "{{ user_group }}"
effective_user_home: "{{ user_home }}"
emacs_enabled: false
xdg_user_directories:
- Desktop

View File

@@ -1,6 +1,4 @@
---
desktop_protonmail_bridge_cert_path: ~/.var/app/ch.protonmail.protonmail-bridge/config/protonmail/bridge-v3/cert.pem
desktop_environment: minimal
desktop_allow_display_manager_switch: false
@@ -96,10 +94,6 @@ desktop_common_dotfiles:
src: .bashrc.d/20-editor-desktop.sh
dest: .bashrc.d/20-editor-desktop.sh
mode: "0644"
- name: Bash Emacs client fragment
src: .bashrc.d/25-emacs-client-desktop.sh
dest: .bashrc.d/25-emacs-client-desktop.sh
mode: "0644"
- name: Bash VM helper fragment
src: .bashrc.d/30-runvm.sh
dest: .bashrc.d/30-runvm.sh
@@ -172,6 +166,10 @@ desktop_minimal_managed_paths:
- .local/bin/udiskie-password
desktop_emacs_dotfiles:
- name: Bash Emacs client fragment
src: .bashrc.d/25-emacs-client-desktop.sh
dest: .bashrc.d/25-emacs-client-desktop.sh
mode: "0644"
- name: Emacs config
src: .emacs.d/
dest: .emacs.d/
@@ -241,6 +239,28 @@ desktop_hyprland_dotfiles:
dest: .config/foot/
mode: preserve
desktop_niri_dotfiles:
- name: foot config
src: .config/foot/
dest: .config/foot/
mode: preserve
- name: dunst config
src: .config/dunst/
dest: .config/dunst/
mode: preserve
- name: rofi config
src: .config/rofi/
dest: .config/rofi/
mode: preserve
- name: waybar config
src: .config/waybar/
dest: .config/waybar/
mode: preserve
- name: niri config
src: .config/niri/
dest: .config/niri/
mode: preserve
desktop_xfce_dotfiles:
- name: XFCE configuration
src: .config/xfce4/

View File

@@ -0,0 +1,29 @@
---
desktop_profile: cinnamon
desktop_default_session: cinnamon
cinnamon_theme_gtk: Mint-Y-Dark-Aqua
cinnamon_theme_icons: Mint-Y-Aqua
cinnamon_font_ui: Sans 10
cinnamon_font_monospace: Monospace 10
# WM-agnostic desktop dotfiles from desktop_common_dotfiles that do NOT apply to
# Cinnamon: the autostart entry is the (removed) Protonmail mail bridge, and the
# GTK theme script conflicts with Cinnamon's own dconf-managed theming.
cinnamon_desktop_dotfiles_exclude:
- XDG autostart entries
- GTK theme setup script
cinnamon_dconf_settings:
- key: /org/cinnamon/desktop/interface/gtk-theme
value: "'{{ cinnamon_theme_gtk }}'"
- key: /org/cinnamon/desktop/interface/icon-theme
value: "'{{ cinnamon_theme_icons }}'"
- key: /org/cinnamon/desktop/interface/font-name
value: "'{{ cinnamon_font_ui }}'"
- key: /org/cinnamon/desktop/interface/monospace-font-name
value: "'{{ cinnamon_font_monospace }}'"
- key: /org/cinnamon/desktop/interface/clock-use-24h
value: "true"
- key: /org/cinnamon/desktop/wm/preferences/button-layout
value: "'menu:minimize,maximize,close'"

View File

@@ -0,0 +1,3 @@
---
desktop_profile: hyprland
desktop_default_session: hyprland

View File

@@ -0,0 +1,5 @@
---
desktop_profile: niri
desktop_sessions_enabled:
- niri
desktop_default_session: niri

View File

@@ -0,0 +1,2 @@
---
desktop_profile: sway

View File

@@ -0,0 +1,3 @@
---
host_capabilities:
- graphical_desktop

View File

@@ -0,0 +1,108 @@
---
platform_profile: freebsd
platform_family: freebsd
platform_package_manager: pkg
platform_service_manager: rc
ansible_python_interpreter: /usr/local/bin/python3
effective_user_group: "{{ user_group }}"
effective_user_home: "/home/{{ effective_username }}"
user_home: "/home/{{ username }}"
freebsd_packages_base:
- bash
- bash-completion
- bat
- curl
- fzf
- git
- jq
- python3
- ripgrep
- rsync
- tmux
- tree
- unzip
- vim
- wget
- zip
- zoxide
freebsd_development_packages:
- clang
- cmake
- gdb
- go
- gmake
- node
- npm
- pkgconf
- py311-pip
- rust
- shellcheck
freebsd_desktop_common_packages:
- dbus
- dconf
- firefox
- fontconfig
- gnome-keyring
- libsecret
- mpv
- pinentry-gnome
- pipewire
- polkit
- thunderbird
- wireplumber
- xdg-desktop-portal
freebsd_hyprland_packages:
- alacritty
- cliphist
- dunst
- foot
- grim
- hypridle
- hyprland
- hyprlock
- hyprpaper
- rofi-wayland
- seatd
- slurp
- waybar
- wl-clipboard
- xdg-desktop-portal-gtk
- xdg-desktop-portal-hyprland
- xwayland
freebsd_niri_packages:
- cliphist
- dunst
- foot
- grim
- niri
- rofi-wayland
- seatd
- slurp
- waybar
- wl-clipboard
- xdg-desktop-portal-gtk
freebsd_lab_packages:
- lldb
- llvm
- podman
- qemu
- smartmontools
freebsd_rc_conf:
- name: dbus_enable
value: "YES"
- name: seatd_enable
value: "YES"
freebsd_enabled_services:
- dbus
- seatd
freebsd_xdg_config_dir: /usr/local/etc/xdg

View File

@@ -0,0 +1,100 @@
---
platform_profile: mint
platform_family: debian
platform_package_manager: apt
platform_service_manager: systemd
# syncthing runs per-user via the packaged system unit template
# (Debian/Mint ship syncthing@.service, parametrised by username).
enabled_services:
- "syncthing@{{ username }}.service"
mint_manage_flatpak: true
mint_flatpak_remote_name: flathub
mint_flatpak_remote_url: https://dl.flathub.org/repo/flathub.flatpakrepo
mint_packages_base:
- ca-certificates
- curl
- flatpak
- gpg
- htop
- make
- python3-pip
- ripgrep
- rsync
- shellcheck
mint_development_packages:
- build-essential
- clang
- clang-tools
- cmake
- gdb
- golang
- nodejs
- npm
- pkg-config
- python3-venv
mint_desktop_common_packages:
- dconf-cli
- deja-dup
- firefox
- fonts-liberation
- fonts-noto-color-emoji
- git-delta
- gnome-keyring
- libsecret-tools
- mpv
- pinentry-gnome3
- pinentry-gtk2
- rclone
- syncthing
- thunderbird
- tmux
- xdg-user-dirs
- yt-dlp
mint_emacs_packages:
- autoconf
- automake
- emacs
- hunspell
- hunspell-it
- libfreetype-dev
- libpoppler-glib-dev
- libpoppler-private-dev
- libtool-bin
- libvterm-dev
- libx11-dev
mint_cinnamon_packages:
- cinnamon
- cinnamon-control-center
- cinnamon-screensaver
- lightdm
- slick-greeter
- xdg-desktop-portal
- xdg-desktop-portal-gtk
mint_personal_workstation_packages:
- libreoffice
- meld
- pdfarranger
- vim
mint_flatpak_packages:
- ch.protonmail.protonmail-bridge
- com.calibre_ebook.calibre
- com.spotify.Client
- org.telegram.desktop
# Nerd Fonts referenced by the desktop configs deployed on Mint. Debian has no
# equivalent of Void's nerd-fonts-ttf package, so they are fetched from the
# upstream ryanoasis/nerd-fonts release.
mint_nerd_fonts_version: v3.3.0
mint_nerd_fonts:
- Hack
- UbuntuSans
- NerdFontsSymbolsOnly

View File

@@ -0,0 +1,5 @@
---
platform_profile: void
platform_family: void
platform_package_manager: xbps
platform_service_manager: runit

View File

@@ -0,0 +1,11 @@
---
machine_role: lab
role_profile: lab
role_stability: experimental
experimental_profile: true
lab_workspace_directories:
- path: "{{ user_home }}/Lab"
mode: "0755"
- path: "{{ user_home }}/Scratch"
mode: "0755"

View File

@@ -0,0 +1,24 @@
---
machine_role: personal_workstation
role_profile: personal_workstation
role_stability: stable
personal_workstation_directories:
- path: "{{ user_home }}/Documents"
mode: "0755"
- path: "{{ user_home }}/Downloads"
mode: "0755"
- path: "{{ user_home }}/Org"
mode: "0755"
- path: "{{ user_home }}/Remotes"
mode: "0755"
personal_workstation_dotfiles:
- src: .gitignore_global
dest: .gitignore_global
mode: "0644"
- src: .themes.gitignore
dest: .themes.gitignore
mode: "0644"
personal_workstation_flatpak_packages: []

View File

@@ -23,7 +23,6 @@ void_packages_base:
- go
- hugo
- ImageMagick
- isync
- libtool
- linux
- linux-headers
@@ -33,8 +32,6 @@ void_packages_base:
- lm_sensors
- man-pages-devel
- man-pages-posix
- msmtp
- mu4e
- nodejs
- ntfs-3g
- pipewire
@@ -103,13 +100,15 @@ desktop_common_packages:
- cups-pk-helper
- flatpak
- libsecret
- pinentry-emacs
- sane
- sane-airscan
- turnstile
- xdg-desktop-portal
- xdg-user-dirs
desktop_emacs_packages:
- pinentry-emacs
desktop_minimal_packages:
- alacritty
- blueman
@@ -222,6 +221,28 @@ desktop_hyprland_packages:
- xdg-desktop-portal-hyprland
- xorg-server-xwayland
desktop_niri_packages:
- cliphist
- dunst
- foot
- foot-terminfo
- gtklock
- grim
- niri
- rofi
- slurp
- SwayOSD
- Waybar
- wl-clipboard
- xdg-desktop-portal-gtk
- xorg-server-xwayland
void_lab_packages:
- llvm
- podman
- qemu
- smartmontools
profile_packages:
- bash-language-server
- bluez
@@ -231,7 +252,6 @@ profile_packages:
- deluge-gtk
- delve
- dnsmasq
- emacs-pgtk
- poppler-glib
- poppler-utils
- fontconfig-devel
@@ -273,3 +293,6 @@ profile_packages:
- yaru
- yaru-plus
- zstd
profile_emacs_packages:
- emacs-pgtk

View File

@@ -1,20 +1,11 @@
---
hostname: ikaros
desktop_sessions_enabled:
- sway
- hyprland
desktop_default_session: hyprland
desktop_default_session_env: wayland
host_packages:
- openssh
- mesa-dri
- vulkan-loader
- mesa-vulkan-radeon
- mesa-vaapi
- xf86-video-amdgpu
- openssh-client
- openssh-server
- mesa-vulkan-drivers
- xserver-xorg-video-amdgpu
host_ufw_rules:
- rule: allow
@@ -34,4 +25,4 @@ host_sshd_allow_users:
host_authorized_ssh_keys: "{{ vault_ikaros_authorized_ssh_keys | default([]) }}"
host_enabled_services:
- sshd
- ssh

View File

@@ -1,50 +1,7 @@
---
hostname: nymph
desktop_sessions_enabled:
- sway
- hyprland
desktop_default_session: hyprland
desktop_default_session_env: wayland
desktop_emptty_session_error_logging: rotate
host_packages:
- nvidia580
- linux-mainline-headers
- mesa-dri
- vulkan-loader
- mesa-vulkan-intel
- intel-video-accel
- power-profiles-daemon
- tlp
- tlp-rdw
- upower
host_enabled_services:
- tlp
host_sway_dotfiles:
- src: .config/sway/host.conf
dest: .config/sway/host.conf
mode: "0644"
- src: .config/sway/session-env
dest: .config/sway/session-env
mode: "0644"
- src: .config/kanshi/
dest: .config/kanshi/
mode: preserve
- src: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf
dest: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf
mode: "0644"
host_hyprland_dotfiles:
- src: .config/hypr/host.conf
dest: .config/hypr/host.conf
mode: "0644"
- src: .config/hypr/session-env
dest: .config/hypr/session-env
mode: "0644"
- src: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf
dest: .config/wireplumber/wireplumber.conf.d/60-camera-priority.conf
mode: "0644"
# Void Linux/Niri laptop target. Keep host-specific packages empty until hardware
# support is verified on the installed system.
host_packages: []
host_enabled_services: []

View File

@@ -1,7 +1,24 @@
---
all:
children:
platform_void:
hosts:
nymph:
ansible_connection: local
platform_mint:
hosts:
ikaros:
ansible_connection: local
platform_freebsd:
hosts: {}
void:
children:
platform_void:
graphical_desktop:
hosts:
ikaros:
ansible_connection: local
@@ -9,12 +26,35 @@ all:
ansible_connection: local
desktop:
children:
graphical_desktop:
role_personal_workstation:
hosts:
ikaros:
ansible_connection: local
role_lab:
hosts:
nymph:
ansible_connection: local
desktop_sway:
hosts: {}
desktop_hyprland:
hosts: {}
desktop_niri:
hosts:
nymph:
ansible_connection: local
desktop_cinnamon:
hosts:
ikaros:
ansible_connection: local
ubuntu:
children:
workstation_dev_wsl:

View File

@@ -0,0 +1,34 @@
---
- name: Install packages on FreeBSD
tags: [packages]
community.general.pkgng:
name: >-
{{
(
(freebsd_packages_base | default([]))
+ (freebsd_development_packages | default([]))
+ (
(freebsd_desktop_common_packages | default([]))
if 'graphical_desktop' in group_names
else []
)
+ (
(freebsd_hyprland_packages | default([]))
if 'desktop_hyprland' in group_names
else []
)
+ (
(freebsd_niri_packages | default([]))
if 'desktop_niri' in group_names
else []
)
+ (
(freebsd_lab_packages | default([]))
if 'role_lab' in group_names
else []
)
+ (host_packages | default([]))
)
| unique
}}
state: present

View File

@@ -0,0 +1,88 @@
---
- name: Refresh apt package cache on Linux Mint
tags: [packages]
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Install packages on Linux Mint
tags: [packages]
ansible.builtin.apt:
name: >-
{{
(
(common_packages | default([]))
+ (mint_packages_base | default([]))
+ (mint_development_packages | default([]))
+ (
(mint_desktop_common_packages | default([]))
if 'graphical_desktop' in group_names
else []
)
+ (
(mint_emacs_packages | default([]))
if (
'graphical_desktop' in group_names
and (emacs_enabled | default(false) | bool)
)
else []
)
+ (
(mint_cinnamon_packages | default([]))
if 'desktop_cinnamon' in group_names
else []
)
+ (
(mint_personal_workstation_packages | default([]))
if 'role_personal_workstation' in group_names
else []
)
+ (host_packages | default([]))
)
| unique
}}
state: present
- name: Ensure Flathub remote is configured on Linux Mint
tags: [packages]
community.general.flatpak_remote:
name: "{{ mint_flatpak_remote_name | default('flathub') }}"
state: present
flatpakrepo_url: "{{ mint_flatpak_remote_url | default('https://dl.flathub.org/repo/flathub.flatpakrepo') }}"
when:
- mint_manage_flatpak | default(true)
- >-
(
(mint_flatpak_packages | default([]))
+ (personal_workstation_flatpak_packages | default([]))
) | length > 0
- name: Install Linux Mint Flatpak applications
tags: [packages]
community.general.flatpak:
name: >-
{{
(
(mint_flatpak_packages | default([]))
+ (
(personal_workstation_flatpak_packages | default([]))
if 'role_personal_workstation' in group_names
else []
)
)
| unique
}}
state: present
remote: "{{ mint_flatpak_remote_name | default('flathub') }}"
method: system
when:
- mint_manage_flatpak | default(true)
- >-
(
(mint_flatpak_packages | default([]))
+ (
(personal_workstation_flatpak_packages | default([]))
if 'role_personal_workstation' in group_names
else []
)
) | length > 0

View File

@@ -76,6 +76,14 @@
)
else []
)
+ (
(desktop_niri_packages | default([]))
if (
(desktop_environment | default('minimal')) == 'minimal'
and 'niri' in (desktop_sessions_enabled | default([]))
)
else []
)
| unique
}}
@@ -88,6 +96,7 @@
(desktop_minimal_packages | default([]))
+ (desktop_sway_packages | default([]))
+ (desktop_hyprland_packages | default([]))
+ (desktop_niri_packages | default([]))
+ (desktop_xfce_packages | default([]))
+ (desktop_kde_packages | default([]))
)
@@ -105,8 +114,11 @@
(common_packages | default([]))
+ (void_packages_base | default([]))
+ (profile_packages | default([]))
+ ((profile_emacs_packages | default([])) if (emacs_enabled | default(false) | bool) else [])
+ (desktop_common_packages | default([]))
+ ((desktop_emacs_packages | default([])) if (emacs_enabled | default(false) | bool) else [])
+ (packages_void_selected_desktop_packages | default([]))
+ ((void_lab_packages | default([])) if 'role_lab' in group_names else [])
+ (host_packages | default([]))
)
| unique

View File

@@ -0,0 +1,229 @@
---
- name: Ensure Cinnamon user config directories exist
tags: [dotfiles, dotfiles:desktop, cinnamon]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
loop:
- "{{ user_home }}/.config"
- "{{ user_home }}/.local"
- "{{ user_home }}/.local/share"
- "{{ user_home }}/.local/bin"
- "{{ user_home }}/.local/state"
- "{{ user_home }}/.bashrc.d"
- "{{ user_home }}/.tmux"
- "{{ user_home }}/.tmux/bin"
- "{{ user_home }}/.tmux/plugins"
- name: Apply Cinnamon dconf settings
tags: [cinnamon]
community.general.dconf:
key: "{{ item.key }}"
value: "{{ item.value }}"
state: present
become: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
loop: "{{ cinnamon_dconf_settings | default([]) }}"
loop_control:
label: "{{ item.key }}"
- name: Ensure Emacs config directory exists
tags: [dotfiles, dotfiles:desktop, emacs]
ansible.builtin.file:
path: "{{ user_home }}/.emacs.d"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
when: emacs_enabled | default(false) | bool
- name: Ensure GnuPG directory exists
tags: [dotfiles, dotfiles:desktop, git]
ansible.builtin.file:
path: "{{ user_home }}/.gnupg"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0700"
- name: Ensure private user directories exist
tags: [dotfiles, dotfiles:desktop]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0700"
loop:
- "{{ user_home }}/.ssh"
- "{{ user_home }}/.local/state/ssh/sockets"
- name: Copy Emacs desktop dotfiles
tags: [dotfiles, dotfiles:desktop, emacs]
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_emacs_dotfiles | default([]) }}"
when: emacs_enabled | default(false) | bool
loop_control:
label: "{{ item.dest }}"
- name: Copy WM-agnostic 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([])
| rejectattr('name', 'in', cinnamon_desktop_dotfiles_exclude | default([]))
| list
}}
loop_control:
label: "{{ item.dest }}"
- name: Copy gpg-agent configuration
tags: [dotfiles, dotfiles:desktop, git]
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: Render git configuration with private values
tags: [dotfiles, dotfiles:desktop, git]
ansible.builtin.template:
src: desktop/.gitconfig.j2
dest: "{{ user_home }}/.gitconfig"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0644"
- name: Bootstrap tmux plugin manager checkout
tags: [dotfiles, dotfiles:desktop, tmux]
ansible.builtin.git:
repo: https://github.com/tmux-plugins/tpm
dest: "{{ user_home }}/.tmux/plugins/tpm"
version: master
update: true
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
- name: Install tmux plugins through TPM
tags: [dotfiles, dotfiles:desktop, tmux]
ansible.builtin.command:
cmd: "{{ user_home }}/.tmux/plugins/tpm/bin/install_plugins"
become_user: "{{ username }}"
environment:
HOME: "{{ user_home }}"
register: cinnamon_tmux_plugin_install
changed_when: >-
(cinnamon_tmux_plugin_install.stdout | default('')) is search('download success') or
(cinnamon_tmux_plugin_install.stderr | default('')) is search('download success')
- name: Install desktop npm packages
tags: [packages, npm]
community.general.npm:
name: "{{ item.name }}"
global: true
state: "{{ item.state | default('present') }}"
become: true
loop: "{{ desktop_npm_packages | default([]) }}"
when: desktop_npm_packages | length > 0
loop_control:
label: "{{ item.name }}"
- name: Ensure /usr/src is writable for source builds
tags: [packages]
ansible.builtin.file:
path: /usr/src
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
- name: Build and install the gf debugger frontend from source
tags: [packages]
ansible.builtin.include_tasks:
file: "{{ role_path }}/../profile_desktop_common/tasks/source_tool.yml"
apply:
tags: [packages]
loop: >-
{{
desktop_source_tools
| default([])
| selectattr('name', 'equalto', 'gf')
| list
}}
loop_control:
loop_var: source_tool
label: "{{ source_tool.name }}"
- name: Ensure Nerd Fonts base directory exists
tags: [packages, fonts]
ansible.builtin.file:
path: /usr/local/share/fonts/nerd-fonts
state: directory
owner: root
group: root
mode: "0755"
become: true
- name: Ensure per-font Nerd Fonts directories exist
tags: [packages, fonts]
ansible.builtin.file:
path: "/usr/local/share/fonts/nerd-fonts/{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
become: true
loop: "{{ mint_nerd_fonts | default([]) }}"
- name: Download Nerd Font archives
tags: [packages, fonts]
ansible.builtin.get_url:
url: "https://github.com/ryanoasis/nerd-fonts/releases/download/{{ mint_nerd_fonts_version }}/{{ item }}.zip"
dest: "/usr/local/share/fonts/nerd-fonts/{{ item }}.zip"
owner: root
group: root
mode: "0644"
become: true
loop: "{{ mint_nerd_fonts | default([]) }}"
loop_control:
label: "{{ item }}"
- name: Extract Nerd Font archives
tags: [packages, fonts]
ansible.builtin.unarchive:
src: "/usr/local/share/fonts/nerd-fonts/{{ item }}.zip"
dest: "/usr/local/share/fonts/nerd-fonts/{{ item }}"
remote_src: true
owner: root
group: root
become: true
loop: "{{ mint_nerd_fonts | default([]) }}"
loop_control:
label: "{{ item }}"
register: cinnamon_nerd_fonts_extract
- name: Refresh system font cache after installing Nerd Fonts
tags: [packages, fonts]
ansible.builtin.command: fc-cache -f
become: true
changed_when: false
when: cinnamon_nerd_fonts_extract is changed

View File

@@ -9,7 +9,7 @@
or (desktop_sessions_enabled | default([]) | length > 0)
- >-
(desktop_environment | default('minimal')) != 'minimal'
or (desktop_sessions_enabled | default([]) | difference(['sway', 'hyprland']) | length == 0)
or (desktop_sessions_enabled | default([]) | difference(['sway', 'hyprland', 'niri']) | length == 0)
- >-
(desktop_environment | default('minimal')) != 'minimal'
or desktop_default_session in (desktop_sessions_enabled | default([]))
@@ -315,32 +315,18 @@
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ desktop_emacs_dotfiles | default([]) }}"
when: emacs_enabled | default(false) | bool
loop_control:
label: "{{ item.dest }}"
- name: Render desktop templates with private values
tags: [dotfiles, dotfiles:desktop]
- name: Render git configuration with private values
tags: [dotfiles, dotfiles:desktop, git]
ansible.builtin.template:
src: "{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
src: desktop/.gitconfig.j2
dest: "{{ user_home }}/.gitconfig"
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 }}"
mode: "0644"
- name: Define managed tmux plugin directories
tags: [dotfiles, dotfiles:desktop, tmux]
@@ -451,19 +437,6 @@
- path: /usr/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: Make Qt apps follow the GTK theme
tags: [theme]
ansible.builtin.copy:
@@ -592,7 +565,7 @@
label: "{{ item.name }}"
- name: Install desktop Python tools with uv
tags: [packages, emacs]
tags: [packages]
ansible.builtin.command:
cmd: "uv tool install --upgrade {{ item }}"
become: true

View File

@@ -0,0 +1,4 @@
[preferred]
default=gtk
org.freedesktop.impl.portal.Screenshot=hyprland
org.freedesktop.impl.portal.ScreenCast=hyprland

View File

@@ -0,0 +1,58 @@
---
- name: Ensure FreeBSD Hyprland user config directories exist
tags: [dotfiles, dotfiles:desktop, hyprland]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
loop:
- "{{ user_home }}/.config"
- "{{ user_home }}/.config/alacritty"
- "{{ user_home }}/.config/dunst"
- "{{ user_home }}/.config/foot"
- "{{ user_home }}/.config/hypr"
- "{{ user_home }}/.config/rofi"
- "{{ user_home }}/.config/waybar"
- "{{ user_home }}/.local"
- "{{ user_home }}/.local/bin"
- name: Copy common Hyprland desktop dotfiles on FreeBSD
tags: [dotfiles, dotfiles:desktop, hyprland]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/desktop/{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ desktop_hyprland_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
- name: Render FreeBSD Hyprland session launcher
tags: [packages, services, hyprland]
ansible.builtin.template:
src: start-hyprland-session.j2
dest: /usr/local/bin/start-hyprland-session
owner: root
group: wheel
mode: "0755"
- name: Ensure FreeBSD xdg-desktop-portal config directory exists
tags: [packages, services, hyprland, portal]
ansible.builtin.file:
path: "{{ freebsd_xdg_config_dir | default('/usr/local/etc/xdg') }}/xdg-desktop-portal"
state: directory
owner: root
group: wheel
mode: "0755"
- name: Configure xdg-desktop-portal backend preferences for FreeBSD Hyprland
tags: [packages, services, hyprland, portal]
ansible.builtin.copy:
src: hyprland-portals.conf
dest: "{{ freebsd_xdg_config_dir | default('/usr/local/etc/xdg') }}/xdg-desktop-portal/hyprland-portals.conf"
owner: root
group: wheel
mode: "0644"

View File

@@ -0,0 +1,24 @@
#!/bin/sh
[ -r /etc/profile ] && . /etc/profile
[ -r "$HOME/.profile" ] && . "$HOME/.profile"
export XDG_CURRENT_DESKTOP=Hyprland
export XDG_SESSION_DESKTOP=Hyprland
export XDG_SESSION_TYPE=wayland
export MOZ_ENABLE_WAYLAND=1
export QT_QPA_PLATFORM='wayland;xcb'
export _JAVA_AWT_WM_NONREPARENTING=1
export SDL_VIDEODRIVER=wayland
export GDK_BACKEND='wayland,x11'
export SSH_AUTH_SOCK="$HOME/.local/state/ssh-agent/socket"
[ -r "$HOME/.config/hypr/session-env" ] && . "$HOME/.config/hypr/session-env"
if command -v dbus-run-session >/dev/null 2>&1; then
exec dbus-run-session Hyprland
fi
exec Hyprland

View File

@@ -0,0 +1,4 @@
[preferred]
default=gtk
org.freedesktop.impl.portal.Screenshot=gtk
org.freedesktop.impl.portal.ScreenCast=gtk

View File

@@ -0,0 +1,5 @@
[Desktop Entry]
Name=Niri
Comment=Niri scrollable-tiling (Wayland)
Exec=/usr/local/bin/start-niri
Type=Application

View File

@@ -0,0 +1,81 @@
---
- name: Ensure niri config directories exist
tags: [dotfiles, dotfiles:desktop, niri]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
loop:
- "{{ user_home }}/.config/foot"
- "{{ user_home }}/.config/dunst"
- "{{ user_home }}/.config/rofi"
- "{{ user_home }}/.config/waybar"
- "{{ user_home }}/.config/niri"
when:
- (desktop_environment | default('minimal')) == 'minimal'
- "'niri' in (desktop_sessions_enabled | default([]))"
- name: Install allowed emptty Wayland sessions
tags: [packages, services, emptty, niri]
ansible.builtin.copy:
src: niri.desktop
dest: /etc/emptty/wayland-sessions/niri.desktop
owner: root
group: root
mode: "0644"
when:
- (desktop_environment | default('minimal')) == 'minimal'
- "'niri' in (desktop_sessions_enabled | default([]))"
- name: Install Niri session launcher in /usr/local/bin
tags: [packages, services, niri]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/desktop/.local/bin/start-niri"
dest: /usr/local/bin/start-niri
owner: root
group: root
mode: "0755"
when:
- (desktop_environment | default('minimal')) == 'minimal'
- "'niri' in (desktop_sessions_enabled | default([]))"
- name: Ensure /etc/xdg/xdg-desktop-portal exists
tags: [packages, services, niri, portal]
ansible.builtin.file:
path: /etc/xdg/xdg-desktop-portal
state: directory
owner: root
group: root
mode: "0755"
when:
- (desktop_environment | default('minimal')) == 'minimal'
- "'niri' in (desktop_sessions_enabled | default([]))"
- name: Configure xdg-desktop-portal backend preferences for niri
tags: [packages, services, niri, portal]
ansible.builtin.copy:
src: niri-portals.conf
dest: /etc/xdg/xdg-desktop-portal/niri-portals.conf
owner: root
group: root
mode: "0644"
when:
- (desktop_environment | default('minimal')) == 'minimal'
- "'niri' in (desktop_sessions_enabled | default([]))"
- name: Copy niri desktop dotfiles
tags: [dotfiles, dotfiles:desktop, niri]
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_niri_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
when:
- (desktop_environment | default('minimal')) == 'minimal'
- "'niri' in (desktop_sessions_enabled | default([]))"

View File

@@ -0,0 +1,41 @@
---
- name: Ensure FreeBSD Niri user config directories exist
tags: [dotfiles, dotfiles:desktop, niri]
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "0755"
loop:
- "{{ user_home }}/.config"
- "{{ user_home }}/.config/dunst"
- "{{ user_home }}/.config/foot"
- "{{ user_home }}/.config/niri"
- "{{ user_home }}/.config/rofi"
- "{{ user_home }}/.config/waybar"
- "{{ user_home }}/.local"
- "{{ user_home }}/.local/bin"
- "{{ user_home }}/.local/state"
- "{{ user_home }}/.local/state/ssh-agent"
- name: Copy common Niri desktop dotfiles on FreeBSD
tags: [dotfiles, dotfiles:desktop, niri]
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_niri_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"
- name: Render FreeBSD Niri session launcher
tags: [packages, services, niri]
ansible.builtin.template:
src: start-niri-session.j2
dest: /usr/local/bin/start-niri-session
owner: root
group: wheel
mode: "0755"

View File

@@ -0,0 +1,24 @@
#!/bin/sh
[ -r /etc/profile ] && . /etc/profile
[ -r "$HOME/.profile" ] && . "$HOME/.profile"
export XDG_CURRENT_DESKTOP=niri
export XDG_SESSION_DESKTOP=niri
export XDG_SESSION_TYPE=wayland
export MOZ_ENABLE_WAYLAND=1
export QT_QPA_PLATFORM='wayland;xcb'
export _JAVA_AWT_WM_NONREPARENTING=1
export SDL_VIDEODRIVER=wayland
export GDK_BACKEND='wayland,x11'
export SSH_AUTH_SOCK="$HOME/.local/state/ssh-agent/socket"
[ -r "$HOME/.config/niri/session-env" ] && . "$HOME/.config/niri/session-env"
if command -v dbus-run-session >/dev/null 2>&1; then
exec dbus-run-session niri --session
fi
exec niri --session

View File

@@ -0,0 +1,12 @@
---
- name: Ensure lab workspace directories exist
tags: [dotfiles]
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ lab_workspace_directories | default([]) }}"
loop_control:
label: "{{ item.path }}"

View File

@@ -0,0 +1,24 @@
---
- name: Ensure personal workstation directories exist
tags: [dotfiles, dotfiles:workstation]
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ personal_workstation_directories | default([]) }}"
loop_control:
label: "{{ item.path }}"
- name: Copy personal workstation dotfiles
tags: [dotfiles, dotfiles:workstation]
ansible.builtin.copy:
src: "{{ playbook_dir }}/../dotfiles/workstation/{{ item.src }}"
dest: "{{ user_home }}/{{ item.dest }}"
owner: "{{ username }}"
group: "{{ user_group }}"
mode: "{{ item.mode }}"
loop: "{{ personal_workstation_dotfiles | default([]) }}"
loop_control:
label: "{{ item.dest }}"

View File

@@ -0,0 +1,20 @@
---
- name: Configure FreeBSD rc.conf values
tags: [services, packages]
community.general.sysrc:
name: "{{ item.name }}"
value: "{{ item.value }}"
state: present
loop: "{{ freebsd_rc_conf | default([]) }}"
loop_control:
label: "{{ item.name }}"
- name: Enable FreeBSD rc services
tags: [services, packages]
ansible.builtin.service:
name: "{{ item }}"
enabled: true
state: started
loop: "{{ freebsd_enabled_services | default([]) + host_enabled_services | default([]) }}"
loop_control:
label: "{{ item }}"

View File

@@ -18,4 +18,3 @@
loop: "{{ host_enabled_services | default([]) }}"
loop_control:
label: "{{ item }}"

View File

@@ -1,36 +1,101 @@
---
- hosts: all
- name: Configure common user environment
hosts: all
become: true
pre_tasks:
- name: Load local vault variables when available
tags: [always]
ansible.builtin.include_vars:
file: "{{ playbook_dir }}/../secrets/vault.yml"
when: lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.yml', errors='ignore', wantlist=True) | length > 0
when: >-
lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.yml',
errors='ignore', wantlist=True) | length > 0
- name: Load machine-local vault variables when available
tags: [always]
ansible.builtin.include_vars:
file: "{{ playbook_dir }}/../secrets/vault.local.yml"
when: lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.local.yml', errors='ignore', wantlist=True) | length > 0
when: >-
lookup('ansible.builtin.fileglob', playbook_dir + '/../secrets/vault.local.yml',
errors='ignore', wantlist=True) | length > 0
roles:
- dotfiles_common
- hosts: void
- name: Configure Void platform
hosts: platform_void
become: true
roles:
- packages_void
- services_runit
- name: Configure Void graphical desktop
hosts: platform_void:&graphical_desktop
become: true
roles:
- profile_desktop_common
- profile_desktop_sway
- profile_desktop_hyprland
- profile_desktop_niri
- profile_desktop_kde
- profile_desktop_xfce
- profile_desktop_host
- hosts: workstation_dev_fedora
- name: Configure lab role on Void
hosts: platform_void:&role_lab
become: true
roles:
- profile_lab
- name: Configure Linux Mint platform
hosts: platform_mint
become: true
roles:
- packages_mint
- services_systemd
- name: Configure personal workstation role on Linux Mint
hosts: platform_mint:&role_personal_workstation
become: true
roles:
- profile_personal_workstation
- name: Configure Cinnamon desktop on Linux Mint
hosts: platform_mint:&desktop_cinnamon
become: true
roles:
- profile_desktop_cinnamon
- name: Configure FreeBSD platform
hosts: platform_freebsd
become: true
roles:
- packages_freebsd
- services_freebsd
- name: Configure lab role on FreeBSD
hosts: platform_freebsd:&role_lab
become: true
roles:
- profile_lab
- name: Configure Niri desktop on FreeBSD
hosts: platform_freebsd:&desktop_niri
become: true
roles:
- profile_desktop_niri_freebsd
- name: Configure Fedora workstation development layer
hosts: workstation_dev_fedora
become: true
roles:
@@ -38,13 +103,15 @@
- services_systemd
- profile_workstation_dev_common
- hosts: workstation_host_linux
- name: Configure native Linux workstation host layer
hosts: workstation_host_linux
become: true
roles:
- profile_workstation_gnome
- hosts: workstation_dev_wsl
- name: Configure WSL workstation development layer
hosts: workstation_dev_wsl
become: true
roles:
@@ -53,7 +120,8 @@
- profile_workstation_dev_common
- profile_workstation_dev_wsl
- hosts: ubuntu_server
- name: Configure Ubuntu server
hosts: ubuntu_server
become: true
roles:

View File

@@ -29,9 +29,19 @@
[mergetool]
prompt = false
[mergetool "meld"]
cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
trustExitCode = false
[diff]
tool = meld
[difftool]
prompt = false
[difftool "meld"]
cmd = meld "$LOCAL" "$REMOTE"
[color]
ui = always

View File

@@ -1,47 +0,0 @@
##################### iCloud Account ##################################
IMAPStore iCloud-remote
Host imap.mail.me.com
Port 993
User {{ vault_icloud_email }}
PassCmd "secret-tool lookup icloud-mail icloud"
AuthMechs *
TLSType IMAPS
TLSVersions +1.2 +1.3
PipelineDepth 1
MaildirStore iCloud-local
Path ~/Maildir/iCloudAccount/
Inbox ~/Maildir/iCloudAccount/INBOX
SubFolders Verbatim
Channel iCloud
Far :iCloud-remote:
Near :iCloud-local:
Patterns *
Create Both
Expunge Both
SyncState *
##################### Protonmail Account ##################################
IMAPStore protonmail-remote
Host 127.0.0.1
Port 1143
User {{ vault_protonmail_email }}
PassCmd "secret-tool lookup protonmail-bridge protonmail"
AuthMechs *
TLSType STARTTLS
PipelineDepth 1
CertificateFile {{ desktop_protonmail_bridge_cert_path }}
MaildirStore protonmail-local
Path ~/Maildir/ProtonMailAccount/
Inbox ~/Maildir/ProtonMailAccount/INBOX
SubFolders Verbatim
Channel Protonmail
Far :protonmail-remote:
Near :protonmail-local:
Patterns *
Create Both
Expunge Both
SyncState *

View File

@@ -1,51 +0,0 @@
# Set default values for all following accounts.
defaults
# Always use TLS
tls on
# Set a list of trusted CAs for TLS. The default is to use system settings,
# but you can select your own file.
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile ~/.cache/msmtp.log
# Account iCloud
account icloud
# Host name of the SMTP server
host smtp.mail.me.com
# Use the mail submission port 587 instead of the SMTP port 25
port 587
# Envelop-from address
from {{ vault_icloud_email }}
# Authentication. The password is given using one of five methods
auth on
user {{ vault_icloud_email }}
passwordeval "secret-tool lookup icloud-mail icloud"
# Account Protonmail
account protonmail
# Hostname of the Protonmail bridge
host 127.0.0.1
# Port of the Protonmail bridge
port 1025
# Envelop-from address
from {{ vault_protonmail_email }}
# Security
tls on
tls_trust_file {{ desktop_protonmail_bridge_cert_path }}
# Authentication
auth on
user {{ vault_protonmail_email }}
passwordeval "secret-tool lookup protonmail-bridge protonmail"
# Set a default account
account default : icloud

View File

@@ -1,53 +0,0 @@
;;; email.el -*-
(use-package mu4e
:ensure nil
:load-path "/usr/share/emacs/site-lisp/mu4e/"
:defer 20 ; Wait until 20 seconds after startup
:config
;; This is set to 't' to avoid mail syncing issues when using mbsync
(setq mu4e-change-filenames-when-moving t)
;; Refresh mail using isync every 10 minutes
(setq mu4e-update-interval (* 10 60))
(setq mu4e-get-mail-command "~/.emacs.d/scripts/email_sync.sh")
(setq mu4e-maildir "~/Maildir")
;; Configure email accounts
(setq mu4e-contexts
(list
;; Protonmail Account
(make-mu4e-context
:name "Protonmail"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/ProtonMailAccount" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "{{ vault_protonmail_email }}")
(user-full-name . "{{ vault_personal_full_name }}")
(mu4e-drafts-folder . "/ProtonMailAccount/Drafts")
(mu4e-sent-folder . "/ProtonMailAccount/Sent")
(mu4e-refile-folder . "/ProtonMailAccount/All Mail")
(mu4e-trash-folder . "/ProtonMailAccount/Trash")))
;; iCloud Account
(make-mu4e-context
:name "iCloud Mail"
:match-func
(lambda (msg)
(when msg
(string-prefix-p "/iCloudAccount" (mu4e-message-field msg :maildir))))
:vars '((user-mail-address . "{{ vault_icloud_email }}")
(user-full-name . "{{ vault_personal_full_name }}")
(mu4e-drafts-folder . "/iCloudAccount/Drafts")
(mu4e-sent-folder . "/iCloudAccount/Sent Messages")
(mu4e-refile-folder . "/iCloudAccount/INBOX")
(mu4e-trash-folder . "/iCloudAccount/Junk")))))
(setq sendmail-program "/usr/bin/msmtp"
mail-user-agent 'mu4e-user-agent
read-mail-command 'mu4e
send-mail-function 'sendmail-send-it
message-sendmail-f-is-evil t
message-sendmail-extra-arguments '("--read-envelope-from")
message-send-mail-function 'message-send-mail-with-sendmail))