Every script/config built this session (sanity-check, attacker-check, the Gitea backup pipeline on both ends) now lives in this repo as reference copies, not just described in prose - previously they only existed on the live servers. Split into scripts/alpha/ (Ubuntu 24.04.4 LTS) and scripts/clients/vlda-01/ (Unraid 7.3.2), each with its own README stating the exact OS/kernel and a file-by-file map to deployed paths, since a script written for one host's conventions doesn't just work unchanged on the other - the vlda-01 README in particular documents the persistence gotchas that actually broke earlier attempts (RAM- backed root filesystem, VFAT /boot with no execute bit, Unassigned Device auto-mount). Root README.md now links directly to these files from each relevant section instead of only describing them. Explicitly not included: the dedicated SSH private key vlda-01 uses to authenticate to alpha - noted in clients/vlda-01/README.md to regenerate rather than ever commit one. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
62 lines
4.4 KiB
Markdown
62 lines
4.4 KiB
Markdown
# Scripts running on `vlda-01`
|
|
|
|
**OS**: Unraid `7.3.2`, kernel `6.18.38-Unraid`. **Very different
|
|
persistence model from Ubuntu/`alpha`** — this tripped up the first version
|
|
of every script here, so it's worth stating plainly before anything else:
|
|
|
|
- `/` and `/usr` are RAM-backed (`rootfs` / an `overlay` on top of the
|
|
read-only squashfs image loaded from the boot USB stick). **Anything
|
|
written there — a plain crontab, a script dropped in `/usr/local/sbin`
|
|
— is silently gone on the next reboot.** Only `/boot` (the actual USB
|
|
stick, mounted read/write as a normal filesystem) survives.
|
|
- `/boot` is **VFAT**, which has no concept of a Unix execute bit at all.
|
|
A script stored there can never be `chmod +x`'d in any way that sticks —
|
|
don't try to `exec` it directly from another script; invoke it via
|
|
`bash <path>` instead. (The **User Scripts** plugin itself handles this
|
|
correctly when it runs a script *through the plugin* — it copies the
|
|
content to a RAM-backed tmp location and `chmod +x`s that copy before
|
|
running it — but a script invoking *another* script directly, as the
|
|
`-onboot` wrapper here does, has to work around it manually.)
|
|
- Real, persistent storage lives on the array (`/mnt/user/...`) or on
|
|
**Unassigned Devices** — extra disks attached but not part of the
|
|
protected array, mounted at `/mnt/disks/<label>` — which is where these
|
|
backups actually land. An Unassigned Device is **not guaranteed to
|
|
already be mounted** when a script runs; see `gitea-backup-pull`'s own
|
|
handling of this below.
|
|
- Scheduled tasks persist via the **User Scripts** plugin (already
|
|
installed, already used for this box's other maintenance), which stores
|
|
scripts under `/boot/config/plugins/user.scripts/scripts/<name>/` and
|
|
scheduling in `/boot/config/plugins/user.scripts/schedule.json` — both
|
|
on the persistent USB stick. `update_cron` folds the JSON's cron-style
|
|
entries into the live `/etc/cron.d/root` at every boot; `"frequency":
|
|
"boot"` entries instead run once via the plugin's own `disks_mounted`
|
|
array-start event hook, **not** through cron at all.
|
|
- SSH keys under `/root/.ssh` needed no special persistence handling —
|
|
Unraid already auto-mirrors that whole directory to
|
|
`/boot/config/ssh/root/` on its own.
|
|
|
|
## Files, and where they're actually deployed
|
|
|
|
| File here | Deployed path | Purpose |
|
|
|---|---|---|
|
|
| `user-scripts/gitea-backup-pull/script` | `/boot/config/plugins/user.scripts/scripts/gitea-backup-pull/script` | Pulls new `gitea-dump` archives from `alpha` via the restricted `giteabackup` SFTP account, verifies each one's sha256 checksum, deletes both files on `alpha` only after a confirmed match, prunes its own local retention (30). Resolves and mounts the `WSD2L840` Unassigned Device itself first — see the script's own header comment for the full reasoning. |
|
|
| `user-scripts/gitea-backup-pull/description` | `.../gitea-backup-pull/description` | Shown in the User Scripts UI. |
|
|
| `user-scripts/gitea-backup-pull-onboot/script` | `.../gitea-backup-pull-onboot/script` | One-line wrapper: `bash`-invokes the script above. Exists only because `schedule.json` supports one schedule per script *path* — this is how the "also run once at every restart" requirement was added alongside the existing daily `03:30` schedule without disturbing it. |
|
|
| `user-scripts/gitea-backup-pull-onboot/description` | `.../gitea-backup-pull-onboot/description` | Shown in the User Scripts UI. |
|
|
| `user-scripts/schedule.json` | `/boot/config/plugins/user.scripts/schedule.json` | **Whole file, as deployed** — includes entries for this box's *other*, pre-existing scheduled maintenance (`delete_dangling_images`, `rc.fancontrol`, etc.) that predate this project and aren't described elsewhere in this repo. Only the `gitea-backup-pull` and `gitea-backup-pull-onboot` entries near the bottom belong to this project. |
|
|
|
|
## Redeploying from this checked-in copy
|
|
|
|
```bash
|
|
# on vlda-01:
|
|
mkdir -p /boot/config/plugins/user.scripts/scripts/gitea-backup-pull
|
|
mkdir -p /boot/config/plugins/user.scripts/scripts/gitea-backup-pull-onboot
|
|
# copy script/description files into place from this repo, then:
|
|
cp /boot/config/plugins/user.scripts/schedule.json /tmp/user.scripts/schedule.json
|
|
/usr/local/sbin/update_cron
|
|
```
|
|
The dedicated ed25519 keypair this depends on (`/root/.ssh/gitea-backup/`,
|
|
authorized on `alpha`'s `giteabackup` account) is **not** in this repo —
|
|
regenerate it and re-authorize the new public key on `alpha` rather than
|
|
ever committing a private key here.
|