Files
reterminal-dm4/emmc-provisioning/docs/EDIT-CLOUDINIT-ON-DEVICE.md
nearxos 808fbf5c7c Refactor golden image handling in backup upload process</message>
<message>Update the _set_golden_from_path function to improve the handling of existing golden image files. Replace the existing unlink logic with a more robust method that safely removes files or broken symlinks using the missing_ok parameter. This change enhances the reliability of the backup upload process by ensuring that stale references are properly cleared before setting a new golden image path.
2026-02-24 00:19:40 +02:00

4.5 KiB
Raw Blame History

How to edit cloud-init files on the device before capturing the image

The cloud-init NoCloud files live on the boot partition. On the running device they are at:

File Path on device
user-data /boot/firmware/user-data
meta-data /boot/firmware/meta-data
network-config /boot/firmware/network-config

They are owned by root and need sudo to edit.


Method 1: Edit on the device over SSH

  1. SSH into the device (e.g. via jump host):

    ssh -o ConnectTimeout=10 -J root@10.20.30.153 pi@10.20.50.147
    
  2. Edit with nano (or vi if you prefer):

    sudo nano /boot/firmware/user-data
    sudo nano /boot/firmware/meta-data
    sudo nano /boot/firmware/network-config
    
  3. Save and exit: in nano, Ctrl+O then Enter to save, Ctrl+X to exit.

  4. YAML: use spaces only for indentation (no tabs). Wrong indentation can break cloud-init.


Method 2: Copy to your PC, edit, copy back

  1. Copy from device to your PC (from your project machine):

    scp -o ConnectTimeout=10 -J root@10.20.30.153 \
      pi@10.20.50.147:/boot/firmware/user-data   ./user-data
    scp -o ConnectTimeout=10 -J root@10.20.30.153 \
      pi@10.20.50.147:/boot/firmware/meta-data  ./meta-data
    scp -o ConnectTimeout=10 -J root@10.20.30.153 \
      pi@10.20.50.147:/boot/firmware/network-config ./network-config
    

    If you get "Permission denied" reading from /boot/firmware/, on the device run:
    sudo cp /boot/firmware/user-data /boot/firmware/meta-data /boot/firmware/network-config /tmp/ && sudo chmod 644 /tmp/user-data /tmp/meta-data /tmp/network-config
    then from your PC: scp -J root@10.20.30.153 pi@10.20.50.147:/tmp/user-data ./user-data (and same for meta-data, network-config).

  2. Edit user-data, meta-data, and network-config on your PC.

  3. Copy back (push from PC to device). Because the destination is root-owned, use a two-step on the device, or use root SSH:

    Option A copy to home then move with sudo:

    # On your PC: copy to pi's home
    scp -o ConnectTimeout=10 -J root@10.20.30.153 ./user-data ./meta-data ./network-config \
      pi@10.20.50.147:~/
    
    # Then on the device (SSH in as pi):
    sudo cp ~/user-data ~/meta-data ~/network-config /boot/firmware/
    sudo chmod 644 /boot/firmware/user-data /boot/firmware/meta-data /boot/firmware/network-config
    

    Option B if you have root SSH to the device:

    scp -o ConnectTimeout=10 -J root@10.20.30.153 ./user-data root@10.20.50.147:/boot/firmware/
    scp -o ConnectTimeout=10 -J root@10.20.30.153 ./meta-data root@10.20.50.147:/boot/firmware/
    scp -o ConnectTimeout=10 -J root@10.20.30.153 ./network-config root@10.20.50.147:/boot/firmware/
    

What to edit (typical)

  • meta-data

    • instance_id: change if you want cloud-init to treat this as a new instance (e.g. per device).
    • Add local-hostname: guard (or your hostname) so the hostname is set on first boot.
  • user-data

    • Uncomment and set hostname: ... if you dont use meta-data hostname.
    • To run your first-boot script from the provisioning server, add a runcmd section that downloads and runs it (see cloud-init/user-data-remote-gnss.example in the repo).
    • In that runcmd, set the FILE_SERVER URL to match your deployment network (e.g. http://10.20.50.1:5000/files/first-boot or your LXC IP).
  • network-config

    • Uncomment and adjust if you need static IP or specific WiFi; otherwise DHCP is usually enough.

Example: minimal user-data that runs first-boot from your server

You can replace (or add to) the default template with something like this, and adjust the URL to your file server:

#cloud-config
package_update: true
package_upgrade: false
packages: [curl]

runcmd:
  - curl -fsSL "http://10.20.50.1:5000/files/first-boot.sh" -o /tmp/first-boot.sh
  - curl -fsSL "http://10.20.50.1:5000/files/first-boot.conf" -o /tmp/first-boot.conf
  - chmod +x /tmp/first-boot.sh
  - /tmp/first-boot.sh

Full example with user, SSH, and optional first-boot config: emmc-provisioning/cloud-init/user-data-remote-gnss.example.


After editing

  • No reboot needed for the edits to “take effect”; they are just files on the boot partition.
  • When you capture the image (backup), the boot partition is included, so the updated user-data, meta-data, and network-config will be on the golden image.
  • On first boot after deploy, cloud-init reads these files and runs accordingly.