Update cloud-init scripts and documentation for enhanced DNS management and provisioning steps</message>
<message>Modify the first-boot.sh script to include an additional step for managing screen brightness during the provisioning process. Update user-data.bootstrap to improve DNS configuration by ensuring NetworkManager manages /etc/resolv.conf correctly, and remove obsolete scripts related to systemd-resolved. Enhance documentation to reflect these changes and clarify the setup process for users, improving overall network boot functionality and user experience.
This commit is contained in:
203
emmc-provisioning/scripts/deploy-screen-brightness-to-device.sh
Executable file
203
emmc-provisioning/scripts/deploy-screen-brightness-to-device.sh
Executable file
@@ -0,0 +1,203 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deploy screen-brightness daemon to an existing reTerminal DM.
|
||||
#
|
||||
# Usage:
|
||||
# On device (local files in current directory):
|
||||
# sudo ./deploy-screen-brightness-to-device.sh
|
||||
#
|
||||
# On device (download from file server) — use ONE of these (sudo often strips env):
|
||||
# sudo ./deploy-screen-brightness-to-device.sh "http://file.server:5000/files"
|
||||
# sudo -E BOOTSTRAP_URL="http://file.server:5000/files" ./deploy-screen-brightness-to-device.sh
|
||||
#
|
||||
# From host (deploy via SSH; repo files used from ../cloud-init/fileserver/):
|
||||
# ./deploy-screen-brightness-to-device.sh [user@]hostname
|
||||
#
|
||||
# From host via jump server (bastion):
|
||||
# SSH_JUMP_HOST="user@jump.example.com" ./deploy-screen-brightness-to-device.sh pi@10.0.0.5
|
||||
# Or in ~/.ssh/config set ProxyJump for the device; then no env var needed.
|
||||
#
|
||||
# Does not overwrite existing /etc/screen-brightness.conf (keeps vessel tuning).
|
||||
# See docs/SCREEN-BRIGHTNESS-MANUAL-SETUP.md for full manual steps.
|
||||
|
||||
set -e
|
||||
|
||||
# Unconditional first output so we know the script is running (helps if run via sudo)
|
||||
echo "screen-brightness deploy: starting..."
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)"
|
||||
FILESERVER_DIR="$(cd "$SCRIPT_DIR/../cloud-init/fileserver" 2>/dev/null && pwd)"
|
||||
ARG1="${1:-}"
|
||||
|
||||
# If first argument looks like a URL (not user@host), use it as BOOTSTRAP_URL
|
||||
if [[ -n "$ARG1" && "$ARG1" == http* && "$ARG1" != *"@"* ]]; then
|
||||
BOOTSTRAP_URL="${ARG1%/}" # strip trailing slash for clean ${URL}/${name}
|
||||
REMOTE=""
|
||||
else
|
||||
REMOTE="$ARG1"
|
||||
fi
|
||||
|
||||
# Require root for local install
|
||||
if [[ -z "$REMOTE" && "$(id -u)" -ne 0 ]]; then
|
||||
echo "This script must be run as root for local install. Use: sudo $0 ${1:-}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ── Remote deploy (from host via SSH) ─────────────────────────────────────────
|
||||
# REMOTE is set when first arg is not a URL (e.g. pi@device or Host alias from ~/.ssh/config)
|
||||
if [[ -n "$REMOTE" ]]; then
|
||||
if [[ ! -d "$FILESERVER_DIR" ]]; then
|
||||
echo "ERROR: Fileserver dir not found: $FILESERVER_DIR" >&2
|
||||
exit 1
|
||||
fi
|
||||
# Optional: deploy via jump server (e.g. SSH_JUMP_HOST="user@jump.example.com")
|
||||
SSH_OPTS=()
|
||||
SCP_OPTS=()
|
||||
if [[ -n "${SSH_JUMP_HOST:-}" ]]; then
|
||||
SSH_OPTS=(-J "$SSH_JUMP_HOST")
|
||||
SCP_OPTS=(-o "ProxyJump=$SSH_JUMP_HOST")
|
||||
echo "Using jump host: $SSH_JUMP_HOST"
|
||||
fi
|
||||
echo "Deploying screen-brightness + overlay to $REMOTE (from $FILESERVER_DIR) ..."
|
||||
ssh "${SSH_OPTS[@]}" "${REMOTE}" "mkdir -p /tmp/screen-brightness-deploy"
|
||||
scp -q "${SCP_OPTS[@]}" \
|
||||
"$FILESERVER_DIR/screen-brightness.py" \
|
||||
"$FILESERVER_DIR/screen-brightness.service" \
|
||||
"$FILESERVER_DIR/screen-brightness.conf" \
|
||||
"$FILESERVER_DIR/brightness-api.py" \
|
||||
"$FILESERVER_DIR/brightness-api.service" \
|
||||
"$FILESERVER_DIR/brightness-overlay.py" \
|
||||
"$FILESERVER_DIR/brightness-overlay-launch.sh" \
|
||||
"$FILESERVER_DIR/brightness-overlay.desktop" \
|
||||
"${REMOTE}:/tmp/screen-brightness-deploy/"
|
||||
ssh "${SSH_OPTS[@]}" "${REMOTE}" "sudo bash -s" << 'REMOTE_SCRIPT'
|
||||
set -e
|
||||
cd /tmp/screen-brightness-deploy
|
||||
install -m 755 screen-brightness.py /usr/local/bin/screen-brightness.py
|
||||
install -m 644 screen-brightness.service /etc/systemd/system/screen-brightness.service
|
||||
[[ ! -f /etc/screen-brightness.conf ]] && install -m 644 screen-brightness.conf /etc/screen-brightness.conf || true
|
||||
mkdir -p /run/screen-brightness
|
||||
printf '%s\n' 'd /run/screen-brightness 0755 root root -' > /etc/tmpfiles.d/screen-brightness.conf
|
||||
systemctl daemon-reload
|
||||
systemctl enable screen-brightness.service
|
||||
systemctl restart screen-brightness.service
|
||||
echo "Installed and restarted screen-brightness.service"
|
||||
|
||||
# Brightness API (for overlay)
|
||||
install -m 755 brightness-api.py /usr/local/bin/brightness-api.py
|
||||
install -m 644 brightness-api.service /etc/systemd/system/brightness-api.service
|
||||
systemctl daemon-reload
|
||||
systemctl enable brightness-api.service
|
||||
systemctl restart brightness-api.service
|
||||
echo "Installed and restarted brightness-api.service"
|
||||
|
||||
# Overlay (crew manual control) — install for user pi
|
||||
OVERLAY_USER=pi
|
||||
OVERLAY_HOME=/home/$OVERLAY_USER
|
||||
if [[ -f brightness-overlay.py && -f brightness-overlay.desktop ]] && id "$OVERLAY_USER" &>/dev/null; then
|
||||
install -m 755 brightness-overlay.py "$OVERLAY_HOME/brightness-overlay.py"
|
||||
[[ -f brightness-overlay-launch.sh ]] && install -m 755 brightness-overlay-launch.sh "$OVERLAY_HOME/brightness-overlay-launch.sh"
|
||||
mkdir -p "$OVERLAY_HOME/.config/autostart"
|
||||
sed "s|/home/pi|$OVERLAY_HOME|g" brightness-overlay.desktop > "$OVERLAY_HOME/.config/autostart/brightness-overlay.desktop"
|
||||
chown -R "$OVERLAY_USER:$OVERLAY_USER" "$OVERLAY_HOME/brightness-overlay.py" "$OVERLAY_HOME/brightness-overlay-launch.sh" "$OVERLAY_HOME/.config/autostart/brightness-overlay.desktop" 2>/dev/null || true
|
||||
echo "Installed brightness overlay for $OVERLAY_USER (autostart; starts ~6s after login)"
|
||||
else
|
||||
echo "Skipped overlay (files missing or user $OVERLAY_USER not found)"
|
||||
fi
|
||||
REMOTE_SCRIPT
|
||||
ssh "${SSH_OPTS[@]}" "${REMOTE}" "rm -rf /tmp/screen-brightness-deploy"
|
||||
echo "Done. Check: ssh ${SSH_OPTS[*]} $REMOTE systemctl status screen-brightness.service"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ── Local deploy (on device) ─────────────────────────────────────────────────
|
||||
if [[ -n "${BOOTSTRAP_URL:-}" ]]; then
|
||||
echo "Downloading from $BOOTSTRAP_URL ..."
|
||||
DOWNLOAD_DIR="/tmp/screen-brightness-deploy"
|
||||
mkdir -p "$DOWNLOAD_DIR"
|
||||
REQUIRED="screen-brightness.py screen-brightness.service screen-brightness.conf"
|
||||
OPTIONAL="brightness-api.py brightness-api.service brightness-overlay.py brightness-overlay-launch.sh brightness-overlay.desktop"
|
||||
for name in $REQUIRED; do
|
||||
url="${BOOTSTRAP_URL}/${name}"
|
||||
if ! curl -fSL "$url" -o "$DOWNLOAD_DIR/$name" 2>/tmp/screen-brightness-curl-err; then
|
||||
echo "ERROR: Failed to download $url" >&2
|
||||
[[ -s /tmp/screen-brightness-curl-err ]] && cat /tmp/screen-brightness-curl-err >&2
|
||||
rm -f /tmp/screen-brightness-curl-err
|
||||
rm -rf "$DOWNLOAD_DIR"
|
||||
exit 1
|
||||
fi
|
||||
rm -f /tmp/screen-brightness-curl-err
|
||||
echo " $name OK"
|
||||
done
|
||||
for name in $OPTIONAL; do
|
||||
url="${BOOTSTRAP_URL}/${name}"
|
||||
if curl -fSL "$url" -o "$DOWNLOAD_DIR/$name" 2>/dev/null; then
|
||||
echo " $name OK"
|
||||
fi
|
||||
done
|
||||
DEPLOY_DIR="$DOWNLOAD_DIR"
|
||||
else
|
||||
if [[ -f "$SCRIPT_DIR/screen-brightness.py" ]]; then
|
||||
DEPLOY_DIR="$SCRIPT_DIR"
|
||||
elif [[ -d "$FILESERVER_DIR" && -f "$FILESERVER_DIR/screen-brightness.py" ]]; then
|
||||
DEPLOY_DIR="$FILESERVER_DIR"
|
||||
else
|
||||
# Assume files are in current directory
|
||||
DEPLOY_DIR="$(pwd)"
|
||||
fi
|
||||
if [[ ! -f "$DEPLOY_DIR/screen-brightness.py" ]]; then
|
||||
echo "ERROR: screen-brightness.py not found." >&2
|
||||
echo " Run from a directory containing screen-brightness.py, .service, .conf" >&2
|
||||
echo " Or set BOOTSTRAP_URL to download from a file server." >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Using files from: $DEPLOY_DIR"
|
||||
fi
|
||||
|
||||
install -m 755 "$DEPLOY_DIR/screen-brightness.py" /usr/local/bin/screen-brightness.py
|
||||
install -m 644 "$DEPLOY_DIR/screen-brightness.service" /etc/systemd/system/screen-brightness.service
|
||||
|
||||
if [[ ! -f /etc/screen-brightness.conf ]]; then
|
||||
install -m 644 "$DEPLOY_DIR/screen-brightness.conf" /etc/screen-brightness.conf
|
||||
echo "Installed /etc/screen-brightness.conf"
|
||||
else
|
||||
echo "Keeping existing /etc/screen-brightness.conf"
|
||||
fi
|
||||
|
||||
mkdir -p /run/screen-brightness
|
||||
printf '%s\n' 'd /run/screen-brightness 0755 root root -' > /etc/tmpfiles.d/screen-brightness.conf
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable screen-brightness.service
|
||||
systemctl restart screen-brightness.service
|
||||
echo "Installed and restarted screen-brightness.service"
|
||||
|
||||
# Brightness API (for overlay)
|
||||
if [[ -f "${DEPLOY_DIR:-}/brightness-api.py" ]]; then
|
||||
install -m 755 "$DEPLOY_DIR/brightness-api.py" /usr/local/bin/brightness-api.py
|
||||
if [[ -f "$DEPLOY_DIR/brightness-api.service" ]]; then
|
||||
install -m 644 "$DEPLOY_DIR/brightness-api.service" /etc/systemd/system/brightness-api.service
|
||||
systemctl daemon-reload
|
||||
systemctl enable brightness-api.service
|
||||
systemctl restart brightness-api.service
|
||||
echo "Installed and restarted brightness-api.service"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Overlay (crew manual control)
|
||||
OVERLAY_USER="${SUDO_USER:-pi}"
|
||||
OVERLAY_HOME=$(getent passwd "$OVERLAY_USER" 2>/dev/null | cut -d: -f6)
|
||||
OVERLAY_HOME="${OVERLAY_HOME:-/home/pi}"
|
||||
if [[ -f "${DEPLOY_DIR:-}/brightness-overlay.py" && -f "${DEPLOY_DIR:-}/brightness-overlay.desktop" ]] && [[ -d "$OVERLAY_HOME" ]]; then
|
||||
install -m 755 "$DEPLOY_DIR/brightness-overlay.py" "$OVERLAY_HOME/brightness-overlay.py"
|
||||
[[ -f "${DEPLOY_DIR:-}/brightness-overlay-launch.sh" ]] && install -m 755 "$DEPLOY_DIR/brightness-overlay-launch.sh" "$OVERLAY_HOME/brightness-overlay-launch.sh"
|
||||
mkdir -p "$OVERLAY_HOME/.config/autostart"
|
||||
sed "s|/home/pi|$OVERLAY_HOME|g" "$DEPLOY_DIR/brightness-overlay.desktop" > "$OVERLAY_HOME/.config/autostart/brightness-overlay.desktop"
|
||||
chown "$OVERLAY_USER:$OVERLAY_USER" "$OVERLAY_HOME/brightness-overlay.py" "$OVERLAY_HOME/.config/autostart/brightness-overlay.desktop"
|
||||
[[ -f "$OVERLAY_HOME/brightness-overlay-launch.sh" ]] && chown "$OVERLAY_USER:$OVERLAY_USER" "$OVERLAY_HOME/brightness-overlay-launch.sh"
|
||||
echo "Installed brightness overlay for $OVERLAY_USER (autostart; starts ~6s after login)"
|
||||
fi
|
||||
|
||||
[[ "${DEPLOY_DIR:-}" == "/tmp/screen-brightness-deploy" ]] && rm -rf "$DEPLOY_DIR"
|
||||
|
||||
echo ""
|
||||
systemctl status screen-brightness.service --no-pager || true
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
# Mount a Raspberry Pi OS .img or .img.xz, edit cloud-init NoCloud files on the boot
|
||||
# partition, then unmount and (if .img.xz) recompress. Requires sudo for loop/mount.
|
||||
# partition, then unmount and (if .img.xz) recompress to a NEW file with current
|
||||
# date/time prefix. Original image is never overwritten. Requires sudo for loop/mount.
|
||||
#
|
||||
# Usage:
|
||||
# ./edit-cloudinit-on-image.sh <path-to-image.img.xz>
|
||||
@@ -13,7 +14,7 @@
|
||||
# Example:
|
||||
# ./edit-cloudinit-on-image.sh /path/to/gnss-bootstrap-20260223-215010.img.xz
|
||||
#
|
||||
# Backup the image before running if you want to keep the original.
|
||||
# The original image is preserved; output uses a new timestamp (e.g. gnss-bootstrap-20250305-143022.img.xz).
|
||||
|
||||
set -e
|
||||
|
||||
@@ -118,10 +119,19 @@ sudo losetup -d "$LOOP"
|
||||
LOOP=""
|
||||
|
||||
if [[ -n "$ORIGINAL_XZ" && -z "$NO_RECOMPRESS" ]]; then
|
||||
echo "Recompressing to $(basename "$ORIGINAL_XZ")…"
|
||||
ORIG_DIR="$(dirname "$ORIGINAL_XZ")"
|
||||
ORIG_BASE="$(basename "$ORIGINAL_XZ" .img.xz)"
|
||||
if [[ "$ORIG_BASE" =~ ^(.+)-[0-9]{8}-[0-9]{6}$ ]]; then
|
||||
BASE_NAME="${BASH_REMATCH[1]}"
|
||||
else
|
||||
BASE_NAME="$ORIG_BASE"
|
||||
fi
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
NEW_IMG_XZ="$ORIG_DIR/${BASE_NAME}-${TIMESTAMP}.img.xz"
|
||||
echo "Recompressing to $(basename "$NEW_IMG_XZ")…"
|
||||
xz -T 0 -z -f -k "$IMG_FILE"
|
||||
mv -f "${IMG_FILE}.xz" "$ORIGINAL_XZ"
|
||||
echo "Done. Updated: $ORIGINAL_XZ"
|
||||
mv -f "${IMG_FILE}.xz" "$NEW_IMG_XZ"
|
||||
echo "Done. New image (original unchanged): $NEW_IMG_XZ"
|
||||
rm -rf "$WORK_DIR"
|
||||
WORK_DIR=""
|
||||
elif [[ -n "$NO_RECOMPRESS" && -n "$ORIGINAL_XZ" ]]; then
|
||||
|
||||
@@ -79,13 +79,12 @@ if ! command -v vconfig >/dev/null 2>&1; then
|
||||
apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq vlan
|
||||
fi
|
||||
|
||||
# 2) dnsmasq config for eth1 only (DHCP + DNS). PXE/TFTP in network-boot-pxe.conf when needed (toggle-network-boot-dhcp.sh)
|
||||
# 2) dnsmasq config: DHCP on eth1 only; DNS on all interfaces (no bind-interfaces/listen-address).
|
||||
# PXE/TFTP in network-boot-pxe.conf when needed (toggle-network-boot-dhcp.sh)
|
||||
mkdir -p /etc/dnsmasq.d
|
||||
cat > /etc/dnsmasq.d/network-boot.conf << DNSMASQ
|
||||
# DHCP + DNS on eth1 only (provisioning LAN)
|
||||
# (TFTP/PXE options in network-boot-pxe.conf when network boot is enabled)
|
||||
# DHCP on eth1 only; DNS on all interfaces (eth0, eth1, eth1.40, etc.)
|
||||
interface=eth1
|
||||
bind-interfaces
|
||||
dhcp-range=${DHCP_RANGE_START},${DHCP_RANGE_END},12h
|
||||
# DNS: file.server resolves to this host (eth1) so scripts can use http://file.server/...
|
||||
address=/file.server/${LAN_GW}
|
||||
|
||||
@@ -12,11 +12,15 @@
|
||||
# ├── first-boot.conf ← cloud-init runcmd downloads this (required)
|
||||
# ├── first-boot.conf.example ← reference
|
||||
# ├── bootstrap.sh ← user-data.bootstrap downloads this (main path)
|
||||
# └── first-boot/ ← FILE_SERVER points here
|
||||
# ├── screen-brightness.py ← manual deploy: .../files/screen-brightness.py
|
||||
# ├── screen-brightness.service
|
||||
# ├── screen-brightness.conf
|
||||
# └── first-boot/ ← FILE_SERVER points here (first-boot + step 14)
|
||||
# ├── steps/
|
||||
# │ ├── 01-hostname.sh … 13-reboot.sh
|
||||
# │ ├── 01-hostname.sh … 14-screen_brightness.sh
|
||||
# ├── start-chromium.sh
|
||||
# ├── splash.png
|
||||
# ├── screen-brightness.py (and .service, .conf)
|
||||
# └── ...
|
||||
#
|
||||
# Usage: ./sync-portal-files-to-lxc.sh [user@lxc_ip]
|
||||
@@ -34,6 +38,10 @@ REMOTE_FIRST_BOOT="${REMOTE_PORTAL}/first-boot"
|
||||
# Files we sync to the portal root (outside first-boot/)
|
||||
PORTAL_ROOT_FILES=(first-boot.sh first-boot.conf first-boot.conf.example bootstrap.sh)
|
||||
|
||||
# Files from fileserver/ that we also copy to portal root so /files/<name> works
|
||||
# (e.g. manual deploy: sudo ./deploy-screen-brightness-to-device.sh "http://HOST:5000/files")
|
||||
FILESERVER_FILES_AT_PORTAL_ROOT=(screen-brightness.py screen-brightness.service screen-brightness.conf)
|
||||
|
||||
# ── Validate local files ────────────────────────────────────────────────
|
||||
if [[ ! -d "$FILESERVER_DIR" ]]; then
|
||||
echo "Error: fileserver dir not found: $FILESERVER_DIR"
|
||||
@@ -67,6 +75,13 @@ for f in "${PORTAL_ROOT_FILES[@]}"; do
|
||||
echo " ✗ $f (not found locally, will skip)"
|
||||
fi
|
||||
done
|
||||
for f in "${FILESERVER_FILES_AT_PORTAL_ROOT[@]}"; do
|
||||
if [[ -f "$FILESERVER_DIR/$f" ]]; then
|
||||
echo " ✓ $f (from fileserver/)"
|
||||
else
|
||||
echo " ✗ $f (not in fileserver/, will skip portal root copy)"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
echo "first-boot/ assets ($REMOTE_FIRST_BOOT/):"
|
||||
CHANGES=$(rsync -avzn --delete "$FILESERVER_DIR/" "$LXC:$REMOTE_FIRST_BOOT/" 2>&1 | grep -v '^\(sending\|sent\|total\|$\|building\|\.d\.\.\.\.\.\.\.\.\.\)' | head -40)
|
||||
@@ -98,12 +113,23 @@ echo ""
|
||||
echo "── Syncing fileserver/ → first-boot/ ──────────────────────────"
|
||||
rsync -avz --delete "$FILESERVER_DIR/" "$LXC:$REMOTE_FIRST_BOOT/"
|
||||
|
||||
# ── Copy screen-brightness (and similar) from fileserver to portal root ───
|
||||
# So http://HOST:5000/files/screen-brightness.py works for manual deploy
|
||||
echo ""
|
||||
echo "── Copying fileserver files to portal root ───────────────────"
|
||||
for f in "${FILESERVER_FILES_AT_PORTAL_ROOT[@]}"; do
|
||||
if [[ -f "$FILESERVER_DIR/$f" ]]; then
|
||||
rsync -avz "$FILESERVER_DIR/$f" "$LXC:$REMOTE_PORTAL/"
|
||||
echo " ✓ $f"
|
||||
fi
|
||||
done
|
||||
|
||||
# ── Check for extra files in portal root ────────────────────────────────
|
||||
echo ""
|
||||
echo "── Checking for extra files in portal root ────────────────────"
|
||||
|
||||
REMOTE_FILES=$(ssh "$LXC" "find $REMOTE_PORTAL -maxdepth 1 -not -path $REMOTE_PORTAL -printf '%f\n' 2>/dev/null" | sort)
|
||||
EXPECTED_FILES=$(printf '%s\n' "${PORTAL_ROOT_FILES[@]}" "first-boot" | sort -u)
|
||||
EXPECTED_FILES=$(printf '%s\n' "${PORTAL_ROOT_FILES[@]}" "${FILESERVER_FILES_AT_PORTAL_ROOT[@]}" "first-boot" | sort -u)
|
||||
EXTRA_FILES=$(comm -23 <(echo "$REMOTE_FILES") <(echo "$EXPECTED_FILES"))
|
||||
|
||||
if [[ -z "$EXTRA_FILES" ]]; then
|
||||
|
||||
Reference in New Issue
Block a user