* deploy(lux-devnet): bump luxd → v1.27.23 (proto v1.0.2 unblocks build)
v1.27.22 had a build error from the kill-subnet rename in
luxfi/node#116: proto/p2p/p2p_zap.go aliased p2p.ChainUptime but
the upstream luxfi/proto package still exported SubnetUptime —
"undefined: p2p.ChainUptime" broke every `go build ./...` for
the whole node tree. Companion PR luxfi/proto#6 (commit
e96f95cd86) merged the upstream rename to ChainUptime; tagging
luxfi/proto v1.0.2 and bumping the node module pin (215f4e3d7b)
makes main HEAD build clean. v1.27.23 tag produced ghcr.io/
luxfi/node:v1.27.23 via the Docker workflow (run 26689130579).
Carries v1.27.22 content: canonical evmAddr/utxoAddr (genesis
v1.12.15), kill-subnet vocabulary, kill-fuji vocabulary.
Devnet rollout:
- Scale STS 5→0, delete all 5 luxd PVCs (devnet expendable
per PR #88 path-1 fix already re-runs from scratch)
- kubectl replace luxd-genesis CM from canonical source
~/work/lux/genesis/configs/devnet/genesis.json (evmAddr/
utxoAddr only, no legacy luxAddr/ethAddr translation)
- Patch STS image + scale 0→5
- All 5 luxd pods Ready on v1.27.23, P-chain producing blocks
(h≥3 observed), C-Chain healthy, BLS + bootstrapped OK,
sybil protection ON
- Deployer key idx=5 (P-dev1jx9p2hxfemcgdlylth05zj20klsn4t06s0t5kv,
0x9011E888251AB053B7bD1cdB598Db4f9DEd94714) unlocked
balance: 50000000000000 nLUX = 50K LUX (per source unlockSchedule
locktime=0)
L2 bootstrap: BLOCKED on consensus quirk where the P-chain
proposer doesn't auto-accept its own block. Two CreateNetworkTx
landed in blocks 2 + 3 from the cluster's view, but bootstrap-l2
hangs polling getTxStatus on the proposer's local view — same
pattern as the 2026-05-30T09:30Z `spc-pending-consensus-retry`
remark, now observed on every L2 attempt not just spc. 0/4 L2
EVMs live. Needs a separate investigation into the luxd
proposer-accept path (alpha=2 k=3 validatorCount=5 sample/quorum
math, BFT vote-back loop) before 4/4 L2 EVMs can land on a
v1.27.x devnet.
* chore(exchange): collapse 3 divergent overlays into shared base + env overlays
Before: three divergent exchange manifests scattered across the tree —
- k8s/lux-mainnet/exchange.yaml + exchange-proxy.yaml
- k8s/lux-explorer/exchange.yaml + exchange-proxy.yaml + exchange-whitelabel.yaml
- k8s/zoo-exchange/deployment.yaml
After: one canonical base + per-env overlays under k8s/exchange/.
base/ Deployment, Service, Middleware, namespaceless
overlays/lux-mainnet/ lux.exchange + markets/exchange.lux.network + exchange-proxy
overlays/lux-testnet/ exchange-testnet.lux.network + lux-test.exchange
overlays/lux-devnet/ exchange-devnet.lux.network + lux-dev.exchange
overlays/zoo-mainnet/ zoo.exchange (zooai/exchange image, KMSSecret)
overlays/pars-mainnet/ pars.market (lux image + brand config.json)
Common: container args, ports (3000), probes, resources, labels (app: exchange).
Per overlay: namespace, image tag, env vars, brand patch.sh, IngressRoute hosts.
Verified:
- kubectl --dry-run=client apply -k k8s/exchange/overlays/<env>/ clean for all 5
- kubectl diff against do-sfo3-lux-k8s shows zero diffs for production hostnames
(zoo.exchange, lux.exchange still routed via existing in-cluster resources)
Side updates:
- lux-k8s/kustomization.yaml: drop ../lux-explorer/exchange.yaml ref
- migrate-namespaces.sh: point at -k k8s/exchange/overlays/lux-mainnet
- STACK.md: replace old paths with k8s/exchange/overlays/<env>
158 lines
6.1 KiB
Bash
Executable File
158 lines
6.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Migration script: lux-explorer → lux-mainnet / lux-testnet / lux-devnet
|
|
#
|
|
# This script migrates resources from the monolithic lux-explorer namespace
|
|
# into per-network namespaces. Run with --apply to execute, otherwise dry-run.
|
|
#
|
|
# Prerequisites:
|
|
# - kubectl configured with do-sfo3-lux-k8s context
|
|
# - ghcr-luxfi imagePullSecret already exists in target namespaces
|
|
#
|
|
# Migration order:
|
|
# 1. Create secrets (ghcr-luxfi, blockscout-postgres-*) in new namespaces
|
|
# 2. Apply ConfigMaps and Services first
|
|
# 3. Apply Deployments/StatefulSets
|
|
# 4. Apply IngressRoutes (takes over traffic)
|
|
# 5. Verify health
|
|
# 6. Scale down old namespace resources
|
|
# 7. (Manual) Delete lux-explorer namespace after verification
|
|
|
|
set -euo pipefail
|
|
|
|
CTX="do-sfo3-lux-k8s"
|
|
K="kubectl --context $CTX"
|
|
DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
MODE="${1:-dry-run}"
|
|
|
|
log() { echo "[$(date +%H:%M:%S)] $*"; }
|
|
|
|
if [ "$MODE" != "--apply" ]; then
|
|
log "DRY RUN — pass --apply to execute"
|
|
K="$K --dry-run=client"
|
|
fi
|
|
|
|
###############################################################################
|
|
# Phase 1: Copy required secrets to new namespaces
|
|
###############################################################################
|
|
log "Phase 1: Ensuring secrets exist in target namespaces"
|
|
|
|
copy_secret() {
|
|
local name=$1 src=$2 dst=$3
|
|
if $K get secret "$name" -n "$dst" &>/dev/null; then
|
|
log " Secret $name already exists in $dst"
|
|
else
|
|
log " Copying secret $name from $src to $dst"
|
|
$K get secret "$name" -n "$src" -o json \
|
|
| jq "del(.metadata.namespace,.metadata.resourceVersion,.metadata.uid,.metadata.creationTimestamp,.metadata.annotations)" \
|
|
| jq ".metadata.namespace = \"$dst\"" \
|
|
| $K apply -f -
|
|
fi
|
|
}
|
|
|
|
# ghcr-luxfi already exists in all targets (confirmed)
|
|
# Copy blockscout postgres secrets
|
|
for ns in lux-mainnet lux-testnet lux-devnet; do
|
|
for secret in blockscout-postgres-mainnet blockscout-postgres-testnet blockscout-postgres-devnet blockscout-postgres-zoo blockscout-postgres-hanzo blockscout-postgres-spc blockscout-postgres-pars indexer-postgres-secret; do
|
|
if $K get secret "$secret" -n lux-explorer &>/dev/null; then
|
|
copy_secret "$secret" "lux-explorer" "$ns" 2>/dev/null || true
|
|
fi
|
|
done
|
|
done
|
|
|
|
###############################################################################
|
|
# Phase 2: Apply lux-mainnet resources
|
|
###############################################################################
|
|
log "Phase 2: Applying lux-mainnet resources"
|
|
|
|
# ExternalName service first (dependencies need it)
|
|
$K apply -f "$DIR/lux-mainnet/lux-sql.yaml"
|
|
|
|
# ConfigMaps
|
|
$K apply -f "$DIR/lux-mainnet/configmap.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/configmap-chains.yaml"
|
|
|
|
# Stateful infrastructure (graph-node + postgres)
|
|
$K apply -f "$DIR/lux-mainnet/graph-node.yaml"
|
|
|
|
# Microservices (needed by explorer)
|
|
$K apply -f "$DIR/lux-mainnet/microservices.yaml"
|
|
|
|
# Explorer backends + frontends
|
|
$K apply -f "$DIR/lux-mainnet/explorer-mainnet.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/frontend-mainnet.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/explorer-chains.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/frontend-chains.yaml"
|
|
|
|
# Exchange stack — deduplicated into k8s/exchange/ (base + per-env overlays).
|
|
$K apply -k "$DIR/exchange/overlays/lux-mainnet"
|
|
|
|
# Indexers
|
|
$K apply -f "$DIR/lux-mainnet/indexer-mainnet.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/indexer-all-chains.yaml"
|
|
|
|
# Sites
|
|
$K apply -f "$DIR/lux-mainnet/lux-build.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/lux-market.yaml"
|
|
|
|
# Maintenance page
|
|
$K apply -f "$DIR/lux-mainnet/maintenance.yaml"
|
|
|
|
# IngressRoutes (traffic cutover)
|
|
$K apply -f "$DIR/lux-mainnet/ingress.yaml"
|
|
$K apply -f "$DIR/lux-mainnet/ingress-chains.yaml"
|
|
|
|
###############################################################################
|
|
# Phase 3: Apply lux-testnet resources
|
|
###############################################################################
|
|
log "Phase 3: Applying lux-testnet resources"
|
|
|
|
$K apply -f "$DIR/lux-testnet/configmap.yaml"
|
|
$K apply -f "$DIR/lux-testnet/frontend-testnet.yaml"
|
|
$K apply -f "$DIR/lux-testnet/indexer-testnet.yaml"
|
|
$K apply -f "$DIR/lux-testnet/ingress.yaml"
|
|
|
|
###############################################################################
|
|
# Phase 4: Apply lux-devnet resources
|
|
###############################################################################
|
|
log "Phase 4: Applying lux-devnet resources"
|
|
|
|
$K apply -f "$DIR/lux-devnet/configmap.yaml"
|
|
$K apply -f "$DIR/lux-devnet/frontend-devnet.yaml"
|
|
$K apply -f "$DIR/lux-devnet/indexer-devnet.yaml"
|
|
$K apply -f "$DIR/lux-devnet/ingress.yaml"
|
|
|
|
###############################################################################
|
|
# Phase 5: Health check
|
|
###############################################################################
|
|
if [ "$MODE" = "--apply" ]; then
|
|
log "Phase 5: Waiting for rollouts..."
|
|
sleep 10
|
|
|
|
log "Checking lux-mainnet pods:"
|
|
$K get pods -n lux-mainnet -l app=lux-exchange --no-headers 2>/dev/null | head -5
|
|
$K get pods -n lux-mainnet -l app=exchange-api --no-headers 2>/dev/null | head -5
|
|
$K get pods -n lux-mainnet -l app=explorer-backend --no-headers 2>/dev/null | head -5
|
|
|
|
log "Checking lux-testnet pods:"
|
|
$K get pods -n lux-testnet -l app=lux-frontend --no-headers 2>/dev/null | head -5
|
|
|
|
log "Checking lux-devnet pods:"
|
|
$K get pods -n lux-devnet -l app=lux-frontend --no-headers 2>/dev/null | head -5
|
|
fi
|
|
|
|
###############################################################################
|
|
# Phase 6: Scale down old namespace (manual step)
|
|
###############################################################################
|
|
log ""
|
|
log "Migration complete. Next steps:"
|
|
log " 1. Verify all services are healthy in new namespaces"
|
|
log " 2. Check IngressRoutes are routing correctly"
|
|
log " 3. Scale down old resources:"
|
|
log " kubectl --context $CTX scale --replicas=0 -n lux-explorer deployment --all"
|
|
log " 4. After verification period, delete old namespace:"
|
|
log " kubectl --context $CTX delete namespace lux-explorer"
|
|
log ""
|
|
log "NOTE: graph-node PVCs in lux-explorer cannot be moved."
|
|
log " New graph-node in lux-mainnet will need subgraph redeployment."
|
|
log " Keep lux-explorer alive until graph-node is reindexed."
|