#cloud-config # {{ ansible_managed }} -- rendered by `make bootfs BOOTFS=...` # # First boot of the label print proxy. The job of this file is to make the Pi # REACHABLE and nothing more: a login that works, a network that works, and a # rescue access point for when it does not. The printer driver and the CUPS # queue are Ansible's job -- see roles/labelprint/. # # The Wi-Fi profiles and the rescue watchdog below are rendered from the very # same templates the role uses, so the first `make deploy-labelprint` reports no # change on any of them. That is the point: the Pi can already rescue itself # before Ansible has ever run. # # Applies on FIRST BOOT ONLY. Rewriting this file on a card that has already # booted does nothing -- reflash the image. hostname: {{ labelprint_hostname }} manage_etc_hosts: true manage_resolv_conf: false timezone: America/New_York keyboard: model: pc105 layout: "us" apt: preserve_sources_list: true users: - name: {{ labelprint_user }} shell: /bin/bash lock_passwd: false # Deliberately trivial, and deliberately not hashed: this password is # documented in roles/labelprint/README.md, so a hash of it would protect # nothing while pretending otherwise. It exists so that a Pi which will not # take the SSH key -- wrong key, reflashed card, someone else's laptop -- is # still reachable from the LAN or the rescue AP, which is the only place it # can be reached from at all (see templates/nftables.conf.j2). plain_text_passwd: {{ labelprint_user_password }} sudo: "ALL=(ALL) NOPASSWD:ALL" groups: [sudo, adm, lpadmin, plugdev, dialout, netdev, users] ssh_authorized_keys: - {{ lookup('file', labelprint_authorized_key_file) }} # The key is what Ansible actually uses; the password is the fallback. ssh_pwauth: true disable_root: true chpasswd: expire: false # Pre-installing what the role needs makes the first deploy quick, and means a # Pi that comes up on the rescue AP with no internet still has cups and # NetworkManager. Ansible installs the same list, so nothing here is load-bearing. package_update: true packages: {% for pkg in labelprint_deps %} - {{ pkg }} {% endfor %} write_files: # Stop cloud-init rewriting the network on a future re-instance. - path: /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg owner: root:root permissions: '0644' content: | network: {config: disabled} # Belt and braces. netplan can hand NetworkManager an "only manage what I # listed" policy, and what this image lists is eth0; a stock Raspberry Pi OS # leaves that policy empty, but an unmanaged wlan0 would take the rescue AP # down with it, so it is not worth depending on. - path: /etc/NetworkManager/conf.d/10-labelprint.conf owner: root:root permissions: '0644' content: | [keyfile] unmanaged-devices=none [device] # A randomised MAC would give the Pi a different DHCP lease on every # association, which makes it hard to find on the UDM Pro's client list. wifi.scan-rand-mac-address=no - path: /etc/NetworkManager/system-connections/home-wifi.nmconnection owner: root:root permissions: '0600' content: | {{ lookup('template', 'roles/labelprint/templates/home-wifi.nmconnection.j2') | indent(6) }} - path: /etc/NetworkManager/system-connections/rescue-ap.nmconnection owner: root:root permissions: '0600' content: | {{ lookup('template', 'roles/labelprint/templates/rescue-ap.nmconnection.j2') | indent(6) }} - path: /usr/local/sbin/wifi-rescue owner: root:root permissions: '0755' content: | {{ lookup('template', 'roles/labelprint/templates/wifi-rescue.sh.j2') | indent(6) }} - path: /etc/systemd/system/wifi-rescue.service owner: root:root permissions: '0644' content: | {{ lookup('template', 'roles/labelprint/templates/wifi-rescue.service.j2') | indent(6) }} - path: /etc/systemd/system/wifi-rescue.timer owner: root:root permissions: '0644' content: | {{ lookup('template', 'roles/labelprint/templates/wifi-rescue.timer.j2') | indent(6) }} runcmd: # RPi OS soft-blocks the radio until a regulatory domain is known. cmdline.txt # carries cfg80211.ieee80211_regdom=US, but unblock anyway -- a blocked radio # is the one failure that takes the rescue AP down with it. - [rfkill, unblock, wifi] - [systemctl, enable, --now, ssh] - [systemctl, enable, --now, avahi-daemon] # Let NetworkManager pick up the keyfiles written above. The profile netplan # renders from network-config is left alone on purpose -- see the "Coexisting # with netplan" note in roles/labelprint/tasks/wifi.yml. - [nmcli, connection, reload] - [systemctl, daemon-reload] - [systemctl, enable, --now, wifi-rescue.timer]