Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
# Fast release build of trace-commons-ingest for the pilot host.
# Fast release build of the pilot binaries (trace-commons-ingest AND
# trace-commons-upload-claim-issuer) for the pilot host.
#
# The pilot host (tc-pilot-host) is Ubuntu 24.04 (glibc 2.39, OpenSSL 3). This
# builds on a matching ubuntu:24.04 image on a high-CPU machine and pushes the
# builds on a matching ubuntu:24.04 image on a high-CPU machine and pushes each
# binary to GCS for the host to pull (deploy/pilot-gcp/pull-and-install.sh).
#
# The ONNX runtime (ort/fastembed) is statically linked (ort downloads
# libonnxruntime.a at build time), so the only runtime deps are standard
# Ubuntu 24.04 system libs that the host already has.
# BOTH binaries are built because the pilot runs both services and changes can
# land in either: ingest (account API + the migration runner that applies V30+
# on boot) or the issuer (EdDSA upload claims, device-key registration, the
# per-user `subject` derivation, and the instance-enroll `/v1/enroll` handler).
# ingest builds with the cloud features; the issuer builds without them (it does
# not use GCS/KMS/NEAR-AI), matching the operator runbook. The ONNX runtime
# (ort/fastembed, ingest only) is statically linked.
#
# Run:
# gcloud builds submit --config cloudbuild.yaml \
# --project tracecommons-pilot-2026 \
# --substitutions _TAG=$(git rev-parse --short HEAD)
#
# (a .gcloudignore keeps target/ and .git out of the source upload.)

substitutions:
_TAG: 'manual' # short SHA or tag; defaults to BUILD_ID below if 'manual'
Expand All @@ -36,9 +39,13 @@ steps:
. "$$HOME/.cargo/env"
cargo build --release --bin trace-commons-ingest \
--features gcs-client,gcp-kms,near-ai-scorer
# Reuses the deps compiled above; the issuer takes no features.
cargo build --release --bin trace-commons-upload-claim-issuer
mkdir -p /workspace/out
cp target/release/trace-commons-ingest /workspace/out/trace-commons-ingest
( cd /workspace/out && sha256sum trace-commons-ingest > trace-commons-ingest.sha256 )
for b in trace-commons-ingest trace-commons-upload-claim-issuer; do
cp "target/release/$$b" "/workspace/out/$$b"
( cd /workspace/out && sha256sum "$$b" > "$$b.sha256" )
done

- name: 'gcr.io/cloud-builders/gcloud'
id: publish
Expand All @@ -48,15 +55,16 @@ steps:
- |
set -euxo pipefail
TAG="${_TAG}"; [ "$$TAG" = "manual" ] && TAG="${BUILD_ID}"
DEST="gs://${_BUCKET}/binaries/trace-commons-ingest/$$TAG"
gcloud storage cp /workspace/out/trace-commons-ingest "$$DEST/trace-commons-ingest"
gcloud storage cp /workspace/out/trace-commons-ingest.sha256 "$$DEST/trace-commons-ingest.sha256"
# latest pointer the host's pull script reads
printf '%s' "$$DEST/trace-commons-ingest" \
| gcloud storage cp - "gs://${_BUCKET}/binaries/trace-commons-ingest/latest.txt"
echo "published: $$DEST/trace-commons-ingest"
for b in trace-commons-ingest trace-commons-upload-claim-issuer; do
DEST="gs://${_BUCKET}/binaries/$$b/$$TAG"
gcloud storage cp "/workspace/out/$$b" "$$DEST/$$b"
gcloud storage cp "/workspace/out/$$b.sha256" "$$DEST/$$b.sha256"
# latest pointer the host's pull script reads
printf '%s' "$$DEST/$$b" | gcloud storage cp - "gs://${_BUCKET}/binaries/$$b/latest.txt"
echo "published: $$DEST/$$b"
done

options:
machineType: 'E2_HIGHCPU_32'
diskSizeGb: 120
timeout: '3000s'
timeout: '3600s'
87 changes: 53 additions & 34 deletions deploy/pilot-gcp/pull-and-install.sh
Original file line number Diff line number Diff line change
@@ -1,46 +1,65 @@
#!/usr/bin/env bash
# Pull a Cloud Build-produced trace-commons-ingest binary from GCS and install it
# on the pilot host, then restart the service. Pairs with cloudbuild.yaml.
# Pull Cloud Build-produced binaries from GCS and install them on the pilot host,
# restarting the services. Pairs with cloudbuild.yaml.
#
# The pilot runs two services; both can change, so this deploys BOTH by default:
# - trace-commons-upload-claim-issuer (EdDSA claims, device-key registration,
# per-user subject, /v1/enroll; serves the JWKS the ingest verifies at boot)
# - trace-commons-ingest (account API; applies migrations on boot)
# The issuer is installed first so its (possibly rotated) JWKS is up before ingest
# restarts and fetches it.
#
# Usage (on tc-pilot-host):
# deploy/pilot-gcp/pull-and-install.sh [<gs://.../trace-commons-ingest>]
# With no arg it reads the `latest.txt` pointer the build publishes.
# deploy/pilot-gcp/pull-and-install.sh # both binaries (default)
# deploy/pilot-gcp/pull-and-install.sh ingest # just ingest
# deploy/pilot-gcp/pull-and-install.sh issuer # just the issuer
#
# Verifies the sha256 sidecar, backs up the running binary, installs, and
# restarts trace-commons-ingest (which auto-applies any pending migrations).
# Each install verifies the sha256 sidecar, backs up the running binary, installs,
# and restarts the service. Reads the per-binary `latest.txt` pointer the build
# publishes.
set -euo pipefail

BUCKET="${TC_ARTIFACT_BUCKET:-tc-pilot-artifacts-20260518}"
BIN_DEST="/opt/tracecommons/bin/trace-commons-ingest"
LATEST="gs://${BUCKET}/binaries/trace-commons-ingest/latest.txt"

SRC="${1:-}"
if [ -z "$SRC" ]; then
SRC="$(gcloud storage cat "$LATEST")"
fi
echo "Pulling: $SRC"

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
gcloud storage cp "$SRC" "$TMP/trace-commons-ingest"
gcloud storage cp "${SRC}.sha256" "$TMP/trace-commons-ingest.sha256" || true
install_one() {
local bin="$1" svc="$2"
local latest="gs://${BUCKET}/binaries/${bin}/latest.txt"
local src
src="$(gcloud storage cat "$latest")"
echo "[$bin] pulling: $src"

if [ -f "$TMP/trace-commons-ingest.sha256" ]; then
( cd "$TMP" && awk '{print $1" trace-commons-ingest"}' trace-commons-ingest.sha256 | sha256sum -c - )
echo "sha256 verified"
else
echo "WARNING: no sha256 sidecar found; skipping checksum verification" >&2
fi
local tmp
tmp="$(mktemp -d)"
gcloud storage cp "$src" "$tmp/$bin"
if gcloud storage cp "${src}.sha256" "$tmp/$bin.sha256" 2>/dev/null; then
( cd "$tmp" && sha256sum -c "$bin.sha256" )
echo "[$bin] sha256 verified"
else
echo "[$bin] WARNING: no sha256 sidecar; skipping checksum" >&2
fi
chmod 0755 "$tmp/$bin"

chmod 0755 "$TMP/trace-commons-ingest"
"$TMP/trace-commons-ingest" --version 2>/dev/null || true
local stamp dest
stamp="$(date -u +%Y%m%dT%H%M%SZ)"
dest="/opt/tracecommons/bin/$bin"
sudo cp -av "$dest" "${dest}.bak-${stamp}"
sudo install -o root -g root -m 0755 "$tmp/$bin" "$dest"
rm -rf "$tmp"
echo "[$bin] installed $dest"

STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
sudo cp -av "$BIN_DEST" "${BIN_DEST}.bak-${STAMP}"
sudo install -o root -g root -m 0755 "$TMP/trace-commons-ingest" "$BIN_DEST"
echo "installed $BIN_DEST"
sudo systemctl restart "$svc"
sleep 8
echo "[$bin] $(systemctl is-active "$svc")"
echo "[$bin] rollback: sudo install -m0755 ${dest}.bak-${stamp} ${dest} && sudo systemctl restart $svc"
}

sudo systemctl restart trace-commons-ingest
sleep 10
systemctl is-active trace-commons-ingest
echo "done; rollback with: sudo install -m0755 ${BIN_DEST}.bak-${STAMP} ${BIN_DEST} && sudo systemctl restart trace-commons-ingest"
case "${1:-both}" in
ingest) install_one trace-commons-ingest trace-commons-ingest ;;
issuer) install_one trace-commons-upload-claim-issuer trace-commons-upload-claim-issuer ;;
both)
install_one trace-commons-upload-claim-issuer trace-commons-upload-claim-issuer
install_one trace-commons-ingest trace-commons-ingest
;;
*) echo "usage: $0 [both|ingest|issuer]" >&2; exit 2 ;;
esac
echo "done."