Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 45715b61ea | |||
| 54ebb83bb1 | |||
| a67d972217 | |||
| 875ea874b4 | |||
| 119f21b821 | |||
| 80275c42e4 | |||
| a30deae866 | |||
| dc9a7ff9c4 | |||
| 7937d6cf92 | |||
| 21333de814 | |||
| b3bdebe1c9 | |||
| e6b318e28e |
@@ -8,6 +8,17 @@ orchestration code; see each submodule's own `CHANGELOG.md`
|
||||
[sso-manager-node](https://github.com/theta42/sso-manager-node/blob/master/CHANGELOG.md))
|
||||
for what changed inside the apps it composes.
|
||||
|
||||
## [v1.35.2] - 2026-08-03
|
||||
|
||||
### Fixed
|
||||
- **Unbound `CFG_CREATE_ALL_HTTP` variable in `setup.sh`** — Fixed unbound variable error during host registration in `setup.sh` when `ensure_secrets_files()` is skipped on pre-configured installations.
|
||||
|
||||
## [v1.35.1] - 2026-08-03
|
||||
|
||||
### Fixed
|
||||
- **Directory & Configuration UI enhancements** — Live Cytoscape graph update on parent/child edge modifications, improved discovery reconciler host matching, updated configuration sidebar layout, relocated discovery and messaging plugins to Directory and Configuration pages.
|
||||
- **Managed Host Target Filter** — Filter SSH connection targets in Jump Host to managed hosts only.
|
||||
|
||||
## [v1.35.0] - 2026-08-02
|
||||
|
||||
### Added
|
||||
|
||||
Vendored
+2
@@ -423,10 +423,12 @@ async function seedDirectory(token, clientId, jumpClientId) {
|
||||
const host = await ensure('host', HOST_FACTS.name || 'Stack host', hostSlug, site.id, {
|
||||
subType: 'linux',
|
||||
ip: HOST_FACTS.ip,
|
||||
address: HOST_FACTS.ip,
|
||||
macAddress: HOST_FACTS.mac,
|
||||
os: HOST_FACTS.os,
|
||||
kernel: HOST_FACTS.kernel,
|
||||
sshPort: 22,
|
||||
managed: true,
|
||||
}, ['stack-host']);
|
||||
await ensure('service', 'SSO Manager', 'sso-manager', host.id, {
|
||||
address: `https://${SSO_HOST}`,
|
||||
|
||||
+1
-1
Submodule jump-host updated: c56bfe21e5...8c4ec67282
+1
-1
Submodule proxy updated: 62cdaa2cdd...eb08b6b5b9
@@ -106,6 +106,13 @@ env_upsert() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Read KEY= from ./.env (empty if absent)
|
||||
env_get() {
|
||||
local key="$1" file=./.env
|
||||
[[ -f "$file" ]] || return 0
|
||||
grep -m1 "^${key}=" "$file" 2>/dev/null | cut -d= -f2- || true
|
||||
}
|
||||
|
||||
# Detect docker compose (v2 plugin `docker compose` or v1 standalone `docker-compose`).
|
||||
if docker compose version >/dev/null 2>&1; then
|
||||
COMPOSE=(docker compose)
|
||||
@@ -178,6 +185,8 @@ fi
|
||||
# resolved in ensure_config; this is only the hostname override.
|
||||
[[ -f ./setup.env ]] && parse_kv_file ./setup.env
|
||||
export CFG_JUMP_HOST
|
||||
CFG_CREATE_ALL_HTTP="${CFG_CREATE_ALL_HTTP:-0}"
|
||||
export CFG_CREATE_ALL_HTTP
|
||||
|
||||
# ── Optional outbound HTTP(S) proxy for docker build + the running containers ─
|
||||
# CFG_HTTP_PROXY / CFG_HTTPS_PROXY / CFG_NO_PROXY (from ./setup.env or the
|
||||
@@ -686,13 +695,37 @@ fi
|
||||
|
||||
status_json=$(docker exec openbao bao status -format=json 2>/dev/null || true)
|
||||
if echo "$status_json" | grep -q '"sealed": true'; then
|
||||
info "Unsealing openbao..."
|
||||
UNSEAL_KEY=$(grep -A1 '"unseal_keys_b64":' "$CONFIG_DIR/bao-init.json" | tail -n1 | cut -d'"' -f2)
|
||||
docker exec openbao bao operator unseal "$UNSEAL_KEY" >/dev/null
|
||||
UNSEAL_KEY=""
|
||||
if [[ -f "$CONFIG_DIR/bao-init.json" ]]; then
|
||||
UNSEAL_KEY=$(grep -A1 '"unseal_keys_b64":' "$CONFIG_DIR/bao-init.json" 2>/dev/null | tail -n1 | cut -d'"' -f2 || true)
|
||||
fi
|
||||
if [[ -z "$UNSEAL_KEY" ]]; then
|
||||
UNSEAL_KEY="$(env_get VAULT_UNSEAL_KEY)"
|
||||
fi
|
||||
|
||||
if [[ -n "$UNSEAL_KEY" ]]; then
|
||||
info "Unsealing openbao..."
|
||||
docker exec openbao bao operator unseal "$UNSEAL_KEY" >/dev/null
|
||||
else
|
||||
die "OpenBao is sealed, but no unseal key was found in $CONFIG_DIR/bao-init.json or .env (VAULT_UNSEAL_KEY)."
|
||||
fi
|
||||
fi
|
||||
|
||||
export VAULT_TOKEN
|
||||
VAULT_TOKEN=$(grep '"root_token":' "$CONFIG_DIR/bao-init.json" | cut -d'"' -f4)
|
||||
if [[ -f "$CONFIG_DIR/bao-init.json" ]]; then
|
||||
VAULT_TOKEN=$(grep '"root_token":' "$CONFIG_DIR/bao-init.json" 2>/dev/null | cut -d'"' -f4 || true)
|
||||
fi
|
||||
if [[ -z "$VAULT_TOKEN" ]]; then
|
||||
VAULT_TOKEN="$(env_get VAULT_TOKEN)"
|
||||
fi
|
||||
|
||||
if [[ -z "$VAULT_TOKEN" ]]; then
|
||||
die "Could not determine OpenBao VAULT_TOKEN from $CONFIG_DIR/bao-init.json or .env."
|
||||
fi
|
||||
|
||||
if [[ -n "$UNSEAL_KEY" ]]; then
|
||||
env_upsert VAULT_UNSEAL_KEY "$UNSEAL_KEY"
|
||||
fi
|
||||
env_upsert VAULT_TOKEN "$VAULT_TOKEN"
|
||||
|
||||
if ! docker exec -e BAO_TOKEN="$VAULT_TOKEN" openbao bao secrets list -format=json 2>/dev/null | grep -q '"secret/":'; then
|
||||
@@ -722,21 +755,6 @@ ensure_policy() {
|
||||
docker exec -i -e BAO_TOKEN="$VAULT_TOKEN" openbao bao policy write "$name" - >/dev/null
|
||||
}
|
||||
|
||||
# Read KEY= from ./.env (empty if absent) — reuse a previously minted token
|
||||
# instead of minting a fresh one on every setup.sh run.
|
||||
env_get() {
|
||||
local key="$1" file=./.env
|
||||
[[ -f "$file" ]] || return 0
|
||||
# `|| true` is load-bearing: under `set -euo pipefail`, a no-match `grep`
|
||||
# exits 1 and (pipefail) makes the whole pipeline return 1. Callers do
|
||||
# `existing="$(env_get ...)"` as a bare assignment — a non-zero return there
|
||||
# trips `set -e` and silently kills the whole script (this is exactly what
|
||||
# aborted a fresh install right after "Minting per-app OpenBao tokens": the
|
||||
# root VAULT_TOKEN env_upsert had already created .env, but the app-token
|
||||
# keys were absent, so the first env_get returned 1). "Key absent" is the
|
||||
# normal path here, so always return 0 with empty output.
|
||||
grep -m1 "^${key}=" "$file" 2>/dev/null | cut -d= -f2- || true
|
||||
}
|
||||
|
||||
# Mint an orphan, renewable token for `policy` and persist it to .env as `key`,
|
||||
# OR reuse the token already in .env if it is still valid (re-mint on expiry).
|
||||
@@ -978,7 +996,7 @@ async function ensureHost(host, ip, targetPort) {
|
||||
host: host,
|
||||
ip: ip,
|
||||
targetPort: targetPort,
|
||||
forcessl: $( [[ "$CFG_CREATE_ALL_HTTP" == "1" ]] && echo false || echo true ),
|
||||
forcessl: $( [[ "${CFG_CREATE_ALL_HTTP:-0}" == "1" ]] && echo false || echo true ),
|
||||
targetssl: false,
|
||||
sso_enabled: false,
|
||||
created_by: 'setup.sh',
|
||||
@@ -1035,7 +1053,7 @@ const {Host} = require('/app/models').models;
|
||||
try { await Host.get($(js_str "$JUMP_HOST")); console.log('SKIP ${JUMP_HOST} (already exists)'); }
|
||||
catch (e) {
|
||||
if (e.name !== 'EntryNotFound') throw e;
|
||||
await Host.create({ host: $(js_str "$JUMP_HOST"), ip: 'jump-host', targetPort: 3002, forcessl: $( [[ "$CFG_CREATE_ALL_HTTP" == "1" ]] && echo false || echo true ), targetssl: false, sso_enabled: false, created_by: 'setup.sh' });
|
||||
await Host.create({ host: $(js_str "$JUMP_HOST"), ip: 'jump-host', targetPort: 3002, forcessl: $( [[ "${CFG_CREATE_ALL_HTTP:-0}" == "1" ]] && echo false || echo true ), targetssl: false, sso_enabled: false, created_by: 'setup.sh' });
|
||||
console.log('CREATED ${JUMP_HOST} -> jump-host:3002');
|
||||
}
|
||||
process.exit(0);
|
||||
@@ -1064,7 +1082,7 @@ if [[ "$CFG_THETA_AGENT_ENABLE" == "1" ]]; then
|
||||
AGENT_TOKEN="$(rand_hex 16)"
|
||||
sudo sed -i "s/REPLACE_WITH_AGENT_TOKEN/$AGENT_TOKEN/" /etc/theta/agent.yml
|
||||
# We want to connect to either https or http depending on CFG_CREATE_ALL_HTTP
|
||||
if [[ "$CFG_CREATE_ALL_HTTP" == "1" ]]; then
|
||||
if [[ "${CFG_CREATE_ALL_HTTP:-0}" == "1" ]]; then
|
||||
sudo sed -i "s|https://sso.example.com|http://${SSO_HOST}|" /etc/theta/agent.yml
|
||||
else
|
||||
sudo sed -i "s|https://sso.example.com|https://${SSO_HOST}|" /etc/theta/agent.yml
|
||||
|
||||
+1
-1
Submodule sso-manager-node updated: 8143ef8ca8...d802c399a3
+1
-1
Submodule theta-agent updated: 821ce5f991...6500fadafb
Reference in New Issue
Block a user