From ca0271ba444b38a5c7aa6fde567ffa5c79ad21a3 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Sat, 19 Sep 2026 20:41:07 +0200 Subject: [PATCH] Disable the Raspberry Pi first-boot user wizard Removing the SSH banner only hid the symptom. userconfig.service is a Type=oneshot unit that runs whiptail --inputbox "Which user would you like to rename:" 20 60 pi on tty8 and waits for an answer, which on a headless Pi never comes - it had been sitting in "activating" for four and a half hours on musicdolphin. It is WantedBy=multi-user.target, so that target never finished activating either, and the boot job for it was still queued from boot. Anything ordered After=multi-user.target then gets a start job that queues behind it and hangs forever: musicmouse.service never started, and the ansible task that starts it blocked until killed. The pi user already exists on these images, so the wizard has nothing to do. Co-Authored-By: Claude Opus 5 --- roles/pi_standard_setup/tasks/main.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/roles/pi_standard_setup/tasks/main.yml b/roles/pi_standard_setup/tasks/main.yml index d9f29de..e1eb43c 100644 --- a/roles/pi_standard_setup/tasks/main.yml +++ b/roles/pi_standard_setup/tasks/main.yml @@ -32,6 +32,25 @@ path: /etc/ssh/sshd_config.d/rename_user.conf state: absent notify: Restart sshd +- name: Check for the Raspberry Pi first-boot user wizard + ansible.builtin.stat: + path: /lib/systemd/system/userconfig.service + register: pi_standard_setup_userconfig + +- name: Disable the Raspberry Pi first-boot user wizard + # Removing the SSH banner above only hides the symptom. The wizard itself is a + # Type=oneshot unit that runs `whiptail --inputbox "Which user would you like to + # rename:"` on tty8 and waits for an answer that never comes on a headless box - it + # sits in "activating" forever. Because it is WantedBy=multi-user.target, that target + # never finishes activating either, and every unit ordered After=multi-user.target + # (musicmouse.service among them) gets a start job that queues behind it and hangs. + # The pi user already exists on these images, so there is nothing for it to do. + ansible.builtin.systemd: + name: userconfig.service + state: stopped + enabled: false + masked: true + when: pi_standard_setup_userconfig.stat.exists - name: Get hostname ansible.builtin.command: "raspi-config nonint get_hostname" register: pi_standard_setup_pi_hostname