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.
This commit is contained in:
nearxos
2026-02-24 00:19:40 +02:00
parent df180120aa
commit 808fbf5c7c
136 changed files with 407837 additions and 2 deletions

View File

@@ -0,0 +1,121 @@
# 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.