Compare commits

...

2 Commits

Author SHA1 Message Date
nearxos
8233304ee2 Update documentation and .gitignore for improved deployment clarity and log management</message>
<message>Enhance the README files to provide clearer instructions for deploying the CM4 eMMC provisioning service on Proxmox, including detailed prerequisites and deployment steps. Update the .gitignore to exclude deploy logs generated during the deployment process, ensuring a cleaner repository. Additionally, refine archived documentation for better historical context and clarity on the active provisioning workflow.
2026-03-04 19:43:52 +02:00
nearxos
2a6355033e Remove obsolete files related to provisioning and custom scripts</message>
<message>Delete the start.elf file and several log files from the emmc-provisioning scripts, which are no longer needed for the deployment process. Additionally, remove the plymouth-custom.script file from the cloud-init duplicates archive, streamlining the project and reducing clutter in the repository.
2026-03-04 19:43:21 +02:00
10 changed files with 409 additions and 198 deletions

3
.gitignore vendored
View File

@@ -4,6 +4,9 @@
*.img *.img
!emmc-provisioning/network-boot-initramfs/*.img !emmc-provisioning/network-boot-initramfs/*.img
# Deploy logs (generated by deploy-to-proxmox.sh when DEPLOY_LOG=1)
emmc-provisioning/scripts/deploy-*.log
# Backup/data from devices (large DBs and logs) # Backup/data from devices (large DBs and logs)
backup-from-device/**/data/*.db backup-from-device/**/data/*.db
backup-from-device/**/logs/ backup-from-device/**/logs/

View File

@@ -22,6 +22,7 @@ A single **revision number** is kept in `REVISION` and in a comment line in trac
## Quick start ## Quick start
1. Read **emmc-provisioning/docs/EMMC-PROVISIONING-GUIDE.md** for full setup. 1. **New deployment:** Follow **[emmc-provisioning/docs/DEPLOY-NEW-PROXMOX.md](emmc-provisioning/docs/DEPLOY-NEW-PROXMOX.md)** for step-by-step instructions (Proxmox host prep → LXC deploy → network boot → portal files).
2. Use **emmc-provisioning/scripts/sync-portal-files-to-lxc.sh** to sync first-boot assets (including kiosk) to the file server. 2. **Sync first-boot assets** to the file server after deploy:
3. Provision devices via USB boot or network boot; first-boot configures kiosk, labwc, rotation, wallpaper, dark theme, and optional CM4 boot order. `./emmc-provisioning/scripts/sync-portal-files-to-lxc.sh root@<LXC-IP>`
3. Provision devices via USB boot or network boot; first-boot configures the Chromium kiosk, labwc Wayland desktop, screen rotation, wallpaper, dark theme, and CM4 boot order.

View File

@@ -1,10 +1,9 @@
# Archive # Archive
This folder holds files that are no longer part of the active reTerminal DM4 / eMMC provisioning workflow. Kept for reference only. This folder holds files that are no longer part of the active reTerminal DM4 / eMMC provisioning workflow. Kept for historical reference only.
| Subfolder | Contents | | Subfolder | Contents |
|-----------|----------| |-----------|----------|
| **chromium-setup-legacy/** | Old Chromium-setup guides and scripts: KDE installation, LED/buzzer control, audio config, touchscreen options, Flask apps, test scripts, revert-to-lxde. Kiosk assets (start-chromium.sh, chromium-kiosk.desktop) live in `emmc-provisioning/cloud-init/` and `emmc-provisioning/cloud-init/config-files/`. | | **chromium-setup-legacy/** | Old Chromium-setup guides and scripts: KDE installation, LED/buzzer control, audio config, touchscreen options, Flask apps, test scripts, revert-to-lxde. The active kiosk launcher lives at `emmc-provisioning/cloud-init/fileserver/start-chromium.sh` (Wayland/labwc). |
| **cloud-init-duplicates/** | Duplicate or superseded cloud-init files (e.g. plymouth-custom.script duplicate of `files-from-guard/plymouth-custom/custom.script`). |
Do not rely on archived files for deployment; use the main tree under **emmc-provisioning/**. Do not rely on archived files for deployment; use the active tree under **emmc-provisioning/**.

View File

@@ -1,40 +0,0 @@
screen_width = Window.GetWidth();
screen_height = Window.GetHeight();
theme_image = Image("splash.png");
image_width = theme_image.GetWidth();
image_height = theme_image.GetHeight();
scale_x = image_width / screen_width;
scale_y = image_height / screen_height;
if (scale_x > 1 || scale_y > 1)
{
if (scale_x > scale_y)
{
resized_image = theme_image.Scale(screen_width, image_height / scale_x);
image_x = 0;
image_y = (screen_height - ((image_height * screen_width) / image_width)) / 2;
}
else
{
resized_image = theme_image.Scale(image_width / scale_y, screen_height);
image_x = (screen_width - ((image_width * screen_height) / image_height)) / 2;
image_y = 0;
}
}
else
{
resized_image = theme_image.Scale(image_width, image_height);
image_x = (screen_width - image_width) / 2;
image_y = (screen_height - image_height) / 2;
}
if (Plymouth.GetMode() != "shutdown")
{
sprite = Sprite(resized_image);
sprite.SetPosition(image_x, image_y, -100);
}
fun message_callback(text) {
}

View File

@@ -13,12 +13,19 @@ Revisions are tracked project-wide; see repo root **README.md** and `scripts/bum
emmc-provisioning/ emmc-provisioning/
├── README.md ← You are here ├── README.md ← You are here
├── docs/ Documentation ├── docs/ Documentation
│ ├── DEPLOY-NEW-PROXMOX.md Step-by-step: deploy to a new Proxmox instance │ ├── DEPLOY-NEW-PROXMOX.md ★ START HERE: full deploy guide (host prep, LXC, scripts, network boot)
│ ├── EMMC-PROVISIONING-GUIDE.md Full setup and usage │ ├── EMMC-PROVISIONING-GUIDE.md Golden image creation, cloud-init, PiShrink
│ ├── NETWORK-BOOT-LXC.md Network boot (PXE/dnsmasq) and LXC │ ├── PROXMOX-LXC-DEPLOYMENT.md Reference: what is deployed, redeploy, troubleshooting
│ ├── NETWORK-BOOT-LXC.md Network boot architecture (PXE/dnsmasq, interfaces)
│ ├── NETWORK-BOOT-DEPLOYMENT-FLOW.md Full data flow for network boot provisioning
│ ├── NETWORK-BOOT-TROUBLESHOOTING.md Troubleshooting network boot issues
│ ├── DEVICE-DNS-DHCP-RESOLVCONF.md Device DNS from DHCP, resolv.conf, cloud-init │ ├── DEVICE-DNS-DHCP-RESOLVCONF.md Device DNS from DHCP, resolv.conf, cloud-init
│ ├── DNSMASQ-DNS-FILESERVER.md dnsmasq DNS and file.server on LXC │ ├── DNSMASQ-DNS-FILESERVER.md dnsmasq DNS and file.server on LXC
│ ├── PROXMOX-LXC-DEPLOYMENT.md Proxmox LXC + host setup (reference) │ ├── PROXMOX-HOST-COMPARISON.md Diff between Proxmox hosts (fixes checklist)
│ ├── PREPARE-IMAGE-FOR-CLOUDINIT.md How to shrink and prep a golden image
│ ├── BACKUP-DEVICE-CONFIG-AUDIT.md Audit of backup image contents
│ ├── DEVICE-REMOVABLE-PACKAGES.md Packages to purge from the device image
│ ├── EDIT-CLOUDINIT-ON-DEVICE.md Edit NoCloud files on-device or in .img.xz
│ └── PORTAL_STYLING_GUIDE.md Dashboard UI styling reference │ └── PORTAL_STYLING_GUIDE.md Dashboard UI styling reference
├── host/ Scripts that run on the provisioning host (Proxmox host) ├── host/ Scripts that run on the provisioning host (Proxmox host)
│ ├── flash-emmc-on-connect.sh rpiboot + wait for Backup/Deploy choice, then dd │ ├── flash-emmc-on-connect.sh rpiboot + wait for Backup/Deploy choice, then dd
@@ -55,8 +62,8 @@ emmc-provisioning/
## Quick start ## Quick start
1. **Read** [docs/EMMC-PROVISIONING-GUIDE.md](docs/EMMC-PROVISIONING-GUIDE.md) for setup and usage. 1. **New deployment:** Follow **[docs/DEPLOY-NEW-PROXMOX.md](docs/DEPLOY-NEW-PROXMOX.md)** — covers Proxmox host prep, LXC creation, host scripts, network boot, and portal file sync.
2. **Deploy to a new Proxmox:** Follow [docs/DEPLOY-NEW-PROXMOX.md](docs/DEPLOY-NEW-PROXMOX.md) for clear step-by-step instructions. 2. **Full setup reference:** [docs/EMMC-PROVISIONING-GUIDE.md](docs/EMMC-PROVISIONING-GUIDE.md) for golden image creation, cloud-init, PiShrink.
3. **Proxmox reference:** [scripts/deploy-to-proxmox.sh](scripts/deploy-to-proxmox.sh) and [docs/PROXMOX-LXC-DEPLOYMENT.md](docs/PROXMOX-LXC-DEPLOYMENT.md) for options, layout, and troubleshooting. 3. **Redeploy / update:** Re-run `scripts/deploy-to-proxmox.sh root@HOST` — updates scripts, dashboard, udev, and systemd without touching your golden image or enabled flag.
4. **Manual host:** Copy scripts from `host/` to the host and install the udev rule (see the guide). 4. **Sync portal files:** After deploy or when kiosk/first-boot assets change: `scripts/sync-portal-files-to-lxc.sh root@<LXC-IP>`.
5. Put **golden.img** in `/var/lib/cm4-provisioning/` (or your configured path). When a device is detected (USB or network), the **dashboard** asks **Backup** or **Deploy**. 5. **Troubleshooting:** [docs/PROXMOX-LXC-DEPLOYMENT.md](docs/PROXMOX-LXC-DEPLOYMENT.md) for USB errors, rpiboot failures, and monitoring. [docs/NETWORK-BOOT-TROUBLESHOOTING.md](docs/NETWORK-BOOT-TROUBLESHOOTING.md) for network boot issues.

View File

@@ -1,33 +1,86 @@
# Deploy CM4 eMMC Provisioning to a New Proxmox Instance # Deploying the CM4 eMMC Provisioning Stack to Proxmox
Step-by-step guide to deploy the provisioning service (host + LXC) on a **new** Proxmox server. For redeploy/update and troubleshooting, see [PROXMOX-LXC-DEPLOYMENT.md](PROXMOX-LXC-DEPLOYMENT.md). Complete step-by-step guide for deploying the provisioning service (Proxmox host + LXC container) on a new or existing Proxmox server. Covers host preparation, network bridge configuration, LXC deployment, post-deploy setup, network boot, and first-boot asset sync.
For reference details (troubleshooting, redeploy, architecture), see [PROXMOX-LXC-DEPLOYMENT.md](PROXMOX-LXC-DEPLOYMENT.md).
--- ---
## Prerequisites (before running the deploy script) ## Overview
| Requirement | Details | The provisioning stack consists of two parts that work together:
|-------------|---------|
| **Proxmox host** | A Proxmox VE node (new or existing) where you want the service. |
| **SSH as root** | You must be able to run `ssh root@YOUR_PROXMOX_HOST` with **key-based auth** (no password prompt). |
| **Proxmox storage** | At least one active storage (e.g. `local` or `local-lvm`). Check on the host: `pvesm status`. |
| **Host internet** (recommended) | Needed so the deploy script can download the Debian 12 LXC template (if missing), and install **usbboot** and **PiShrink** on the host. Without internet, deploy still runs but you must install usbboot and PiShrink manually later. |
**Optional (set before deploy):** | Component | Where it runs | What it does |
|-----------|--------------|--------------|
| **Host scripts + udev** | Proxmox host | Detects CM4 over USB, runs `rpiboot`, then `dd` to write/read the eMMC |
| **LXC container** (`cm4-provisioning`) | Proxmox LXC | Runs the Flask dashboard on port 5000; serves portal files and golden images |
- `DEPLOY_ROOTFS_STORAGE=local-lvm` — Skip interactive storage choice when creating the LXC. The host and LXC share `/var/lib/cm4-provisioning/` via a bind-mount, so images and status files are visible from both.
- `DEPLOY_LXC_ROOT_PASSWORD=yourpassword` — Set LXC root password and enable SSH.
- `DEPLOY_LXC_SSH_KEY=/path/to/pub` — Copy this key into the LXC (default: `~/.ssh/id_ed25519.pub` or `id_rsa.pub`). ```
- `CM4_BACKUPS_HOST_PATH=/mnt/storage/cm4-backups` — Store backups on this host path (create the directory on the host if needed). Workstation (this repo)
- **Network (WAN/LAN):**
`DEPLOY_LXC_WAN_BRIDGE=vmbr0` (default), `DEPLOY_LXC_WAN_IP=dhcp` (default), │ deploy-to-proxmox.sh (SSH + rsync)
`DEPLOY_LXC_LAN_BRIDGE=vmbr1`, `DEPLOY_LXC_LAN_SUBNET=10.20.50.1/24` — To add eth1 as provisioning LAN. **Set these if you want the portal reachable from the LAN** (e.g. http://10.20.50.1:5000); the dashboard listens on all interfaces.
Proxmox Host
├── udev → cm4-flash-trigger.sh → flash-emmc-on-connect.sh
├── /opt/cm4-provisioning/ (scripts, env)
├── /var/lib/cm4-provisioning/ (golden.img, backups, status.json) ◄──────┐
└── LXC: cm4-provisioning │ bind-mount
├── Flask dashboard :5000 │
├── /opt/cm4-provisioning/dashboard/ │
└── /var/lib/cm4-provisioning/ ◄────────────────────────────────────┘
```
--- ---
## Step 1: Run the deploy script ## Part 1 — Proxmox Host Prerequisites
From your **workstation** (where the repo is cloned), run: ### 1.1 Hardware & OS
- Proxmox VE 7 or 8 installed on a physical machine.
- At least one USB port accessible to the host (not passed through to a VM) for the reTerminal USB slave cable.
- At least one active storage (local or local-lvm). Check: `pvesm status`.
- Internet access on the host (needed for initial usbboot/PiShrink install and LXC template download).
### 1.2 SSH key access from your workstation
The deploy script connects as `root` using key-based auth. Set this up if not already done:
```bash
# On your workstation — copy your public key to the Proxmox host
ssh-copy-id root@YOUR_PROXMOX_HOST
# Verify
ssh root@YOUR_PROXMOX_HOST "echo OK"
```
### 1.3 Proxmox network bridges
The LXC needs at minimum one bridge for WAN access. For provisioning LAN (DHCP to devices), it needs a second bridge.
#### WAN bridge (required)
The default WAN bridge is `vmbr0`, which is created automatically by Proxmox during installation and connects to your primary network. No extra configuration needed.
#### LAN bridge for provisioning (required for network boot / device DHCP)
If you want the LXC to serve DHCP, TFTP, and DNS on a dedicated provisioning LAN (so devices can network-boot), create a second Linux bridge on the Proxmox host:
1. Open **Proxmox Web UI → Node → Network → Create → Linux Bridge**.
2. Set:
- **Name:** `vmbr1` (or any unused bridge name)
- **Bridge ports:** the physical NIC connected to your provisioning LAN switch (e.g. `enp2s0`). Leave blank for an internal-only bridge (useful for testing with no physical switch).
- **IPv4/CIDR:** leave blank (the LXC handles the IP on this bridge, not the host).
- **Autostart:** checked.
3. Click **Create**, then **Apply Configuration**.
> **Note:** If you connect the reTerminals via a switch that is also connected to `enp2s0`, traffic flows directly. If there is no physical NIC to dedicate, leave bridge ports blank and connect all provisioning devices as VMs/LXCs on the same internal bridge.
---
## Part 2 — Running the Deploy Script
From your **workstation** (where this repo is cloned), run a single command to deploy everything:
```bash ```bash
cd /path/to/reTerminal\ DM4 cd /path/to/reTerminal\ DM4
@@ -35,9 +88,26 @@ cd /path/to/reTerminal\ DM4
./emmc-provisioning/scripts/deploy-to-proxmox.sh root@YOUR_PROXMOX_HOST ./emmc-provisioning/scripts/deploy-to-proxmox.sh root@YOUR_PROXMOX_HOST
``` ```
Replace `YOUR_PROXMOX_HOST` with the Proxmox hostname or IP (e.g. `10.20.30.40`). Replace `YOUR_PROXMOX_HOST` with the Proxmox hostname or IP address.
**Example with options:** ### 2.1 Deploy script environment variables
Set these before running the script to customise the deployment:
| Variable | Default | Description |
|----------|---------|-------------|
| `DEPLOY_ROOTFS_STORAGE` | *(interactive)* | LXC rootfs storage name (e.g. `local-lvm`). If not set, script lists storages and asks. |
| `DEPLOY_LXC_WAN_BRIDGE` | `vmbr0` | Proxmox bridge for WAN (eth0 in LXC). |
| `DEPLOY_LXC_WAN_IP` | `dhcp` | WAN address: `dhcp` or a static IP like `192.168.1.10/24`. |
| `DEPLOY_LXC_LAN_BRIDGE` | *(none)* | If set, adds eth1 as provisioning LAN on this bridge (e.g. `vmbr1`). |
| `DEPLOY_LXC_LAN_SUBNET` | `10.20.50.1/24` | LXC IP/prefix on the LAN bridge. Used only when `DEPLOY_LXC_LAN_BRIDGE` is set. |
| `DEPLOY_LXC_ROOT_PASSWORD` | *(default)* | Sets LXC root password and enables SSH inside the container. |
| `DEPLOY_LXC_SSH_KEY` | `~/.ssh/id_ed25519.pub` | Public key to add to LXC root's `authorized_keys`. Defaults to your workstation key. |
| `CM4_BACKUPS_HOST_PATH` | *(none)* | Host directory for backup images (e.g. `/mnt/storage/cm4-backups`). Bind-mounted into LXC. |
| `DEPLOY_EMMC_SIZE_GB` | `32` | eMMC size hint in GB (used only when multiple block devices appear after rpiboot). |
| `DEPLOY_LOG` | *(off)* | Set to `1` to write a timestamped log file in `scripts/`. |
### 2.2 Full deploy example
```bash ```bash
DEPLOY_ROOTFS_STORAGE=local-lvm \ DEPLOY_ROOTFS_STORAGE=local-lvm \
@@ -47,117 +117,352 @@ DEPLOY_LXC_LAN_SUBNET=10.20.50.1/24 \
./emmc-provisioning/scripts/deploy-to-proxmox.sh root@10.20.30.40 ./emmc-provisioning/scripts/deploy-to-proxmox.sh root@10.20.30.40
``` ```
- On **first run**, the script will ask you to choose LXC rootfs storage (unless `DEPLOY_ROOTFS_STORAGE` is set). It then creates the LXC, installs host scripts, udev, systemd units, and the dashboard in the LXC. ### 2.3 What the deploy script does
- The script prints **LXC IP (WAN)** and, if you set `DEPLOY_LXC_LAN_BRIDGE`, **LXC IP (LAN)**. The portal is reachable at `http://<IP>:5000` on both; use the LAN IP from devices on the provisioning LAN.
The script runs five stages:
1. **Check** — SSHes to the host, finds existing `cm4-provisioning` container by hostname (or lists storage for new container creation).
2. **Clean + Rsync** — Wipes `/tmp/emmc-provisioning-deploy` on the host and rsyncs the entire repo there (excluding `.git` and deploy logs).
3. **Remote install (host + LXC)** — Runs a remote heredoc that:
- Creates the LXC (Debian 12, 1 GB RAM, 8 GB rootfs) if it doesn't exist, or reuses it by hostname.
- Adds eth1 (LAN bridge) if `DEPLOY_LXC_LAN_BRIDGE` is set.
- Configures the bind-mount for `/var/lib/cm4-provisioning/`.
- Installs host scripts to `/opt/cm4-provisioning/` and udev rules to `/etc/udev/rules.d/`.
- Installs and enables systemd units: `cm4-flash.service`, `cm4-build-cloudinit.path/.service`, `cm4-shrink.path/.service`.
- Writes `/opt/cm4-provisioning/env` (golden image path, rpiboot dir, eMMC size).
- Installs `python3-flask` and `openssh-server` in the LXC (skipped if already present).
- Deploys the Flask dashboard and enables/restarts `cm4-dashboard.service` in the LXC.
- Installs usbboot (`rpiboot`) on the host if not already present.
- Installs PiShrink on the host if not already present.
4. **LXC start** — Starts the LXC if stopped.
5. **Summary** — Prints LXC WAN IP (and LAN IP if set), dashboard URL, and remaining manual steps.
On **redeploy** (container already exists): host scripts, dashboard, env, systemd, and udev are always updated. LXC creation, bind-mounts, apt installs, usbboot, and PiShrink are skipped when already present.
--- ---
## Step 2: Install usbboot on the host (if host had no internet during deploy) ## Part 3 — Post-Deploy: Required Manual Steps
USB flash/backup needs **rpiboot** on the Proxmox **host**. If the deploy log said usbboot install failed or was skipped: ### Step 1: Verify the dashboard is up
**From your workstation:**
```bash ```bash
scp emmc-provisioning/scripts/install-usbboot-on-host.sh root@YOUR_PROXMOX_HOST:/tmp/ # Get the LXC IP from deploy output, or:
ssh root@YOUR_PROXMOX_HOST "bash /tmp/install-usbboot-on-host.sh" ssh root@YOUR_PROXMOX_HOST \
"CID=\$(pct list | awk '\$3==\"cm4-provisioning\"{print \$1}'); pct exec \$CID -- hostname -I"
# Open the dashboard
open http://<LXC-IP>:5000
``` ```
**Or on the Proxmox host** (if `/tmp/emmc-provisioning-deploy` is still there): The dashboard should show **"Waiting for device in USB boot mode"** on the home page.
### Step 2: Verify host services
SSH to the Proxmox host and confirm the host side is healthy:
```bash ```bash
ssh root@YOUR_PROXMOX_HOST ssh root@YOUR_PROXMOX_HOST
bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh
# Check udev rule is installed
ls /etc/udev/rules.d/90-cm4-boot-mode.rules
# Check flash trigger script
ls /usr/local/bin/cm4-flash-trigger.sh
# Check host scripts
ls /opt/cm4-provisioning/
# Expected: flash-emmc-on-connect.sh, build-cloudinit-image.sh,
# run-shrink-on-host.sh, fix-gadget-bootcode-on-host.sh, env
# Check systemd path units are active
systemctl status cm4-build-cloudinit.path cm4-shrink.path
# Check auto-flash is enabled
ls /etc/cm4-provisioning/enabled
``` ```
--- ### Step 3: Add a golden image
## Step 3: Add a golden image (required for Deploy) A **golden image** is required for **Deploy** (writing an image to the device's eMMC). Backup (reading from device) works without it.
To **write** an image to a device (Deploy), the host must have a **golden image** at `/var/lib/cm4-provisioning/golden.img`. Backup (read from device) works without it. **Option A — Build via the dashboard:**
1. Open `http://<LXC-IP>:5000` → Admin tab.
**Option A — From the dashboard** 2. Click **Build cloud-init image**: the host downloads the latest Raspberry Pi OS, injects your cloud-init `user-data`, and creates `golden.img`.
3. Click **Set as golden** once the build finishes.
1. Open **http://&lt;LXC-IP&gt;:5000** (use the LXC IP from the deploy output).
2. Build a cloud-init image or upload/set an existing backup as golden (see dashboard Admin).
**Option B — Copy an image from your machine**
**Option B — Copy an existing image:**
```bash ```bash
scp /path/to/your-golden.img root@YOUR_PROXMOX_HOST:/var/lib/cm4-provisioning/golden.img scp /path/to/your-golden.img root@YOUR_PROXMOX_HOST:/var/lib/cm4-provisioning/golden.img
``` ```
--- **Option C — Promote a backup:**
In the dashboard Admin → Images tab, select a backup and click **Set as golden**.
## Accessing the portal from the LAN ### Step 4: Enable SSH into the LXC (optional)
The dashboard listens on **all interfaces** (`0.0.0.0:5000`), so it is reachable on both WAN and LAN IPs when the LXC has two networks. If you ran the deploy with `DEPLOY_LXC_ROOT_PASSWORD` or a default SSH key, the LXC already has SSH enabled. Otherwise:
- **Deploy with a LAN interface:** set `DEPLOY_LXC_LAN_BRIDGE=vmbr1` (and optionally `DEPLOY_LXC_LAN_SUBNET=10.20.50.1/24`) when running the deploy script. The LXC will get eth1 with the LAN IP (e.g. 10.20.50.1). ```bash
- **From the provisioning LAN:** open **http://&lt;LAN-IP&gt;:5000** (e.g. http://10.20.50.1:5000). Devices on that subnet can use the portal without going through WAN. # From your workstation — adds your default SSH key and enables root SSH
- If you did not set a LAN bridge at deploy time, you only have one IP (WAN); use that for the portal. To add LAN later you would need to add eth1 to the container and reconfigure (see PROXMOX-LXC-DEPLOYMENT.md). ./emmc-provisioning/scripts/setup-lxc-ssh.sh root@YOUR_PROXMOX_HOST
--- # Or with a specific key and password
ROOT_PASSWORD='YourPassword' \
## Step 4: (Optional) SSH into the LXC ./emmc-provisioning/scripts/setup-lxc-ssh.sh root@YOUR_PROXMOX_HOST ~/.ssh/id_ed25519.pub
```
If you set `DEPLOY_LXC_ROOT_PASSWORD` or had a default SSH key, you can already run:
Then connect:
```bash ```bash
ssh root@<LXC-IP> ssh root@<LXC-IP>
``` ```
Otherwise, enable root SSH and add your key: ---
## Part 4 — Sync Portal Files (First-Boot Assets)
The LXC serves first-boot assets (kiosk scripts, desktop files, splash, theme, etc.) from `/var/lib/cm4-provisioning/portal-files/`. These must be synced from the repo.
```bash ```bash
./emmc-provisioning/scripts/setup-lxc-ssh.sh root@YOUR_PROXMOX_HOST # From your workstation
# Or with password: ROOT_PASSWORD='YourPassword' ./emmc-provisioning/scripts/setup-lxc-ssh.sh root@YOUR_PROXMOX_HOST ~/.ssh/id_ed25519.pub ./emmc-provisioning/scripts/sync-portal-files-to-lxc.sh root@<LXC-IP>
``` ```
This rsyncs everything under `emmc-provisioning/cloud-init/fileserver/` to the LXC portal-files directory. Run this every time you update kiosk assets or first-boot scripts.
**What gets synced:**
| File | Purpose |
|------|---------|
| `start-chromium.sh` | Wayland/labwc Chromium kiosk launcher |
| `five-tap-close-chromium.py` | 5-tap touch overlay to close Chromium |
| `chromium-kiosk.desktop` | Autostart: launches Chromium kiosk |
| `chromium-kiosk-no-select/` | Chromium extension: disables text selection |
| `set-rotation-at-login.sh/.desktop` | Per-login screen rotation |
| `01-set-rotation-once.sh/.desktop` | One-shot: rotation + dark theme + kanshi |
| `02-set-wallpaper-once.sh/.desktop` | One-shot: set wallpaper |
| `99-default-session.conf` | LightDM session = `rpd-labwc` |
| `custom.plymouth` + `custom.script` | Plymouth boot splash theme |
| `splash.png` | Boot splash / wallpaper image |
| `steps/0113*.sh` | First-boot step scripts sourced by `first-boot.sh` |
--- ---
## Step 5: (Optional) Network boot (DHCP + TFTP on eth1) ## Part 5 — Network Boot Setup (Optional)
Only if you deployed with **`DEPLOY_LXC_LAN_BRIDGE`** (and optionally `DEPLOY_LXC_LAN_SUBNET`) and want to offer network boot to devices on that LAN: Only needed if you want devices to **boot over the network** (PXE-style via TFTP) for provisioning, rather than via USB cable.
### 5.1 Prerequisites
- The LXC must have been deployed with a **LAN bridge** (`DEPLOY_LXC_LAN_BRIDGE` set). The LXC's eth1 will be the provisioning LAN gateway.
- Devices must be connected to the same LAN as the LXC's eth1.
### 5.2 Run the network boot setup script
From your workstation:
```bash ```bash
./emmc-provisioning/scripts/setup-network-boot-on-lxc.sh root@<LXC-IP> ./emmc-provisioning/scripts/setup-network-boot-on-lxc.sh root@<LXC-IP>
``` ```
See [NETWORK-BOOT-LXC.md](NETWORK-BOOT-LXC.md) for details. This SSH-connects to the LXC and runs the full setup inside the container. It performs:
1. **Installs dnsmasq** (DHCP + DNS server) and the `vlan` package (for VLAN interfaces).
2. **Configures dnsmasq** on eth1:
- DHCP range: `<LAN_BASE>.100` `<LAN_BASE>.200` (e.g. `10.20.50.100``10.20.50.200`).
- DNS: static record `file.server` → LAN gateway IP, so first-boot scripts can reach `http://file.server/...`.
- DHCP option 6: sends LXC as DNS server to all DHCP clients.
3. **Configures extra IPs on eth1**: `192.168.30.1/24`, `192.168.127.1/24` (for serving multiple subnets).
4. **Creates VLAN 40** interface `eth1.40` at `192.168.0.1/24` (for VLAN-tagged networks on the provisioning LAN).
5. **Enables IP forwarding** (`net.ipv4.ip_forward=1`) persisted in `/etc/sysctl.d/`.
6. **Configures NAT** (nftables or iptables fallback): masquerades all LAN traffic out eth0 so devices on the provisioning LAN get internet access.
7. **Enables and starts dnsmasq**.
Config files written:
- `/etc/dnsmasq.d/network-boot.conf` — DHCP + DNS on eth1
- `/etc/nftables.d/nat-lan.conf` — NAT rules
- `/etc/network/interfaces.d/70-cm4-extra-lan` — extra IPs and VLAN persisted
### 5.3 Enable PXE / TFTP network boot
TFTP is not enabled by default (dnsmasq is configured for DHCP + DNS only). To enable PXE/TFTP so devices can load a kernel and initramfs over the network:
```bash
# SSH into the LXC
ssh root@<LXC-IP>
# Enable PXE/TFTP (adds the PXE options to dnsmasq and restarts it)
/opt/cm4-provisioning/toggle-network-boot-dhcp.sh enable
```
This activates the PXE snippet at `/etc/dnsmasq.d/network-boot-pxe.conf` (DHCP options 66/67: next-server + boot file) and reloads dnsmasq.
To disable PXE again (keep DHCP/DNS only):
```bash
/opt/cm4-provisioning/toggle-network-boot-dhcp.sh disable
```
### 5.4 Populate the TFTP boot files
The TFTP root (`/srv/tftpboot`) needs Raspberry Pi 4 / CM4 boot files. From your workstation:
```bash
./emmc-provisioning/scripts/populate-tftpboot-from-git.sh root@<LXC-IP>
```
This downloads the official Raspberry Pi firmware `boot/` folder from GitHub into `/srv/tftpboot` on the LXC.
To add the custom provisioning initramfs (Alpine-based, allows Backup/Deploy from network boot):
```bash
# Ensure the initramfs image is built (or use the pre-built one in the repo)
ls emmc-provisioning/network-boot-initramfs/initrd.img
# Copy it to the LXC TFTP root
scp emmc-provisioning/network-boot-initramfs/initrd.img root@<LXC-IP>:/srv/tftpboot/
# Then ensure config.txt references it
./emmc-provisioning/scripts/ensure-tftpboot-config-kernel-initrd.sh root@<LXC-IP>
```
### 5.5 Configure device EEPROM for network boot
For a reTerminal to boot from the network (when eMMC is empty or network boot order is set), its EEPROM `BOOT_ORDER` must include network boot. The recommended order is `0xf21` (eMMC first, then network):
```bash
# Check current EEPROM boot order on a connected device
./emmc-provisioning/scripts/check-network-boot-priority.sh root@<DEVICE-IP>
```
To set boot order via the provisioning dashboard (when device is in USB boot mode), use the **Update EEPROM** button in the dashboard.
### 5.6 Verify network boot is working
On the LXC, check the following:
```bash
# Is dnsmasq running?
systemctl status dnsmasq
# Is TFTP/PXE enabled?
/opt/cm4-provisioning/toggle-network-boot-dhcp.sh status
# Are TFTP boot files present?
ls /srv/tftpboot/start4cd.elf
# Any DHCP leases from devices?
cat /var/lib/misc/dnsmasq.leases
# Monitor live DHCP/TFTP traffic when powering on a device
tcpdump -i eth1 -n port 67 or port 68 or port 69
```
--- ---
## Step 6: (Optional) Install PiShrink on the host ## Part 6 — Installing usbboot Manually (if needed)
If the deploy log said PiShrink install failed (e.g. no internet), and you want **Shrink/Compress** in the dashboard to work: If the deploy script could not install usbboot (e.g. no internet during deploy), install it manually:
```bash
# From your workstation
scp emmc-provisioning/scripts/install-usbboot-on-host.sh root@YOUR_PROXMOX_HOST:/tmp/
ssh root@YOUR_PROXMOX_HOST "bash /tmp/install-usbboot-on-host.sh"
```
Or, if `/tmp/emmc-provisioning-deploy` is still on the host:
```bash
ssh root@YOUR_PROXMOX_HOST "bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh"
```
After install, verify:
```bash
ssh root@YOUR_PROXMOX_HOST "ls /opt/usbboot/rpiboot && ls /opt/usbboot/mass-storage-gadget64/"
```
---
## Part 7 — Installing PiShrink Manually (if needed)
PiShrink enables the dashboard **Shrink/Compress** function (shrinks backup images before compressing). Install if the deploy failed:
```bash ```bash
ssh root@YOUR_PROXMOX_HOST "bash /tmp/emmc-provisioning-deploy/scripts/install-pishrink-on-host.sh" ssh root@YOUR_PROXMOX_HOST "bash /tmp/emmc-provisioning-deploy/scripts/install-pishrink-on-host.sh"
# Or stream from workstation:
ssh root@YOUR_PROXMOX_HOST 'bash -s' < emmc-provisioning/scripts/install-pishrink-on-host.sh
``` ```
Or from your machine (stream the script): use the same pattern as in [PROXMOX-LXC-DEPLOYMENT.md](PROXMOX-LXC-DEPLOYMENT.md) for `install-pishrink-on-host.sh`.
--- ---
## Summary checklist ## Part 8 — Updating / Redeploying
| Step | Action | Required? | To push code changes (scripts, dashboard, udev, systemd) to an existing deployment:
|------|--------|------------|
| 1 | Run `deploy-to-proxmox.sh root@YOUR_PROXMOX_HOST` | **Yes** |
| 2 | Install usbboot on host (if deploy couldnt) | For USB flash/backup |
| 3 | Add `golden.img` for Deploy | For Deploy only |
| 4 | SSH to LXC (or use setup-lxc-ssh.sh) | Optional |
| 5 | Run setup-network-boot-on-lxc.sh (if using eth1 LAN) | Optional |
| 6 | Install PiShrink on host (if deploy couldnt) | For Shrink/Compress |
**After deployment:** ```bash
./emmc-provisioning/scripts/deploy-to-proxmox.sh root@YOUR_PROXMOX_HOST
```
- **Dashboard:** http://&lt;LXC-IP&gt;:5000 (WAN). If you set `DEPLOY_LXC_LAN_BRIDGE`, also **http://&lt;LAN-IP&gt;:5000** (e.g. http://10.20.50.1:5000) from the LAN. The script finds the container by hostname (`cm4-provisioning`) and updates all files. It does **not** overwrite your `golden.img` or `/etc/cm4-provisioning/enabled`.
- **Golden image path (host and LXC):** `/var/lib/cm4-provisioning/golden.img`
- **Disable auto-flash:** `ssh root@YOUR_PROXMOX_HOST "rm /etc/cm4-provisioning/enabled"`
- **Enable again:** `ssh root@YOUR_PROXMOX_HOST "touch /etc/cm4-provisioning/enabled"`
**If you see "rpiboot failed or no device connected":** The error is from the **Proxmox host** (where USB is connected). On the host run: `tail -50 /var/lib/cm4-provisioning/flash.log` to see the real rpiboot message. Ensure the reTerminal is in **boot mode** (eMMC disable jumper, USB slave port), then unplug/replug. See [PROXMOX-LXC-DEPLOYMENT.md](PROXMOX-LXC-DEPLOYMENT.md) § "If rpiboot fails" for full steps. To update **only the dashboard** (faster when only `app.py` or templates changed):
Full reference: [PROXMOX-LXC-DEPLOYMENT.md](PROXMOX-LXC-DEPLOYMENT.md). ```bash
./emmc-provisioning/scripts/deploy-dashboard-to-lxc.sh root@<LXC-IP>
```
To update **only the portal files** (kiosk assets, first-boot scripts):
```bash
./emmc-provisioning/scripts/sync-portal-files-to-lxc.sh root@<LXC-IP>
```
---
## Deployment Checklist
| # | Action | Script / Command | Required? |
|---|--------|-----------------|-----------|
| **Host prep** | | | |
| 1 | SSH key access to Proxmox host | `ssh-copy-id root@HOST` | **Yes** |
| 2 | Create LAN bridge on Proxmox (`vmbr1`) | Proxmox Web UI | For network boot |
| **Deploy** | | | |
| 3 | Run deploy script | `deploy-to-proxmox.sh root@HOST` | **Yes** |
| 4 | Verify dashboard is up | `http://<LXC-IP>:5000` | **Yes** |
| 5 | Verify host services and udev rule | `ssh root@HOST "ls /etc/udev/rules.d/90-cm4-boot-mode.rules"` | **Yes** |
| **Post-deploy** | | | |
| 6 | Add golden image for Deploy | Dashboard Admin or `scp golden.img root@HOST:/var/lib/cm4-provisioning/` | For Deploy |
| 7 | Sync portal files (kiosk/first-boot assets) | `sync-portal-files-to-lxc.sh root@<LXC-IP>` | For first-boot provisioning |
| 8 | Enable SSH into LXC | `setup-lxc-ssh.sh root@HOST` | Optional |
| **Network boot** | | | |
| 9 | Run network boot setup on LXC | `setup-network-boot-on-lxc.sh root@<LXC-IP>` | For network boot only |
| 10 | Enable PXE/TFTP | `ssh root@<LXC-IP> /opt/cm4-provisioning/toggle-network-boot-dhcp.sh enable` | For PXE boot |
| 11 | Populate TFTP boot files | `populate-tftpboot-from-git.sh root@<LXC-IP>` | For PXE boot |
| 12 | Copy provisioning initramfs to TFTP | `scp network-boot-initramfs/initrd.img root@<LXC-IP>:/srv/tftpboot/` | For provisioning via netboot |
| 13 | Configure device EEPROM boot order | Dashboard **Update EEPROM** or `rpi-eeprom-config` | For network boot |
| **If needed** | | | |
| 14 | Install usbboot manually | `install-usbboot-on-host.sh` | If deploy had no internet |
| 15 | Install PiShrink manually | `install-pishrink-on-host.sh` | If deploy had no internet |
---
## After Deployment: Quick Reference
| What | How |
|------|-----|
| **Dashboard (WAN)** | `http://<LXC-IP>:5000` |
| **Dashboard (LAN)** | `http://10.20.50.1:5000` (if LAN bridge was set) |
| **SSH to LXC** | `ssh root@<LXC-IP>` |
| **Get LXC IP** | `ssh root@HOST "pct list; pct exec <CTID> -- hostname -I"` |
| **Golden image path** | `/var/lib/cm4-provisioning/golden.img` (same on host and in LXC) |
| **Disable auto-flash** | `ssh root@HOST "rm /etc/cm4-provisioning/enabled"` |
| **Re-enable auto-flash** | `ssh root@HOST "touch /etc/cm4-provisioning/enabled"` |
| **Flash log (on host)** | `ssh root@HOST "tail -f /var/lib/cm4-provisioning/flash.log"` |
| **Status JSON (on host)** | `ssh root@HOST "cat /var/lib/cm4-provisioning/status.json"` |
| **Full host snapshot** | `ssh root@HOST 'bash -s' < emmc-provisioning/scripts/monitor-from-host.sh` |
| **DHCP leases (LXC)** | `ssh root@<LXC-IP> "cat /var/lib/misc/dnsmasq.leases"` |
---
## Troubleshooting
For USB flash errors (rpiboot failures, block device not found, USB transfer errors) and LXC/dashboard issues, see the full troubleshooting section in [PROXMOX-LXC-DEPLOYMENT.md](PROXMOX-LXC-DEPLOYMENT.md).
For network boot issues (DHCP not working, device not appearing in dashboard), see [NETWORK-BOOT-TROUBLESHOOTING.md](NETWORK-BOOT-TROUBLESHOOTING.md).

View File

@@ -1,24 +0,0 @@
[2026-02-18T09:57:49+02:00] Logging to /home/nearxos/Projects/reTerminal DM4/chromium-setup/emmc-provisioning/scripts/deploy-20260218-095749.log
[2026-02-18T09:57:49+02:00] Deploying to root@10.130.60.224 ...
[2026-02-18T09:57:49+02:00] [1/4] Cleaning remote staging dir ...
[2026-02-18T09:57:50+02:00] [2/4] Rsync repo to root@10.130.60.224 ...
[2026-02-18T09:57:50+02:00] [3/4] Running remote install (host + LXC) ...
[2026-02-18T08:01:21+00:00] LXC 201 already exists.
[2026-02-18T08:01:21+00:00] Host: installing scripts and udev ...
[2026-02-18T08:01:22+00:00] Host: env and dirs ...
[2026-02-18T08:01:22+00:00] Starting LXC 201 if stopped ...
[2026-02-18T08:01:25+00:00] LXC: installing flash scripts ...
failed to create file: /opt/cm4-provisioning/: Is a directory
[2026-02-18T08:01:45+00:00] LXC: installing dashboard ...
failed to create file: /opt/cm4-provisioning/dashboard/: Is a directory
failed to create file: /opt/cm4-provisioning/dashboard/templates/: Is a directory
[2026-02-18T08:01:59+00:00] Deploy done (remote).
Next: Install usbboot on host when online: ssh <host> 'bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh'
Next: Enable dashboard in LXC 201: pct exec 201 -- bash -c 'apt-get install -y python3-flask; cp /opt/cm4-provisioning/dashboard/cm4-dashboard.service /etc/systemd/system/; systemctl daemon-reload; systemctl enable --now cm4-dashboard'
failed to create file: /opt/cm4-provisioning/dashboard/: Is a directory
[2026-02-18T09:58:31+02:00] [4/4] Deploy finished.
Done. Put golden.img in /var/lib/cm4-provisioning/ on the host (or scp to LXC 201 at /var/lib/cm4-provisioning/).
When the host has internet, run on the host: bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh
Dashboard: install flask in LXC 201 and enable cm4-dashboard.service (see docs/PROXMOX-LXC-DEPLOYMENT.md).
Log written to: /home/nearxos/Projects/reTerminal DM4/chromium-setup/emmc-provisioning/scripts/deploy-20260218-095749.log

View File

@@ -1,20 +0,0 @@
[2026-02-18T09:58:59+02:00] Logging to /home/nearxos/Projects/reTerminal DM4/chromium-setup/emmc-provisioning/scripts/deploy-20260218-095859.log
[2026-02-18T09:58:59+02:00] Deploying to root@10.130.60.224 ...
[2026-02-18T09:58:59+02:00] [1/4] Cleaning remote staging dir ...
[2026-02-18T09:59:00+02:00] [2/4] Rsync repo to root@10.130.60.224 ...
[2026-02-18T09:59:00+02:00] [3/4] Running remote install (host + LXC) ...
[2026-02-18T08:02:32+00:00] LXC 201 already exists.
[2026-02-18T08:02:32+00:00] Host: installing scripts and udev ...
[2026-02-18T08:02:32+00:00] Host: env and dirs ...
[2026-02-18T08:02:32+00:00] Starting LXC 201 if stopped ...
[2026-02-18T08:02:35+00:00] LXC: installing flash scripts ...
[2026-02-18T08:02:55+00:00] LXC: installing dashboard ...
[2026-02-18T08:03:09+00:00] Deploy done (remote).
Next: Install usbboot on host when online: ssh <host> 'bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh'
Next: Enable dashboard in LXC 201: pct exec 201 -- bash -c 'apt-get install -y python3-flask; cp /opt/cm4-provisioning/dashboard/cm4-dashboard.service /etc/systemd/system/; systemctl daemon-reload; systemctl enable --now cm4-dashboard'
[2026-02-18T09:59:41+02:00] [4/4] Deploy finished.
Done. Put golden.img in /var/lib/cm4-provisioning/ on the host (or scp to LXC 201 at /var/lib/cm4-provisioning/).
When the host has internet, run on the host: bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh
Dashboard: install flask in LXC 201 and enable cm4-dashboard.service (see docs/PROXMOX-LXC-DEPLOYMENT.md).
Log written to: /home/nearxos/Projects/reTerminal DM4/chromium-setup/emmc-provisioning/scripts/deploy-20260218-095859.log

View File

@@ -1,20 +0,0 @@
[2026-02-18T10:11:19+02:00] Logging to /home/nearxos/Projects/reTerminal DM4/chromium-setup/emmc-provisioning/scripts/deploy-20260218-101119.log
[2026-02-18T10:11:19+02:00] Deploying to root@10.130.60.224 ...
[2026-02-18T10:11:19+02:00] [1/4] Cleaning remote staging dir ...
[2026-02-18T10:11:20+02:00] [2/4] Rsync repo to root@10.130.60.224 ...
[2026-02-18T10:11:21+02:00] [3/4] Running remote install (host + LXC) ...
[2026-02-18T08:14:52+00:00] LXC 201 already exists.
[2026-02-18T08:14:52+00:00] Host: installing scripts and udev ...
[2026-02-18T08:14:52+00:00] Host: env and dirs ...
[2026-02-18T08:14:52+00:00] Starting LXC 201 if stopped ...
[2026-02-18T08:14:56+00:00] LXC: installing flash scripts ...
[2026-02-18T08:15:16+00:00] LXC: installing dashboard ...
[2026-02-18T08:15:30+00:00] Deploy done (remote).
Next: Install usbboot on host when online: ssh <host> 'bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh'
Next: Enable dashboard in LXC 201: pct exec 201 -- bash -c 'apt-get install -y python3-flask; cp /opt/cm4-provisioning/dashboard/cm4-dashboard.service /etc/systemd/system/; systemctl daemon-reload; systemctl enable --now cm4-dashboard'
[2026-02-18T10:12:02+02:00] [4/4] Deploy finished.
Done. Put golden.img in /var/lib/cm4-provisioning/ on the host (or scp to LXC 201 at /var/lib/cm4-provisioning/).
When the host has internet, run on the host: bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh
Dashboard: install flask in LXC 201 and enable cm4-dashboard.service (see docs/PROXMOX-LXC-DEPLOYMENT.md).
Log written to: /home/nearxos/Projects/reTerminal DM4/chromium-setup/emmc-provisioning/scripts/deploy-20260218-101119.log

View File