142 lines
5.1 KiB
YAML
142 lines
5.1 KiB
YAML
name: Deploy
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: self-hosted
|
|
steps:
|
|
# Checkout code
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
# Setup SSH for services server
|
|
- name: Setup SSH
|
|
shell: bash
|
|
env:
|
|
SERVICE_SSH_KEY: ${{ secrets.SERVICE_SSH_KEY }}
|
|
SERVICE_HOST: ${{ secrets.SERVICE_HOST }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
if ! command -v ssh >/dev/null 2>&1; then
|
|
if command -v apk >/dev/null 2>&1; then
|
|
apk add --no-cache openssh-client
|
|
elif command -v apt-get >/dev/null 2>&1; then
|
|
apt-get update
|
|
apt-get install -y openssh-client
|
|
else
|
|
echo "ssh client not found and no known package manager available" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
: "${SERVICE_HOST:?Missing secret SERVICE_HOST}"
|
|
: "${SERVICE_SSH_KEY:?Missing secret SERVICE_SSH_KEY}"
|
|
|
|
SERVICE_IP="$(getent ahostsv4 "$SERVICE_HOST" | awk '{print $1; exit}')"
|
|
if [[ -z "${SERVICE_IP}" ]]; then
|
|
echo "ERROR: Could not resolve IPv4 for $SERVICE_HOST" >&2
|
|
getent hosts "$SERVICE_HOST" || true
|
|
exit 1
|
|
fi
|
|
|
|
timeout 5 bash -lc "</dev/tcp/$SERVICE_IP/22" || {
|
|
echo "ERROR: Cannot reach $SERVICE_HOST ($SERVICE_IP):22 from runner container" >&2
|
|
exit 1
|
|
}
|
|
|
|
mkdir -p ~/.ssh
|
|
printf '%s\n' "$SERVICE_SSH_KEY" | tr -d '\r' > ~/.ssh/id_ed25519
|
|
chmod 600 ~/.ssh/id_ed25519
|
|
|
|
ssh-keyscan -4 -T 5 -H "$SERVICE_HOST" "$SERVICE_IP" >> ~/.ssh/known_hosts || {
|
|
echo "ERROR: ssh-keyscan failed for $SERVICE_HOST ($SERVICE_IP)" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Deploy infra-controller to services server
|
|
- name: Deploy infra-controller (services server)
|
|
shell: bash
|
|
env:
|
|
SERVICE_HOST: ${{ secrets.SERVICE_HOST }}
|
|
SERVICE_USER: ${{ secrets.SERVICE_USER }}
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
: "${SERVICE_HOST:?Missing secret SERVICE_HOST}"
|
|
: "${SERVICE_USER:?Missing secret SERVICE_USER}"
|
|
|
|
GIT_SHA="${{ github.sha }}"
|
|
REPO_URL="$(git remote get-url origin)"
|
|
|
|
echo "Deploying infra-controller ($GIT_SHA) to $SERVICE_USER@$SERVICE_HOST ..."
|
|
|
|
ssh -i ~/.ssh/id_ed25519 "$SERVICE_USER@$SERVICE_HOST" /bin/sh -lc "set -euo pipefail
|
|
|
|
if ! command -v sudo >/dev/null 2>&1; then
|
|
echo 'ERROR: sudo not installed on services server' >&2
|
|
exit 1
|
|
fi
|
|
if ! sudo -n /usr/bin/git --version >/dev/null 2>&1; then
|
|
echo 'ERROR: passwordless sudo is required for CI deploy (configure NOPASSWD for this SSH user and required commands)' >&2
|
|
exit 1
|
|
fi
|
|
|
|
if ! getent hosts "$(hostname)" >/dev/null 2>&1; then
|
|
sudo -n /usr/bin/python3 -c 'import os
|
|
from pathlib import Path
|
|
hn = os.popen("hostname").read().strip()
|
|
p = Path("/etc/hosts")
|
|
t = p.read_text(encoding="utf-8") if p.exists() else ""
|
|
lines = t.splitlines()
|
|
ok = any((ln.strip() and not ln.lstrip().startswith("#") and hn in ln.split()) for ln in lines)
|
|
if not ok:
|
|
if t and not t.endswith("\n"):
|
|
t += "\n"
|
|
t += f"127.0.1.1 {hn}\n"
|
|
p.write_text(t, encoding="utf-8")
|
|
'
|
|
fi
|
|
|
|
sudo -n mkdir -p /opt/infra-controller /etc/infra-controller /var/lib/infra-controller /var/log/infra-controller
|
|
|
|
if [ ! -d /opt/infra-controller/.git ]; then
|
|
sudo -n rm -rf /opt/infra-controller/*
|
|
sudo -n git clone '$REPO_URL' /opt/infra-controller
|
|
fi
|
|
|
|
cd /opt/infra-controller
|
|
sudo -n git fetch --all --prune
|
|
sudo -n git checkout -f '$GIT_SHA'
|
|
|
|
if [ ! -d /opt/infra-controller/venv ]; then
|
|
sudo -n python3 -m venv /opt/infra-controller/venv
|
|
fi
|
|
sudo -n /opt/infra-controller/venv/bin/pip install --upgrade pip
|
|
sudo -n /opt/infra-controller/venv/bin/pip install -e .
|
|
|
|
if [ ! -f /etc/infra-controller/config.toml ]; then
|
|
sudo -n cp config/controller.toml.example /etc/infra-controller/config.toml
|
|
fi
|
|
if [ ! -f /etc/infra-controller/controller.env ]; then
|
|
sudo -n cp systemd/infra-controller.env /etc/infra-controller/controller.env
|
|
fi
|
|
|
|
sudo -n cp systemd/infra-controller.service /etc/systemd/system/
|
|
sudo -n cp systemd/infra-controller-once.service /etc/systemd/system/
|
|
sudo -n cp systemd/infra-controller-watch.service /etc/systemd/system/
|
|
sudo -n systemctl daemon-reload
|
|
|
|
sudo -n systemctl disable --now infra-controller.path 2>/dev/null || true
|
|
sudo -n systemctl enable --now infra-controller-watch.service
|
|
sudo -n systemctl restart infra-controller-watch.service
|
|
|
|
sudo -n chown -R infractl:infractl /opt/infra-controller /var/lib/infra-controller /var/log/infra-controller || true
|
|
|
|
/opt/infra-controller/venv/bin/infra-controller --once
|
|
"
|