CI : Deployment
This commit is contained in:
227
deploy/install-agent.sh
Normal file
227
deploy/install-agent.sh
Normal file
@@ -0,0 +1,227 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Installe (ou met à jour) l'agent Stream Control sur une VM Linux.
|
||||
#
|
||||
# curl -fsSL https://gitea.exemple.com/api/packages/jeanbon/generic/stream-control-agent/latest/install-agent.sh \
|
||||
# | sudo bash -s -- \
|
||||
# --registry https://gitea.exemple.com \
|
||||
# --server ws://control.lan:8080/ws/agent \
|
||||
# --token <JETON_ENROLEMENT>
|
||||
#
|
||||
# Réexécuter le script met à jour le binaire sans toucher à l'identité d'un
|
||||
# agent déjà enrôlé.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REGISTRY=""
|
||||
OWNER="jeanbon"
|
||||
VERSION="latest"
|
||||
PACKAGE_NAME="stream-control-agent"
|
||||
PACKAGE_TOKEN=""
|
||||
|
||||
SERVER_URL=""
|
||||
TOKEN=""
|
||||
AGENT_NAME="$(hostname)"
|
||||
OBS_HOST="127.0.0.1"
|
||||
OBS_PORT="4455"
|
||||
OBS_PASSWORD=""
|
||||
|
||||
RUN_USER=""
|
||||
INSTALL_DIR="/opt/stream-control-agent"
|
||||
SERVICE="stream-control-agent"
|
||||
|
||||
die() { echo "✗ $*" >&2; exit 1; }
|
||||
info() { echo "· $*"; }
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Installe (ou met à jour) l'agent Stream Control sur une VM Linux.
|
||||
|
||||
curl -fsSL https://gitea.exemple.com/api/packages/jeanbon/generic/stream-control-agent/latest/install-agent.sh \
|
||||
| sudo bash -s -- \
|
||||
--registry https://gitea.exemple.com \
|
||||
--server ws://control.lan:8080/ws/agent \
|
||||
--token <JETON_ENROLEMENT>
|
||||
|
||||
Réexécuter le script met à jour le binaire sans toucher à l'identité d'un agent
|
||||
déjà enrôlé.
|
||||
|
||||
Options :
|
||||
--registry URL Base de l'instance Gitea (obligatoire)
|
||||
--server URL WebSocket du plan de contrôle (obligatoire à la 1re install)
|
||||
--token JETON Jeton d'enrôlement (obligatoire à la 1re install)
|
||||
--name NOM Nom affiché dans le dashboard (défaut : hostname)
|
||||
--user UTILISATEUR Compte exécutant l'agent (défaut : l'utilisateur sudo)
|
||||
--obs-host HOTE Défaut 127.0.0.1
|
||||
--obs-port PORT Défaut 4455
|
||||
--obs-password MDP Mot de passe obs-websocket
|
||||
--version VERSION Version du paquet à installer (défaut : latest)
|
||||
--owner PROPRIETAIRE Propriétaire du paquet Gitea (défaut : jeanbon)
|
||||
--package-token JETON Jeton de lecture si le paquet est privé
|
||||
--help
|
||||
EOF
|
||||
exit 0
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--registry) REGISTRY="${2:?}"; shift 2 ;;
|
||||
--server) SERVER_URL="${2:?}"; shift 2 ;;
|
||||
--token) TOKEN="${2:?}"; shift 2 ;;
|
||||
--name) AGENT_NAME="${2:?}"; shift 2 ;;
|
||||
--user) RUN_USER="${2:?}"; shift 2 ;;
|
||||
--obs-host) OBS_HOST="${2:?}"; shift 2 ;;
|
||||
--obs-port) OBS_PORT="${2:?}"; shift 2 ;;
|
||||
--obs-password) OBS_PASSWORD="${2:?}"; shift 2 ;;
|
||||
--version) VERSION="${2:?}"; shift 2 ;;
|
||||
--owner) OWNER="${2:?}"; shift 2 ;;
|
||||
--package-token) PACKAGE_TOKEN="${2:?}"; shift 2 ;;
|
||||
--help|-h) usage ;;
|
||||
*) die "Option inconnue : $1 (--help pour l'aide)" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$(id -u)" -eq 0 ] || die "À exécuter en root (sudo)."
|
||||
[ -n "$REGISTRY" ] || die "--registry est obligatoire."
|
||||
REGISTRY="${REGISTRY%/}"
|
||||
|
||||
# L'agent doit tourner sous le compte qui ouvre la session graphique d'OBS :
|
||||
# c'est ce qui lui donne accès à l'affichage pour le rappel plein écran.
|
||||
if [ -z "$RUN_USER" ]; then
|
||||
RUN_USER="${SUDO_USER:-root}"
|
||||
fi
|
||||
id "$RUN_USER" >/dev/null 2>&1 || die "L'utilisateur « $RUN_USER » n'existe pas."
|
||||
|
||||
CONFIG_FILE="$INSTALL_DIR/agent.config.json"
|
||||
IS_UPGRADE=false
|
||||
[ -f "$CONFIG_FILE" ] && IS_UPGRADE=true
|
||||
|
||||
if [ "$IS_UPGRADE" = false ]; then
|
||||
[ -n "$SERVER_URL" ] || die "--server est obligatoire pour une première installation."
|
||||
[ -n "$TOKEN" ] || die "--token est obligatoire pour une première installation."
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Installation de l'agent Stream Control"
|
||||
echo " utilisateur : $RUN_USER"
|
||||
echo " destination : $INSTALL_DIR"
|
||||
echo " version : $VERSION"
|
||||
echo
|
||||
|
||||
# --- Node.js ----------------------------------------------------------------
|
||||
NODE_MAJOR=0
|
||||
if command -v node >/dev/null 2>&1; then
|
||||
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)"
|
||||
fi
|
||||
|
||||
if [ "$NODE_MAJOR" -lt 22 ]; then
|
||||
info "Node.js 22+ requis (trouvé : ${NODE_MAJOR:-aucun}) — installation depuis NodeSource"
|
||||
command -v apt-get >/dev/null 2>&1 \
|
||||
|| die "Distribution non gérée automatiquement : installe Node.js 22+ puis relance."
|
||||
curl -fsSL https://deb.nodesource.com/setup_24.x | bash -
|
||||
apt-get install -y nodejs
|
||||
else
|
||||
info "Node.js $(node -v) présent"
|
||||
fi
|
||||
|
||||
# --- xdotool (rappel plein écran) -------------------------------------------
|
||||
if ! command -v xdotool >/dev/null 2>&1; then
|
||||
if command -v apt-get >/dev/null 2>&1; then
|
||||
info "Installation de xdotool (rappel plein écran)"
|
||||
apt-get install -y xdotool >/dev/null
|
||||
else
|
||||
echo "! xdotool absent : le rappel plein écran sera indisponible."
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Téléchargement du bundle -----------------------------------------------
|
||||
URL="$REGISTRY/api/packages/$OWNER/generic/$PACKAGE_NAME/$VERSION/agent.cjs"
|
||||
info "Téléchargement depuis $URL"
|
||||
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
CURL_AUTH=()
|
||||
[ -n "$PACKAGE_TOKEN" ] && CURL_AUTH=(--header "Authorization: token $PACKAGE_TOKEN")
|
||||
|
||||
curl -fsSL "${CURL_AUTH[@]}" -o "$INSTALL_DIR/agent.cjs.tmp" "$URL" \
|
||||
|| die "Téléchargement impossible. Vérifie --registry, --version, et --package-token si le paquet est privé."
|
||||
|
||||
node --check "$INSTALL_DIR/agent.cjs.tmp" 2>/dev/null \
|
||||
|| die "Le fichier téléchargé n'est pas un script Node valide."
|
||||
mv "$INSTALL_DIR/agent.cjs.tmp" "$INSTALL_DIR/agent.cjs"
|
||||
|
||||
# --- Configuration ----------------------------------------------------------
|
||||
if [ "$IS_UPGRADE" = true ]; then
|
||||
# Un agent déjà enrôlé possède un jeton permanent : l'écraser avec le jeton
|
||||
# d'enrôlement le ferait réapparaître comme un second agent dans le dashboard.
|
||||
info "Configuration existante conservée (identité de l'agent préservée)"
|
||||
else
|
||||
umask 077
|
||||
cat > "$CONFIG_FILE" <<EOF
|
||||
{
|
||||
"serverUrl": "$SERVER_URL",
|
||||
"token": "$TOKEN",
|
||||
"name": "$AGENT_NAME",
|
||||
"obs": {
|
||||
"host": "$OBS_HOST",
|
||||
"port": $OBS_PORT,
|
||||
"password": "$OBS_PASSWORD"
|
||||
}
|
||||
}
|
||||
EOF
|
||||
info "Configuration écrite dans $CONFIG_FILE"
|
||||
fi
|
||||
|
||||
chown -R "$RUN_USER" "$INSTALL_DIR"
|
||||
chmod 600 "$CONFIG_FILE"
|
||||
|
||||
# --- Service systemd --------------------------------------------------------
|
||||
USER_HOME="$(getent passwd "$RUN_USER" | cut -d: -f6)"
|
||||
|
||||
cat > "/etc/systemd/system/$SERVICE.service" <<EOF
|
||||
[Unit]
|
||||
Description=Stream Control — agent OBS
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=$RUN_USER
|
||||
WorkingDirectory=$INSTALL_DIR
|
||||
Environment=NODE_ENV=production
|
||||
Environment=AGENT_CONFIG=$CONFIG_FILE
|
||||
# Accès à la session graphique, nécessaire au rappel plein écran via xdotool.
|
||||
Environment=DISPLAY=:0
|
||||
Environment=XAUTHORITY=$USER_HOME/.Xauthority
|
||||
ExecStart=$(command -v node) $INSTALL_DIR/agent.cjs
|
||||
Restart=always
|
||||
RestartSec=5
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
|
||||
systemctl daemon-reload
|
||||
systemctl enable "$SERVICE" >/dev/null 2>&1 || true
|
||||
systemctl restart "$SERVICE"
|
||||
|
||||
# --- Vérification -----------------------------------------------------------
|
||||
echo
|
||||
sudo -u "$RUN_USER" AGENT_CONFIG="$CONFIG_FILE" \
|
||||
"$(command -v node)" "$INSTALL_DIR/agent.cjs" --check || true
|
||||
|
||||
sleep 2
|
||||
if systemctl is-active --quiet "$SERVICE"; then
|
||||
echo "✓ Agent installé et démarré."
|
||||
else
|
||||
echo "✗ Le service n'est pas actif. Journal :"
|
||||
journalctl -u "$SERVICE" -n 20 --no-pager || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
|
||||
état : systemctl status $SERVICE
|
||||
journal: journalctl -u $SERVICE -f
|
||||
test : sudo -u $RUN_USER node $INSTALL_DIR/agent.cjs --check
|
||||
|
||||
EOF
|
||||
Reference in New Issue
Block a user