Build optimization: pre-built PM3 binaries, ARM64 CI, base image caching

Replace PM3 compile-from-source in pi-gen with pre-built tarball extraction
(saves 43-58 min). Merge stagePM3 into stageDangerousPi as 02-pm3-install
substage, renumber all subsequent substages. Switch CI PM3 build to native
ARM64 runner (ubuntu-24.04-arm64) eliminating QEMU overhead. Add weekly
base-image workflow for pre-baking stages 0-2. Support PM3_TARBALL,
BASE_IMAGE, and APT_PROXY env vars in build-image.sh.

Also includes prior Phase 5 work: theme system, design system integration,
component update system, OS updates, CI build pipeline, and test results.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
michael
2026-03-04 12:01:01 -08:00
parent 2ec89041ef
commit a9acdb85ce
163 changed files with 8124 additions and 921 deletions

View File

@@ -13,4 +13,4 @@ FIRST_USER_PASS="proxmark3"
ENABLE_SSH=1
WPA_COUNTRY="US"
DISABLE_FIRST_BOOT_USER_RENAME=1
STAGE_LIST="stage0 stage1 stage2 stagePM3 stageDangerousPi"
STAGE_LIST="stage0 stage1 stage2 stageDangerousPi"

View File

@@ -0,0 +1,17 @@
# Consolidated package list for stageDangerousPi
# All packages needed across substages, installed in one apt-get call
# to avoid redundant apt-get update / Reading package lists overhead.
# 01-Wireless-AP: WiFi access point + reverse proxy
hostapd
dnsmasq
nftables
nginx
# 03-dangerous-pi: backend/frontend runtime + utilities
nodejs
npm
lrzsz
# 04-pisugar: I2C tools for UPS battery monitoring
i2c-tools

View File

@@ -7,13 +7,7 @@
echo "=== Setting up WiFi Access Point ==="
# Install required packages
echo "Installing hostapd, dnsmasq, nginx..."
apt-get install -y \
hostapd \
dnsmasq \
nftables \
nginx
# Packages (hostapd, dnsmasq, nftables, nginx) installed by 00-apt-setup stage
# Note: We no longer use static config file for wlan0 management.
# The wifi_manager now uses 'nmcli device set wlan0 managed yes/no' dynamically.

View File

@@ -6,9 +6,25 @@
echo "=== Starting Proxmark3 build with Python bindings ==="
# Check if build can be skipped (manifest unchanged from previous build)
if [ -f /tmp/SKIP_PM3_BUILD ]; then
echo "=== PM3 build manifest unchanged — checking cached installation ==="
DEFAULT_USER=$(awk -F: '$3 >= 1000 && $3 < 65534 {print $1; exit}' /etc/passwd)
DEFAULT_HOME=$(eval echo ~${DEFAULT_USER:-pi})
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/client/proxmark3" ] && \
[ -f "$DEFAULT_HOME/.pm3/proxmark3/firmware/fullimage.elf" ]; then
echo "✓ PM3 client binary present"
echo "✓ PM3 firmware present"
echo "=== Skipping Proxmark3 build (cached) ==="
exit 0
else
echo "✗ PM3 binaries missing despite manifest match — rebuilding"
fi
fi
# Install build dependencies
# apt-get update not needed: metadata inherited from stage0 (same build session)
echo "Installing build dependencies..."
apt-get update
apt-get install -y \
cmake \
python3-dev \
@@ -29,12 +45,23 @@ apt-get install -y \
libbluetooth-dev \
libgd-dev
# Read pinned version config if available
PM3_REPO="https://github.com/RfidResearchGroup/proxmark3"
PM3_COMMIT=""
if [ -f /tmp/pm3-version.conf ]; then
. /tmp/pm3-version.conf
fi
# Clone Proxmark3 repository
echo "Cloning Proxmark3 repository..."
cd /tmp
rm -rf proxmark3 # Clean any existing clone
git clone https://github.com/RfidResearchGroup/proxmark3
git clone "$PM3_REPO" proxmark3
cd proxmark3
if [ -n "$PM3_COMMIT" ]; then
echo "Checking out pinned commit: $PM3_COMMIT"
git checkout "$PM3_COMMIT"
fi
# Apply LED PWM control patch (custom Dangerous Pi feature)
# Patch was copied to /tmp by 00-run.sh (pre-chroot script)
@@ -368,6 +395,13 @@ else
echo "✗ WARNING: Rebuild script not installed"
fi
# Save build manifest for future cache checks
if [ -f /tmp/pm3-build-manifest ]; then
mkdir -p /opt/dangerous-pi
cp /tmp/pm3-build-manifest /opt/dangerous-pi/.pm3-build-manifest
echo "✓ Build manifest saved for cache"
fi
# Print summary
echo "=== Proxmark3 build complete ==="
echo "Installation location: $DEFAULT_HOME/.pm3/proxmark3/"

View File

@@ -0,0 +1,282 @@
#!/bin/bash -e
# Install Proxmark3 from pre-built tarball or compile from source as fallback.
#
# Pre-built tarball: extracted from /tmp/pm3-prebuilt.tar.gz (staged by 00-run.sh)
# Compile fallback: triggered when /tmp/PM3_COMPILE_FROM_SOURCE exists
echo "=== Proxmark3 Installation ==="
# --- Check if we need to compile from source (fallback) ---
if [ -f /tmp/PM3_COMPILE_FROM_SOURCE ]; then
echo "No pre-built tarball available — compiling from source"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
if [ -f "${SCRIPT_DIR}/00-run-chroot-compile.sh" ]; then
exec "${SCRIPT_DIR}/00-run-chroot-compile.sh"
else
echo "ERROR: Compile fallback script not found"
exit 1
fi
fi
# --- Pre-built tarball installation ---
if [ ! -f /tmp/pm3-prebuilt.tar.gz ]; then
echo "ERROR: PM3 tarball not found at /tmp/pm3-prebuilt.tar.gz"
echo "Set PM3_TARBALL env var or place a tarball in 02-pm3-install/files/"
exit 1
fi
# Install runtime dependencies only (no build tools needed)
echo "Installing runtime dependencies..."
apt-get install -y \
libreadline8t64 \
libusb-1.0-0 \
liblz4-1 \
libbz2-1.0 \
libjansson4 \
libgd3t64 \
libssl3t64 \
libbluetooth3
# Detect the default user (first UID >= 1000, excluding nobody)
DEFAULT_USER=$(awk -F: '$3 >= 1000 && $3 < 65534 {print $1; exit}' /etc/passwd)
if [ -z "$DEFAULT_USER" ]; then
DEFAULT_USER="pi"
fi
DEFAULT_HOME=$(eval echo ~$DEFAULT_USER)
echo "Installing for user: $DEFAULT_USER (home: $DEFAULT_HOME)"
# Create installation directory
mkdir -p "$DEFAULT_HOME/.pm3/proxmark3"
# Extract pre-built tarball
# Tarball structure: pm3/{client/,firmware/,patches/,scripts/,pm3-flash-*,COMPONENT_VERSION}
echo "Extracting PM3 tarball..."
tar -xzf /tmp/pm3-prebuilt.tar.gz -C "$DEFAULT_HOME/.pm3/proxmark3" --strip-components=1
# Ensure _pm3.so symlink exists (critical for Python import)
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/libpm3rrg_rdv4.so" ] && \
[ ! -f "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/_pm3.so" ]; then
echo "Creating _pm3.so symlink..."
cd "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts"
ln -sf libpm3rrg_rdv4.so _pm3.so
fi
# Ensure flash utilities are executable
chmod +x "$DEFAULT_HOME/.pm3/proxmark3/pm3-flash-"* 2>/dev/null || true
# Install PM3 rebuild script (for on-device source rebuilds)
echo "Installing rebuild script..."
mkdir -p "$DEFAULT_HOME/.pm3/proxmark3/scripts"
cat > "$DEFAULT_HOME/.pm3/proxmark3/scripts/rebuild-pm3.sh" << 'REBUILD_EOF'
#!/bin/bash
# Rebuild Proxmark3 client and firmware with LED PWM control patch
# Usage: ./rebuild-pm3.sh [--flash]
set -e
PM3_HOME="$HOME/.pm3/proxmark3"
BUILD_DIR="/tmp/proxmark3-rebuild"
PATCH_FILE="$PM3_HOME/patches/led-pwm-control.patch"
echo "=== Proxmark3 Rebuild Script ==="
echo "This will rebuild the PM3 client and firmware with LED PWM control."
echo ""
# Check for ARM toolchain
if ! command -v arm-none-eabi-gcc &> /dev/null; then
echo "ERROR: ARM toolchain not found. Install with:"
echo " sudo apt install gcc-arm-none-eabi"
exit 1
fi
# Clean previous build
rm -rf "$BUILD_DIR"
# Clone fresh copy
echo "Cloning Proxmark3 repository..."
git clone --depth 1 https://github.com/RfidResearchGroup/proxmark3 "$BUILD_DIR"
cd "$BUILD_DIR"
# Apply LED PWM control patch
if [ -f "$PATCH_FILE" ]; then
echo "Applying LED PWM control patch..."
patch -p1 < "$PATCH_FILE"
echo "Patch applied"
else
echo "WARNING: LED patch not found at $PATCH_FILE"
fi
# Apply HF booster detection patch
if [ -f "$PM3_HOME/patches/hf-booster-detection.patch" ]; then
echo "Applying HF booster detection patch..."
patch -p1 < "$PM3_HOME/patches/hf-booster-detection.patch"
fi
# Add Dangerous Pi branding to version string
echo "Adding Dangerous Pi branding..."
sed -i 's/^fullgitinfo="Iceman"$/fullgitinfo="Iceman\/DangerousPi"/' tools/mkversion.sh
# Configure build
echo "Configuring build..."
cat > Makefile.platform << EOF
PLATFORM=PM3GENERIC
LED_ORDER=PM3EASY
EOF
# Build firmware and client
echo "Building firmware (this takes a while on Pi Zero)..."
make clean
make -j$(nproc)
# Build client with Python bindings
echo "Building client..."
cd client
mkdir -p build
cd build
cmake .. -DBUILD_PYTHON_LIB=ON
make -j$(nproc)
# Build experimental Python library
echo "Building Python bindings..."
cd ../experimental_lib
./00make_swig.sh
./01make_lib.sh
cd "$BUILD_DIR"
# Backup current installation
echo "Backing up current installation..."
if [ -f "$PM3_HOME/client/proxmark3" ]; then
cp "$PM3_HOME/client/proxmark3" "$PM3_HOME/client/proxmark3.bak"
fi
if [ -f "$PM3_HOME/firmware/fullimage.elf" ]; then
cp "$PM3_HOME/firmware/fullimage.elf" "$PM3_HOME/firmware/fullimage.elf.bak"
fi
# Install new binaries
echo "Installing new client..."
cp "$BUILD_DIR/client/build/proxmark3" "$PM3_HOME/client/"
cp "$BUILD_DIR/client/experimental_lib/build/libpm3rrg_rdv4.so" "$PM3_HOME/client/pyscripts/"
cp "$BUILD_DIR/client/pyscripts/*.py" "$PM3_HOME/client/pyscripts/"
echo "Installing new firmware..."
cp "$BUILD_DIR/bootrom/obj/bootrom.elf" "$PM3_HOME/firmware/"
cp "$BUILD_DIR/armsrc/obj/fullimage.elf" "$PM3_HOME/firmware/"
# Update flash utilities
echo "Updating flash utilities..."
cp "$BUILD_DIR/pm3-flash-all" "$PM3_HOME/"
cp "$BUILD_DIR/pm3-flash-bootrom" "$PM3_HOME/"
cp "$BUILD_DIR/pm3-flash-fullimage" "$PM3_HOME/"
chmod +x "$PM3_HOME/pm3-flash-"*
# Update version
echo "Updating version info..."
cd "$BUILD_DIR"
git describe --always --tags > "$PM3_HOME/VERSION.txt"
echo "Build date: $(date -u +"%Y-%m-%d %H:%M:%S UTC")" >> "$PM3_HOME/VERSION.txt"
echo "Built with LED PWM control patch" >> "$PM3_HOME/VERSION.txt"
echo ""
echo "=== Build Complete ==="
echo "New client: $PM3_HOME/client/proxmark3"
echo "New firmware: $PM3_HOME/firmware/"
echo ""
# Flash if requested
if [ "$1" == "--flash" ]; then
echo "Flashing firmware to connected device..."
cd "$PM3_HOME"
./pm3-flash-all
echo "Flash complete"
else
echo "To flash the new firmware, run:"
echo " cd $PM3_HOME && ./pm3-flash-all"
fi
# Cleanup
rm -rf "$BUILD_DIR"
echo "Cleanup complete"
REBUILD_EOF
chmod +x "$DEFAULT_HOME/.pm3/proxmark3/scripts/rebuild-pm3.sh"
# Set proper ownership
echo "Setting ownership..."
chown -R "$DEFAULT_USER:$DEFAULT_USER" "$DEFAULT_HOME/.pm3"
# Add Python path to environment
echo "Configuring Python path..."
touch "$DEFAULT_HOME/.bashrc"
if ! grep -q "PYTHONPATH.*\.pm3" "$DEFAULT_HOME/.bashrc"; then
echo 'export PYTHONPATH=$HOME/.pm3/proxmark3/client/pyscripts:$PYTHONPATH' >> "$DEFAULT_HOME/.bashrc"
fi
# --- Verification ---
echo "Verifying installation..."
ERRORS=0
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/client/proxmark3" ]; then
echo "Client executable installed"
else
echo "ERROR: Client executable not found"
ERRORS=$((ERRORS + 1))
fi
# Verify library architecture
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/libpm3rrg_rdv4.so" ]; then
LIB_ARCH=$(file "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/libpm3rrg_rdv4.so" | grep -o 'ARM aarch64\|x86-64\|ARM,')
if [ "$LIB_ARCH" = "ARM aarch64" ]; then
echo "Library architecture correct: $LIB_ARCH"
else
echo "ERROR: Library architecture mismatch! Expected ARM aarch64, got: $LIB_ARCH"
ERRORS=$((ERRORS + 1))
fi
fi
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/pm3.py" ]; then
echo "Python module installed"
else
echo "ERROR: Python module not found"
ERRORS=$((ERRORS + 1))
fi
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/_pm3.so" ]; then
echo "Python bindings library installed (_pm3.so)"
else
echo "ERROR: Python bindings library not found (_pm3.so)"
ERRORS=$((ERRORS + 1))
fi
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/firmware/fullimage.elf" ]; then
echo "Firmware files installed"
else
echo "ERROR: Firmware files not found"
ERRORS=$((ERRORS + 1))
fi
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/pm3-flash-all" ]; then
echo "Flash utilities installed"
else
echo "WARNING: Flash utilities not found"
fi
if [ $ERRORS -gt 0 ]; then
echo "ERROR: $ERRORS verification checks failed"
exit 1
fi
# Clean up tarball
rm -f /tmp/pm3-prebuilt.tar.gz
# Print summary
echo "=== Proxmark3 installation complete ==="
echo "Installation: $DEFAULT_HOME/.pm3/proxmark3/"
echo "Client: $DEFAULT_HOME/.pm3/proxmark3/client/proxmark3"
echo "Flash utils: $DEFAULT_HOME/.pm3/proxmark3/pm3-flash-all"
echo "Python: $DEFAULT_HOME/.pm3/proxmark3/client/pyscripts/pm3.py"
echo "Firmware: $DEFAULT_HOME/.pm3/proxmark3/firmware/"
if [ -f "$DEFAULT_HOME/.pm3/proxmark3/COMPONENT_VERSION" ]; then
echo "Version info:"
cat "$DEFAULT_HOME/.pm3/proxmark3/COMPONENT_VERSION"
fi

View File

@@ -0,0 +1,93 @@
#!/bin/bash -e
# Pre-chroot script: Source a pre-built PM3 tarball for installation.
# This runs on the host before the chroot script.
#
# Tarball sources (checked in order):
# 1. PM3_TARBALL env var (explicit path to a local tarball)
# 2. Local file in this substage's files/ directory
# 3. Download from GitHub Releases (dangerous-tacos/dangerous-pi)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
# --- Detect Python ABI in chroot ---
PYTHON_VERSION=$(chroot "${ROOTFS_DIR}" python3 -c \
'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || echo "3.12")
PYTHON_ABI="cp$(echo "$PYTHON_VERSION" | tr -d '.')"
echo "Detected Python ${PYTHON_VERSION} (ABI: ${PYTHON_ABI}) in chroot"
# --- Read PM3 version config ---
PM3_COMMIT=""
if [ -f "${SCRIPT_DIR}/pm3-version.conf" ]; then
. "${SCRIPT_DIR}/pm3-version.conf"
fi
# --- Locate tarball ---
TARBALL=""
# 1. Explicit env var
if [ -n "${PM3_TARBALL:-}" ] && [ -f "$PM3_TARBALL" ]; then
echo "Using PM3 tarball from PM3_TARBALL: $PM3_TARBALL"
TARBALL="$PM3_TARBALL"
fi
# 2. Local file in files/ directory
if [ -z "$TARBALL" ]; then
LOCAL_MATCH=$(ls "${SCRIPT_DIR}"/files/pm3-*-aarch64-linux-${PYTHON_ABI}.tar.gz 2>/dev/null | head -1)
if [ -n "$LOCAL_MATCH" ]; then
echo "Using local PM3 tarball: $LOCAL_MATCH"
TARBALL="$LOCAL_MATCH"
fi
fi
# 3. Download from GitHub Releases
if [ -z "$TARBALL" ]; then
GH_REPO="dangerous-tacos/dangerous-pi"
echo "Downloading PM3 tarball from GitHub Releases (${GH_REPO})..."
# Determine which release to fetch
if [ -n "$PM3_COMMIT" ]; then
# Try to find a release matching the commit
RELEASE_URL="https://api.github.com/repos/${GH_REPO}/releases/latest"
else
RELEASE_URL="https://api.github.com/repos/${GH_REPO}/releases/latest"
fi
# Get asset download URL for the matching ABI
ASSET_PATTERN="pm3-.*-aarch64-linux-${PYTHON_ABI}\\.tar\\.gz"
DOWNLOAD_URL=$(curl -sL "$RELEASE_URL" | \
grep -oP "\"browser_download_url\":\\s*\"\\K[^\"]*${ASSET_PATTERN}" | head -1)
if [ -n "$DOWNLOAD_URL" ]; then
TARBALL="/tmp/pm3-prebuilt-download.tar.gz"
echo "Downloading: $DOWNLOAD_URL"
curl -sL -o "$TARBALL" "$DOWNLOAD_URL"
echo "Downloaded PM3 tarball ($(du -h "$TARBALL" | cut -f1))"
else
echo "WARNING: Could not find PM3 tarball for ABI ${PYTHON_ABI} in latest release"
echo "Falling back to compile-from-source (this will take 45-60 min under QEMU)"
echo "To avoid this, set PM3_TARBALL=/path/to/pm3-*.tar.gz"
# Copy patches and version config for the compile fallback
if [ -f "${SCRIPT_DIR}/led-pwm-control.patch" ]; then
cp "${SCRIPT_DIR}/led-pwm-control.patch" "${ROOTFS_DIR}/tmp/"
fi
if [ -f "${SCRIPT_DIR}/hf-booster-detection.patch" ]; then
cp "${SCRIPT_DIR}/hf-booster-detection.patch" "${ROOTFS_DIR}/tmp/"
fi
if [ -f "${SCRIPT_DIR}/pm3-version.conf" ]; then
cp "${SCRIPT_DIR}/pm3-version.conf" "${ROOTFS_DIR}/tmp/"
fi
touch "${ROOTFS_DIR}/tmp/PM3_COMPILE_FROM_SOURCE"
exit 0
fi
fi
# --- Copy tarball into rootfs ---
cp "$TARBALL" "${ROOTFS_DIR}/tmp/pm3-prebuilt.tar.gz"
echo "PM3 tarball staged at /tmp/pm3-prebuilt.tar.gz in rootfs"
# Clean up downloaded temp file
if [ "${TARBALL}" = "/tmp/pm3-prebuilt-download.tar.gz" ]; then
rm -f "$TARBALL"
fi

View File

@@ -2,7 +2,7 @@ diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index 88ce070..cbeb7d2 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -921,6 +921,70 @@ static void PacketReceived(PacketCommandNG *packet) {
@@ -921,6 +921,100 @@ static void PacketReceived(PacketCommandNG *packet) {
reply_ng(CMD_SET_TEAROFF, PM3_SUCCESS, NULL, 0);
break;
}
@@ -163,7 +163,7 @@ index 0df8935..6d8246f 100644
// As soon as our button let go, we didn't hold long enough
if (BUTTON_PRESS() == false) {
@@ -415,3 +415,90 @@ void convertToHexArray(uint32_t num, uint8_t *partialkey) {
@@ -415,3 +415,241 @@ void convertToHexArray(uint32_t num, uint8_t *partialkey) {
partialkey[i] = (uint8_t)strtoul(group, NULL, 2);
}
}
@@ -409,7 +409,7 @@ diff --git a/armsrc/util.h b/armsrc/util.h
index fd99ac7..d558dda 100644
--- a/armsrc/util.h
+++ b/armsrc/util.h
@@ -105,4 +105,7 @@ bool data_available_fast(void);
@@ -105,4 +105,13 @@ bool data_available_fast(void);
uint32_t flash_size_from_cidr(uint32_t cidr);
uint32_t get_flash_size(void);
@@ -427,7 +427,7 @@ diff --git a/client/src/cmdhw.c b/client/src/cmdhw.c
index 9bbdc98..ad877b0 100644
--- a/client/src/cmdhw.c
+++ b/client/src/cmdhw.c
@@ -1504,6 +1504,115 @@ int set_fpga_mode(uint8_t mode) {
@@ -1504,6 +1504,193 @@ int set_fpga_mode(uint8_t mode) {
return resp.status;
}
@@ -719,7 +719,7 @@ diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h
index 860dfa9..e1551b5 100644
--- a/include/pm3_cmd.h
+++ b/include/pm3_cmd.h
@@ -465,6 +465,13 @@ typedef struct {
@@ -465,6 +465,17 @@ typedef struct {
uint8_t data[];
} PACKED smart_card_raw_t;

View File

@@ -0,0 +1,5 @@
# Proxmark3 build version config
# Change PM3_COMMIT to rebuild with a different upstream version.
# Leave PM3_COMMIT empty to build from latest master (non-deterministic).
PM3_REPO="https://github.com/RfidResearchGroup/proxmark3"
PM3_COMMIT="ef82d5ba1"

View File

@@ -13,16 +13,8 @@ DEFAULT_HOME=$(eval echo ~$DEFAULT_USER)
echo "Detected default user: $DEFAULT_USER (home: $DEFAULT_HOME)"
# Install pip3 if not already installed
if ! command -v pip3 &> /dev/null; then
echo "Installing pip3..."
apt-get update
apt-get install -y python3-pip
fi
# Install Node.js for frontend (Remix SSR) and utilities
echo "Installing Node.js and utilities..."
apt-get install -y nodejs npm lrzsz
# Packages (nodejs, npm, lrzsz) installed by 00-apt-setup stage
# pip3 is available from stage2 Python installation
# Install Python packages from requirements.txt
pip3 install --break-system-packages -r /tmp/dangerous-pi-files/requirements.txt
@@ -63,14 +55,28 @@ fi
# Add user to netdev group for network management
usermod -a -G netdev $DEFAULT_USER
# Build frontend (Remix SSR)
echo "Building frontend..."
# Frontend setup (Remix SSR)
# build_frontend() in build-image.sh pre-builds on the host.
# All production deps are pure JS (no native modules), so the host
# node_modules works on arm64 without reinstalling.
cd /opt/dangerous-pi/app/frontend
npm ci --production=false # Install dev deps for build
npm run build
# Remove dev dependencies and node_modules bloat after build
rm -rf node_modules/.cache
npm prune --production
if [ -d "build/server" ]; then
echo "Using pre-built frontend from host..."
# Remove build-time-only packages to save ~100MB of image space
rm -rf node_modules/.cache \
node_modules/@rollup \
node_modules/@esbuild \
node_modules/@remix-run/dev \
node_modules/vite \
node_modules/typescript \
node_modules/@types
else
echo "Building frontend in chroot (no pre-built output found)..."
npm install --production=false
npm run build
rm -rf node_modules/.cache
npm prune --production
fi
cd /opt/dangerous-pi
# Install frontend systemd service

View File

@@ -26,4 +26,15 @@ echo "0.1.0-$(date +%Y%m%d)" > "${ROOTFS_DIR}/tmp/dangerous-pi-files/VERSION"
mkdir -p "${ROOTFS_DIR}/tmp/dangerous-pi-files/data"
mkdir -p "${ROOTFS_DIR}/tmp/dangerous-pi-files/logs"
# Copy dt-design-system to /opt/ so frontend's file: dependency resolves
# Frontend package.json has: "@dangerousthings/web": "file:../../../dt-design-system/packages/web"
# From /opt/dangerous-pi/app/frontend/, ../../../ resolves to /opt/
if [ -d "${SCRIPT_DIR}/files/dt-design-system" ]; then
echo "Copying dt-design-system for frontend dependency resolution..."
mkdir -p "${ROOTFS_DIR}/opt/dt-design-system/packages"
cp -r "${SCRIPT_DIR}/files/dt-design-system/packages/web" "${ROOTFS_DIR}/opt/dt-design-system/packages/"
cp -r "${SCRIPT_DIR}/files/dt-design-system/packages/tokens" "${ROOTFS_DIR}/opt/dt-design-system/packages/"
cp "${SCRIPT_DIR}/files/dt-design-system/package.json" "${ROOTFS_DIR}/opt/dt-design-system/"
fi
echo "Files prepared successfully"

Some files were not shown because too many files have changed in this diff Show More