chore: sync installers from triton v1.0.0-rc.1

This commit is contained in:
github-actions[bot] 2026-05-20 15:01:09 +00:00
parent 1d635a9338
commit 4057cebb27
5 changed files with 35 additions and 124 deletions

View file

@ -64,7 +64,6 @@ services:
volumes:
- triton-manage-bins:/bins
- ${TLS_CERT_HOST_DIR:-/etc/triton/tls}:/etc/triton/tls:ro
- /etc/machine-id:/etc/machine-id:ro
ports:
- "${TRITON_MANAGE_HOST_PORT:-8082}:8082"
- "${TRITON_MANAGE_GATEWAY_HOST_PORT:-8443}:8443"

View file

@ -54,18 +54,5 @@ TLS_CERT_HOST_DIR=/etc/triton/tls
# ─── Sessions ────────────────────────────────────────────────────────────
TRITON_MANAGE_SESSION_TTL=24h
# ─── Licence ─────────────────────────────────────────────────────────────
# Offline licence token from your vendor bundle (license.lic). Set by
# install.sh automatically — do not edit manually.
TRITON_LICENSE_KEY=
# Vendor's Ed25519 public key (64 hex chars). Baked into the image at
# build time — leave empty unless you need to override the compiled-in key.
TRITON_MANAGE_LICENSE_SERVER_PUBKEY=
# Vendor's License Server URL. Optional — enables ongoing heartbeats and
# binary sync. Leave empty for fully air-gapped deployments.
TRITON_LICENSE_SERVER_URL=
# ─── Image ───────────────────────────────────────────────────────────────
TRITON_MANAGE_IMAGE=ghcr.io/primatekuntech/triton-manage-server:latest

View file

@ -5,42 +5,32 @@
# Container-based via Podman or Docker (auto-detected).
#
# Usage:
# sudo bash install.sh --license-file /path/to/bundle/license.lic
# sudo bash install.sh
#
# The license bundle (provided by your vendor) is a single file:
# license.lic — signed offline licence token
# The vendor's public key is baked into the image at build time.
#
# Flags:
# --license-file PATH Path to license.lic from your vendor bundle. Required.
# Flags (all optional):
# --gateway-hostname HOST Agent mTLS hostname (defaults to current FQDN).
# --manage-host-ip IP Host LAN IP — used for "+ This machine".
# --port PORT Host port for the web UI (default: 8082).
# --image TAG Pin a specific manage-server image tag.
# --no-tls Skip the TLS-required sanity check (dev).
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" &>/dev/null && pwd)"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
cd "$SCRIPT_DIR"
info() { printf '[manage-server] %s\n' "$*"; }
die() { printf '[manage-server] error: %s\n' "$*" >&2; exit 1; }
# ── arg parsing ──────────────────────────────────────────────────────────
LICENSE_FILE=""
GATEWAY_HOST=""
HOST_IP=""
PORT=""
IMAGE=""
NO_TLS=0
while [[ $# -gt 0 ]]; do
case "$1" in
--license-file) LICENSE_FILE="$2"; shift 2 ;;
--gateway-hostname) GATEWAY_HOST="$2"; shift 2 ;;
--manage-host-ip) HOST_IP="$2"; shift 2 ;;
--port) PORT="$2"; shift 2 ;;
--image) IMAGE="$2"; shift 2 ;;
--no-tls) NO_TLS=1; shift ;;
--gateway-hostname) GATEWAY_HOST="$2"; shift 2 ;;
--manage-host-ip) HOST_IP="$2"; shift 2 ;;
--image) IMAGE="$2"; shift 2 ;;
--no-tls) NO_TLS=1; shift ;;
-h|--help) grep '^#' "$0" | sed 's/^# //;s/^#//'; exit 0 ;;
*) die "unknown flag: $1 (try --help)" ;;
esac
@ -48,12 +38,6 @@ done
[[ $EUID -eq 0 ]] || die "must run as root"
# ── validate license bundle ──────────────────────────────────────────────
[[ -n "$LICENSE_FILE" ]] || die "--license-file is required (path to license.lic from your vendor bundle)"
[[ -f "$LICENSE_FILE" ]] || die "license file not found: $LICENSE_FILE"
LICENSE_TOKEN="$(cat "$LICENSE_FILE")"
# ── runtime detection ────────────────────────────────────────────────────
if command -v podman-compose >/dev/null 2>&1; then
COMPOSE=(podman-compose)
@ -87,15 +71,11 @@ if [[ ! -f "$ENV_FILE" ]]; then
-e "s|^TRITON_MANAGE_WORKER_KEY=.*|TRITON_MANAGE_WORKER_KEY=$WORKER_KEY|" \
-e "s|^TRITON_VAULT_KEY=.*|TRITON_VAULT_KEY=$VAULT_KEY|" \
"$ENV_FILE"
info "secrets generated"
sed -i "s|^TRITON_LICENSE_KEY=.*|TRITON_LICENSE_KEY=$LICENSE_TOKEN|" "$ENV_FILE"
info "licence configured"
info "vault key generated (PostgreSQL AES-256-GCM)"
[[ -n "$GATEWAY_HOST" ]] && sed -i "s|^TRITON_MANAGE_GATEWAY_HOSTNAME=.*|TRITON_MANAGE_GATEWAY_HOSTNAME=$GATEWAY_HOST|" "$ENV_FILE"
[[ -n "$HOST_IP" ]] && sed -i "s|^TRITON_MANAGE_HOST_IP=.*|TRITON_MANAGE_HOST_IP=$HOST_IP|" "$ENV_FILE"
[[ -n "$PORT" ]] && sed -i "s|^TRITON_MANAGE_HOST_PORT=.*|TRITON_MANAGE_HOST_PORT=$PORT|" "$ENV_FILE"
[[ -n "$IMAGE" ]] && sed -i "s|^TRITON_MANAGE_IMAGE=.*|TRITON_MANAGE_IMAGE=$IMAGE|" "$ENV_FILE"
[[ -n "$HOST_IP" ]] && sed -i "s|^TRITON_MANAGE_HOST_IP=.*|TRITON_MANAGE_HOST_IP=$HOST_IP|" "$ENV_FILE"
[[ -n "$IMAGE" ]] && sed -i "s|^TRITON_MANAGE_IMAGE=.*|TRITON_MANAGE_IMAGE=$IMAGE|" "$ENV_FILE"
info ".env created at $ENV_FILE"
info " back this up — it contains the JWT signing key, worker key, and vault key"
@ -103,10 +83,6 @@ else
info "reusing existing .env at $ENV_FILE"
fi
# ── pull latest image ────────────────────────────────────────────────────
info "pulling latest image..."
"${COMPOSE[@]}" --env-file "$ENV_FILE" pull manage-server
# ── start ────────────────────────────────────────────────────────────────
info "starting containers..."
"${COMPOSE[@]}" --env-file "$ENV_FILE" up -d
@ -118,6 +94,7 @@ HOST_PORT=${HOST_PORT:-8082}
info "waiting for manage server to become healthy on :${HOST_PORT}..."
for i in $(seq 1 30); do
CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${HOST_PORT}/" || echo "000")
# 302 (redirect to setup or login) means the server is up.
if [[ "$CODE" == "302" || "$CODE" == "200" ]]; then
info "manage server is up"
break
@ -128,29 +105,9 @@ done
info ""
info "Installation complete. Next steps:"
info " 1. Open http://localhost:${HOST_PORT} (or your public URL)"
info " 2. Complete the setup wizard"
info " 2. Complete the setup wizard:"
info " - Set your manage server name"
info " - Enter your Triton licence server URL and licence ID"
info " - Or upload an air-gap licence file"
info " 3. Configure TLS via reverse proxy (see docs)"
info ""
# ── machine ID ───────────────────────────────────────────────────────────
# Print the SHA-3-256 hash of /etc/machine-id so the customer can share
# it with the vendor when requesting an offline .lic bound to this host.
# The hash is stable: /etc/machine-id never changes after OS installation.
if [[ -f /etc/machine-id ]]; then
MACHINE_ID_RAW=$(cat /etc/machine-id | tr -d '[:space:]')
if command -v python3 >/dev/null 2>&1; then
MACHINE_ID_HASH=$(python3 -c "import hashlib; print(hashlib.sha3_256('${MACHINE_ID_RAW}'.encode()).hexdigest())")
elif command -v sha3sum >/dev/null 2>&1; then
MACHINE_ID_HASH=$(echo -n "$MACHINE_ID_RAW" | sha3sum -a 256 | awk '{print $1}')
elif command -v openssl >/dev/null 2>&1; then
MACHINE_ID_HASH=$(printf '%s' "${MACHINE_ID_RAW}" | openssl dgst -sha3-256 -hex 2>/dev/null | awk '{print $2}')
else
MACHINE_ID_HASH=""
fi
if [[ -n "$MACHINE_ID_HASH" ]]; then
info "── Host Machine ID ──────────────────────────────────────────────────────"
info " Provide this value to your vendor when requesting a host-bound .lic file."
info " Machine ID (SHA-3-256): $MACHINE_ID_HASH"
info "────────────────────────────────────────────────────────────────────────"
fi
fi

View file

@ -1,15 +1,15 @@
#!/usr/bin/env bash
# uninstall.sh — stop and remove Manage Server containers and image.
# uninstall.sh — stop and remove Manage Server containers.
#
# By default, KEEPS the PostgreSQL volume (scan history, hosts, users).
# Pass --purge-data to delete the volumes as well — irreversible.
#
# Usage:
# sudo bash uninstall.sh # stop + remove containers + image, keep DB
# sudo bash uninstall.sh # stop + remove containers, keep DB
# sudo bash uninstall.sh --purge-data # also delete DB + binaries volume
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" &>/dev/null && pwd)"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
cd "$SCRIPT_DIR"
info() { printf '[manage-server] %s\n' "$*"; }
@ -39,15 +39,11 @@ else
podman rm -f triton-manageserver triton-manage-db 2>/dev/null || true
fi
# ── remove image ──────────────────────────────────────────────────────────
IMAGE=$(grep -E '^TRITON_MANAGE_IMAGE=' .env 2>/dev/null | cut -d= -f2)
IMAGE=${IMAGE:-ghcr.io/primatekuntech/triton-manage-server:latest}
info "removing image ${IMAGE}..."
podman rmi "$IMAGE" 2>/dev/null || docker rmi "$IMAGE" 2>/dev/null || true
if [[ $PURGE -eq 1 ]]; then
info "DESTRUCTIVE: removing manage server volumes..."
info " this deletes: scan history, hosts, users, worker binaries"
read -r -p " Are you sure? Type 'yes' to confirm: " CONFIRM
[[ "$CONFIRM" == "yes" ]] || die "aborted"
for vol in triton-manage-db-data triton-manage-bins; do
podman volume rm -f "$vol" 2>/dev/null \
|| docker volume rm -f "$vol" 2>/dev/null \

View file

@ -1,16 +1,14 @@
#!/usr/bin/env bash
# upgrade.sh — pull the latest manage-server image and restart.
#
# Takes a pre-upgrade pg_dump backup. DB schema migrations run automatically
# on container startup — no manual migration step required.
# Takes a pre-upgrade pg_dump. DB schema migrations run on startup.
#
# Usage:
# sudo bash upgrade.sh # latest from ghcr.io
# sudo bash upgrade.sh --image TAG # pin a specific image tag
# sudo bash upgrade.sh --port PORT # change the web UI host port
# sudo bash upgrade.sh --image TAG # pin a specific image
set -euo pipefail
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]:-$0}")" &>/dev/null && pwd)"
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
cd "$SCRIPT_DIR"
info() { printf '[manage-server] %s\n' "$*"; }
@ -19,74 +17,48 @@ die() { printf '[manage-server] error: %s\n' "$*" >&2; exit 1; }
[[ $EUID -eq 0 ]] || die "must run as root"
[[ -f .env ]] || die ".env not found — run install.sh first"
# ── arg parsing ───────────────────────────────────────────────────────────
IMAGE=""
PORT=""
while [[ $# -gt 0 ]]; do
case "$1" in
--image) IMAGE="$2"; shift 2 ;;
--port) PORT="$2"; shift 2 ;;
-h|--help) grep '^#' "$0" | sed 's/^# //;s/^#//'; exit 0 ;;
*) die "unknown flag: $1" ;;
esac
done
# ── runtime detection ─────────────────────────────────────────────────────
if command -v podman-compose >/dev/null 2>&1; then COMPOSE=(podman-compose); RUNTIME=podman
elif podman compose version >/dev/null 2>&1; then COMPOSE=(podman compose); RUNTIME=podman
elif docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose); RUNTIME=docker
else die "no compose runtime found"; fi
# ── pin image if requested ────────────────────────────────────────────────
if [[ -n "$IMAGE" ]]; then
sed -i "s|^TRITON_MANAGE_IMAGE=.*|TRITON_MANAGE_IMAGE=$IMAGE|" .env
info "pinned image to $IMAGE"
fi
if [[ -n "$PORT" ]]; then
sed -i "s|^TRITON_MANAGE_HOST_PORT=.*|TRITON_MANAGE_HOST_PORT=$PORT|" .env
info "host port set to $PORT"
fi
# ── pre-upgrade DB backup ─────────────────────────────────────────────────
case "$(uname -s)" in
Linux) BACKUP_DIR="/var/backups/triton" ;;
Darwin) BACKUP_DIR="${HOME}/Library/Application Support/triton/backups" ;;
*) BACKUP_DIR="$SCRIPT_DIR/backups" ;;
esac
mkdir -p "$BACKUP_DIR"
DUMP_FILE="${BACKUP_DIR}/manage-pre-upgrade-$(date +%F-%H%M%S).sql.gz"
if command -v podman-compose >/dev/null 2>&1; then COMPOSE=(podman-compose)
elif podman compose version >/dev/null 2>&1; then COMPOSE=(podman compose)
elif docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose)
else die "no compose runtime found"; fi
info "pre-upgrade DB backup..."
PG_USER=$(grep -E '^POSTGRES_USER=' .env | cut -d= -f2)
PG_USER=${PG_USER:-triton}
PG_DB=$(grep -E '^POSTGRES_DB=' .env | cut -d= -f2)
PG_DB=${PG_DB:-triton_manage}
mkdir -p /var/backups/triton
DUMP_FILE="/var/backups/triton/manage-pre-upgrade-$(date +%F-%H%M%S).sql.gz"
podman exec triton-manage-db pg_dump -U triton triton_manage 2>/dev/null \
| gzip > "$DUMP_FILE" || die "pg_dump failed — aborting upgrade"
info " saved: $DUMP_FILE"
"$RUNTIME" exec triton-manage-db pg_dump -U "$PG_USER" "$PG_DB" 2>/dev/null \
| gzip > "$DUMP_FILE" || die "pg_dump failed — aborting upgrade (DB container may not be running)"
info " backup saved: $DUMP_FILE"
# ── pull new image ────────────────────────────────────────────────────────
info "pulling latest image..."
"${COMPOSE[@]}" --env-file .env pull manage-server
# ── recreate container (DB migrations run on startup) ─────────────────────
info "recreating manage-server container..."
info " DB schema migrations will run automatically on startup"
"${COMPOSE[@]}" --env-file .env up -d --no-deps manage-server
# ── wait for healthy (confirms migrations succeeded) ──────────────────────
HOST_PORT=$(grep -E '^TRITON_MANAGE_HOST_PORT=' .env | cut -d= -f2)
HOST_PORT=${HOST_PORT:-8082}
info "waiting for server to become healthy on :${HOST_PORT}..."
info "waiting for new container to become healthy..."
for i in $(seq 1 30); do
CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost:${HOST_PORT}/" || echo "000")
if [[ "$CODE" == "302" || "$CODE" == "200" ]]; then
info "upgrade complete — server is healthy (migrations applied)"
info " rollback if needed: gunzip -c ${DUMP_FILE} | $RUNTIME exec -i triton-manage-db psql -U ${PG_USER} ${PG_DB}"
info "upgrade complete"
exit 0
fi
sleep 2
done
die "server did not become healthy in 60s — check logs: $RUNTIME logs triton-manageserver"
die "new container did not become healthy in 60s — check logs"