From 16bda6c7491f7511f3f30a0bc705ae6eb037c765 Mon Sep 17 00:00:00 2001 From: "Thomas A. Christensen II" <25492070+MillironX@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:21:35 -0500 Subject: [PATCH 1/2] refactor: Merge playbooks by host group Claude led me astray again. Something that should have been simple was complicated by using includes when I should have used groups. Here I correct my mistake in preparation for adding non-root install steps. --- inventory.yaml | 31 ++++-- playbook.yaml | 219 ++++++++++++++++++++++++++++++++++++++--- playbooks/amd64.yaml | 42 -------- playbooks/asahi.yaml | 22 ----- playbooks/desktop.yaml | 85 ---------------- playbooks/fedora.yaml | 45 --------- 6 files changed, 226 insertions(+), 218 deletions(-) delete mode 100644 playbooks/amd64.yaml delete mode 100644 playbooks/asahi.yaml delete mode 100644 playbooks/desktop.yaml delete mode 100644 playbooks/fedora.yaml diff --git a/inventory.yaml b/inventory.yaml index 23211d9..aa5572b 100644 --- a/inventory.yaml +++ b/inventory.yaml @@ -1,12 +1,27 @@ --- -all: +ungrouped: hosts: localhost: ansible_connection: local - children: - workstations: - hosts: - harmony: - ansible_connection: local - odyssey: - ansible_connection: local \ No newline at end of file + harmony: + ansible_connection: local + odyssey: + ansible_connection: local + +asahi: + hosts: + harmony: + +amd64: + hosts: + odyssey: + +fedora: + hosts: + harmony: + odyssey: + +desktop: + hosts: + harmony: + odyssey: diff --git a/playbook.yaml b/playbook.yaml index d8fc2dc..ae90647 100644 --- a/playbook.yaml +++ b/playbook.yaml @@ -1,22 +1,209 @@ --- -- name: Configure harmony - hosts: harmony +# Asahi Linux comes with its own strange version of RPMFusion installed, so +# RPMFusion is installed only on amd64 systems. In addition, VeraCrypt and +# Zotero *are* available via COPR, but from different repos than their amd64 +# counterparts. +# Also, Asahi has its own version string, so we have to manually specify the +# chroot for COPR repos added via Ansible. This is handled automatically when +# using `dnf copr enable ...`, but not via Ansible. +- name: Configure Asahi Linux-specific repos and packages + hosts: asahi become: true tasks: - - name: Include arch-specific tasks - ansible.builtin.include_tasks: playbooks/asahi.yaml - - name: Include Linux tasks - ansible.builtin.include_tasks: playbooks/fedora.yaml - - name: Include desktop tasks - ansible.builtin.include_tasks: playbooks/desktop.yaml + - name: Install Zotero COPR repository + community.general.copr: + name: "isaksamsten/Zotero" + chroot: "fedora-{{ ansible_distribution_major_version }}-aarch64" + - name: Install VeraCrypt COPR repository + community.general.copr: + name: "architektapx/veracrypt" + chroot: "fedora-{{ ansible_distribution_major_version }}-aarch64" + - name: Install aarch64-specific packages + ansible.builtin.dnf: + name: + - veracrypt -- name: Configure odyssey - hosts: odyssey +# These are repos and packages that are useless or unavailable on Asahi Linux. +- name: Configure amd64 specific repos and packages + hosts: amd64 become: true tasks: - - name: Include arch-specific tasks - ansible.builtin.include_tasks: playbooks/amd64.yaml - - name: Include Linux tasks - ansible.builtin.include_tasks: playbooks/fedora.yaml - - name: Include desktop tasks - ansible.builtin.include_tasks: playbooks/desktop.yaml + - name: Install RPM Fusion free repository + ansible.builtin.dnf: + name: "https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm" + state: present + disable_gpg_check: false + - name: Install RPM Fusion nonfree repository + ansible.builtin.dnf: + name: "https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm" + state: present + disable_gpg_check: false + - name: Install RPM Fusion free-tainted repository + ansible.builtin.dnf: + name: rpmfusion-free-release-tainted + state: present + - name: Install Zotero COPR repository + community.general.copr: + name: "mozes/zotero7" + - name: Install x86-specific packages + ansible.builtin.dnf: + name: + - libdvdcss + - mkvtoolnix + - mpv + - x264 + - x264-libs + state: present + - name: Install VeraCrypt + ansible.builtin.dnf: + name: https://launchpad.net/veracrypt/trunk/1.26.20/+download/veracrypt-1.26.20-Fedora-40-x86_64.rpm + state: present + disable_gpg_check: true + +# I no longer have any machines that are Fedora but not workstations (bosephus +# is now NixOS), so this section is around for more historical reasons, I guess. +# Regardless, Tailscale and zsh are pretty essential for any machine before +# starting anything on them, so it warrants its own play in my mind. +- name: Configure common (all arch, headless and workstation) repos and packages + hosts: fedora + become: true + tasks: + - name: Install Tailscale repo + ansible.builtin.yum_repository: + name: tailscale-stable + description: Tailscale stable repo + baseurl: https://pkgs.tailscale.com/stable/fedora/$basearch + enabled: true + gpgcheck: true + gpgkey: https://pkgs.tailscale.com/stable/fedora/repo.gpg + - name: Install common Linux packages + ansible.builtin.dnf: + name: + - tailscale + - zsh + state: present + +# The Determinate Nix installer is the most stable way to install Nix on +# non-NixOS systems I've found. +# 1. It handles SELinux rule creation +# 2. It enables flakes and the `nix` command *by default* +# I use a rule that would *probably* fail on regular Nix systems to detect if +# Nix was installed via the Determinate installer. +# IMPORTANT: I am installing regular Nix via the Determinate Systems installer. +# I **DO NOT** want to install their "determinate nix," as I want to be only +# reliant on nixpkgs, and not their binary cache. +- name: Install Nix via determinate systems + hosts: fedora + become: true + tasks: + - name: Determine if Nix is installed + ansible.builtin.shell: | + /nix/var/nix/profiles/default/bin/nix --version + register: nix_check + ignore_errors: true + changed_when: false + - name: Download Determinate Nix installer + ansible.builtin.get_url: + url: https://install.determinate.systems/nix + dest: /tmp/nix-installer + mode: 755 + when: nix_check.rc != 0 + - name: Install Nix via Determinate Nix installer + ansible.builtin.shell: | + sh /tmp/nix-installer install linux --verbose --no-confirm + when: nix_check.rc != 0 + register: nix_install + changed_when: nix_install.rc == 0 + +# Install packages with a GUI that would be useless on a headless server, or +# otherwise have no use outside of a workstation environment +- name: Configure desktop/workstation packages + hosts: desktop + become: true + tasks: + # I love the Zed editor, but I hate the way it is installed by default. The + # recommended way to install via a package manager is by using Terra repos. + # Problem 1: Terra doesn't have a single .repo file to plop in using + # ansible.builtin.yum_repository (like Tailscale or FirefoxPWA) nor a + # package that installs the correct repo files with ansible.builtin.dnf + # (like RPMFusion). Instead Terra uses the `--repofrompath` option to + # bootstrap itself as its source of truth - a feature Ansible doesn't + # support. This is the one case where I use ansible.builtin.shell to execute + # a dnf install because of that. + # Problem 2: Terra leads to chaos as it specifies many of the same packages + # from the Fedora and/or RPMFusion repositories. The solution is to + # configure Terra repos with a low priority, see: + # https://discussion.fedoraproject.org/t/zed-editor-this-is-too-much/151269/2 + # community.general.dnf_config_manager *only* supports enabling/disabling + # repos, and not seeing/specifying other options, so I use some ugly + # pipelines to determine if the priority is already set right, and adjust + # appropriately. + - name: Determine if Terra is installed + ansible.builtin.stat: + path: /etc/yum.repos.d/terra.repo + register: terra_installed + - name: Install Terra repository + ansible.builtin.shell: | + dnf install --assumeyes --nogpgcheck --repofrompath terra,https://repos.fyralabs.com/terra{{ ansible_distribution_major_version }} terra-release + when: not terra_installed.stat.exists + register: terra_install + changed_when: terra_install.rc == 0 + - name: Determine Terra repository priority + ansible.builtin.shell: + cmd: set -o pipefail && dnf --dump-repo-config=terra | grep 'priority = 100' || echo "false" + executable: /bin/bash + register: terra_check + changed_when: false + - name: Set Terra repository priority to low + ansible.builtin.shell: dnf config-manager setopt terra\*.priority=100 + when: "'false' in terra_check.stdout" + register: terra_priority + changed_when: terra_priority.rc != 0 + # FirefoxPWA and RStudio are actually both compatible with all arches! Yay! + # Note that I still have to specify the chroot b/c of Asahi + - name: Install FirefoxPWA repository + ansible.builtin.yum_repository: + name: firefoxpwa + description: FirefoxPWA repository + baseurl: https://packagecloud.io/filips/FirefoxPWA/fedora/$releasever/$basearch + gpgcheck: true + gpgkey: https://packagecloud.io/filips/FirefoxPWA/gpgkey + enabled: true + - name: Install RStudio copr repository + community.general.copr: + name: "iucar/rstudio" + chroot: "fedora-{{ ansible_distribution_major_version }}-{{ ansible_architecture }}" + # The main package list - the primary goal of this entire playbook, finally + - name: Install common desktop environment packages + ansible.builtin.dnf: + name: + - chromium + - firefoxpwa + - inkscape + - kate + - kdenlive + - kdiff3 + - krita + - musescore + - nextcloud-client + - nextcloud-client-dolphin + - obs-studio + - qownnotes + - qt + - rssguard + - rstudio-desktop + - steam + - thunderbird + - vlc + - vorta + - yakuake + - zed + - zotero + - R + state: present + # MS Core fonts aren't needed on anything without a GUI + - name: Install Microsoft Core Fonts + ansible.builtin.dnf: + name: https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm + state: present + disable_gpg_check: true diff --git a/playbooks/amd64.yaml b/playbooks/amd64.yaml deleted file mode 100644 index e595d5a..0000000 --- a/playbooks/amd64.yaml +++ /dev/null @@ -1,42 +0,0 @@ ---- -# Playbook for x86-64 specific systems - -### ================ ### -### Package installs ### -### ================ ### - -### Repositories ### -- name: Install RPM Fusion free repository - ansible.builtin.dnf: - name: "https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-{{ ansible_distribution_major_version }}.noarch.rpm" - state: present - disable_gpg_check: false -- name: Install RPM Fusion nonfree repository - ansible.builtin.dnf: - name: "https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-{{ ansible_distribution_major_version }}.noarch.rpm" - state: present - disable_gpg_check: false -- name: Install RPM Fusion free-tainted repository - ansible.builtin.dnf: - name: rpmfusion-free-release-tainted - state: present -- name: Install Zotero COPR repository - community.general.copr: - name: "mozes/zotero7" - -### Packages ### -- name: Install x86-specific packages - ansible.builtin.dnf: - name: - - libdvdcss - - mkvtoolnix - - mpv - - x264 - - x264-libs - state: present - -- name: Install VeraCrypt - ansible.builtin.dnf: - name: https://launchpad.net/veracrypt/trunk/1.26.20/+download/veracrypt-1.26.20-Fedora-40-x86_64.rpm - state: present - disable_gpg_check: true diff --git a/playbooks/asahi.yaml b/playbooks/asahi.yaml deleted file mode 100644 index bbd95f8..0000000 --- a/playbooks/asahi.yaml +++ /dev/null @@ -1,22 +0,0 @@ ---- -# Asahi Linux playbook - to be run on all Asahi Linux hosts - -### ================ ### -### Package installs ### -### ================ ### - -### Repositories ### -- name: Install Zotero COPR repository - community.general.copr: - name: "isaksamsten/Zotero" - chroot: "fedora-{{ ansible_distribution_major_version }}-aarch64" -- name: Install VeraCrypt COPR repository - community.general.copr: - name: "architektapx/veracrypt" - chroot: "fedora-{{ ansible_distribution_major_version }}-aarch64" - -### Packages ### -- name: Install aarch64-specific packages - ansible.builtin.dnf: - name: - - veracrypt diff --git a/playbooks/desktop.yaml b/playbooks/desktop.yaml deleted file mode 100644 index 54561eb..0000000 --- a/playbooks/desktop.yaml +++ /dev/null @@ -1,85 +0,0 @@ ---- -# Desktop environment playbook - common to all desktop Fedora hosts - -### ================ ### -### Package installs ### -### ================ ### - -### Repositories ### - -# Add Terra - the source of the Zed editor -- name: Determine if Terra is installed - ansible.builtin.stat: - path: /etc/yum.repos.d/terra.repo - register: terra_installed -- name: Install Terra repository - ansible.builtin.shell: | - dnf install --assumeyes --nogpgcheck --repofrompath terra,https://repos.fyralabs.com/terra{{ ansible_distribution_major_version }} terra-release - when: not terra_installed.stat.exists - register: terra_install - changed_when: terra_install.rc == 0 -- name: Determine Terra repository priority - ansible.builtin.shell: - cmd: set -o pipefail && dnf --dump-repo-config=terra | grep 'priority = 100' || echo "false" - executable: /bin/bash - register: terra_check - changed_when: false -- name: Set Terra repository priority to low - ansible.builtin.shell: dnf config-manager setopt terra\*.priority=100 - when: "'false' in terra_check.stdout" - register: terra_priority - changed_when: terra_priority.rc != 0 - -# Add FirefoxPWA repository -- name: Install FirefoxPWA repository - ansible.builtin.yum_repository: - name: firefoxpwa - description: FirefoxPWA repository - baseurl: https://packagecloud.io/filips/FirefoxPWA/fedora/$releasever/$basearch - gpgcheck: true - gpgkey: https://packagecloud.io/filips/FirefoxPWA/gpgkey - enabled: true - -# Add RStudio copr repository -- name: Install RStudio copr repository - community.general.copr: - name: "iucar/rstudio" - chroot: "fedora-{{ ansible_distribution_major_version }}-{{ ansible_architecture }}" - -### Packages ### - -# Install common desktop environment packages -- name: Install common desktop environment packages - ansible.builtin.dnf: - name: - - chromium - - firefoxpwa - - inkscape - - kate - - kdenlive - - kdiff3 - - krita - - musescore - - nextcloud-client - - nextcloud-client-dolphin - - obs-studio - - qownnotes - - qt - - rssguard - - rstudio-desktop - - steam - - thunderbird - - vlc - - vorta - - yakuake - - zed - - zotero - - R - state: present - -# noarch url packages -- name: Install Microsoft Core Fonts - ansible.builtin.dnf: - name: https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm - state: present - disable_gpg_check: true diff --git a/playbooks/fedora.yaml b/playbooks/fedora.yaml deleted file mode 100644 index 95bb12f..0000000 --- a/playbooks/fedora.yaml +++ /dev/null @@ -1,45 +0,0 @@ ---- -# Ansible playbook common to all Fedora systems - -### Package installs ### -# Repositories - -# Tailscale -- name: Install Tailscale repo - ansible.builtin.yum_repository: - name: tailscale-stable - description: Tailscale stable repo - baseurl: https://pkgs.tailscale.com/stable/fedora/$basearch - enabled: true - gpgcheck: true - gpgkey: https://pkgs.tailscale.com/stable/fedora/repo.gpg - -### dnf packages -- name: Install common Linux packages - ansible.builtin.dnf: - name: - - tailscale - - zsh - state: present - -### ======================= ### -### Install determinate nix ### -### ======================= ### -- name: Determine if Nix is installed - ansible.builtin.shell: | - /nix/var/nix/profiles/default/bin/nix --version - register: nix_check - ignore_errors: true - changed_when: false -- name: Download Determinate Nix installer - ansible.builtin.get_url: - url: https://install.determinate.systems/nix - dest: /tmp/nix-installer - mode: 755 - when: nix_check.rc != 0 -- name: Install Nix via Determinate Nix installer - ansible.builtin.shell: | - sh /tmp/nix-installer install linux --verbose --no-confirm - when: nix_check.rc != 0 - register: nix_install - changed_when: nix_install.rc == 0 From fd96856085d2b2f7b308ef7a9b670c3878e8a628 Mon Sep 17 00:00:00 2001 From: "Thomas A. Christensen II" <25492070+MillironX@users.noreply.github.com> Date: Tue, 22 Jul 2025 17:22:09 -0500 Subject: [PATCH 2/2] Add flatpak and home-manager to Ansible playbook --- playbook.yaml | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/playbook.yaml b/playbook.yaml index ae90647..37a1a6f 100644 --- a/playbook.yaml +++ b/playbook.yaml @@ -207,3 +207,78 @@ name: https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm state: present disable_gpg_check: true + # Allows me to run the playbook as a way to upgrade the system packages + # This is a violation of ansible-lint's rules, but one of the key reasons I + # wrote this playbook in the first place + - name: Upgrade all packages + ansible.builtin.dnf: + name: "*" + state: latest # noqa: package-latest + # Generally speaking, I try to install Flatpak applications at the user + # level b/c that really gives more credence to the whole sandboxing idea + # (concept of least privilege). Regardless, we should make sure all the + # system-level Flatpaks are up-to-date. + - name: Upgrade system Flatpaks + community.general.flatpak: + name: "*" + state: latest + method: system + +# User-installed Flatpaks are to be installed via home-manager - or at least, +# that's the goal. (There currently seems to be a bug where my GPG configuration +# is getting in the way of validating the Flathub remote, but I am still +# specifying Flatpaks in services.flatpak.) Thanks to that bug, I want a way to +# have this play upgrade my Flatpaks. +- name: Ensure Flatpak packages are up-to-date + hosts: desktop + become: false + tasks: + - name: Upgrade user Flatpaks + community.general.flatpak: + name: "*" + state: latest + method: user + +# Install home-manager for the first time +- name: Ensure home-manager configuration is up-to-date + hosts: fedora + become: false + tasks: + # First, determine if the repo is in place and clone it if not. The odds of + # the repo *not* being present are pretty slim, considering that is where + # I will be deploying this playbook from, but still document the process. + # IMPORTANT: The playbook will not have access to SSH/GPG keys (because they + # can't be generated without home-manager's dotfiles), so it clones a copy + # of via https. **THIS MUST BE CHANGED TO THE ssh REMOTE AFTER CONFIGURATION + # IS COMPLETE!** + - name: Determine if the home-manager repo is present + ansible.builtin.stat: + path: "{{ ansible_env.HOME }}/.config/home-manager" + register: home_manager_repo + - name: Clone the home-manager repo + ansible.builtin.git: + repo: "https://code.millironx.com/millironx/nix-dotfiles.git" # noqa: latest + dest: "{{ ansible_env.HOME }}/.config/home-manager" + when: not home_manager_repo.stat.exists + register: home_manager_clone + changed_when: home_manager_clone.rc == 0 + - name: Determine if home-manager is installed + ansible.builtin.stat: + path: "{{ ansible_env.HOME }}/.nix-profile/bin/home-manager" + register: home_manager_exists + - name: Init home-manager + ansible.builtin.shell: | + /nix/var/nix/profiles/default/bin/nix run home-manager switch --flake ~/.config/home-manager#{{ ansible_user_id }}@{{ ansible_hostname }} + when: not home_manager_exists.stat.exists + register: home_manager_init + changed_when: home_manager_init.rc == 0 + - name: Update home-manager git config + ansible.builtin.shell: | + cd $HOME/.config/home-manager || exit 1 \ + && git pull \ + && cd - + changed_when: false + - name: Update home-manager derivation + ansible.builtin.shell: | + $HOME/.nix-profile/bin/home-manager switch --flake ~/.config/home-manager#{{ ansible_user_id }}@{{ ansible_hostname }} + changed_when: false