code wiki / _hdl_build / nx_deploy_gate.nx
nx_deploy_gate.nx source
↩ module page · 61 lines · 4167 B
1// nx_deploy_gate.nx -- proves the deploy SAFETY guarantees that turn pushing-live from F-level into reliable:
2// (1) VALIDATE is fail-closed -- a corrupt/empty artifact is rejected BEFORE anything ships (neg-controls).
3// (2) the DECIDE state machine AUTO-ROLLBACKS an unhealthy deploy and NEVER promotes an invalid one, so the
4// site can't be left down. No NAS needed -- this gates the logic that makes the live path safe. license_tier: ORIGINAL
5import "nx_deploy_lib.nx"
6
7func main() -> i64 {
8 var fails: i64 = 0
9 // fixtures
10 let eb: *u8 = sys_mmap(16); eb[0]=127 as u8; eb[1]=69 as u8; eb[2]=76 as u8; eb[3]=70 as u8; eb[4]=2 as u8; eb[5]=1 as u8
11 dp_writefile("/tmp/dep_elf" as *u8, eb, 6)
12 dp_writefile("/tmp/dep_garbage" as *u8, "garbage data, no elf magic, no tag" as *u8, 34)
13 dp_writefile("/tmp/dep_html" as *u8, "<!doctype html><html><body>ok</body></html>" as *u8, 43)
14 dp_writefile("/tmp/dep_empty" as *u8, "" as *u8, 0)
15
16 // VALIDATE: binary (ELF) -- valid magic vs garbage
17 let v1: i64 = dep_validate("/tmp/dep_elf" as *u8, 0)
18 let v2: i64 = dep_validate("/tmp/dep_garbage" as *u8, 0)
19 dp_w(1, "validate bin : elf=" as *u8); dp_wn(1, v1); dp_w(1, " garbage=" as *u8); dp_wn(1, v2); dp_w(1, " (expect 1,0)\n" as *u8)
20 if v1 != 1 { fails = fails + 1 }
21 if v2 != 0 { fails = fails + 1 }
22 // VALIDATE: html -- has-tag vs no-tag (garbage)
23 let v3: i64 = dep_validate("/tmp/dep_html" as *u8, 1)
24 let v4: i64 = dep_validate("/tmp/dep_garbage" as *u8, 1)
25 dp_w(1, "validate html: html=" as *u8); dp_wn(1, v3); dp_w(1, " garbage=" as *u8); dp_wn(1, v4); dp_w(1, " (expect 1,0)\n" as *u8)
26 if v3 != 1 { fails = fails + 1 }
27 if v4 != 0 { fails = fails + 1 }
28 // VALIDATE: empty -> invalid (fail-closed)
29 let v5: i64 = dep_validate("/tmp/dep_empty" as *u8, 2)
30 dp_w(1, "validate empty: " as *u8); dp_wn(1, v5); dp_w(1, " (expect 0)\n" as *u8)
31 if v5 != 0 { fails = fails + 1 }
32
33 // DECIDE state machine
34 let d_ok: i64 = dep_decide(1, 0, 0, 1) // all good -> SUCCESS(0)
35 let d_roll: i64 = dep_decide(1, 0, 0, 0) // promoted but UNHEALTHY -> ROLLBACK(1) <== the key safety
36 let d_prom: i64 = dep_decide(1, 0, 1, 1) // promote failed -> ROLLBACK(1)
37 let d_bad: i64 = dep_decide(0, 0, 0, 1) // INVALID artifact -> ABORT(2), never promote
38 let d_ship: i64 = dep_decide(1, 1, 0, 1) // ship failed -> ABORT(2)
39 dp_w(1, "decide: ok=" as *u8); dp_wn(1, d_ok); dp_w(1, " unhealthy=" as *u8); dp_wn(1, d_roll); dp_w(1, " promotefail=" as *u8); dp_wn(1, d_prom); dp_w(1, " invalid=" as *u8); dp_wn(1, d_bad); dp_w(1, " shipfail=" as *u8); dp_wn(1, d_ship); dp_w(1, "\n" as *u8)
40 if d_ok != 0 { fails = fails + 1 }
41 if d_roll != 1 { fails = fails + 1 } // NEG-CONTROL: unhealthy MUST roll back (never leave site down)
42 if d_prom != 1 { fails = fails + 1 }
43 if d_bad != 2 { fails = fails + 1 } // NEG-CONTROL: invalid MUST abort (never promote garbage)
44 if d_ship != 2 { fails = fails + 1 }
45
46 // HEALTH-PARSE (the fix for the LIVE false-green): the deployed daemon's "...: UP" must be present in the
47 // status OUTPUT. "...: DOWN" -> NOT healthy -> deploy auto-rolls-back. This is the exact case the exit-code missed.
48 let up: *u8 = "sites.elf(web:8443): UP" as *u8
49 let okbuf: *u8 = "hdr\nsites.elf(web:8443): UP\nnx_wiki_gw.elf(:18791): UP\n" as *u8
50 let downbuf: *u8 = "hdr\nsites.elf(web:8443): DOWN\nnx_wiki_gw.elf(:18791): UP\n" as *u8
51 let h_up: i64 = dep_status_healthy(okbuf, dp_len(okbuf), up)
52 let h_dn: i64 = dep_status_healthy(downbuf, dp_len(downbuf), up)
53 dp_w(1, "health-parse : up=" as *u8); dp_wn(1, h_up); dp_w(1, " down=" as *u8); dp_wn(1, h_dn); dp_w(1, " (expect 1,0 -- catches the DOWN the exit-code missed)\n" as *u8)
54 if h_up != 1 { fails = fails + 1 }
55 if h_dn != 0 { fails = fails + 1 }
56
57 if fails == 0 { dp_w(1, "GATE nx_deploy verdict=GREEN pass=12/12 (validate fail-closed + abort + auto-rollback + REAL health-parse UP/DOWN)\n" as *u8); sys_exit(0); return 0 }
58 dp_w(1, "GATE nx_deploy verdict=RED fails=" as *u8); dp_wn(1, fails); dp_w(1, "\n" as *u8)
59 sys_exit(1)
60 return 1
61}