Files
jarvis/deploy/jarvis-deploy.sh
T
myron ecbc2e09a5 Fix 8 code-review findings: security + reliability
1. agent.py: shell allow-check reads cfg, not server payload (RCE fix)
2. webhook.php: move WEBHOOK_SECRET to gitignored config.php; rotate secret
3. agent.py: replace recursive main() with while loop (RecursionError fix)
4. jarvis-deploy.sh: push force-revert to GitHub on syntax fail (loop fix)
5. agent.py: self_update() verifies SHA-256 before exec (integrity fix)
6. agent.php: remove JARVIS_IP from browser-action bypass (auth fix)
7. jarvis-watchdog.sh: escape SQL vars in alert() to prevent injection
8. jarvis-deploy.sh: atomic mv instead of cat+truncate (TOCTOU fix)

Also: distribute jarvis-agent.py.sha256 alongside agent for integrity checks
2026-05-25 14:27:27 +00:00

85 lines
3.0 KiB
Bash
Executable File

#!/bin/bash
# JARVIS Auto-Deploy Runner — processes GitHub webhook queue every minute.
# Validates PHP syntax before deploying; auto-reverts on bad code.
# Restarts OLS after JARVIS deploys to pick up PHP changes.
QUEUE=/tmp/jarvis-deploy-queue.txt
LOG=/home/jarvis.orbishosting.com/logs/deploy.log
PHP=/usr/bin/php8.3
TS() { date '+%Y-%m-%d %H:%M:%S'; }
log() { echo "[$(TS)] $1" >> "$LOG"; }
[ ! -f "$QUEUE" ] && exit 0
[ ! -s "$QUEUE" ] && exit 0
# Atomically take ownership of the queue via rename — prevents TOCTOU loss of
# entries written between a cat and truncate
PROCESSING="${QUEUE}.processing"
mv "$QUEUE" "$PROCESSING" 2>/dev/null || exit 0
SNAPSHOT=$(cat "$PROCESSING")
rm -f "$PROCESSING"
while IFS= read -r path; do
[ -z "$path" ] && continue
[ ! -d "$path/.git" ] && log "SKIP $path — not a git repo" && continue
log "Deploying $path"
cd "$path" || continue
BEFORE=$(git rev-parse HEAD 2>/dev/null)
git fetch origin main >> "$LOG" 2>&1
REMOTE=$(git rev-parse origin/main 2>/dev/null)
if [ "$BEFORE" = "$REMOTE" ]; then
log "Already up to date: $path"
continue
fi
git pull origin main >> "$LOG" 2>&1
AFTER=$(git rev-parse HEAD 2>/dev/null)
CHANGED=$(git diff --name-only "$BEFORE" "$AFTER" 2>/dev/null)
# PHP syntax validation — check every changed .php file
SYNTAX_OK=true
BAD_FILE=""
while IFS= read -r f; do
[[ "$f" != *.php ]] && continue
[ ! -f "$f" ] && continue
if ! $PHP -l "$f" > /dev/null 2>&1; then
SYNTAX_OK=false
BAD_FILE="$f"
break
fi
done <<< "$CHANGED"
if [ "$SYNTAX_OK" = false ]; then
log "SYNTAX ERROR in $BAD_FILE — reverting locally and pushing revert to GitHub"
git reset --hard "$BEFORE" >> "$LOG" 2>&1
# Push the revert so GitHub matches the live server — prevents infinite re-deploy loop
git push --force origin HEAD:main >> "$LOG" 2>&1
PUSH_EXIT=$?
if [ $PUSH_EXIT -ne 0 ]; then
log "WARNING: Force-push of revert failed (exit $PUSH_EXIT) — bad commit still on GitHub"
fi
# Insert alert into JARVIS DB
BAD_ESCAPED=$(printf '%s' "$BAD_FILE" | sed "s/'/\\\\\\'/g")
mysql -u jarvis_user -pJ4rv1s_Pr0t0c0l_2026! jarvis_db -se \
"INSERT INTO alerts (alert_type,title,message,severity)
VALUES ('deploy_fail','Deploy reverted: syntax error',
'PHP syntax error in $BAD_ESCAPED. Commit $AFTER was reverted and force-pushed to GitHub.','critical');" 2>/dev/null
log "Reverted. Bad commit: $AFTER"
continue
fi
log "Deploy OK ($BEFORE -> $AFTER): $path"
log "Changed: $(echo "$CHANGED" | tr '\n' ' ')"
# Restart OLS after any JARVIS deploy to pick up PHP changes
if [[ "$path" == *"jarvis"* ]]; then
systemctl reload lsws 2>/dev/null || systemctl restart lsws 2>/dev/null
log "OLS reloaded for JARVIS deploy"
fi
done <<< "$SNAPSHOT"