Martin Bauer a973bc8d75 Make the kiosk autologin survive a reboot, and allow forcing a display mode
Two problems on musicdolphin, found after its first reboot.

getty@tty1 was never enabled. The role installed the autologin drop-in and the
handler restarted the unit, which works until the next boot - these images do
not enable getty@tty1 themselves, getty.target pulls in getty-static.service and
nothing else, so after a reboot nobody logs in and the kiosk never starts. Enable
it as well as starting it.

And the attached screen reads back 0 bytes of EDID on both micro-HDMI ports while
reporting "disconnected", so the kernel offers no modes, no framebuffer is
created, and X exits with "no screens found". That is the signature of a cable or
adapter whose DDC/HPD lines are broken but whose video pairs are fine. Forcing
the connector on is not enough on its own - with no EDID there is still no mode
to set - so allow a `video=` kernel parameter, which forces the output and names
the mode. hdmi_force_hotplug=1 is no use here; vc4-kms-v3d ignores it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-20 12:10:34 +02:00
2024-07-28 08:45:01 +02:00
2026-09-19 16:28:00 +02:00
2026-09-10 21:33:19 +02:00
2026-09-19 16:28:00 +02:00
2026-09-10 21:33:19 +02:00

ansible

Personal Ansible setup for provisioning and maintaining a fleet of Raspberry Pis (audio players, sensors, music mouse, etc.) plus one home server.

Layout

  • inventory.yml — hosts and group vars (Pis under iot, plus server). group_vars/ and host_vars/ hold vars for the mediapis group (the four parallel audio-player Pis) and their host-specific overrides.
  • mediapis.yml, working.yml, server.yml, newrpi-provisioning.yml, octopisetup.yml — top-level playbooks. mediapis.yml is the canonical playbook for the mediapis group (musicdolphin, kitchenpi, bedroompi, musicmouse); the others are narrower/ad-hoc runs kept around for specific hosts or one-off tasks.
  • roles/ — one role per piece of functionality (audio backends, sensors, bluetooth monitoring, server basics, etc.). Each has a short README.md.
  • update-packages.yml — deliberate, fleet-wide package update (see "Keeping packages up to date" below). update-packages-pinned-example.yml is a template for pinning or bumping a single package outside that.
  • lookup_plugins/keepass.py — custom lookup plugin that fetches secrets (device passwords, wifi passphrase) from a running KeePassXC instance via its browser-integration protocol, instead of storing them in the repo.
  • pis/ — loose config files/scripts used when provisioning Pis by hand.
  • scripts/ — standalone helper scripts (Raspbian image creation, a network logger) that aren't Ansible roles.
  • archive/ — retired setups kept for reference (not actively maintained).

Setup

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Secrets are pulled from KeePassXC at run time via the keepass lookup plugin — see the header of lookup_plugins/keepass.py for how to enable Browser Integration in KeePassXC. Freshly-flashed Raspberry Pis are reached first with the OS-default pi/raspberry credentials (see roles/pi_standard_setup), which the role then rotates to a KeePassXC-managed password.

Running a playbook

ansible-playbook mediapis.yml --limit <host>

ansible.cfg points Ansible at inventory.yml and roles/ by default, so no extra flags are needed for those.

Keeping packages up to date

Regular playbook runs (mediapis.yml, server.yml, etc.) use state: present for packages, so they only install what's missing — they never upgrade anything as a side effect of an unrelated config change. Two separate, deliberate mechanisms handle upgrades instead:

Security patches — automatic. The unattended_upgrades role (applied to every host in mediapis.yml/server.yml) configures unattended-upgrades to install security-origin updates automatically, with a scheduled reboot window (default 03:00, see roles/unattended_upgrades/defaults/main.yml) for patches that need one. Not scoped to full dist-upgrades.

Everything else — deliberate, ad hoc.

just update <host_or_group>          # e.g. `just update kitchenpi` or `just update`
venv/bin/ansible-playbook update-packages.yml --limit <host> --check --diff   # dry run first

Defaults to upgrade: safe (upgrades in place, never installs/removes packages to resolve dependencies — see the comment header in update-packages.yml for the tradeoff against dist). There is no cron/ schedule wired up for this yet; run it ad hoc when you want the fleet updated, or add a crontab entry yourself (a starting point is documented in update-packages.yml's header).

To pin a package to an exact version, or deliberately bump one named package to latest outside this schedule, copy the pattern in update-packages-pinned-example.yml.

Description
No description provided
Readme 85 MiB
Languages
Jupyter Notebook 79.8%
Python 13.3%
Jinja 3.2%
C++ 1.7%
Shell 1.3%
Other 0.6%