mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-30 00:19:30 +00:00
* feat(remote-ui/common): scaffold shared-core directory (ref #127) * feat(remote-ui/common): extract palette.css from round/ (ref #127) * fix(remote-ui/common): trim palette.css to spec (6 module + 8 C3BOX tokens) (ref #127) * feat(remote-ui/common): extract base.css verbatim from round/ (ref #127) * feat(remote-ui/common): extract ICONS to icons.js (ref #127) * docs(remote-ui/common): correct icons.js header comment — sizes are {22,48,96} not 128 (ref #127) * feat(remote-ui/common): extract RINGS + CX/CY/SA to modules-table.js (ref #127) * feat(remote-ui/common): extract CFG to config.js (replaces jwt-helper.js per #127 plan revision) * feat(remote-ui/common): extract TransportManager with onModuleTap/onTransportChange hooks (ref #127) * feat(remote-ui/common): extract SIM + simStep to sim.js (ref #127) * feat(remote-ui/common): move 24 SecuBox module PNG icons to common/assets/icons/ (ref #127) * feat(remote-ui/common): move secubox-otg-gadget.sh, add GADGET_NAME env override + arm64 serial fallback (ref #127) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(remote-ui/common): trim whitespace from device-tree serial-number read (ref #127) * feat(remote-ui/common): move secubox-otg-host-up.sh + variant-aware comment (ref #127) * refactor(remote-ui/round): consume common/ via <link>/<script> tags (ref #127) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(secubox-system): add form_factor to RemoteUIConnectedRequest with TDD (ref #127) * feat(remote-ui/round): deploy.sh bundles common/ alongside round/ (ref #127) * fix(remote-ui/round): deploy.sh COMMON_SRC path resolution + rsync --delete (ref #127) * feat(remote-ui/round): build-eye-remote-image.sh embeds common/ + nginx /common/ alias (ref #127) * docs(remote-ui): document common/ dependency in round/ docs (ref #127) * docs(remote-ui/round): clarify palette.css is forward-looking (ref #127) * docs(remote-ui): Task 18 regression-gate report — structural verification (ref #127) Full diffoscope gate blocked by missing hyperpixel2r.dtbo prerequisite. Structural equivalence verified instead: Phase 1 changes are purely additive (common/ embed + nginx /common/ alias + extracted JS/CSS/icons), no behavioural change to round/'s existing logic. User must run the full image diffoscope manually after sourcing the hyperpixel2r.dtbo blob, before final merge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ci(eye-remote): bump workflow VERSION env 2.2.0 → 2.2.1 (ref #127) Pre-existing drift: build-eye-remote-image.sh writes secubox-eye-remote-2.2.1.img but the workflow's Compress/Checksum/ Upload steps reference ${{ env.VERSION }} = 2.2.0, so the compress step fails with "No such file or directory" after a successful build. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: CyberMind-FR <gandalf@Gk2.net> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
242 lines
12 KiB
Bash
Executable File
242 lines
12 KiB
Bash
Executable File
#!/bin/bash
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
# SecuBox Remote UI — deploy.sh
|
|
# Déploie/met à jour le dashboard sur un RPi Zero W déjà configuré
|
|
#
|
|
# CyberMind — https://cybermind.fr
|
|
# Author: Gérald Kerma <gandalf@gk2.net>
|
|
# License: Proprietary / ANSSI CSPN candidate
|
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
set -euo pipefail
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# CONFIGURATION
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
VERSION="1.0.0"
|
|
INDEX_HTML="$SCRIPT_DIR/index.html"
|
|
|
|
# Couleurs
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
log() { echo -e "${GREEN}[deploy]${NC} $*"; }
|
|
warn() { echo -e "${YELLOW}[warn]${NC} $*"; }
|
|
err() { echo -e "${RED}[error]${NC} $*" >&2; }
|
|
|
|
# Valeurs par défaut
|
|
HOST=""
|
|
USER="secubox"
|
|
PORT=22
|
|
API_URL=""
|
|
API_PASS=""
|
|
SIMULATE=""
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# AIDE
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
usage() {
|
|
cat << EOF
|
|
SecuBox Remote UI — Déploiement Dashboard RPi Zero W
|
|
|
|
Usage: $0 [OPTIONS]
|
|
|
|
Options requises:
|
|
-h, --host HOST Adresse IP ou hostname du RPi Zero W
|
|
|
|
Options facultatives:
|
|
-u, --user USER Utilisateur SSH (défaut: $USER)
|
|
-p, --port PORT Port SSH (défaut: $PORT)
|
|
--api-url URL URL de l'API SecuBox (ex: http://192.168.1.1:8000)
|
|
--api-pass PASS Mot de passe API pour le dashboard
|
|
--sim Activer le mode simulation (hors-ligne)
|
|
--no-sim Désactiver le mode simulation
|
|
--help Afficher cette aide
|
|
|
|
Exemples:
|
|
$0 -h secubox-round.local --api-url http://192.168.1.1:8000 --api-pass motdepasse
|
|
$0 -h 192.168.1.42 -u pi --sim
|
|
|
|
EOF
|
|
exit 0
|
|
}
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# PARSING ARGUMENTS
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
-h|--host) HOST="$2"; shift 2 ;;
|
|
-u|--user) USER="$2"; shift 2 ;;
|
|
-p|--port) PORT="$2"; shift 2 ;;
|
|
--api-url) API_URL="$2"; shift 2 ;;
|
|
--api-pass) API_PASS="$2"; shift 2 ;;
|
|
--sim) SIMULATE="true"; shift ;;
|
|
--no-sim) SIMULATE="false"; shift ;;
|
|
--help) usage ;;
|
|
*) err "Option inconnue: $1"; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# VALIDATIONS
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
if [[ -z "$HOST" ]]; then
|
|
err "Adresse du RPi Zero W requise (-h)"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$INDEX_HTML" ]]; then
|
|
err "index.html non trouvé: $INDEX_HTML"
|
|
exit 1
|
|
fi
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# PRÉPARATION DU FICHIER
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
log "═══════════════════════════════════════════════════════════════"
|
|
log "SecuBox Remote UI — Déploiement v$VERSION"
|
|
log "═══════════════════════════════════════════════════════════════"
|
|
log ""
|
|
log "Cible: ${USER}@${HOST}:${PORT}"
|
|
log "API URL: ${API_URL:-<non modifié>}"
|
|
log "Simulate: ${SIMULATE:-<non modifié>}"
|
|
log ""
|
|
|
|
# Créer une copie temporaire pour les patches
|
|
TEMP_HTML=$(mktemp)
|
|
cp "$INDEX_HTML" "$TEMP_HTML"
|
|
|
|
# Patch CFG.API_BASE si fourni
|
|
if [[ -n "$API_URL" ]]; then
|
|
log "Patch API_BASE → $API_URL"
|
|
sed -i "s|API_BASE: '[^']*'|API_BASE: '$API_URL'|" "$TEMP_HTML"
|
|
fi
|
|
|
|
# Patch CFG.LOGIN_PASS si fourni
|
|
if [[ -n "$API_PASS" ]]; then
|
|
log "Patch LOGIN_PASS..."
|
|
sed -i "s|LOGIN_PASS: '[^']*'|LOGIN_PASS: '$API_PASS'|" "$TEMP_HTML"
|
|
fi
|
|
|
|
# Patch CFG.SIMULATE si demandé
|
|
if [[ -n "$SIMULATE" ]]; then
|
|
log "Patch SIMULATE → $SIMULATE"
|
|
sed -i "s|SIMULATE: [a-z]*|SIMULATE: $SIMULATE|" "$TEMP_HTML"
|
|
fi
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# TEST CONNEXION SSH
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
log "Test connexion SSH..."
|
|
if ! ssh -p "$PORT" -o ConnectTimeout=10 -o BatchMode=yes "${USER}@${HOST}" "echo ok" &>/dev/null; then
|
|
err "Impossible de se connecter à ${USER}@${HOST}:${PORT}"
|
|
err "Vérifiez que:"
|
|
err " - Le RPi est démarré et connecté au réseau"
|
|
err " - SSH est activé"
|
|
err " - Votre clé SSH est autorisée"
|
|
rm -f "$TEMP_HTML"
|
|
exit 1
|
|
fi
|
|
log "Connexion SSH OK"
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# DÉPLOIEMENT
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
log "Copie de common/ (icons, css, js, shell)..."
|
|
# Round/index.html references ../common/css/* and ../common/js/* (rel paths).
|
|
# On the device: /var/www/common/ must be a sibling of /var/www/secubox-round/.
|
|
COMMON_SRC="$(dirname "$SCRIPT_DIR")/common"
|
|
if [ ! -d "$COMMON_SRC" ]; then
|
|
err "Répertoire common/ introuvable: $COMMON_SRC"
|
|
rm -f "$TEMP_HTML"
|
|
exit 1
|
|
fi
|
|
rsync -avz --delete -e "ssh -p $PORT" "$COMMON_SRC/" "${USER}@${HOST}:/tmp/secubox-common/"
|
|
|
|
log "Copie du dashboard..."
|
|
scp -P "$PORT" "$TEMP_HTML" "${USER}@${HOST}:/tmp/index.html"
|
|
|
|
log "Installation..."
|
|
ssh -p "$PORT" "${USER}@${HOST}" << 'REMOTE_SCRIPT'
|
|
set -e
|
|
|
|
# Move common/ payload into /var/www/common/
|
|
sudo rm -rf /var/www/common
|
|
sudo mv /tmp/secubox-common /var/www/common
|
|
sudo chown -R www-data:www-data /var/www/common
|
|
|
|
# Copier vers le répertoire web
|
|
sudo cp /tmp/index.html /var/www/secubox-round/index.html
|
|
sudo chown www-data:www-data /var/www/secubox-round/index.html
|
|
rm /tmp/index.html
|
|
|
|
# Recharger nginx
|
|
sudo systemctl reload nginx
|
|
|
|
echo "OK"
|
|
REMOTE_SCRIPT
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# PATCH NGINX PROXY (si API_URL fourni)
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
if [[ -n "$API_URL" ]]; then
|
|
# Extraire l'hôte et le port de l'URL
|
|
API_HOST=$(echo "$API_URL" | sed -E 's|https?://([^:/]+).*|\1|')
|
|
API_PORT=$(echo "$API_URL" | sed -E 's|https?://[^:]+:?([0-9]*).*|\1|')
|
|
API_PORT=${API_PORT:-8000}
|
|
|
|
log "Patch nginx proxy → ${API_HOST}:${API_PORT}"
|
|
ssh -p "$PORT" "${USER}@${HOST}" << REMOTE_NGINX
|
|
set -e
|
|
sudo sed -i "s|proxy_pass http://[^;]*;|proxy_pass http://${API_HOST}:${API_PORT};|" /etc/nginx/sites-available/secubox-round
|
|
sudo nginx -t
|
|
sudo systemctl reload nginx
|
|
REMOTE_NGINX
|
|
fi
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# TEST HTTP
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
log "Test HTTP..."
|
|
HTTP_CODE=$(ssh -p "$PORT" "${USER}@${HOST}" "curl -s -o /dev/null -w '%{http_code}' http://localhost:8080" 2>/dev/null || echo "000")
|
|
|
|
if [[ "$HTTP_CODE" == "200" ]]; then
|
|
log "Test HTTP OK (200)"
|
|
else
|
|
warn "Test HTTP retourne $HTTP_CODE (attendu 200)"
|
|
fi
|
|
|
|
# Nettoyage
|
|
rm -f "$TEMP_HTML"
|
|
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
# RÉSUMÉ
|
|
# ══════════════════════════════════════════════════════════════════════════════
|
|
|
|
log ""
|
|
log "═══════════════════════════════════════════════════════════════"
|
|
log "Déploiement terminé !"
|
|
log "═══════════════════════════════════════════════════════════════"
|
|
log ""
|
|
log "Dashboard accessible sur le HyperPixel 2.1 Round"
|
|
log "Debug via: ssh ${USER}@${HOST} 'journalctl -u lightdm -f'"
|
|
log ""
|
|
|
|
if [[ "$SIMULATE" == "true" ]]; then
|
|
warn "Mode SIMULATION activé — données fictives"
|
|
fi
|