feat: Added package management
Server Deploy / deploy (push) Successful in 3m44s
Agent Release / build (push) Successful in 10m21s

This commit is contained in:
domrichardson
2026-06-24 16:31:51 +01:00
parent fab87c82c6
commit 5c91db0d4c
16 changed files with 976 additions and 799 deletions
-17
View File
@@ -1,17 +0,0 @@
services:
migrate:
image: mongo:8
depends_on:
mongo:
condition: service_healthy
volumes:
- ./migrate/server-migrate.sh:/migrate.sh:ro
command: bash /migrate.sh
environment:
MONGO_HOST: mongo
MONGO_PORT: "27017"
SRC_DB: keymanager
DST_DB: vantage
# Set DROP_SRC=true to automatically drop the keymanager database after migration
DROP_SRC: "false"
restart: "no"
-219
View File
@@ -1,219 +0,0 @@
#!/usr/bin/env bash
# Migrates an existing keymanager-agent installation to vantage-agent.
# Run as root on each managed server.
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info() { echo -e "${GREEN}[migrate]${NC} $*"; }
warn() { echo -e "${YELLOW}[migrate]${NC} $*"; }
die() { echo -e "${RED}[migrate]${NC} $*" >&2; exit 1; }
[ "$(id -u)" -eq 0 ] || die "Must be run as root"
GITEA_HOST="${GITEA_HOST:-}"
GITEA_OWNER="${GITEA_OWNER:-}"
# ---------------------------------------------------------------------------
# 1. Detect old installation
# ---------------------------------------------------------------------------
OLD_BINARY="/usr/local/bin/keymanager-agent"
OLD_CONFIG_DIR="/etc/keymanager"
OLD_CONFIG="$OLD_CONFIG_DIR/config.yaml"
OLD_SERVICE="keymanager-agent"
OLD_SERVICE_FILE="/etc/systemd/system/${OLD_SERVICE}.service"
OLD_SSH_CONF="/root/.ssh/keymanager.conf"
OLD_SSH_CONFIG="/root/.ssh/config"
NEW_BINARY="/usr/local/bin/vantage-agent"
NEW_CONFIG_DIR="/etc/vantage"
NEW_CONFIG="$NEW_CONFIG_DIR/config.yaml"
NEW_SERVICE="vantage-agent"
NEW_SERVICE_FILE="/etc/systemd/system/${NEW_SERVICE}.service"
NEW_SSH_CONF="/root/.ssh/vantage.conf"
if [ ! -f "$OLD_CONFIG" ] && [ ! -f "$OLD_BINARY" ]; then
warn "No keymanager-agent installation found — nothing to migrate."
exit 0
fi
info "Found keymanager-agent installation. Starting migration to vantage-agent..."
# ---------------------------------------------------------------------------
# 2. Stop and disable old service
# ---------------------------------------------------------------------------
if systemctl is-active --quiet "$OLD_SERVICE" 2>/dev/null; then
info "Stopping $OLD_SERVICE..."
systemctl stop "$OLD_SERVICE"
fi
if systemctl is-enabled --quiet "$OLD_SERVICE" 2>/dev/null; then
systemctl disable "$OLD_SERVICE"
fi
# ---------------------------------------------------------------------------
# 3. Migrate config directory
# ---------------------------------------------------------------------------
if [ -f "$OLD_CONFIG" ] && [ ! -f "$NEW_CONFIG" ]; then
info "Migrating config: $OLD_CONFIG -> $NEW_CONFIG"
mkdir -p "$NEW_CONFIG_DIR"
chmod 0700 "$NEW_CONFIG_DIR"
cp "$OLD_CONFIG" "$NEW_CONFIG"
chmod 0600 "$NEW_CONFIG"
elif [ -f "$NEW_CONFIG" ]; then
warn "$NEW_CONFIG already exists — skipping config copy."
fi
# ---------------------------------------------------------------------------
# 4. Migrate SSH managed conf file
# ---------------------------------------------------------------------------
if [ -f "$OLD_SSH_CONF" ]; then
info "Migrating SSH conf: $OLD_SSH_CONF -> $NEW_SSH_CONF"
# Rewrite IdentityFile paths: /root/.ssh/keymanager_* -> /root/.ssh/vantage_*
sed 's|/root/\.ssh/keymanager_|/root/.ssh/vantage_|g' "$OLD_SSH_CONF" > "$NEW_SSH_CONF"
chmod 0600 "$NEW_SSH_CONF"
fi
# Update Include directive in /root/.ssh/config
if [ -f "$OLD_SSH_CONFIG" ]; then
if grep -q "Include /root/.ssh/keymanager.conf" "$OLD_SSH_CONFIG"; then
info "Updating Include directive in $OLD_SSH_CONFIG"
sed -i 's|Include /root/\.ssh/keymanager\.conf|Include /root/.ssh/vantage.conf|g' "$OLD_SSH_CONFIG"
fi
fi
# ---------------------------------------------------------------------------
# 5. Rename generated key files
# ---------------------------------------------------------------------------
shopt -s nullglob
OLD_KEYS=(/root/.ssh/keymanager_*)
if [ ${#OLD_KEYS[@]} -gt 0 ]; then
info "Renaming ${#OLD_KEYS[@]} key file(s)..."
for old_path in "${OLD_KEYS[@]}"; do
filename=$(basename "$old_path")
new_filename="${filename/keymanager_/vantage_}"
new_path="/root/.ssh/$new_filename"
if [ ! -e "$new_path" ]; then
cp "$old_path" "$new_path"
chmod "$(stat -c '%a' "$old_path")" "$new_path"
info " $old_path -> $new_path"
else
warn " $new_path already exists — skipping"
fi
done
fi
shopt -u nullglob
# ---------------------------------------------------------------------------
# 6. Download new vantage-agent binary
# ---------------------------------------------------------------------------
ARCH="$(uname -m)"
case "$ARCH" in
x86_64) ARCH="amd64" ;;
aarch64) ARCH="arm64" ;;
*) die "Unsupported architecture: $ARCH" ;;
esac
if [ -n "$GITEA_HOST" ] && [ -n "$GITEA_OWNER" ]; then
info "Fetching latest vantage-agent release from $GITEA_HOST..."
RELEASE_JSON=$(curl -fsSL "https://${GITEA_HOST}/api/v1/repos/${GITEA_OWNER}/vantage/releases?limit=1&type=tag" 2>/dev/null || echo "")
if [ -n "$RELEASE_JSON" ]; then
DOWNLOAD_URL=$(echo "$RELEASE_JSON" | grep -o "\"browser_download_url\":\"[^\"]*vantage-agent-linux-${ARCH}\"" | head -1 | cut -d'"' -f4)
CHECKSUM_URL=$(echo "$RELEASE_JSON" | grep -o "\"browser_download_url\":\"[^\"]*checksums\.txt\"" | head -1 | cut -d'"' -f4)
if [ -n "$DOWNLOAD_URL" ]; then
info "Downloading $DOWNLOAD_URL..."
TMP_BIN="/tmp/vantage-agent-new"
curl -fsSL -o "$TMP_BIN" "$DOWNLOAD_URL"
if [ -n "$CHECKSUM_URL" ]; then
TMP_SUMS="/tmp/vantage-checksums.txt"
curl -fsSL -o "$TMP_SUMS" "$CHECKSUM_URL"
EXPECTED=$(grep "vantage-agent-linux-${ARCH}" "$TMP_SUMS" | awk '{print $1}')
ACTUAL=$(sha256sum "$TMP_BIN" | awk '{print $1}')
[ "$EXPECTED" = "$ACTUAL" ] || die "Checksum mismatch! Expected $EXPECTED, got $ACTUAL"
rm -f "$TMP_SUMS"
info "Checksum verified."
fi
chmod 0755 "$TMP_BIN"
mv "$TMP_BIN" "$NEW_BINARY"
info "Installed $NEW_BINARY"
else
warn "Could not find vantage-agent binary in release — skipping binary install."
fi
else
warn "Could not reach Gitea API — skipping binary download."
fi
elif [ -f "$OLD_BINARY" ]; then
warn "GITEA_HOST/GITEA_OWNER not set — skipping binary download."
warn "You must manually install the vantage-agent binary to $NEW_BINARY before starting the service."
fi
# ---------------------------------------------------------------------------
# 7. Install new systemd service
# ---------------------------------------------------------------------------
info "Installing $NEW_SERVICE_FILE..."
cat > "$NEW_SERVICE_FILE" <<'EOF'
[Unit]
Description=Vantage Agent
Documentation=https://github.com/your-org/vantage
After=network.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/vantage-agent
Restart=always
RestartSec=10
User=root
StandardOutput=journal
StandardError=journal
SyslogIdentifier=vantage-agent
NoNewPrivileges=true
ProtectSystem=false
ProtectHome=false
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable "$NEW_SERVICE"
# ---------------------------------------------------------------------------
# 8. Start new service (only if binary exists)
# ---------------------------------------------------------------------------
if [ -f "$NEW_BINARY" ]; then
info "Starting $NEW_SERVICE..."
systemctl start "$NEW_SERVICE"
sleep 2
if systemctl is-active --quiet "$NEW_SERVICE"; then
info "vantage-agent is running."
else
warn "vantage-agent failed to start. Check: journalctl -u vantage-agent"
fi
else
warn "Binary not yet installed — service NOT started."
warn "Install the binary then run: systemctl start vantage-agent"
fi
# ---------------------------------------------------------------------------
# 9. Clean up old installation
# ---------------------------------------------------------------------------
info "Cleaning up old keymanager-agent files..."
rm -f "$OLD_SERVICE_FILE"
rm -f "$OLD_BINARY"
rm -rf "$OLD_CONFIG_DIR"
rm -f "$OLD_SSH_CONF"
shopt -s nullglob
for old_key in /root/.ssh/keymanager_*; do
rm -f "$old_key"
done
shopt -u nullglob
systemctl daemon-reload
info "Migration complete."
-124
View File
@@ -1,124 +0,0 @@
#!/usr/bin/env bash
# Runs inside the migration container.
# Copies all collections + indexes from $SRC_DB to $DST_DB,
# verifies document counts, then optionally drops the source.
set -euo pipefail
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'
info() { echo -e "${GREEN}[migrate]${NC} $*"; }
warn() { echo -e "${YELLOW}[migrate]${NC} $*"; }
die() { echo -e "${RED}[migrate]${NC} $*" >&2; exit 1; }
MONGO_HOST="${MONGO_HOST:-mongo}"
MONGO_PORT="${MONGO_PORT:-27017}"
SRC_DB="${SRC_DB:-keymanager}"
DST_DB="${DST_DB:-vantage}"
DROP_SRC="${DROP_SRC:-false}"
MONGO_URI="mongodb://${MONGO_HOST}:${MONGO_PORT}"
mongosh_eval() {
local db="$1"; local script="$2"
mongosh --quiet "${MONGO_URI}/${db}" --eval "$script"
}
# ---------------------------------------------------------------------------
# 1. Wait for MongoDB to be reachable
# ---------------------------------------------------------------------------
info "Waiting for MongoDB at ${MONGO_HOST}:${MONGO_PORT}..."
for i in $(seq 1 30); do
mongosh --quiet "${MONGO_URI}/admin" --eval "db.adminCommand('ping')" >/dev/null 2>&1 && break
[ "$i" -eq 30 ] && die "MongoDB not reachable after 30 attempts."
sleep 2
done
info "MongoDB is ready."
# ---------------------------------------------------------------------------
# 2. Check source database
# ---------------------------------------------------------------------------
SRC_COLLECTIONS=$(mongosh_eval admin "
const names = db.getSiblingDB('${SRC_DB}').getCollectionNames();
print(names.join(','));
")
if [ -z "$SRC_COLLECTIONS" ] || [ "$SRC_COLLECTIONS" = "," ]; then
warn "Source database '${SRC_DB}' has no collections — nothing to migrate."
warn "If this is a fresh deployment, '${DST_DB}' will be created automatically."
exit 0
fi
info "Collections in '${SRC_DB}': ${SRC_COLLECTIONS}"
# ---------------------------------------------------------------------------
# 3. Copy all collections via \$out
# ---------------------------------------------------------------------------
info "Copying collections from '${SRC_DB}' to '${DST_DB}'..."
mongosh_eval admin "
const src = db.getSiblingDB('${SRC_DB}');
const cols = src.getCollectionNames();
cols.forEach(function(name) {
src[name].aggregate([{ \\\$out: { db: '${DST_DB}', coll: name } }]);
print('Copied: ' + name);
});
"
# ---------------------------------------------------------------------------
# 4. Recreate indexes
# ---------------------------------------------------------------------------
info "Recreating indexes in '${DST_DB}'..."
mongosh_eval admin "
const src = db.getSiblingDB('${SRC_DB}');
const dst = db.getSiblingDB('${DST_DB}');
src.getCollectionNames().forEach(function(col) {
src[col].getIndexes().forEach(function(idx) {
if (idx.name === '_id_') return;
const opts = { name: idx.name };
if (idx.unique) opts.unique = true;
if (idx.sparse) opts.sparse = true;
if (idx.expireAfterSeconds !== undefined) opts.expireAfterSeconds = idx.expireAfterSeconds;
try {
dst[col].createIndex(idx.key, opts);
print('Index: ' + col + '.' + idx.name);
} catch(e) {
print('Skipped index ' + idx.name + ' on ' + col + ': ' + e.message);
}
});
});
"
# ---------------------------------------------------------------------------
# 5. Verify document counts
# ---------------------------------------------------------------------------
info "Verifying document counts..."
MISMATCH=0
IFS=',' read -ra COLS <<< "$SRC_COLLECTIONS"
for col in "${COLS[@]}"; do
[ -z "$col" ] && continue
SRC_N=$(mongosh_eval "$SRC_DB" "print(db['${col}'].countDocuments())")
DST_N=$(mongosh_eval "$DST_DB" "print(db['${col}'].countDocuments())")
if [ "$SRC_N" = "$DST_N" ]; then
info " ${col}: ${SRC_N} docs OK"
else
warn " ${col}: src=${SRC_N} dst=${DST_N} MISMATCH"
MISMATCH=1
fi
done
[ "$MISMATCH" -eq 1 ] && die "Count mismatch — source database NOT dropped. Investigate and re-run."
# ---------------------------------------------------------------------------
# 6. Optionally drop source database
# ---------------------------------------------------------------------------
if [ "$DROP_SRC" = "true" ]; then
info "Dropping source database '${SRC_DB}'..."
mongosh_eval admin "db.getSiblingDB('${SRC_DB}').dropDatabase(); print('Dropped.');"
info "Dropped '${SRC_DB}'."
else
warn "Source database '${SRC_DB}' kept. Set DROP_SRC=true to drop it automatically."
fi
info "Migration complete."