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

122 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 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:
```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.