# 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): ```bash ssh -o ConnectTimeout=10 -J root@10.20.30.153 pi@10.20.50.147 ``` 2. **Edit with nano** (or `vi` if you prefer): ```bash 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): ```bash 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:** ```bash # 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:** ```bash 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 don’t 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: ```yaml #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.