221 lines
6.7 KiB
JSON
221 lines
6.7 KiB
JSON
{
|
|
"adr_refs": [
|
|
"adr-037",
|
|
"adr-038",
|
|
"adr-039"
|
|
],
|
|
"description": "First-time full platform bootstrap. Builds buildkit-runner golden image off-platform, deploys libre-wuji with temporary bootstrap zot, migrates images to wuji S3-backed zot, deploys libre-daoshi (CI/build cluster), deploys ops-vm (signing), and bootstraps Radicle governance repos. Run exactly once per platform instantiation.",
|
|
"emit_audit": true,
|
|
"id": "bootstrap_initial",
|
|
"name": "Initial Bootstrap",
|
|
"params": [
|
|
{
|
|
"default_val": "libre-wuji",
|
|
"description": "Primary workspace (must be libre-wuji)",
|
|
"name": "workspace",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "hcloud context name",
|
|
"name": "hetzner_context",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "DigitalOcean context (for ops-vm)",
|
|
"name": "do_context",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "Temporary OCI registry for image bootstrap",
|
|
"name": "bootstrap_zot_url",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "libre-wuji-zot",
|
|
"description": "S3 bucket for wuji zot",
|
|
"name": "s3_bucket",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "ops-vm SSH host (once provisioned)",
|
|
"name": "ops_vm_host",
|
|
"required": false
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "Path to ops-controller Ed25519 private key PEM",
|
|
"name": "ops_controller_key",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "Path to keeper Ed25519 private key PEM",
|
|
"name": "keeper_key",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "",
|
|
"description": "Radicle DID of first governance delegate",
|
|
"name": "initial_delegate_did",
|
|
"required": true
|
|
},
|
|
{
|
|
"default_val": "false",
|
|
"description": "Skip golden image build if already pushed",
|
|
"name": "skip_golden_image",
|
|
"required": false
|
|
}
|
|
],
|
|
"preconditions": [
|
|
"Hetzner Cloud API token available and project created",
|
|
"DigitalOcean API token available for ops-vm",
|
|
"S3 bucket for zot (libre-wuji-zot) exists with versioning enabled",
|
|
"NATS account server configured and account JWTs available",
|
|
"Domain DNS delegated (for ingress on wuji/daoshi)",
|
|
"SOPS age key generated and accessible",
|
|
"Radicle identity (rad auth) initialized for bootstrapping operator",
|
|
"Bootstrap zot: local registry or any reachable OCI registry for initial image push",
|
|
"Ed25519 key pair generated for initial ops-controller, keeper, and radicle delegate"
|
|
],
|
|
"rollback_strategy": "manual",
|
|
"steps": [
|
|
{
|
|
"depends_on": [],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "verify_prerequisites",
|
|
"name": "Verify all bootstrap prerequisites",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/verify_prerequisites.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"verify_prerequisites"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "build_golden_image",
|
|
"name": "Build buildkit-runner golden image off-platform",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/build_golden_image.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"build_golden_image"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "push_to_bootstrap_zot",
|
|
"name": "Push golden image to bootstrap registry",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/push_to_bootstrap_zot.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"push_to_bootstrap_zot"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "deploy_libre_wuji",
|
|
"name": "Deploy libre-wuji cluster (using bootstrap zot)",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/deploy_libre_wuji.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"deploy_libre_wuji"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "verify_wuji_zot_live",
|
|
"name": "Wait for wuji S3-backed zot to be healthy",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/verify_wuji_zot_live.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"verify_wuji_zot_live"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "migrate_to_wuji_zot",
|
|
"name": "Migrate images from bootstrap registry to wuji zot",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/migrate_to_wuji_zot.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"verify_wuji_zot_live"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "bootstrap_radicle_governance",
|
|
"name": "Create initial Radicle governance repos and set delegation",
|
|
"on_error": "Stop",
|
|
"params": {},
|
|
"script": "steps/bootstrap_radicle_governance.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"migrate_to_wuji_zot",
|
|
"bootstrap_radicle_governance"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "deploy_libre_daoshi",
|
|
"name": "Deploy libre-daoshi CI/build cluster",
|
|
"on_error": "Continue",
|
|
"params": {},
|
|
"script": "steps/deploy_libre_daoshi.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"bootstrap_radicle_governance"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "deploy_ops_vm",
|
|
"name": "Deploy ops-vm on DigitalOcean (signing isolation)",
|
|
"on_error": "Continue",
|
|
"params": {},
|
|
"script": "steps/deploy_ops_vm.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"deploy_libre_daoshi",
|
|
"deploy_ops_vm"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "verify_end_to_end",
|
|
"name": "Run end-to-end ops pipeline smoke test",
|
|
"on_error": "Continue",
|
|
"params": {},
|
|
"script": "steps/verify_end_to_end.nu"
|
|
},
|
|
{
|
|
"depends_on": [
|
|
"verify_end_to_end"
|
|
],
|
|
"dry_run_arg": "--dry-run",
|
|
"id": "emit_audit",
|
|
"name": "Emit bootstrap-complete audit event",
|
|
"on_error": "Continue",
|
|
"params": {
|
|
"event_type": "bootstrap_complete"
|
|
},
|
|
"script": "steps/emit_audit.nu"
|
|
}
|
|
],
|
|
"success_criteria": [
|
|
"libre-wuji cluster running with all components healthy (zot, ops-controller, radicle-seed, observability)",
|
|
"zot serving images from S3 bucket — bootstrap registry no longer needed",
|
|
"Radicle repos created: policy-libre-wuji, desired-libre-wuji, state-libre-wuji, policy-libre-daoshi, desired-libre-daoshi, state-libre-daoshi",
|
|
"Initial delegation set (M=1 threshold) written to all policy repos",
|
|
"libre-daoshi cluster running with forgejo, woodpecker, postgresql, radicle-seed",
|
|
"ops-vm running on DigitalOcean AMS3 with keeper-daemon and radicle-seed",
|
|
"End-to-end: test op submitted via NATS → signed by keeper → applied → audit event in SurrealDB",
|
|
"ops history shows bootstrap-complete audit event"
|
|
],
|
|
"version": 1
|
|
}
|