Files
operator/scripts/migrate-v0.2-to-v0.3.sh
zeekayandGitHub 769bf001d7 feat: bring hanzoai/operator to bootno.de/v1 Kind parity with bootnode/operator (#6)
Aligns the Rust kube-rs operator's CRD surface with the Go
bootnode/operator canonical at `bootno.de/v1`. After this change either
operator, deployed in a cluster, serves identical Kind coverage for all
26 canonical Kinds (the Rust additionally exposes 3 documented Hanzo
compat facades -> 29 total, a superset).

Parity gaps closed:

1. Kind name: `LuxNetwork` -> `LuxRuntime`. The Rust had ported the
   entire Go `LuxRuntime` spec/status/sub-specs faithfully but exposed
   the Kind under the wrong name (`luxnetworks`/`luxnet`). Renamed to the
   canonical `LuxRuntime` (plural `luxruntimes`, shortname `lrt`,
   singular `luxruntime`) to match `bootno.de/v1` exactly. Spec schema
   was already byte-identical; only the Kind envelope changed.

2. Kind name: `Base` -> `BaseApp`. Same situation — the `BaseSpec`
   schema already matched Go `BaseAppSpec` field-for-field (17 fields),
   but the Kind was exposed as `bases`/`base`. Renamed to canonical
   `BaseApp` (plural `baseapps`, shortname `bapp`).

3. Missing field: `LuxRuntimeSpec.replication`. Ported Go `ReplicationSpec`
   (native ZAP replication: CDC incrementals + physical snapshots to S3,
   ML-KEM-768 client-side encryption, restore-on-boot) — 12 fields,
   byte-identical JSON tags including the non-default `s3UseSsl` casing.

Build fix (root cause of broken build):

- `.gitignore` had a too-broad `bin/` rule (Go-scaffold leftover) that
  swallowed the Rust `src/bin/` source dir, so the `generate-crd-yaml`
  binary referenced by Cargo.toml was never committed and `cargo build`
  failed at target resolution. Anchored the rule to `/bin/`.
- Added the real `src/bin/generate_crd_yaml.rs` CRD generator: enumerates
  all 29 Kinds in canonical order, rewrites the API group for white-label
  universes (`--api-group` / `OPERATOR_API_GROUP`), emits the multi-doc
  bundle. Replaces the `echo 'fn main(){}'` Docker stub as the single
  source of truth for `k8s/crds/all-*.yaml`.

Regenerated all 4 white-label bundles (hanzo.ai / lux.cloud / zoo.cloud /
osage.cloud) from the generator — now deterministic, not hand-edited.

Verification:
- All 26 canonical Kinds match bootnode (plural + status subresource +
  shortname). `LuxRuntime` and `BaseApp` OpenAPI v3 spec property sets
  diff-clean against the Go source structs.
- `cargo build --release`, `cargo test` (57 tests), `cargo clippy
  -D warnings`, `cargo fmt --check` all clean.

No `bootno.de/v1` API-version change. No wire-format change beyond the
two Kind-envelope renames that align Rust to the Go canonical. Pure Rust,
no CGO.
2026-06-19 20:28:58 -07:00

64 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Migrate v0.2.x CRs to v0.3.0 schema.
#
# v0.2.x had legacy compat Kinds (HanzoService/HanzoDatastore/HanzoDNS).
# v0.3.0+ collapses those to the unprefixed canonical Kinds:
# HanzoService → Service
# HanzoDatastore → Datastore
# HanzoDNS → DNS
#
# The BaseApp Kind keeps its canonical name across v0.2 → v0.4 (it matches
# the `bootno.de/v1` canonical `BaseApp`), so no Kind rewrite is needed for
# BaseApp CRs.
#
# This script rewrites every legacy CR in the cluster to its unprefixed
# equivalent. Idempotent. Defaults to dry-run; set DRY_RUN=false to apply.
#
# Run BEFORE deploying ghcr.io/hanzoai/operator:v0.3.0 to cluster.
set -euo pipefail
DRY_RUN="${DRY_RUN:-true}"
CONTEXT="${KUBE_CONTEXT:-do-sfo3-hanzo-k8s}"
NAMESPACE="${NAMESPACE:--A}" # -A means all namespaces
if [ "$DRY_RUN" = "true" ]; then
APPLY_FLAGS="--dry-run=client -o yaml"
echo "DRY RUN — no changes applied. Set DRY_RUN=false to apply."
else
APPLY_FLAGS=""
fi
migrate_kind() {
local OLD="$1"
local NEW="$2"
echo "=== ${OLD} → ${NEW} ==="
if ! kubectl --context="${CONTEXT}" get "${OLD}.hanzo.ai" ${NAMESPACE} >/dev/null 2>&1; then
echo " no ${OLD} CRs found, skipping"
return
fi
kubectl --context="${CONTEXT}" get "${OLD}.hanzo.ai" ${NAMESPACE} -o json \
| jq --arg new "${NEW}" '
.items[]
| .kind = $new
| .apiVersion = "hanzo.ai/v1"
| del(.status, .metadata.resourceVersion, .metadata.uid,
.metadata.generation, .metadata.creationTimestamp,
.metadata.managedFields, .metadata.ownerReferences)
' \
| kubectl --context="${CONTEXT}" apply ${APPLY_FLAGS} -f -
}
migrate_kind HanzoService Service
migrate_kind HanzoDatastore Datastore
migrate_kind HanzoDNS DNS
if [ "$DRY_RUN" = "false" ]; then
echo ""
echo "=== Migration complete. Delete legacy CRs once v0.3.0 is verified live: ==="
echo " kubectl --context=${CONTEXT} delete hanzoservices.hanzo.ai -A"
echo " kubectl --context=${CONTEXT} delete hanzodatastores.hanzo.ai -A"
echo " kubectl --context=${CONTEXT} delete hanzodns.hanzo.ai -A"
fi