- Update dbis_core, cross-chain-pmm-lps, explorer-monorepo, metamask-integration, pr-workspace/chains - Omit embedded publish git dirs and empty placeholders from index Made-with: Cursor
187 lines
5.6 KiB
Bash
187 lines
5.6 KiB
Bash
#!/usr/bin/env bash
|
|
# Ensure the Hyperledger FireFly primary on VMID 6200 has a valid compose file
|
|
# and an active systemd unit.
|
|
#
|
|
# Expected runtime:
|
|
# - VMID 6200 running on r630-02
|
|
# - /opt/firefly/docker-compose.yml present
|
|
# - firefly.service enabled and active
|
|
# - firefly-core, firefly-postgres, firefly-ipfs using restart=unless-stopped
|
|
# - GET /api/v1/status succeeds on localhost:5000
|
|
#
|
|
# Usage: ./scripts/maintenance/ensure-firefly-primary-via-ssh.sh [--dry-run]
|
|
# Env: PROXMOX_HOST_R630_02 (default 192.168.11.12)
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
[[ -f "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" ]] && source "${PROJECT_ROOT}/scripts/lib/load-project-env.sh" 2>/dev/null || true
|
|
|
|
DRY_RUN=false
|
|
[[ "${1:-}" == "--dry-run" ]] && DRY_RUN=true
|
|
|
|
PROXMOX_HOST="${PROXMOX_HOST_R630_02:-192.168.11.12}"
|
|
VMID=6200
|
|
|
|
log_info() { echo -e "\033[0;34m[INFO]\033[0m $1"; }
|
|
log_ok() { echo -e "\033[0;32m[✓]\033[0m $1"; }
|
|
log_err() { echo -e "\033[0;31m[ERR]\033[0m $1"; }
|
|
|
|
run_ssh() { ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no root@"$PROXMOX_HOST" "$@"; }
|
|
|
|
normalize_compose() {
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
log_info "Would normalize /opt/firefly/docker-compose.yml and validate it with docker-compose config -q"
|
|
return 0
|
|
fi
|
|
|
|
run_ssh "pct exec $VMID -- bash -lc '
|
|
set -euo pipefail
|
|
test -f /opt/firefly/docker-compose.yml
|
|
if grep -qE \"^version:[[:space:]]*3\\.8[[:space:]]*$\" /opt/firefly/docker-compose.yml; then
|
|
sed -i \"s/^version:[[:space:]]*3\\.8[[:space:]]*$/version: \\\"3.8\\\"/\" /opt/firefly/docker-compose.yml
|
|
fi
|
|
docker-compose -f /opt/firefly/docker-compose.yml config -q
|
|
'"
|
|
}
|
|
|
|
install_firefly_helper() {
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
log_info "Would install an idempotent FireFly helper and systemd unit in VMID $VMID"
|
|
return 0
|
|
fi
|
|
|
|
local helper_tmp unit_tmp
|
|
helper_tmp="$(mktemp)"
|
|
unit_tmp="$(mktemp)"
|
|
|
|
cat > "$helper_tmp" <<'EOF'
|
|
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
COMPOSE_FILE=/opt/firefly/docker-compose.yml
|
|
STATUS_URL=http://127.0.0.1:5000/api/v1/status
|
|
|
|
start_stack() {
|
|
cd /opt/firefly
|
|
test -f "$COMPOSE_FILE"
|
|
if grep -qE '^version:[[:space:]]*3\.8[[:space:]]*$' "$COMPOSE_FILE"; then
|
|
sed -i 's/^version:[[:space:]]*3\.8[[:space:]]*$/version: "3.8"/' "$COMPOSE_FILE"
|
|
fi
|
|
docker-compose -f "$COMPOSE_FILE" config -q
|
|
docker-compose -f "$COMPOSE_FILE" up -d postgres ipfs >/dev/null
|
|
|
|
if docker ps -a --format '{{.Names}}' | grep -qx firefly-core; then
|
|
docker start firefly-core >/dev/null 2>&1 || true
|
|
else
|
|
docker-compose -f "$COMPOSE_FILE" up -d firefly-core >/dev/null
|
|
fi
|
|
|
|
curl -fsS "$STATUS_URL" >/dev/null
|
|
}
|
|
|
|
stop_stack() {
|
|
docker stop firefly-core firefly-postgres firefly-ipfs >/dev/null 2>&1 || true
|
|
}
|
|
|
|
case "${1:-start}" in
|
|
start)
|
|
start_stack
|
|
;;
|
|
stop)
|
|
stop_stack
|
|
;;
|
|
*)
|
|
echo "Usage: $0 [start|stop]" >&2
|
|
exit 64
|
|
;;
|
|
esac
|
|
EOF
|
|
|
|
cat > "$unit_tmp" <<'EOF'
|
|
[Unit]
|
|
Description=Ensure Hyperledger FireFly primary stack
|
|
After=docker.service network-online.target
|
|
Requires=docker.service
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
RemainAfterExit=yes
|
|
WorkingDirectory=/opt/firefly
|
|
User=firefly
|
|
Group=firefly
|
|
ExecStart=/usr/local/bin/ensure-firefly-primary start
|
|
ExecStop=/usr/local/bin/ensure-firefly-primary stop
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
scp -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$helper_tmp" "root@$PROXMOX_HOST:/tmp/ensure-firefly-primary"
|
|
scp -o ConnectTimeout=10 -o StrictHostKeyChecking=no "$unit_tmp" "root@$PROXMOX_HOST:/tmp/firefly.service"
|
|
run_ssh "pct exec $VMID -- rm -f /usr/local/bin/ensure-firefly-primary /etc/systemd/system/firefly.service"
|
|
run_ssh "pct push $VMID /tmp/ensure-firefly-primary /usr/local/bin/ensure-firefly-primary --perms 755"
|
|
run_ssh "pct push $VMID /tmp/firefly.service /etc/systemd/system/firefly.service --perms 644"
|
|
run_ssh "rm -f /tmp/ensure-firefly-primary /tmp/firefly.service"
|
|
rm -f "$helper_tmp" "$unit_tmp"
|
|
}
|
|
|
|
ensure_firefly_service() {
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
log_info "Would reset-failed and enable/start firefly.service in VMID $VMID"
|
|
return 0
|
|
fi
|
|
|
|
run_ssh "pct exec $VMID -- bash -lc '
|
|
set -euo pipefail
|
|
systemctl daemon-reload
|
|
systemctl reset-failed firefly.service || true
|
|
systemctl enable firefly.service >/dev/null 2>&1
|
|
systemctl start firefly.service
|
|
'"
|
|
}
|
|
|
|
verify_firefly_primary() {
|
|
run_ssh "pct exec $VMID -- bash -lc '
|
|
set -euo pipefail
|
|
echo service=\$(systemctl is-active firefly.service)
|
|
docker inspect -f \"{{.HostConfig.RestartPolicy.Name}}\" firefly-core | grep -qx unless-stopped
|
|
docker inspect -f \"{{.HostConfig.RestartPolicy.Name}}\" firefly-postgres | grep -qx unless-stopped
|
|
docker inspect -f \"{{.HostConfig.RestartPolicy.Name}}\" firefly-ipfs | grep -qx unless-stopped
|
|
curl -fsS http://127.0.0.1:5000/api/v1/status
|
|
'" 2>/dev/null
|
|
}
|
|
|
|
echo ""
|
|
echo "=== Ensure FireFly primary ==="
|
|
echo " Host: $PROXMOX_HOST vmid=$VMID dry-run=$DRY_RUN"
|
|
echo ""
|
|
|
|
status="$(run_ssh "pct status $VMID 2>/dev/null | awk '{print \$2}'" 2>/dev/null || echo "missing")"
|
|
if [[ "$status" != "running" ]]; then
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
log_info "Would start VMID $VMID"
|
|
else
|
|
run_ssh "pct start $VMID"
|
|
sleep 8
|
|
fi
|
|
fi
|
|
|
|
normalize_compose
|
|
install_firefly_helper
|
|
|
|
if [[ "$DRY_RUN" == true ]]; then
|
|
log_info "Would enable/start firefly.service and verify API health"
|
|
exit 0
|
|
fi
|
|
|
|
ensure_firefly_service
|
|
|
|
if firefly_info="$(verify_firefly_primary)"; then
|
|
log_ok "FireFly primary healthy"
|
|
printf '%s\n' "$firefly_info"
|
|
else
|
|
log_err "FireFly primary is still not healthy after normalization"
|
|
exit 1
|
|
fi
|