mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 17:37:13 +00:00
fix(build): Add timeouts to prevent build script hangs
- Add 5 min timeout per package in dpkg-buildpackage calls - Add 10-20 min timeout for QEMU chroot apt operations - Add 45 min timeout for sub-script execution - Add 15 min timeout with retries for wget downloads - Fix pipe to tail pattern that swallowed exit codes - Add progress logging for QEMU package installation - Use writable log directory (output/logs) instead of /tmp - Add --verbose flag to build-eye-remote-full.sh - Export VERBOSE for sub-scripts Fixes hangs caused by: - dpkg-buildpackage | tail -5 buffering issues - QEMU chroot apt-get with no timeout - Network operations with no timeout Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ed25dde74e
commit
fd86a6709f
|
|
@ -54,6 +54,7 @@ SKIP_EBIN=0
|
|||
SKIP_RPIZ=0
|
||||
WIFI_SSID=""
|
||||
WIFI_PSK=""
|
||||
VERBOSE=0
|
||||
|
||||
# ── Usage ─────────────────────────────────────────────────────────────────────
|
||||
usage() {
|
||||
|
|
@ -136,11 +137,15 @@ while [[ $# -gt 0 ]]; do
|
|||
IFS=':' read -r WIFI_SSID WIFI_PSK <<< "$2"
|
||||
shift 2
|
||||
;;
|
||||
--verbose|-v) VERBOSE=1; shift ;;
|
||||
--help|-h) usage ;;
|
||||
*) err "Unknown option: $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Export VERBOSE for sub-scripts
|
||||
export VERBOSE
|
||||
|
||||
# ── Prerequisites ─────────────────────────────────────────────────────────────
|
||||
[[ $EUID -ne 0 ]] && err "This script must be run as root (sudo)"
|
||||
|
||||
|
|
@ -206,9 +211,11 @@ build_debs() {
|
|||
|
||||
log "Building SecuBox packages..."
|
||||
|
||||
# Use existing build-all.sh script
|
||||
# Use existing build-all.sh script (with 30 min timeout)
|
||||
if [[ -f "${SCRIPT_DIR}/scripts/build-all.sh" ]]; then
|
||||
bash "${SCRIPT_DIR}/scripts/build-all.sh" "$DEBS_DIR"
|
||||
if ! timeout --kill-after=60s 1800s bash "${SCRIPT_DIR}/scripts/build-all.sh" "$DEBS_DIR"; then
|
||||
warn "build-all.sh timed out or failed, trying inline build..."
|
||||
fi
|
||||
else
|
||||
# Inline build
|
||||
local pkg_dirs
|
||||
|
|
@ -228,11 +235,12 @@ build_debs() {
|
|||
log "[$count/$total] $pkg"
|
||||
cd "$pkg_dir"
|
||||
|
||||
if dpkg-buildpackage -us -uc -b > /tmp/build-$pkg.log 2>&1; then
|
||||
# 5 min timeout per package
|
||||
if timeout --kill-after=30s 300s dpkg-buildpackage -us -uc -b > /tmp/build-$pkg.log 2>&1; then
|
||||
mv ../*.deb "$DEBS_DIR/" 2>/dev/null || true
|
||||
rm -f ../*.buildinfo ../*.changes 2>/dev/null || true
|
||||
else
|
||||
warn "$pkg failed (see /tmp/build-$pkg.log)"
|
||||
warn "$pkg failed or timed out (see /tmp/build-$pkg.log)"
|
||||
failed=$((failed + 1))
|
||||
fi
|
||||
cd "$SCRIPT_DIR"
|
||||
|
|
@ -284,13 +292,16 @@ build_ebin() {
|
|||
fi
|
||||
fi
|
||||
|
||||
# Use build-storage-img.sh if available
|
||||
# Use build-storage-img.sh if available (with 30 min timeout)
|
||||
if [[ -f "${SCRIPT_DIR}/remote-ui/round/build-storage-img.sh" ]]; then
|
||||
log "Building ESPRESSObin storage image with slipstreamed modules..."
|
||||
bash "${SCRIPT_DIR}/remote-ui/round/build-storage-img.sh" \
|
||||
log "This may take 20-30 minutes under QEMU emulation. Timeout: 45 min."
|
||||
if ! timeout --kill-after=60s 2700s bash "${SCRIPT_DIR}/remote-ui/round/build-storage-img.sh" \
|
||||
--source "$EBIN_SOURCE" \
|
||||
--output "$EBIN_STORAGE_IMG" \
|
||||
--debs "$DEBS_DIR"
|
||||
--debs "$DEBS_DIR"; then
|
||||
err "build-storage-img.sh failed or timed out"
|
||||
fi
|
||||
else
|
||||
err "build-storage-img.sh not found"
|
||||
fi
|
||||
|
|
@ -313,13 +324,16 @@ download_rpios() {
|
|||
return 0
|
||||
fi
|
||||
|
||||
log "Downloading RPi OS Lite..."
|
||||
wget -q --show-progress -O "$target" "$url" || {
|
||||
log "Downloading RPi OS Lite (timeout: 15 min)..."
|
||||
# 15 min timeout for download, with connection timeout of 30s
|
||||
if ! timeout --kill-after=30s 900s wget --timeout=30 --tries=3 -q --show-progress -O "$target" "$url"; then
|
||||
warn "Download failed, trying alternative URL..."
|
||||
# Try alternative
|
||||
url="https://downloads.raspberrypi.org/raspios_lite_armhf_latest"
|
||||
wget -q --show-progress -O "$target" "$url" || err "Failed to download RPi OS"
|
||||
}
|
||||
if ! timeout --kill-after=30s 900s wget --timeout=30 --tries=3 -q --show-progress -O "$target" "$url"; then
|
||||
err "Failed to download RPi OS (check network connection)"
|
||||
fi
|
||||
fi
|
||||
|
||||
RPIZ_SOURCE="$target"
|
||||
ok "Downloaded: $target"
|
||||
|
|
@ -369,19 +383,22 @@ build_rpiz() {
|
|||
|
||||
log "Building Pi Zero SD image with embedded ESPRESSObin storage..."
|
||||
|
||||
# Use build-eye-remote-image.sh
|
||||
# Use build-eye-remote-image.sh (with 30 min timeout for QEMU operations)
|
||||
if [[ -f "${SCRIPT_DIR}/remote-ui/round/build-eye-remote-image.sh" ]]; then
|
||||
local wifi_args=""
|
||||
if [[ -n "$WIFI_SSID" ]]; then
|
||||
wifi_args="-s $WIFI_SSID -p $WIFI_PSK"
|
||||
fi
|
||||
|
||||
log "Building Pi Zero image with QEMU emulation. Timeout: 45 min."
|
||||
# Build the base image
|
||||
bash "${SCRIPT_DIR}/remote-ui/round/build-eye-remote-image.sh" \
|
||||
if ! timeout --kill-after=60s 2700s bash "${SCRIPT_DIR}/remote-ui/round/build-eye-remote-image.sh" \
|
||||
-i "$RPIZ_SOURCE" \
|
||||
-o "$OUTPUT_DIR" \
|
||||
$wifi_args \
|
||||
--framebuffer
|
||||
--framebuffer; then
|
||||
err "build-eye-remote-image.sh failed or timed out"
|
||||
fi
|
||||
|
||||
# Find the generated image
|
||||
local built_img
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ info "Packages: ${PACKAGES[*]}"
|
|||
# Create package list file (dynamically based on BUILD_MODE)
|
||||
printf "%s\n" "${PACKAGES[@]}" > "$ROOT_MNT/tmp/package-list.txt"
|
||||
|
||||
# Create install script
|
||||
# Create install script with progress output
|
||||
cat > "$ROOT_MNT/tmp/install-packages.sh" << 'INSTALLSCRIPT'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
|
@ -461,17 +461,32 @@ set -e
|
|||
export DEBIAN_FRONTEND=noninteractive
|
||||
export LC_ALL=C
|
||||
|
||||
echo "=== Updating APT ==="
|
||||
apt-get update -qq
|
||||
echo "=== [1/5] Updating APT (this may take a few minutes under QEMU) ==="
|
||||
apt-get update -q || { echo "APT update failed"; exit 1; }
|
||||
|
||||
echo "=== Installing packages ==="
|
||||
# Read packages from file and install with --no-install-recommends
|
||||
xargs -a /tmp/package-list.txt apt-get install -y -qq --no-install-recommends
|
||||
echo "=== [2/5] Reading package list ==="
|
||||
PACKAGES=$(cat /tmp/package-list.txt | tr '\n' ' ')
|
||||
echo "Packages to install: $PACKAGES"
|
||||
|
||||
echo "=== Enabling pigpiod ==="
|
||||
echo "=== [3/5] Installing packages one by one (QEMU is slow, be patient) ==="
|
||||
INSTALLED=0
|
||||
FAILED=0
|
||||
for pkg in $PACKAGES; do
|
||||
echo " -> Installing: $pkg"
|
||||
if apt-get install -y -qq --no-install-recommends "$pkg" 2>/dev/null; then
|
||||
echo " OK: $pkg"
|
||||
INSTALLED=$((INSTALLED + 1))
|
||||
else
|
||||
echo " WARN: $pkg failed (may be optional)"
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
done
|
||||
echo " Installed: $INSTALLED, Failed: $FAILED"
|
||||
|
||||
echo "=== [4/5] Enabling pigpiod ==="
|
||||
systemctl enable pigpiod || true
|
||||
|
||||
echo "=== Cleaning APT cache ==="
|
||||
echo "=== [5/5] Cleaning APT cache ==="
|
||||
apt-get clean
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
rm -f /tmp/package-list.txt
|
||||
|
|
@ -480,8 +495,18 @@ echo "=== Package installation complete ==="
|
|||
INSTALLSCRIPT
|
||||
chmod +x "$ROOT_MNT/tmp/install-packages.sh"
|
||||
|
||||
# Run install in chroot
|
||||
chroot "$ROOT_MNT" /tmp/install-packages.sh
|
||||
# Run install in chroot with timeout (20 minutes for QEMU ARM emulation)
|
||||
log "Running package installation in QEMU chroot (this takes 10-20 minutes)..."
|
||||
log "Progress will be shown below. If it hangs > 20min, check network/DNS."
|
||||
|
||||
CHROOT_LOG="/tmp/eye-remote-chroot-install.log"
|
||||
if timeout --kill-after=60s 1200s chroot "$ROOT_MNT" /tmp/install-packages.sh 2>&1 | tee "$CHROOT_LOG"; then
|
||||
log "Package installation completed successfully"
|
||||
else
|
||||
err "Package installation failed or timed out (see $CHROOT_LOG)"
|
||||
tail -20 "$CHROOT_LOG" || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Remove policy
|
||||
rm -f "$ROOT_MNT/usr/sbin/policy-rc.d"
|
||||
|
|
@ -683,7 +708,9 @@ systemctl enable lightdm 2>/dev/null || true
|
|||
systemctl enable nginx 2>/dev/null || true
|
||||
USERSCRIPT
|
||||
chmod +x "$ROOT_MNT/tmp/setup-user.sh"
|
||||
chroot "$ROOT_MNT" /tmp/setup-user.sh
|
||||
if ! timeout --kill-after=10s 120s chroot "$ROOT_MNT" /tmp/setup-user.sh 2>&1; then
|
||||
warn "setup-user.sh failed or timed out (non-fatal)"
|
||||
fi
|
||||
|
||||
# LightDM autologin
|
||||
mkdir -p "$ROOT_MNT/etc/lightdm/lightdm.conf.d"
|
||||
|
|
@ -737,7 +764,7 @@ XINITRC
|
|||
chmod +x "$ROOT_MNT/home/secubox/.xinitrc"
|
||||
|
||||
# Fix ownership
|
||||
chroot "$ROOT_MNT" chown -R secubox:secubox /home/secubox
|
||||
timeout --kill-after=5s 30s chroot "$ROOT_MNT" chown -R secubox:secubox /home/secubox 2>/dev/null || true
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
# CONFIGURE NGINX (browser mode only)
|
||||
|
|
@ -802,7 +829,7 @@ if [[ -n "$SSH_PUBKEY" && -f "$SSH_PUBKEY" ]]; then
|
|||
cp "$SSH_PUBKEY" "$ROOT_MNT/home/pi/.ssh/authorized_keys"
|
||||
chmod 700 "$ROOT_MNT/home/pi/.ssh"
|
||||
chmod 600 "$ROOT_MNT/home/pi/.ssh/authorized_keys"
|
||||
chroot "$ROOT_MNT" chown -R pi:pi /home/pi/.ssh
|
||||
timeout --kill-after=5s 30s chroot "$ROOT_MNT" chown -R pi:pi /home/pi/.ssh 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════════
|
||||
|
|
|
|||
|
|
@ -203,35 +203,50 @@ done
|
|||
|
||||
log "Installing ${COPIED_COUNT} compatible packages..."
|
||||
|
||||
# Update apt cache first
|
||||
log "Updating apt cache..."
|
||||
chroot "${TARGET_MOUNT}" apt-get update -qq 2>&1 | tail -5 || true
|
||||
# Timeouts for QEMU chroot operations (very slow under emulation)
|
||||
CHROOT_TIMEOUT="timeout --kill-after=30s 600s" # 10 min timeout
|
||||
|
||||
# Update apt cache first (with timeout)
|
||||
log "Updating apt cache (QEMU, may take several minutes)..."
|
||||
if ! $CHROOT_TIMEOUT chroot "${TARGET_MOUNT}" apt-get update -qq > /tmp/apt-update.log 2>&1; then
|
||||
warn "apt-get update failed or timed out (see /tmp/apt-update.log)"
|
||||
tail -5 /tmp/apt-update.log 2>/dev/null | sed 's/^/ /' || true
|
||||
fi
|
||||
|
||||
# Install secubox-core first (with dependencies)
|
||||
if ls "${DEBS_TMP}"/secubox-core_*.deb >/dev/null 2>&1; then
|
||||
log "Installing secubox-core with dependencies..."
|
||||
CORE_DEB=$(ls "${DEBS_TMP}"/secubox-core_*.deb | head -1)
|
||||
chroot "${TARGET_MOUNT}" apt-get install -y "/tmp/secubox-debs/$(basename $CORE_DEB)" 2>&1 | tail -10 || warn "core install warnings"
|
||||
if ! $CHROOT_TIMEOUT chroot "${TARGET_MOUNT}" apt-get install -y "/tmp/secubox-debs/$(basename "$CORE_DEB")" > /tmp/core-install.log 2>&1; then
|
||||
warn "secubox-core install warnings (see /tmp/core-install.log)"
|
||||
tail -5 /tmp/core-install.log 2>/dev/null | sed 's/^/ /' || true
|
||||
fi
|
||||
fi
|
||||
|
||||
# Install all other packages using apt (handles dependencies)
|
||||
log "Installing remaining packages..."
|
||||
PKG_COUNT=0
|
||||
for deb in "${DEBS_TMP}"/secubox-*.deb; do
|
||||
[[ -f "$deb" ]] || continue
|
||||
PKG_NAME=$(dpkg-deb -f "$deb" Package 2>/dev/null)
|
||||
PKG_COUNT=$((PKG_COUNT + 1))
|
||||
|
||||
# Skip if already installed
|
||||
if chroot "${TARGET_MOUNT}" dpkg -l "$PKG_NAME" 2>/dev/null | grep -q "^ii"; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Try to install with apt
|
||||
chroot "${TARGET_MOUNT}" apt-get install -y "/tmp/secubox-debs/$(basename $deb)" 2>&1 | \
|
||||
grep -E "^(Setting up|is already)" || true
|
||||
log " [$PKG_COUNT] Installing $PKG_NAME..."
|
||||
# 3 min timeout per package
|
||||
if ! timeout --kill-after=10s 180s chroot "${TARGET_MOUNT}" apt-get install -y \
|
||||
"/tmp/secubox-debs/$(basename "$deb")" > "/tmp/install-${PKG_NAME}.log" 2>&1; then
|
||||
warn " $PKG_NAME failed (see /tmp/install-${PKG_NAME}.log)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Fix any remaining broken dependencies
|
||||
chroot "${TARGET_MOUNT}" apt-get -f install -y --fix-broken 2>&1 | tail -5 || true
|
||||
log "Fixing broken dependencies..."
|
||||
$CHROOT_TIMEOUT chroot "${TARGET_MOUNT}" apt-get -f install -y --fix-broken > /tmp/fix-broken.log 2>&1 || true
|
||||
|
||||
# Count installed
|
||||
INSTALLED=$(chroot "${TARGET_MOUNT}" dpkg -l 2>/dev/null | grep "^ii.*secubox" | wc -l)
|
||||
|
|
|
|||
|
|
@ -45,14 +45,15 @@ for pkg_dir in $PACKAGES; do
|
|||
# Clean previous build
|
||||
rm -rf debian/.debhelper debian/"$pkg" 2>/dev/null || true
|
||||
|
||||
# Build
|
||||
if dpkg-buildpackage -us -uc -b > /tmp/build-$pkg.log 2>&1; then
|
||||
# Build with 5 minute timeout per package
|
||||
if timeout --kill-after=30s 300s dpkg-buildpackage -us -uc -b > /tmp/build-$pkg.log 2>&1; then
|
||||
# Move .deb files
|
||||
mv ../*.deb "$OUTPUT_DIR/" 2>/dev/null || true
|
||||
rm -f ../*.buildinfo ../*.changes 2>/dev/null || true
|
||||
ok "$pkg"
|
||||
else
|
||||
err "$pkg - build failed (see /tmp/build-$pkg.log)"
|
||||
err "$pkg - build failed or timed out (see /tmp/build-$pkg.log)"
|
||||
tail -5 /tmp/build-$pkg.log 2>/dev/null | sed 's/^/ /' || true
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -98,15 +98,24 @@ for PKG in "${PACKAGES[@]}"; do
|
|||
# Rendre rules exécutable
|
||||
chmod +x debian/rules 2>/dev/null || true
|
||||
|
||||
# Build le package
|
||||
# Build le package with timeout and proper exit code handling
|
||||
# Use a writable log directory (avoid /tmp permission issues from previous root runs)
|
||||
LOG_DIR="${REPO_DIR}/output/logs"
|
||||
mkdir -p "$LOG_DIR" 2>/dev/null || LOG_DIR="/tmp/secubox-build-$$"
|
||||
mkdir -p "$LOG_DIR" 2>/dev/null || true
|
||||
BUILD_LOG="${LOG_DIR}/build-${PKG}.log"
|
||||
BUILD_OK=0
|
||||
|
||||
# Use timeout to prevent infinite hangs (5 minutes per package)
|
||||
TIMEOUT_CMD="timeout --kill-after=30s 300s"
|
||||
|
||||
if [[ "$ARCH" == "arm64" ]] && [[ "$(uname -m)" != "aarch64" ]]; then
|
||||
# Cross-compile pour arm64
|
||||
if dpkg-buildpackage -a arm64 --host-arch arm64 -us -uc -b 2>&1 | tail -5; then
|
||||
if $TIMEOUT_CMD dpkg-buildpackage -a arm64 --host-arch arm64 -us -uc -b > "$BUILD_LOG" 2>&1; then
|
||||
BUILD_OK=1
|
||||
fi
|
||||
else
|
||||
if dpkg-buildpackage -us -uc -b 2>&1 | tail -5; then
|
||||
if $TIMEOUT_CMD dpkg-buildpackage -us -uc -b > "$BUILD_LOG" 2>&1; then
|
||||
BUILD_OK=1
|
||||
fi
|
||||
fi
|
||||
|
|
@ -115,7 +124,9 @@ for PKG in "${PACKAGES[@]}"; do
|
|||
ok "${PKG} built"
|
||||
((SUCCESS++)) || true
|
||||
else
|
||||
err "${PKG} FAILED"
|
||||
# Show last 10 lines of log for debugging
|
||||
err "${PKG} FAILED (see $BUILD_LOG)"
|
||||
tail -10 "$BUILD_LOG" 2>/dev/null | sed 's/^/ /' || true
|
||||
((FAILED++)) || true
|
||||
fi
|
||||
done
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user