added install script for agent
changed backend to agent
This commit is contained in:
Executable
+251
@@ -0,0 +1,251 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
SERVICE_NAME="incus-backup-agent"
|
||||
DEFAULT_REPO_URL="https://forgejo.digital-droplets.de/philschlo/incus-backup-ui.git"
|
||||
|
||||
INSTALL_DIR="${INSTALL_DIR:-/opt/incus-backup-ui}"
|
||||
REPO_URL="${INCUS_BACKUP_REPO_URL:-$DEFAULT_REPO_URL}"
|
||||
BRANCH="${INCUS_BACKUP_BRANCH:-main}"
|
||||
AGENT_DIR="$INSTALL_DIR/agent"
|
||||
OLD_AGENT_DIR="$INSTALL_DIR/backend"
|
||||
STATE_DIR="${STATE_DIR:-/var/lib/incus-backup-agent}"
|
||||
CONFIG_DIR="${CONFIG_DIR:-/etc/incus-backup-agent}"
|
||||
ENV_FILE="$AGENT_DIR/.env"
|
||||
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service"
|
||||
|
||||
log() {
|
||||
printf '%s\n' "$*"
|
||||
}
|
||||
|
||||
fail() {
|
||||
printf 'ERROR: %s\n' "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
need_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || fail "Required command not found: $1"
|
||||
}
|
||||
|
||||
as_root() {
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
"$@"
|
||||
return
|
||||
fi
|
||||
command -v sudo >/dev/null 2>&1 || fail "Run as root or install sudo."
|
||||
sudo "$@"
|
||||
}
|
||||
|
||||
copy_repo_from_script_location() {
|
||||
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||
repo_dir=$(CDPATH= cd -- "$script_dir/.." && pwd)
|
||||
[ -d "$repo_dir/agent" ] || return 1
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
if [ "$repo_dir" = "$INSTALL_DIR" ]; then
|
||||
return 0
|
||||
fi
|
||||
command -v rsync >/dev/null 2>&1 || return 1
|
||||
rsync -a --delete \
|
||||
--exclude '.git' \
|
||||
--exclude 'agent/.env' \
|
||||
--exclude 'agent/node_modules' \
|
||||
--exclude 'management/node_modules' \
|
||||
--exclude 'frontend/node_modules' \
|
||||
"$repo_dir/" "$INSTALL_DIR/"
|
||||
}
|
||||
|
||||
checkout_or_update_repo() {
|
||||
need_cmd git
|
||||
if [ -d "$INSTALL_DIR/.git" ]; then
|
||||
log "Updating $INSTALL_DIR from Git..."
|
||||
git -C "$INSTALL_DIR" fetch --prune origin "$BRANCH"
|
||||
git -C "$INSTALL_DIR" checkout "$BRANCH"
|
||||
git -C "$INSTALL_DIR" pull --ff-only origin "$BRANCH"
|
||||
return
|
||||
fi
|
||||
|
||||
if copy_repo_from_script_location; then
|
||||
log "Installed files from local checkout to $INSTALL_DIR."
|
||||
return
|
||||
fi
|
||||
|
||||
log "Cloning $REPO_URL to $INSTALL_DIR..."
|
||||
mkdir -p "$(dirname "$INSTALL_DIR")"
|
||||
git clone --branch "$BRANCH" "$REPO_URL" "$INSTALL_DIR"
|
||||
}
|
||||
|
||||
move_old_agent_dir() {
|
||||
if [ -d "$OLD_AGENT_DIR" ] && [ ! -d "$AGENT_DIR" ]; then
|
||||
log "Renaming old backend directory to agent..."
|
||||
mv "$OLD_AGENT_DIR" "$AGENT_DIR"
|
||||
fi
|
||||
|
||||
if [ -f "$OLD_AGENT_DIR/.env" ] && [ ! -f "$ENV_FILE" ]; then
|
||||
log "Moving existing backend .env to agent .env..."
|
||||
mv "$OLD_AGENT_DIR/.env" "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_env_file() {
|
||||
[ -d "$AGENT_DIR" ] || fail "Agent directory not found: $AGENT_DIR"
|
||||
if [ ! -f "$ENV_FILE" ]; then
|
||||
cp "$AGENT_DIR/.env.example" "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
env_has_key() {
|
||||
key="$1"
|
||||
grep -Eq "^[[:space:]]*$key=" "$ENV_FILE"
|
||||
}
|
||||
|
||||
append_env_if_missing() {
|
||||
key="$1"
|
||||
value="$2"
|
||||
if ! env_has_key "$key"; then
|
||||
printf '%s="%s"\n' "$key" "$value" >> "$ENV_FILE"
|
||||
fi
|
||||
}
|
||||
|
||||
replace_env_value() {
|
||||
key="$1"
|
||||
value="$2"
|
||||
tmp_file="$ENV_FILE.tmp"
|
||||
awk -v key="$key" -v value="$value" '
|
||||
BEGIN { done = 0 }
|
||||
$0 ~ "^[[:space:]]*" key "=" {
|
||||
print key "=\"" value "\""
|
||||
done = 1
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
END {
|
||||
if (!done) print key "=\"" value "\""
|
||||
}
|
||||
' "$ENV_FILE" > "$tmp_file"
|
||||
mv "$tmp_file" "$ENV_FILE"
|
||||
chmod 600 "$ENV_FILE"
|
||||
}
|
||||
|
||||
current_env_value() {
|
||||
key="$1"
|
||||
awk -F= -v key="$key" '
|
||||
$1 == key {
|
||||
value = $0
|
||||
sub("^[^=]*=", "", value)
|
||||
gsub(/^"/, "", value)
|
||||
gsub(/"$/, "", value)
|
||||
print value
|
||||
exit
|
||||
}
|
||||
' "$ENV_FILE"
|
||||
}
|
||||
|
||||
random_token() {
|
||||
if command -v openssl >/dev/null 2>&1; then
|
||||
openssl rand -hex 32
|
||||
return
|
||||
fi
|
||||
need_cmd od
|
||||
od -An -N32 -tx1 /dev/urandom | tr -d ' \n'
|
||||
}
|
||||
|
||||
configure_env() {
|
||||
append_env_if_missing "AGENT_DATABASE_PATH" "$STATE_DIR/agent.sqlite"
|
||||
replace_env_value "AGENT_DATABASE_PATH" "${AGENT_DATABASE_PATH:-$STATE_DIR/agent.sqlite}"
|
||||
|
||||
if [ -n "${API_TOKEN:-}" ]; then
|
||||
replace_env_value "API_TOKEN" "$API_TOKEN"
|
||||
else
|
||||
token=$(current_env_value API_TOKEN)
|
||||
if [ ${#token} -lt 32 ] || [ "$token" = "change-me-to-at-least-32-characters" ]; then
|
||||
generated_token=$(random_token)
|
||||
replace_env_value "API_TOKEN" "$generated_token"
|
||||
log "Generated API_TOKEN for this agent:"
|
||||
log "$generated_token"
|
||||
log "Store this token in the management node configuration."
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -z "${HOST:-}" ] || replace_env_value "HOST" "$HOST"
|
||||
[ -z "${PORT:-}" ] || replace_env_value "PORT" "$PORT"
|
||||
[ -z "${ALLOWED_MANAGEMENT_IPS:-}" ] || replace_env_value "ALLOWED_MANAGEMENT_IPS" "$ALLOWED_MANAGEMENT_IPS"
|
||||
[ -z "${HTTPS_ENABLED:-}" ] || replace_env_value "HTTPS_ENABLED" "$HTTPS_ENABLED"
|
||||
[ -z "${TLS_CERT_FILE:-}" ] || replace_env_value "TLS_CERT_FILE" "$TLS_CERT_FILE"
|
||||
[ -z "${TLS_KEY_FILE:-}" ] || replace_env_value "TLS_KEY_FILE" "$TLS_KEY_FILE"
|
||||
}
|
||||
|
||||
install_dependencies() {
|
||||
need_cmd npm
|
||||
log "Installing agent dependencies..."
|
||||
if [ -f "$AGENT_DIR/package-lock.json" ]; then
|
||||
npm --prefix "$AGENT_DIR" ci --omit=dev
|
||||
else
|
||||
npm --prefix "$AGENT_DIR" install --omit=dev
|
||||
fi
|
||||
}
|
||||
|
||||
install_systemd_service() {
|
||||
install -d -m 700 "$STATE_DIR"
|
||||
install -d -m 700 "$CONFIG_DIR"
|
||||
tmp_service="$SERVICE_FILE.tmp"
|
||||
awk -v agent_dir="$AGENT_DIR" '
|
||||
/^WorkingDirectory=/ {
|
||||
print "WorkingDirectory=" agent_dir
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
' "$INSTALL_DIR/deploy/systemd/$SERVICE_NAME.service" > "$tmp_service"
|
||||
chmod 644 "$tmp_service"
|
||||
mv "$tmp_service" "$SERVICE_FILE"
|
||||
systemctl daemon-reload
|
||||
systemctl enable "$SERVICE_NAME"
|
||||
}
|
||||
|
||||
start_service() {
|
||||
if [ "${SKIP_START:-false}" = "true" ]; then
|
||||
log "SKIP_START=true; service was installed but not started."
|
||||
return
|
||||
fi
|
||||
systemctl restart "$SERVICE_NAME"
|
||||
systemctl --no-pager --full status "$SERVICE_NAME" || true
|
||||
}
|
||||
|
||||
main() {
|
||||
need_cmd awk
|
||||
need_cmd grep
|
||||
|
||||
as_root sh -c "true"
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
exec sudo \
|
||||
INSTALL_DIR="$INSTALL_DIR" \
|
||||
INCUS_BACKUP_REPO_URL="$REPO_URL" \
|
||||
INCUS_BACKUP_BRANCH="$BRANCH" \
|
||||
STATE_DIR="$STATE_DIR" \
|
||||
CONFIG_DIR="$CONFIG_DIR" \
|
||||
API_TOKEN="${API_TOKEN:-}" \
|
||||
AGENT_DATABASE_PATH="${AGENT_DATABASE_PATH:-}" \
|
||||
HOST="${HOST:-}" \
|
||||
PORT="${PORT:-}" \
|
||||
ALLOWED_MANAGEMENT_IPS="${ALLOWED_MANAGEMENT_IPS:-}" \
|
||||
HTTPS_ENABLED="${HTTPS_ENABLED:-}" \
|
||||
TLS_CERT_FILE="${TLS_CERT_FILE:-}" \
|
||||
TLS_KEY_FILE="${TLS_KEY_FILE:-}" \
|
||||
SKIP_START="${SKIP_START:-false}" \
|
||||
sh "$0"
|
||||
fi
|
||||
|
||||
checkout_or_update_repo
|
||||
move_old_agent_dir
|
||||
ensure_env_file
|
||||
configure_env
|
||||
install_dependencies
|
||||
install_systemd_service
|
||||
start_service
|
||||
|
||||
log "Agent install/update complete."
|
||||
log "Config: $ENV_FILE"
|
||||
log "Service: $SERVICE_NAME"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -5,7 +5,7 @@ Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
WorkingDirectory=/opt/incus-backup-ui/backend
|
||||
WorkingDirectory=/opt/incus-backup-ui/agent
|
||||
Environment=NODE_ENV=production
|
||||
ExecStart=/usr/bin/npm start
|
||||
Restart=on-failure
|
||||
|
||||
Reference in New Issue
Block a user