Files
ansible/docs/superpowers/plans/2026-05-29-raspberry-pi-ansible-management.md
2026-06-04 01:45:16 +02:00

252 lines
6.5 KiB
Markdown

# Raspberry Pi Ansible Management Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add `naruto` and `pi` Raspberry Pis to Ansible inventory under a new `raspberry_pi` role, starting with `common` as the base.
**Architecture:** New inventory group `raspberry_pi` with a dedicated role of the same name. The playbook applies both `common` and `raspberry_pi` roles. Two ARM incompatibilities in `extra_packages.yaml` are fixed in the `common` role itself so all future ARM hosts benefit.
**Tech Stack:** Ansible, Debian 11 (Bullseye), aarch64
---
## File Map
| Action | Path | Responsibility |
|--------|------|----------------|
| Create | `vars/raspberry_pi.ini` | Inventory group with naruto and pi |
| Create | `vars/group_vars/raspberry_pi/vars.yaml` | Group-level vars (empty, inherits from `all`) |
| Modify | `roles/common/tasks/extra_packages.yaml` | Fix `bottom` arch and Neovim AppImage for ARM |
| Create | `roles/raspberry_pi/tasks/main.yaml` | Role entry point, placeholder for future Pi tasks |
| Create | `playbooks/raspberry-pi.yaml` | Playbook targeting `raspberry_pi` group |
---
### Task 1: Add inventory and group vars
**Files:**
- Create: `vars/raspberry_pi.ini`
- Create: `vars/group_vars/raspberry_pi/vars.yaml`
- [ ] **Create inventory file**
```ini
[raspberry_pi]
naruto
pi
```
Save to `vars/raspberry_pi.ini`.
- [ ] **Create group vars file**
```yaml
---
```
Save to `vars/group_vars/raspberry_pi/vars.yaml`. Empty for now — both hosts inherit all vars from `vars/group_vars/all/`.
- [ ] **Verify Ansible can see both hosts**
```bash
ansible raspberry_pi --list-hosts
```
Expected output:
```
hosts (2):
naruto
pi
```
- [ ] **Commit**
```bash
git add vars/raspberry_pi.ini vars/group_vars/raspberry_pi/vars.yaml
git commit -m "feat(raspberry_pi): add inventory and group vars"
```
---
### Task 2: Fix ARM incompatibilities in `common/tasks/extra_packages.yaml`
**Files:**
- Modify: `roles/common/tasks/extra_packages.yaml`
Two issues to fix:
**Issue 1 — `bottom` deb URL is hardcoded to `amd64`.** The global `arch` variable already resolves to `arm64` on aarch64 hosts.
**Issue 2 — Neovim AppImage doesn't run on aarch64.** `neovim` is already installed via apt in `common_packages`, so on ARM we skip the AppImage entirely and the apt version is used.
- [ ] **Fix `bottom` URL to use `arch` variable**
In `roles/common/tasks/extra_packages.yaml`, replace:
```yaml
- name: Install bottom package
ansible.builtin.apt:
deb: https://github.com/ClementTsang/bottom/releases/download/0.9.6/bottom_0.9.6_amd64.deb
state: present
become: true
```
With:
```yaml
- name: Install bottom package
ansible.builtin.apt:
deb: https://github.com/ClementTsang/bottom/releases/download/0.9.6/bottom_0.9.6_{{ arch }}.deb
state: present
become: true
```
- [ ] **Add `when: ansible_architecture != 'aarch64'` to all Neovim AppImage tasks**
Replace the six Neovim AppImage tasks (from "Check if Neovim is already installed" through "Remove Neovim AppImage") with the version below. The neovim config clone tasks at the end are architecture-independent and stay unchanged.
```yaml
- name: Check if Neovim is already installed
ansible.builtin.command: "which nvim"
register: neovim_installed
changed_when: false
ignore_errors: true
when: ansible_architecture != 'aarch64'
- name: Download Neovim AppImage
ansible.builtin.get_url:
url: https://github.com/neovim/neovim/releases/download/v0.10.0/nvim.appimage
dest: /tmp/nvim.appimage
mode: "0755"
when: ansible_architecture != 'aarch64' and neovim_installed.rc != 0
register: download_result
- name: Extract Neovim AppImage
ansible.builtin.command:
cmd: "./nvim.appimage --appimage-extract"
chdir: /tmp
when: ansible_architecture != 'aarch64' and download_result.changed
register: extract_result
- name: Copy extracted Neovim files to /usr
ansible.builtin.copy:
src: /tmp/squashfs-root/usr/
dest: /usr/
remote_src: true
mode: "0755"
become: true
when: ansible_architecture != 'aarch64' and extract_result.changed
- name: Clean up extracted Neovim files
ansible.builtin.file:
path: /tmp/squashfs-root
state: absent
when: ansible_architecture != 'aarch64' and extract_result.changed
- name: Remove Neovim AppImage
ansible.builtin.file:
path: /tmp/nvim.appimage
state: absent
when: ansible_architecture != 'aarch64' and download_result.changed
```
- [ ] **Commit**
```bash
git add roles/common/tasks/extra_packages.yaml
git commit -m "fix(common): support aarch64 in extra_packages"
```
---
### Task 3: Create `raspberry_pi` role
**Files:**
- Create: `roles/raspberry_pi/tasks/main.yaml`
- [ ] **Create role task entry point**
```yaml
---
```
Save to `roles/raspberry_pi/tasks/main.yaml`. Intentionally empty for now — Pi-specific workloads (Newt on naruto, docker stack on pi) are added in future tasks.
- [ ] **Commit**
```bash
git add roles/raspberry_pi/tasks/main.yaml
git commit -m "feat(raspberry_pi): add empty role scaffold"
```
---
### Task 4: Create playbook
**Files:**
- Create: `playbooks/raspberry-pi.yaml`
- [ ] **Create playbook**
```yaml
---
- name: Set up Raspberry Pis
hosts: raspberry_pi
gather_facts: true
roles:
- role: common
tags:
- common
- role: raspberry_pi
tags:
- raspberry_pi
```
Save to `playbooks/raspberry-pi.yaml`.
- [ ] **Commit**
```bash
git add playbooks/raspberry-pi.yaml
git commit -m "feat(raspberry_pi): add playbook"
```
---
### Task 5: Run and verify
- [ ] **Dry-run against both hosts**
```bash
ansible-playbook playbooks/raspberry-pi.yaml --check
```
Note: the `apt upgrade` task will fail in check mode without `python3-apt` on the remote (same issue seen with mii). If it fails there, proceed to the real run.
- [ ] **Run for real**
```bash
ansible-playbook playbooks/raspberry-pi.yaml
```
Expected: all tasks `ok` or `changed`, no failures. Watch for:
- `bottom` task — should download `arm64` deb
- Neovim AppImage tasks — should be skipped on both hosts
- Hostname task — `pi` will be renamed from `raspberrypi` to `pi`
- [ ] **Verify hostname on pi was updated**
```bash
ssh pi "hostname"
```
Expected: `pi`
- [ ] **Verify bottom installed correctly on both**
```bash
ansible raspberry_pi -a "btm --version"
```
Expected: version string printed for both hosts, no errors.