Added users role to manage the playbook as root and remove admin privileges from deck

This commit is contained in:
2026-10-13 12:49:13 +02:00
parent 80a79fcc99
commit d00d99ce45
18 changed files with 153 additions and 42 deletions
+16
View File
@@ -11,3 +11,19 @@ git clone https://git.nicolabelluti.me/nicolabelluti/bc250-cachyos-handheld
cd bc250-cachyos-handheld cd bc250-cachyos-handheld
nix develop nix develop
``` ```
# Usage
On a fresh install, log in once with the installer's `deck`/`deck` to hand
administration over to `root` (SSH key only) and strip `deck` of its password
and admin rights:
```sh
ansible-playbook site.yml --tags users
```
Then configure the board as `root`:
```sh
ansible-playbook site.yml
```
+1 -3
View File
@@ -2,6 +2,4 @@ bc250:
hosts: hosts:
192.168.1.156: 192.168.1.156:
vars: vars:
ansible_user: deck ansible_user: root
ansible_ssh_pass: deck
ansible_become_password: "{{ ansible_ssh_pass }}"
-3
View File
@@ -1,6 +1,5 @@
# The custom `linux-cachyos-bc250` brings in the 40CU patch # The custom `linux-cachyos-bc250` brings in the 40CU patch
- name: Enable the 40 CU unlock - name: Enable the 40 CU unlock
become: true
ansible.builtin.copy: ansible.builtin.copy:
content: "options amdgpu bc250_cc_write_mode=3\n" content: "options amdgpu bc250_cc_write_mode=3\n"
dest: /etc/modprobe.d/bc250-40cu.conf dest: /etc/modprobe.d/bc250-40cu.conf
@@ -8,13 +7,11 @@
register: cu40_conf register: cu40_conf
- name: Rebuild initramfs - name: Rebuild initramfs
become: true
ansible.builtin.command: limine-mkinitcpio ansible.builtin.command: limine-mkinitcpio
when: cu40_conf.changed when: cu40_conf.changed
changed_when: true changed_when: true
- name: Reboot to reinitialise amdgpu - name: Reboot to reinitialise amdgpu
become: true
ansible.builtin.reboot: ansible.builtin.reboot:
reboot_timeout: 600 reboot_timeout: 600
when: cu40_conf.changed when: cu40_conf.changed
-7
View File
@@ -1,5 +1,4 @@
- name: Install build and runtime prerequisites - name: Install build and runtime prerequisites
become: true
community.general.pacman: community.general.pacman:
name: name:
- git - git
@@ -32,7 +31,6 @@
# pipx keeps this out of the system python environment. # pipx keeps this out of the system python environment.
- name: Install the CLI system-wide - name: Install the CLI system-wide
become: true
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- pipx - pipx
@@ -42,21 +40,18 @@
always: always:
- name: Remove temporary directory - name: Remove temporary directory
become: true
ansible.builtin.file: ansible.builtin.file:
path: "{{ smu_tmp.path }}" path: "{{ smu_tmp.path }}"
state: absent state: absent
when: smu_tmp.path is defined when: smu_tmp.path is defined
- name: Create the config directory - name: Create the config directory
become: true
ansible.builtin.file: ansible.builtin.file:
path: /etc/bc250 path: /etc/bc250
state: directory state: directory
mode: '0755' mode: '0755'
- name: Deploy the overclock profile - name: Deploy the overclock profile
become: true
ansible.builtin.template: ansible.builtin.template:
src: overclock.conf.j2 src: overclock.conf.j2
dest: /etc/bc250/overclock.conf dest: /etc/bc250/overclock.conf
@@ -64,7 +59,6 @@
register: oc_conf register: oc_conf
- name: Install the overclock service - name: Install the overclock service
become: true
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- bc250-apply - bc250-apply
@@ -73,7 +67,6 @@
when: oc_conf.changed when: oc_conf.changed
- name: Enable the overclock service at boot - name: Enable the overclock service at boot
become: true
ansible.builtin.systemd_service: ansible.builtin.systemd_service:
name: bc250-smu-oc name: bc250-smu-oc
enabled: true enabled: true
-3
View File
@@ -1,6 +1,5 @@
# The custom `linux-cachyos-bc250` brings in the nct6678 module # The custom `linux-cachyos-bc250` brings in the nct6678 module
- name: Configure the nct6687 sensor module - name: Configure the nct6687 sensor module
become: true
ansible.builtin.copy: ansible.builtin.copy:
content: | content: |
blacklist nct6683 blacklist nct6683
@@ -9,14 +8,12 @@
mode: '0644' mode: '0644'
- name: Load nct6687 at boot - name: Load nct6687 at boot
become: true
ansible.builtin.copy: ansible.builtin.copy:
content: "nct6687\n" content: "nct6687\n"
dest: /etc/modules-load.d/99-sensors.conf dest: /etc/modules-load.d/99-sensors.conf
mode: '0644' mode: '0644'
- name: Load nct6687 now - name: Load nct6687 now
become: true
community.general.modprobe: community.general.modprobe:
name: nct6687 name: nct6687
state: present state: present
+2
View File
@@ -0,0 +1,2 @@
# Unprivileged user makepkg runs as.
gpu_governor__build_user: deck
-1
View File
@@ -1,5 +1,4 @@
- name: Restart the GPU governor - name: Restart the GPU governor
become: true
ansible.builtin.systemd_service: ansible.builtin.systemd_service:
name: cyan-skillfish-governor-smu name: cyan-skillfish-governor-smu
state: restarted state: restarted
+9 -5
View File
@@ -12,17 +12,23 @@
when: is_gov_installed.rc != 0 when: is_gov_installed.rc != 0
block: block:
- name: Create temporary dir for build - name: Create temporary dir for build
become: true
become_user: "{{ gpu_governor__build_user }}"
ansible.builtin.tempfile: ansible.builtin.tempfile:
state: directory state: directory
suffix: csgov suffix: csgov
register: gov_tmp register: gov_tmp
- name: Download the AUR snapshot - name: Download the AUR snapshot
become: true
become_user: "{{ gpu_governor__build_user }}"
ansible.builtin.get_url: ansible.builtin.get_url:
url: "https://aur.archlinux.org/cgit/aur.git/snapshot/cyan-skillfish-governor-smu.tar.gz" url: "https://aur.archlinux.org/cgit/aur.git/snapshot/cyan-skillfish-governor-smu.tar.gz"
dest: "{{ gov_tmp.path }}/cyan-skillfish-governor-smu.tar.gz" dest: "{{ gov_tmp.path }}/cyan-skillfish-governor-smu.tar.gz"
- name: Extract the snapshot - name: Extract the snapshot
become: true
become_user: "{{ gpu_governor__build_user }}"
ansible.builtin.unarchive: ansible.builtin.unarchive:
src: "{{ gov_tmp.path }}/cyan-skillfish-governor-smu.tar.gz" src: "{{ gov_tmp.path }}/cyan-skillfish-governor-smu.tar.gz"
dest: "{{ gov_tmp.path }}" dest: "{{ gov_tmp.path }}"
@@ -41,13 +47,15 @@
| unique }} | unique }}
- name: Ensure build prerequisites are present - name: Ensure build prerequisites are present
become: true
ansible.builtin.pacman: ansible.builtin.pacman:
name: "{{ ['base-devel', 'fakeroot'] + gov_build_deps }}" name: "{{ ['base-devel', 'fakeroot'] + gov_build_deps }}"
state: present state: present
# makepkg refuses to run as root.
# Rust build, expect several minutes on Zen 2. # Rust build, expect several minutes on Zen 2.
- name: Build the package (no install) - name: Build the package (no install)
become: true
become_user: "{{ gpu_governor__build_user }}"
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- makepkg - makepkg
@@ -64,9 +72,7 @@
file_type: file file_type: file
register: gov_built_pkgs register: gov_built_pkgs
# Install with root, but OUTSIDE makepkg
- name: Install built package(s) - name: Install built package(s)
become: true
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- pacman - pacman
@@ -84,7 +90,6 @@
when: gov_tmp.path is defined when: gov_tmp.path is defined
- name: Deploy the governor configuration - name: Deploy the governor configuration
become: true
ansible.builtin.template: ansible.builtin.template:
src: config.toml.j2 src: config.toml.j2
dest: /etc/cyan-skillfish-governor-smu/config.toml dest: /etc/cyan-skillfish-governor-smu/config.toml
@@ -92,7 +97,6 @@
notify: Restart the GPU governor notify: Restart the GPU governor
- name: Enable and start the GPU governor - name: Enable and start the GPU governor
become: true
ansible.builtin.systemd_service: ansible.builtin.systemd_service:
name: cyan-skillfish-governor-smu name: cyan-skillfish-governor-smu
enabled: true enabled: true
-8
View File
@@ -1,5 +1,4 @@
- name: Add the bc250-cachyos pacman repository - name: Add the bc250-cachyos pacman repository
become: true
ansible.builtin.blockinfile: ansible.builtin.blockinfile:
path: /etc/pacman.conf path: /etc/pacman.conf
marker: "# {mark} - Ansible managed" marker: "# {mark} - Ansible managed"
@@ -11,14 +10,12 @@
register: pacman_repo register: pacman_repo
- name: Perform a full system upgrade - name: Perform a full system upgrade
become: true
community.general.pacman: community.general.pacman:
update_cache: "{{ pacman_repo.changed }}" update_cache: "{{ pacman_repo.changed }}"
upgrade: true upgrade: true
register: sys_upgrade register: sys_upgrade
- name: Give the BC-250 kernel priority in BOOT_ORDER - name: Give the BC-250 kernel priority in BOOT_ORDER
become: true
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/default/limine path: /etc/default/limine
regexp: '^BOOT_ORDER=' regexp: '^BOOT_ORDER='
@@ -26,7 +23,6 @@
register: boot_order register: boot_order
- name: Install the BC-250 kernel and the fallback - name: Install the BC-250 kernel and the fallback
become: true
community.general.pacman: community.general.pacman:
name: name:
- linux-cachyos-bore-bc250 - linux-cachyos-bore-bc250
@@ -37,13 +33,11 @@
register: kernel_pkg register: kernel_pkg
- name: Regenerate Limine entries when only BOOT_ORDER changed - name: Regenerate Limine entries when only BOOT_ORDER changed
become: true
ansible.builtin.command: limine-mkinitcpio ansible.builtin.command: limine-mkinitcpio
when: boot_order.changed and not kernel_pkg.changed when: boot_order.changed and not kernel_pkg.changed
changed_when: true changed_when: true
- name: Preselect the BC-250 kernel for the next boot - name: Preselect the BC-250 kernel for the next boot
become: true
ansible.builtin.shell: ansible.builtin.shell:
executable: /bin/bash executable: /bin/bash
cmd: | cmd: |
@@ -57,7 +51,6 @@
failed_when: efivar_write.rc not in [0, 90] failed_when: efivar_write.rc not in [0, 90]
- name: Reboot into the new kernel - name: Reboot into the new kernel
become: true
ansible.builtin.reboot: ansible.builtin.reboot:
reboot_timeout: 600 reboot_timeout: 600
when: kernel_pkg.changed or boot_order.changed or sys_upgrade.changed when: kernel_pkg.changed or boot_order.changed or sys_upgrade.changed
@@ -72,7 +65,6 @@
fail_msg: "Running {{ ansible_kernel }}" fail_msg: "Running {{ ansible_kernel }}"
- name: Remove the deckify kernel - name: Remove the deckify kernel
become: true
community.general.pacman: community.general.pacman:
name: name:
- linux-cachyos-deckify - linux-cachyos-deckify
-1
View File
@@ -1,4 +1,3 @@
- name: Rebuild initramfs and limine entries - name: Rebuild initramfs and limine entries
become: true
ansible.builtin.command: limine-mkinitcpio ansible.builtin.command: limine-mkinitcpio
changed_when: true changed_when: true
-9
View File
@@ -7,7 +7,6 @@
# default. 3959290 pages of 4K = ~15.1 GiB # default. 3959290 pages of 4K = ~15.1 GiB
# ttm.page_pool_size - must match pages_limit or allocations can fail # ttm.page_pool_size - must match pages_limit or allocations can fail
- name: Add BC-250 kernel parameters - name: Add BC-250 kernel parameters
become: true
ansible.builtin.blockinfile: ansible.builtin.blockinfile:
path: /etc/default/limine path: /etc/default/limine
marker: '# {mark} ANSIBLE bc250 memory' marker: '# {mark} ANSIBLE bc250 memory'
@@ -17,7 +16,6 @@
# lz4 must be in the initramfs for zswap to use it from early boot. # lz4 must be in the initramfs for zswap to use it from early boot.
- name: Add lz4 to the initramfs modules - name: Add lz4 to the initramfs modules
become: true
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/mkinitcpio.conf path: /etc/mkinitcpio.conf
regexp: '^MODULES=' regexp: '^MODULES='
@@ -27,14 +25,12 @@
# CachyOS ships a udev rule that disables zswap when zram comes up. # CachyOS ships a udev rule that disables zswap when zram comes up.
# An empty file with the same name overrides it. # An empty file with the same name overrides it.
- name: Neutralise the CachyOS zram udev rule - name: Neutralise the CachyOS zram udev rule
become: true
ansible.builtin.copy: ansible.builtin.copy:
content: '' content: ''
dest: /etc/udev/rules.d/30-zram.rules dest: /etc/udev/rules.d/30-zram.rules
mode: '0644' mode: '0644'
- name: Lower swappiness - name: Lower swappiness
become: true
ansible.builtin.copy: ansible.builtin.copy:
content: vm.swappiness=10 content: vm.swappiness=10
dest: /etc/sysctl.d/99-bc250.conf dest: /etc/sysctl.d/99-bc250.conf
@@ -42,7 +38,6 @@
register: sysctl_conf register: sysctl_conf
- name: Apply swappiness now - name: Apply swappiness now
become: true
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- sysctl - sysctl
@@ -51,7 +46,6 @@
changed_when: true changed_when: true
- name: Create the swap subvolume - name: Create the swap subvolume
become: true
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- btrfs - btrfs
@@ -62,7 +56,6 @@
creates: /swap creates: /swap
- name: Create the swapfile - name: Create the swapfile
become: true
ansible.builtin.command: ansible.builtin.command:
argv: argv:
- btrfs - btrfs
@@ -77,7 +70,6 @@
creates: /swap/swapfile creates: /swap/swapfile
- name: Add the swapfile to fstab - name: Add the swapfile to fstab
become: true
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/fstab path: /etc/fstab
regexp: '^/swap/swapfile' regexp: '^/swap/swapfile'
@@ -87,6 +79,5 @@
ansible.builtin.meta: flush_handlers ansible.builtin.meta: flush_handlers
- name: Reboot to apply the new kernel parameters - name: Reboot to apply the new kernel parameters
become: true
ansible.builtin.reboot: ansible.builtin.reboot:
reboot_timeout: 600 reboot_timeout: 600
-2
View File
@@ -1,6 +1,5 @@
# community.general.pacman ignores the repo/pkg syntax, so call pacman. # community.general.pacman ignores the repo/pkg syntax, so call pacman.
- name: Install the patched Mesa stack - name: Install the patched Mesa stack
become: true
ansible.builtin.command: ansible.builtin.command:
argv: "{{ ['pacman', '-S', '--noconfirm'] + (mesa_stack | map('regex_replace', '^', 'bc250-cachyos/') | list) }}" argv: "{{ ['pacman', '-S', '--noconfirm'] + (mesa_stack | map('regex_replace', '^', 'bc250-cachyos/') | list) }}"
register: mesa_install register: mesa_install
@@ -20,7 +19,6 @@
# Pin last: IgnorePkg outranks the repo/pkg syntax, so writing it before # Pin last: IgnorePkg outranks the repo/pkg syntax, so writing it before
# the install would make pacman prompt instead of proceeding. # the install would make pacman prompt instead of proceeding.
- name: Pin the Mesa stack against upstream upgrades - name: Pin the Mesa stack against upstream upgrades
become: true
ansible.builtin.lineinfile: ansible.builtin.lineinfile:
path: /etc/pacman.conf path: /etc/pacman.conf
regexp: '^IgnorePkg\s*=' regexp: '^IgnorePkg\s*='
+7
View File
@@ -0,0 +1,7 @@
users__desktop_user: deck
# Groups that grant administrative rights: wheel for sudo and polkit, sys for
# CUPS administration.
users__admin_groups:
- wheel
- sys
+5
View File
@@ -0,0 +1,5 @@
# A reload keeps established sessions, including Ansible's own.
- name: Reload sshd
ansible.builtin.systemd_service:
name: sshd
state: reloaded
+65
View File
@@ -0,0 +1,65 @@
# Runs as the installer's desktop user until root is reachable with a key,
# then switches over and strips that user of its admin rights.
- name: Authorize the SSH key for root
become: true
ansible.posix.authorized_key:
user: root
key: "{{ lookup('ansible.builtin.file', install_ssh_keys__ssh_pubkey_path | expanduser) }}"
# Empty passwords make Ansible skip sshpass and fall back to the key.
- name: Switch the connection to root
ansible.builtin.set_fact:
ansible_user: root
ansible_ssh_pass: ''
ansible_become_password: ''
- name: Drop the desktop user connection
ansible.builtin.meta: reset_connection
# Arch already allows root logins with a key. Stop here, with sshd and the
# desktop user untouched, if root can't get in.
- name: Check root login
ansible.builtin.ping:
- name: Deploy the sshd configuration
ansible.builtin.template:
src: sshd.conf.j2
dest: /etc/ssh/sshd_config.d/01-bc250.conf
mode: '0644'
notify: Reload sshd
- name: Validate the sshd configuration
ansible.builtin.command:
argv:
- sshd
- -t
changed_when: false
- name: Apply the sshd configuration
ansible.builtin.meta: flush_handlers
- name: Grant the desktop user the udisks actions Steam needs
ansible.builtin.template:
src: deck.rules.j2
dest: /etc/polkit-1/rules.d/50-bc250-{{ users__desktop_user }}.rules
mode: '0644'
- name: Read the group database
ansible.builtin.getent:
database: group
- name: Remove the desktop user from the admin groups
ansible.builtin.user:
name: "{{ users__desktop_user }}"
groups: >-
{{ ansible_facts.getent_group | dict2items
| selectattr('value.2', 'search', '(^|,)' ~ users__desktop_user ~ '(,|$)')
| map(attribute='key')
| difference(users__admin_groups) }}
append: false
# '!' with no hash: password logins are impossible, SDDM autologin still works.
- name: Remove and lock the desktop user password
ansible.builtin.user:
name: "{{ users__desktop_user }}"
password: '!'
+17
View File
@@ -0,0 +1,17 @@
// {{ ansible_managed }}
// org.valve.holo.rules only grants these to wheel. Steam needs them to eject
// and power off drives from Game Mode, where no polkit agent can prompt.
polkit.addRule(function(action, subject) {
var permission = {
"org.freedesktop.udisks2.eject-media": polkit.Result.YES,
"org.freedesktop.udisks2.power-off-drive": polkit.Result.YES,
"org.freedesktop.udisks2.filesystem-unmount-others": polkit.Result.YES,
"org.freedesktop.udisks2.eject-media-other-seat": polkit.Result.YES,
"org.freedesktop.udisks2.power-off-drive-other-seat": polkit.Result.YES,
};
if (subject.user == "{{ users__desktop_user }}") {
return permission[action.id];
}
});
+6
View File
@@ -0,0 +1,6 @@
# {{ ansible_managed }}
PermitRootLogin prohibit-password
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers root
+25
View File
@@ -1,3 +1,28 @@
- name: Manage users
hosts: bc250
tags:
- 'never'
- 'users'
vars:
ansible_user: deck
ansible_ssh_pass: deck
ansible_become_password: deck
pre_tasks:
- name: Inserisci il percorso della chiave pubblica
run_once: true # noqa: run-once[task]
ansible.builtin.pause:
prompt: |-
Inserisci il percorso della chiave pubblica [~/.ssh/id_ed25519.pub]
register: install_ssh_keys__ssh_pubkey_path
- name: Imposta il percorso della chiave pubblica
run_once: true # noqa: run-once[task]
ansible.builtin.set_fact:
install_ssh_keys__ssh_pubkey_path: "{{ install_ssh_keys__ssh_pubkey_path.user_input or '~/.ssh/id_ed25519.pub' }}"
roles:
- name: Manage the users
role: users
- name: Configure the BC250 - name: Configure the BC250
hosts: bc250 hosts: bc250
roles: roles: