#!/usr/bin/env bash # Build the meshbay-hub package: hub-specific files on top of meshbay-common. # # Expects build-common.sh to have run first (shared venv exists in staging). # # Usage: ./build-hub.sh [staging-dir] set -euo pipefail REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" STAGING="${1:-/tmp/meshbay-build}" COMMON_ROOT="$STAGING/meshbay-common-root" ROOT="$STAGING/meshbay-hub-root" VENV="$COMMON_ROOT/opt/meshbay-common/venv" PYVER=$(basename "$VENV"/lib/python3.*) SITE="$VENV/lib/$PYVER/site-packages" VERSION=$(python3 -c " import tomllib, pathlib p = pathlib.Path('$REPO/packages/meshbay-hub/pyproject.toml') print(tomllib.loads(p.read_text())['project']['version']) ") echo "==> meshbay-hub $VERSION" [ -d "$VENV" ] || { echo "!! shared venv not found — run build-common.sh first" >&2; exit 1; } rm -rf "$ROOT" mkdir -p "$ROOT" # --- Hub code in the shared venv (owned by meshbay-hub package) ----------- # MOVE (not copy) from the common staging tree so dpkg/rpm knows these files # belong to meshbay-hub, not meshbay-common. build-common.sh installed them # so that shebangs and dependency resolution are correct. HUB_ROOT="$ROOT/opt/meshbay-common/venv/lib/$PYVER/site-packages" mkdir -p "$HUB_ROOT" mv "$SITE/meshbay_hub" "$HUB_ROOT/" mv "$SITE"/meshbay_hub-*.dist-info "$HUB_ROOT/" # Entry point mkdir -p "$ROOT/opt/meshbay-common/venv/bin" mv "$VENV/bin/meshbay-hub" "$ROOT/opt/meshbay-common/venv/bin/" # Symlink in PATH mkdir -p "$ROOT/usr/bin" ln -sf /opt/meshbay-common/venv/bin/meshbay-hub "$ROOT/usr/bin/meshbay-hub" # --- Hub-specific assets -------------------------------------------------- mkdir -p "$ROOT/opt/meshbay-hub" # No alembic.ini is staged. It resolves `script_location` with `%(here)s`, so a # copy of it is only correct where it was copied from: staged into # /opt/meshbay-hub/migrations/ it pointed at # /opt/meshbay-hub/migrations/src/meshbay_hub/db/migrations, which nothing # installs — the migrations live inside the package, in the shared venv. The # unit runs `meshbay-hub migrate` instead, which asks the package. # # The same `%(here)s` trap had already been found once on the server, where a # stray alembic.ini resolved to a month-old snapshot of the tree. # Config example. # # A hard failure, not an `if [ -f ]`. This was a silent skip against a path # that did not exist, so every package built shipped no example config at all # and said nothing about it — and the postinst places no config either, on # purpose, which left an installed hub with nothing to copy from. EXAMPLE="$REPO/packaging/conf/hub.toml.example" [ -f "$EXAMPLE" ] || { echo "!! missing $EXAMPLE" >&2; exit 1; } mkdir -p "$ROOT/opt/meshbay-hub/share" install -m 644 "$EXAMPLE" "$ROOT/opt/meshbay-hub/share/" # Also next to the real config, where an operator looks first. Never # hub.toml itself: an upgrade would overwrite a working deployment. # # Modes are set here rather than left to the builder's umask, which decided # them until now — 775/664 on a machine with umask 002, 755/644 on one with # 022, from the same source tree. The postinst tightens the directory too, but # that then repairs the package instead of the package being right. install -d -m 750 "$ROOT/etc/meshbay" install -m 644 "$ROOT/opt/meshbay-hub/share/hub.toml.example" "$ROOT/etc/meshbay/" # --- Systemd unit --------------------------------------------------------- mkdir -p "$ROOT/usr/lib/systemd/system" cp "$REPO/packaging/systemd/meshbay-hub.service" \ "$ROOT/usr/lib/systemd/system/meshbay-hub.service" echo "==> meshbay-hub staging ready at $ROOT"