Follows the copyparty/ergo updater idiom -- check/update/run/install/uninstall, a conf file the environment overrides, the version pinned into .env so the running release is explicit, DRY_RUN -- but inverts its central assumption. copyparty and ergo come back by themselves after a recreate. OpenBao comes back SEALED: with the default Shamir seal a restart needs three unseal keys typed in by a human. A scheduled `latest` update would therefore take the vault offline at 03:00 and leave it there. So the scheduled path defaults to UPDATE_POLICY= notify and never changes the running version; `install` schedules a daily CHECK and says so. UPDATE_POLICY=auto opts in, and is STILL refused unless an uncommented `seal` stanza is present in config.hcl -- only auto-unseal makes an unattended update defensible. `update` preflights before touching anything, because every one of these fails worse halfway through than up front: - the container must be running; - the vault must be UNSEALED, since a sealed vault cannot produce a snapshot and there would be no rollback plan; - BAO_TOKEN must be present, because the snapshot is token-gated on sys/storage/raft/snapshot; - the target must not cross into 2.7.x while a built-in seal "pkcs11" stanza is active. That stanza is REMOVED in 2.7.0, not deprecated, so the vault would start with no way to unseal at all. The snapshot is the rollback plan, not a formality: OpenBao's upgrade guide states that reverting the image alone does not roll back the data store. It is streamed out with `exec -T ... cat` rather than `compose cp`, which emits a TAR wrapper that will not restore; written 0600 to /var/backups/openbao; and checked for being a non-empty valid gzip archive, with a failure treated as fatal. SKIP_SNAPSHOT=1 exists and warns exactly what it costs. A failed pull or start rolls the OPENBAO_TAG pin back and restarts the previous version. BAO_TOKEN is deliberately never written to the conf file: a long-lived root token sitting next to the vault it opens defeats the vault. Verified: the 2.7-with-active-pkcs11 refusal and its three negative cases (2.6.2 active, 3.x active, 2.7 commented); auto-unseal detection distinguishing a commented stanza from a live one; set_env/env_get; the release-tag parse with and without a leading v; and all four `run` policy branches, including that auto refuses without auto-unseal and that an unknown policy dies. Not verified without a live host: the snapshot, pull and recreate themselves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
35 lines
939 B
Bash
35 lines
939 B
Bash
#!/usr/bin/env bash
|
|
#
|
|
# build.sh -- (re)embed docker-compose.yml, config.hcl, gen-tls.sh and
|
|
# .env.example into deploy.sh as a base64-encoded tar.gz payload after
|
|
# __ARCHIVE_BELOW__. Idempotent: strips any existing payload first.
|
|
|
|
set -euo pipefail
|
|
|
|
DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
SCRIPT="$DIR/deploy.sh"
|
|
MARKER="__ARCHIVE_BELOW__"
|
|
|
|
[[ -f "$SCRIPT" ]] || { echo "deploy.sh not found at $SCRIPT" >&2; exit 1; }
|
|
for f in docker-compose.yml config.hcl gen-tls.sh update.sh .env.example; do
|
|
[[ -f "$DIR/$f" ]] || { echo "Missing $DIR/$f" >&2; exit 1; }
|
|
done
|
|
|
|
PAYLOAD=$(tar -czf - -C "$DIR" docker-compose.yml config.hcl gen-tls.sh update.sh .env.example | base64)
|
|
|
|
TMP=$(mktemp)
|
|
trap 'rm -f "$TMP"' EXIT
|
|
|
|
sed "/^${MARKER}\$/,\$d" "$SCRIPT" > "$TMP"
|
|
{
|
|
echo "$MARKER"
|
|
echo "$PAYLOAD"
|
|
} >> "$TMP"
|
|
|
|
mv "$TMP" "$SCRIPT"
|
|
chmod +x "$SCRIPT"
|
|
trap - EXIT
|
|
|
|
size=$(wc -c < "$SCRIPT")
|
|
echo "Built $SCRIPT (${size} bytes)"
|