Remove obsolete eMMC provisioning scripts and documentation for reTerminal DM4, including udev rules, flash trigger scripts, and related guides.
This commit is contained in:
@@ -1,17 +1,44 @@
|
||||
# reTerminal DM4 eMMC auto-provisioning
|
||||
# reTerminal DM4 eMMC provisioning
|
||||
|
||||
Automatically flash a **golden image** to the CM4 eMMC when the reTerminal is connected in **boot mode** (eMMC disable jumper). Optional **backup** mode saves the current eMMC to a timestamped image file instead. Uses **cloud-init** for first-boot configuration.
|
||||
Automatically **deploy** or **backup** the CM4 eMMC when the reTerminal is connected in **USB boot mode** or when it **boots over the network**. Uses **cloud-init** for first-boot configuration.
|
||||
|
||||
| File | Purpose |
|
||||
|------|--------|
|
||||
| **EMMC-PROVISIONING-GUIDE.md** | Full setup and usage guide – read this first. |
|
||||
| **flash-emmc-on-connect.sh** | Script that runs `rpiboot` then either flashes the golden image to eMMC or backs up eMMC to a file (mode set via dashboard or `mode` file). |
|
||||
| **cm4-flash-trigger.sh** | Called by udev when CM4 in boot mode is connected; starts the flash job. |
|
||||
| **90-cm4-boot-mode.rules** | udev rule: when USB device 2b8e is added, run the trigger script. |
|
||||
| **cloud-init/** | Example NoCloud files (`user-data`, `meta-data`, `network-config`) for the golden image. |
|
||||
| **dashboard/** | Flask web UI: auto-detect device (USB or network), prompt **Backup or Deploy**, show status and connection steps. See **dashboard/README.md**. |
|
||||
| **network-client/** | Script for network-booted devices: register with the dashboard and perform Deploy (pull image, write eMMC) or Backup (upload eMMC). See **network-client/README.md**. |
|
||||
---
|
||||
|
||||
Quick start: see **EMMC-PROVISIONING-GUIDE.md**.
|
||||
## Project layout
|
||||
|
||||
**Proxmox:** LXC 201 + host setup is documented in **PROXMOX-LXC-DEPLOYMENT.md**. Use **scripts/deploy-to-proxmox.sh** to deploy to a Proxmox host; flash runs on the host, golden image is in a bind-mounted dir shared with the LXC.
|
||||
```
|
||||
emmc-provisioning/
|
||||
├── README.md ← You are here
|
||||
├── docs/ Documentation
|
||||
│ ├── EMMC-PROVISIONING-GUIDE.md Full setup and usage
|
||||
│ ├── PROXMOX-LXC-DEPLOYMENT.md Proxmox LXC + host setup
|
||||
│ └── PORTAL_STYLING_GUIDE.md Dashboard UI styling reference
|
||||
├── host/ Scripts that run on the provisioning host (Proxmox host)
|
||||
│ ├── flash-emmc-on-connect.sh rpiboot + wait for Backup/Deploy choice, then dd
|
||||
│ ├── cm4-flash-trigger.sh Called by udev; starts the flash job
|
||||
│ └── 90-cm4-boot-mode.rules udev rule (USB vendor 2b8e)
|
||||
├── scripts/ Deployment and one-off scripts
|
||||
│ ├── deploy-to-proxmox.sh Deploy to Proxmox host + LXC 201
|
||||
│ └── install-usbboot-on-host.sh Build and install rpiboot on the host
|
||||
├── dashboard/ Flask web UI (runs in LXC or standalone)
|
||||
│ ├── app.py
|
||||
│ ├── templates/
|
||||
│ ├── cm4-dashboard.service
|
||||
│ └── README.md
|
||||
├── cloud-init/ Example NoCloud files for the golden image
|
||||
│ ├── user-data
|
||||
│ ├── meta-data
|
||||
│ └── network-config
|
||||
└── network-client/ For network-booted devices
|
||||
├── provisioning-client.sh Register + poll, then Deploy or Backup
|
||||
└── README.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Quick start
|
||||
|
||||
1. **Read** [docs/EMMC-PROVISIONING-GUIDE.md](docs/EMMC-PROVISIONING-GUIDE.md) for setup and usage.
|
||||
2. **Proxmox:** Use [scripts/deploy-to-proxmox.sh](scripts/deploy-to-proxmox.sh) to deploy to a Proxmox host; see [docs/PROXMOX-LXC-DEPLOYMENT.md](docs/PROXMOX-LXC-DEPLOYMENT.md).
|
||||
3. **Manual host:** Copy scripts from `host/` to the host and install the udev rule (see the guide).
|
||||
4. 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**.
|
||||
|
||||
@@ -48,8 +48,8 @@ sudo cp rpiboot /opt/usbboot/
|
||||
#### 3. Install the auto-flash script and trigger
|
||||
|
||||
```bash
|
||||
# From this repo (chromium-setup/emmc-provisioning/)
|
||||
SCRIPT_DIR="$(pwd)"
|
||||
# From this repo (chromium-setup/emmc-provisioning/host/)
|
||||
cd chromium-setup/emmc-provisioning/host
|
||||
|
||||
sudo mkdir -p /opt/cm4-provisioning
|
||||
sudo cp flash-emmc-on-connect.sh /opt/cm4-provisioning/
|
||||
@@ -69,6 +69,7 @@ If your golden image path or rpiboot path is different, set `GOLDEN_IMAGE`, `RPI
|
||||
#### 4. Install udev rule
|
||||
|
||||
```bash
|
||||
# From emmc-provisioning/host/
|
||||
sudo cp 90-cm4-boot-mode.rules /etc/udev/rules.d/
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
@@ -57,7 +57,27 @@ bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh
|
||||
|
||||
This installs dependencies, clones usbboot, builds it, and copies `rpiboot` to `/opt/usbboot/`.
|
||||
|
||||
### 2. Put the golden image on the host (or in the LXC)
|
||||
### 2. Enable root SSH and add your SSH key to LXC 201
|
||||
|
||||
No root password is set by default. To log in as root over SSH:
|
||||
|
||||
- **Option A – Use the setup script (recommended):** From your machine (with SSH key and optional password):
|
||||
|
||||
```bash
|
||||
# Add your default SSH key (~/.ssh/id_ed25519.pub or id_rsa.pub) and enable root SSH
|
||||
./chromium-setup/emmc-provisioning/scripts/setup-lxc-ssh.sh root@10.130.60.224
|
||||
|
||||
# Or specify key file and set root password
|
||||
ROOT_PASSWORD='YourPassword' ./chromium-setup/emmc-provisioning/scripts/setup-lxc-ssh.sh root@10.130.60.224 ~/.ssh/id_ed25519.pub
|
||||
```
|
||||
|
||||
Then connect with `ssh root@<LXC-IP>` (script prints the IP). Get the IP anytime with:
|
||||
`ssh root@10.130.60.224 "pct exec 201 -- hostname -I"`
|
||||
|
||||
- **Option B – Manual:**
|
||||
`ssh root@10.130.60.224` then `pct exec 201 -- bash` to get a shell in the container. Run `apt-get install -y openssh-server`, edit `/etc/ssh/sshd_config` to set `PermitRootLogin yes`, run `passwd` to set root password, add your key to `/root/.ssh/authorized_keys`, and restart `ssh`.
|
||||
|
||||
### 3. Put the golden image on the host (or in the LXC)
|
||||
|
||||
The image must be at **`/var/lib/cm4-provisioning/golden.img`** on the **host**. Because that directory is bind-mounted into the LXC, you can use either:
|
||||
|
||||
@@ -72,7 +92,7 @@ The image must be at **`/var/lib/cm4-provisioning/golden.img`** on the **host**.
|
||||
# Copy to that path inside the container; it's the same as the host path.
|
||||
```
|
||||
|
||||
### 3. Run the provisioning dashboard (optional)
|
||||
### 4. Run the provisioning dashboard (optional)
|
||||
|
||||
The dashboard shows **connection steps** and **live deployment status** (idle / connecting / flashing / done / error) and a recent flash log. It reads the same `status.json` and `flash.log` that the host’s flash script writes (via the bind-mounted `/var/lib/cm4-provisioning`).
|
||||
|
||||
@@ -96,7 +116,7 @@ systemctl enable --now cm4-dashboard
|
||||
|
||||
Then open **http://<LXC-201-IP>:5000** (get the IP with `pct exec 201 -- hostname -I`). If the LXC is on a private network, set up port forwarding on the Proxmox host or use a reverse proxy so you can reach the dashboard from your browser.
|
||||
|
||||
### 4. Optional: disable or enable auto-flash
|
||||
### 5. Optional: disable or enable auto-flash
|
||||
|
||||
- **Disable:**
|
||||
`ssh root@10.130.60.224 "rm /etc/cm4-provisioning/enabled"`
|
||||
11
chromium-setup/emmc-provisioning/host/README.md
Normal file
11
chromium-setup/emmc-provisioning/host/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Host-side provisioning scripts
|
||||
|
||||
These files run on the **provisioning host** (e.g. the Proxmox host where the reTerminal is connected via USB).
|
||||
|
||||
| File | Purpose |
|
||||
|------|--------|
|
||||
| **flash-emmc-on-connect.sh** | Runs `rpiboot`, detects eMMC, waits for dashboard choice (Backup/Deploy), then runs `dd`. Install to `/opt/cm4-provisioning/`. |
|
||||
| **cm4-flash-trigger.sh** | Started by udev when USB device 2b8e is added. Launches the flash script via `systemd-run`. Install to `/usr/local/bin/`. |
|
||||
| **90-cm4-boot-mode.rules** | udev rule: on USB add (vendor 2b8e), run the trigger. Install to `/etc/udev/rules.d/`. |
|
||||
|
||||
See [../docs/EMMC-PROVISIONING-GUIDE.md](../docs/EMMC-PROVISIONING-GUIDE.md) for full setup. The [deploy script](../scripts/deploy-to-proxmox.sh) copies these into place on the Proxmox host and LXC.
|
||||
@@ -55,9 +55,22 @@ if [[ ! -f "$GOLDEN_IMAGE" ]]; then
|
||||
fi
|
||||
|
||||
RPIBOOT_BIN="$RPIBOOT_DIR/rpiboot"
|
||||
# Gadget dir for CM4 (64-bit); fallback to mass-storage-gadget
|
||||
RPIBOOT_GADGET=""
|
||||
for d in "$RPIBOOT_DIR/mass-storage-gadget64" "$RPIBOOT_DIR/mass-storage-gadget"; do
|
||||
if [[ -d "$d" ]]; then
|
||||
RPIBOOT_GADGET="$d"
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ ! -x "$RPIBOOT_BIN" ]]; then
|
||||
log "rpiboot not found: $RPIBOOT_BIN (build usbboot and set RPIBOOT_DIR)"
|
||||
write_status "error" "rpiboot not installed" "null" "rpiboot not found. Run install-usbboot-on-host.sh on the host."
|
||||
write_status "error" "rpiboot not installed" "null" "rpiboot not found. Run install-usbboot-on-host.sh on the host or build-and-deploy-usbboot-to-host.sh from your machine."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "$RPIBOOT_GADGET" ]]; then
|
||||
log "rpiboot gadget dir not found under $RPIBOOT_DIR (need mass-storage-gadget64 or mass-storage-gadget)"
|
||||
write_status "error" "rpiboot gadget missing" "null" "Copy mass-storage-gadget(64) to $RPIBOOT_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -69,7 +82,7 @@ write_status "rpiboot" "Connecting to CM4 in boot mode…" "0"
|
||||
before_devs=$(lsblk -nd -o NAME 2>/dev/null | sort)
|
||||
|
||||
log "Starting rpiboot to expose CM4 eMMC as mass storage..."
|
||||
if ! "$RPIBOOT_BIN"; then
|
||||
if ! "$RPIBOOT_BIN" -d "$RPIBOOT_GADGET"; then
|
||||
log "rpiboot failed or no device connected"
|
||||
write_status "error" "rpiboot failed" "null" "rpiboot failed or no device connected"
|
||||
exit 1
|
||||
51
chromium-setup/emmc-provisioning/scripts/build-and-deploy-usbboot-to-host.sh
Executable file
51
chromium-setup/emmc-provisioning/scripts/build-and-deploy-usbboot-to-host.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# Build usbboot (rpiboot) on THIS machine (e.g. Fedora) and deploy to the Proxmox host.
|
||||
# Use this when the host has no internet. Requires: dnf (Fedora) or apt (Debian/Ubuntu), git, ssh to host.
|
||||
# Usage: ./build-and-deploy-usbboot-to-host.sh [proxmox_host]
|
||||
# Example: ./build-and-deploy-usbboot-to-host.sh root@10.130.60.224
|
||||
|
||||
set -e
|
||||
PROXMOX="${1:-root@10.130.60.224}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
BUILD_DIR="/tmp/usbboot-build-$$"
|
||||
cleanup() { rm -rf "$BUILD_DIR"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
echo "[$(date -Iseconds)] Building usbboot for host $PROXMOX ..."
|
||||
|
||||
# Install build deps (Fedora or Debian/Ubuntu)
|
||||
if command -v dnf &>/dev/null; then
|
||||
echo "Installing build deps (dnf)..."
|
||||
sudo dnf install -y git libusb1-devel pkg-config glibc-devel gcc gcc-c++ make
|
||||
elif command -v apt-get &>/dev/null; then
|
||||
echo "Installing build deps (apt)..."
|
||||
sudo apt-get update -qq
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y git libusb-1.0-0-dev pkg-config build-essential
|
||||
else
|
||||
echo "Error: need dnf or apt-get to install dependencies."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
echo "Cloning usbboot (with submodules)..."
|
||||
git clone --recurse-submodules --shallow-submodules --depth=1 https://github.com/raspberrypi/usbboot
|
||||
cd usbboot
|
||||
echo "Building..."
|
||||
make
|
||||
|
||||
# Deploy: binary + gadget dir(s) to host /opt/usbboot
|
||||
echo "[$(date -Iseconds)] Deploying to $PROXMOX:/opt/usbboot ..."
|
||||
ssh "$PROXMOX" "mkdir -p /opt/usbboot"
|
||||
rsync -a "$BUILD_DIR/usbboot/rpiboot" "$PROXMOX:/opt/usbboot/"
|
||||
# CM4 needs mass-storage-gadget (64-bit); copy whichever exists
|
||||
for dir in mass-storage-gadget64 mass-storage-gadget; do
|
||||
if [[ -d "$BUILD_DIR/usbboot/$dir" ]]; then
|
||||
rsync -a "$BUILD_DIR/usbboot/$dir" "$PROXMOX:/opt/usbboot/"
|
||||
echo " Copied $dir/"
|
||||
fi
|
||||
done
|
||||
ssh "$PROXMOX" "chmod +x /opt/usbboot/rpiboot"
|
||||
|
||||
echo "[$(date -Iseconds)] usbboot deployed to $PROXMOX:/opt/usbboot"
|
||||
echo "Ensure the host flash script runs rpiboot with: -d /opt/usbboot/mass-storage-gadget64 (or mass-storage-gadget)."
|
||||
@@ -0,0 +1,24 @@
|
||||
[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
|
||||
@@ -0,0 +1,20 @@
|
||||
[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
|
||||
@@ -0,0 +1,20 @@
|
||||
[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
|
||||
67
chromium-setup/emmc-provisioning/scripts/deploy-to-proxmox.sh
Normal file → Executable file
67
chromium-setup/emmc-provisioning/scripts/deploy-to-proxmox.sh
Normal file → Executable file
@@ -3,39 +3,58 @@
|
||||
# Usage: ./deploy-to-proxmox.sh [proxmox_host]
|
||||
# Example: ./deploy-to-proxmox.sh root@10.130.60.224
|
||||
# Requires: ssh key access to root@<host>
|
||||
# Logging: set DEPLOY_LOG=1 to also write to deploy-YYYYMMDD-HHMMSS.log in the script dir.
|
||||
|
||||
set -e
|
||||
PROXMOX="${1:-root@10.130.60.224}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
LOG_FILE=""
|
||||
if [[ -n "${DEPLOY_LOG:-}" ]]; then
|
||||
LOG_FILE="$SCRIPT_DIR/deploy-$(date +%Y%m%d-%H%M%S).log"
|
||||
exec > >(tee -a "$LOG_FILE") 2>&1
|
||||
echo "[$(date -Iseconds)] Logging to $LOG_FILE"
|
||||
fi
|
||||
|
||||
echo "Deploying to $PROXMOX ..."
|
||||
log() { echo "[$(date -Iseconds)] $*"; }
|
||||
|
||||
log "Deploying to $PROXMOX ..."
|
||||
# Use a clean staging dir (remove if present so we never write into a symlink or bad state)
|
||||
log "[1/4] Cleaning remote staging dir ..."
|
||||
ssh "$PROXMOX" "rm -rf /tmp/emmc-provisioning-deploy"
|
||||
log "[2/4] Rsync repo to $PROXMOX ..."
|
||||
rsync -a "$REPO_DIR/" "$PROXMOX:/tmp/emmc-provisioning-deploy/" --exclude='.git' --exclude='scripts/deploy-to-proxmox.sh'
|
||||
log "[3/4] Running remote install (host + LXC) ..."
|
||||
|
||||
ssh "$PROXMOX" bash -s << 'REMOTE'
|
||||
set -e
|
||||
DEPLOY=/tmp/emmc-provisioning-deploy
|
||||
log() { echo "[$(date -Iseconds)] $*"; }
|
||||
|
||||
# Ensure LXC 201 exists (create if not)
|
||||
if ! pct status 201 &>/dev/null; then
|
||||
echo "Creating LXC 201 (cm4-provisioning)..."
|
||||
log "Creating LXC 201 (cm4-provisioning)..."
|
||||
pct create 201 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
|
||||
--hostname cm4-provisioning --memory 1024 --swap 0 --cores 1 \
|
||||
--rootfs local-zfs:8 --net0 name=eth0,bridge=vmbr0,ip=dhcp \
|
||||
--unprivileged 0 --features nesting=1 -tag cm4-provisioning
|
||||
mkdir -p /var/lib/cm4-provisioning
|
||||
pct set 201 -mp0 /var/lib/cm4-provisioning,mp=/var/lib/cm4-provisioning
|
||||
log "LXC 201 created and mount configured."
|
||||
else
|
||||
log "LXC 201 already exists."
|
||||
fi
|
||||
|
||||
# Host: install scripts and udev
|
||||
# Host: install scripts and udev (from host/)
|
||||
log "Host: installing scripts and udev ..."
|
||||
mkdir -p /opt/cm4-provisioning /etc/cm4-provisioning
|
||||
cp "$DEPLOY/flash-emmc-on-connect.sh" /opt/cm4-provisioning/
|
||||
cp "$DEPLOY/host/flash-emmc-on-connect.sh" /opt/cm4-provisioning/
|
||||
chmod +x /opt/cm4-provisioning/flash-emmc-on-connect.sh
|
||||
cp "$DEPLOY/cm4-flash-trigger.sh" /usr/local/bin/
|
||||
cp "$DEPLOY/host/cm4-flash-trigger.sh" /usr/local/bin/
|
||||
chmod +x /usr/local/bin/cm4-flash-trigger.sh
|
||||
cp "$DEPLOY/90-cm4-boot-mode.rules" /etc/udev/rules.d/
|
||||
cp "$DEPLOY/host/90-cm4-boot-mode.rules" /etc/udev/rules.d/
|
||||
udevadm control --reload-rules
|
||||
|
||||
log "Host: env and dirs ..."
|
||||
cat > /opt/cm4-provisioning/env << 'ENV'
|
||||
GOLDEN_IMAGE=/var/lib/cm4-provisioning/golden.img
|
||||
RPIBOOT_DIR=/opt/usbboot
|
||||
@@ -45,26 +64,42 @@ touch /etc/cm4-provisioning/enabled
|
||||
mkdir -p /var/lib/cm4-provisioning/backups
|
||||
|
||||
# Start LXC if stopped
|
||||
log "Starting LXC 201 if stopped ..."
|
||||
pct start 201 2>/dev/null || true
|
||||
|
||||
# LXC: install scripts
|
||||
# LXC: install scripts (from host/)
|
||||
log "LXC: installing flash scripts ..."
|
||||
pct exec 201 -- mkdir -p /opt/cm4-provisioning /etc/cm4-provisioning
|
||||
pct push 201 "$DEPLOY/flash-emmc-on-connect.sh" /opt/cm4-provisioning/
|
||||
pct push 201 "$DEPLOY/host/flash-emmc-on-connect.sh" /opt/cm4-provisioning/flash-emmc-on-connect.sh
|
||||
pct exec 201 -- chmod +x /opt/cm4-provisioning/flash-emmc-on-connect.sh
|
||||
pct push 201 "$DEPLOY/cm4-flash-trigger.sh" /usr/local/bin/cm4-flash-trigger.sh
|
||||
pct push 201 "$DEPLOY/host/cm4-flash-trigger.sh" /usr/local/bin/cm4-flash-trigger.sh
|
||||
pct exec 201 -- chmod +x /usr/local/bin/cm4-flash-trigger.sh
|
||||
pct exec 201 -- bash -c 'echo -e "GOLDEN_IMAGE=/var/lib/cm4-provisioning/golden.img\nRPIBOOT_DIR=/opt/usbboot\nEMMC_SIZE_BYTES=8589934592" > /opt/cm4-provisioning/env'
|
||||
|
||||
# LXC: install dashboard
|
||||
log "LXC: installing dashboard ..."
|
||||
pct exec 201 -- mkdir -p /opt/cm4-provisioning/dashboard/templates
|
||||
pct push 201 "$DEPLOY/dashboard/app.py" /opt/cm4-provisioning/dashboard/
|
||||
pct push 201 "$DEPLOY/dashboard/templates/index.html" /opt/cm4-provisioning/dashboard/templates/
|
||||
pct push 201 "$DEPLOY/dashboard/cm4-dashboard.service" /opt/cm4-provisioning/dashboard/
|
||||
pct push 201 "$DEPLOY/dashboard/app.py" /opt/cm4-provisioning/dashboard/app.py
|
||||
pct push 201 "$DEPLOY/dashboard/templates/index.html" /opt/cm4-provisioning/dashboard/templates/index.html
|
||||
pct push 201 "$DEPLOY/dashboard/cm4-dashboard.service" /opt/cm4-provisioning/dashboard/cm4-dashboard.service
|
||||
|
||||
echo "Deploy done. Install usbboot on host when online: ssh $PROXMOX 'bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh'"
|
||||
echo "To enable the 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'"
|
||||
# LXC: install Flask and enable dashboard service
|
||||
log "LXC: installing python3-flask and enabling cm4-dashboard service ..."
|
||||
pct exec 201 -- bash -c 'apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq python3-flask'
|
||||
pct exec 201 -- cp /opt/cm4-provisioning/dashboard/cm4-dashboard.service /etc/systemd/system/
|
||||
pct exec 201 -- systemctl daemon-reload
|
||||
pct exec 201 -- systemctl enable --now cm4-dashboard
|
||||
log "LXC: cm4-dashboard enabled and started."
|
||||
|
||||
log "Deploy done (remote)."
|
||||
echo "Next: Install usbboot on host when online: ssh <host> 'bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh'"
|
||||
REMOTE
|
||||
|
||||
log "[4/4] Deploy finished."
|
||||
echo ""
|
||||
echo "Done. Put golden.img in /var/lib/cm4-provisioning/ on the host (or scp to LXC 201 at /var/lib/cm4-provisioning/)."
|
||||
echo "When the host has internet, run on the host: bash /tmp/emmc-provisioning-deploy/scripts/install-usbboot-on-host.sh"
|
||||
echo "Dashboard: install flask in LXC 201 and enable cm4-dashboard.service (see PROXMOX-LXC-DEPLOYMENT.md)."
|
||||
echo "Dashboard: install flask in LXC 201 and enable cm4-dashboard.service (see docs/PROXMOX-LXC-DEPLOYMENT.md)."
|
||||
if [[ -n "$LOG_FILE" ]]; then
|
||||
echo "Log written to: $LOG_FILE"
|
||||
fi
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run on the Proxmox HOST (root) when the host has internet.
|
||||
# Builds usbboot (rpiboot) and installs to /opt/usbboot so the auto-flash can run.
|
||||
# If the host has no internet, run build-and-deploy-usbboot-to-host.sh from your Fedora machine instead.
|
||||
|
||||
set -e
|
||||
apt-get update
|
||||
apt-get install -y libusb-1.0-0-dev git
|
||||
apt-get install -y libusb-1.0-0-dev git pkg-config build-essential
|
||||
cd /tmp
|
||||
rm -rf usbboot
|
||||
git clone --depth=1 https://github.com/raspberrypi/usbboot
|
||||
git clone --recurse-submodules --shallow-submodules --depth=1 https://github.com/raspberrypi/usbboot
|
||||
cd usbboot
|
||||
make
|
||||
mkdir -p /opt/usbboot
|
||||
cp rpiboot /opt/usbboot/
|
||||
# Copy gadget dir(s) so rpiboot -d works
|
||||
for dir in mass-storage-gadget64 mass-storage-gadget; do
|
||||
[[ -d "$dir" ]] && cp -a "$dir" /opt/usbboot/
|
||||
done
|
||||
echo "usbboot installed at /opt/usbboot/rpiboot"
|
||||
|
||||
72
chromium-setup/emmc-provisioning/scripts/setup-lxc-ssh.sh
Executable file
72
chromium-setup/emmc-provisioning/scripts/setup-lxc-ssh.sh
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
# Enable root SSH login on LXC 201 (cm4-provisioning) and add your SSH key.
|
||||
# Usage:
|
||||
# ./setup-lxc-ssh.sh [proxmox_host] [ssh_public_key_file]
|
||||
# ROOT_PASSWORD='yourpassword' ./setup-lxc-ssh.sh [proxmox_host] [ssh_public_key_file]
|
||||
#
|
||||
# Examples:
|
||||
# ./setup-lxc-ssh.sh root@10.130.60.224
|
||||
# ./setup-lxc-ssh.sh root@10.130.60.224 ~/.ssh/id_ed25519.pub
|
||||
# ROOT_PASSWORD='MySecurePass' ./setup-lxc-ssh.sh root@10.130.60.224
|
||||
#
|
||||
# If ssh_public_key_file is omitted, uses ~/.ssh/id_ed25519.pub or ~/.ssh/id_rsa.pub.
|
||||
|
||||
set -e
|
||||
PROXMOX="${1:-root@10.130.60.224}"
|
||||
KEY_FILE="${2:-}"
|
||||
CTID="${CTID:-201}"
|
||||
|
||||
# Find public key
|
||||
if [[ -z "$KEY_FILE" ]]; then
|
||||
for f in ~/.ssh/id_ed25519.pub ~/.ssh/id_rsa.pub; do
|
||||
if [[ -f "$f" ]]; then
|
||||
KEY_FILE="$f"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
if [[ -z "$KEY_FILE" || ! -f "$KEY_FILE" ]]; then
|
||||
echo "No SSH public key found. Usage: $0 [proxmox_host] [ssh_public_key_file]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
KEY_CONTENT=$(cat "$KEY_FILE")
|
||||
ROOT_PASSWORD="${ROOT_PASSWORD:-}"
|
||||
|
||||
echo "Using key from: $KEY_FILE"
|
||||
echo "Configuring LXC $CTID on $PROXMOX (enable SSH, root login, add key)..."
|
||||
|
||||
ssh "$PROXMOX" bash -s << REMOTE
|
||||
set -e
|
||||
CTID="$CTID"
|
||||
KEY_CONTENT='$(echo "$KEY_CONTENT" | sed "s/'/'\\\\''/g")'
|
||||
ROOT_PASSWORD='$(echo "$ROOT_PASSWORD" | sed "s/'/'\\\\''/g")'
|
||||
|
||||
# Ensure container is running
|
||||
pct start \$CTID 2>/dev/null || true
|
||||
sleep 2
|
||||
|
||||
# Install openssh-server if missing, enable and start
|
||||
pct exec \$CTID -- bash -c 'apt-get update -qq && apt-get install -y -qq openssh-server 2>/dev/null; systemctl enable ssh 2>/dev/null; systemctl start ssh 2>/dev/null' || true
|
||||
|
||||
# Enable root login via password and/or public key
|
||||
pct exec \$CTID -- bash -c '
|
||||
sed -i "s/^#*PermitRootLogin.*/PermitRootLogin yes/" /etc/ssh/sshd_config 2>/dev/null || true
|
||||
grep -q "^PermitRootLogin" /etc/ssh/sshd_config || echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
|
||||
systemctl restart ssh 2>/dev/null || systemctl restart sshd 2>/dev/null || true
|
||||
'
|
||||
|
||||
# Set root password if provided (pass via stdin so no quoting in -c)
|
||||
if [[ -n "\$ROOT_PASSWORD" ]]; then
|
||||
echo "root:\$ROOT_PASSWORD" | pct exec \$CTID -- chpasswd
|
||||
echo "Root password set."
|
||||
fi
|
||||
|
||||
# Add SSH key to root (pass key via stdin to avoid quoting issues)
|
||||
echo "\$KEY_CONTENT" | pct exec \$CTID -- bash -c "mkdir -p /root/.ssh; chmod 700 /root/.ssh; cat >> /root/.ssh/authorized_keys; chmod 600 /root/.ssh/authorized_keys"
|
||||
echo "SSH key added to /root/.ssh/authorized_keys"
|
||||
|
||||
# Show IP for convenience
|
||||
IP=\$(pct exec \$CTID -- hostname -I 2>/dev/null | awk '{print \$1}')
|
||||
echo "Done. Connect with: ssh root@\$IP"
|
||||
REMOTE
|
||||
Reference in New Issue
Block a user