code wiki / (root) / nx_ship.nx

nx_ship.nx source

↩ module page · 97 lines · 5521 B

1// nx_ship.nx -- ONE sovereign command for the whole edit->build loop: pack a source dir, upload it over sovereign 2// TLS-1.3 with a minted mgmt session, unpack it into the NAS buildroot, and compile the target ON THE NAS -- zero 3// scp/curl/tar. Orchestrates the proven organs (nx_treepack + nx_mgmt_client) by fork+capture, gating on each step's 4// success marker. Deploy is intentionally NOT here (destructive; run `nx_mgmt POST /api/deploy` deliberately). 5// nx_ship <target> <tokenfile> <srcdir> 6// <target> the runtime organ name to compile (its source must exist in the synced buildroot/runtime) 7// <tokenfile> a file holding a valid X-Nishi-Session token (mint: nx_mgmt_session_mint on the NAS) 8// <srcdir> the local dir to sync (paths are taken RELATIVE to it -> land under buildroot/runtime); use a 9// small staged mirror for a lean incremental sync, or `runtime` for a full re-sync. 10import "nx_tool_run.nx" // tr_run_capture (fork + argv + stdout capture) 11const K_MAGIC_1048576: i64 = 1048576 12 13func ship_slen(s: *u8) -> i64 { var i: i64 = 0; while s[i] != (0 as u8) { i = i + 1 } return i } 14func ship_puts(s: *u8) -> i64 { sys_write(1, s, ship_slen(s)); return 0 } 15 16// substring search: does buf[0..n) contain the NUL-terminated needle? 17func ship_contains(buf: *u8, n: i64, needle: *u8) -> i64 { 18 let m: i64 = ship_slen(needle) 19 if m == 0 { return 1 } 20 var i: i64 = 0 21 while i + m <= n { 22 var k: i64 = 0 23 while k < m { if buf[i + k] != needle[k] { k = m + 9 } else { k = k + 1 } } 24 if k == m { return 1 } 25 i = i + 1 26 } 27 return 0 28} 29 30// write a small NUL-terminated body string to `path` (form body for the mgmt call). Returns 0 OK. 31func ship_write_body(path: *u8, content: *u8) -> i64 { 32 let fd: i64 = sys_openat_wr(path, 0x1a4) 33 if fd < 0 { return 0 - 1 } 34 sys_write(fd, content, ship_slen(content)) 35 sys_close(fd) 36 return 0 37} 38 39// run a sub-tool (path + up to 8 args, NUL-terminated argv), capture stdout into out, return child exit code. 40func ship_run(path: *u8, av: *i64, out: *u8, cap: i64, olen: *i64) -> i64 { 41 av[0] = path as i64 42 return tr_run_capture(path, av, out, cap, olen) 43} 44 45func main(argc: i64, argv: *i64) -> i64 { 46 if argc < 4 { ship_puts("usage: nx_ship <target> <tokenfile> <srcdir>\n" as *u8); return 1 } 47 let target: *u8 = argv[1] as *u8 48 let tokenfile: *u8 = argv[2] as *u8 49 let srcdir: *u8 = argv[3] as *u8 50 51 let edge: *u8 = "https://nishifamily.com" as *u8 52 let treepack: *u8 = "./_offc/nx_treepack.elf" as *u8 53 let mgmtclient: *u8 = "./_offc/nx_mgmt_client.elf" as *u8 54 let packpath: *u8 = "/tmp/nx_ship.pack" as *u8 55 let unpackbody: *u8 = "/tmp/nx_ship_unpack.body" as *u8 56 let buildbody: *u8 = "/tmp/nx_ship_build.body" as *u8 57 58 let out: *u8 = sys_mmap(K_MAGIC_1048576) 59 let olen: *i64 = sys_mmap(16) as *i64 60 let av: *i64 = sys_mmap(256) as *i64 61 62 // ---- 1. pack srcdir -> packpath (nx_treepack) ---- 63 ship_puts("[nx_ship] 1/4 pack " as *u8); ship_puts(srcdir); ship_puts("\n" as *u8) 64 av[1] = "pack" as *u8 as i64; av[2] = srcdir as i64; av[3] = packpath as i64; av[4] = 0 65 ship_run(treepack, av, out, K_MAGIC_1048576, olen) 66 if ship_contains(out, olen[0], "failed=0" as *u8) == 0 { ship_puts("[nx_ship] PACK FAILED\n" as *u8); sys_write(1, out, olen[0]); sys_exit(2); return 2 } 67 68 // ---- 2. upload packpath -> /api/upload (sovereign TLS + token) ---- 69 ship_puts("[nx_ship] 2/4 upload (sovereign TLS-1.3)\n" as *u8) 70 av[1] = edge as i64; av[2] = "upload" as *u8 as i64; av[3] = "buildsrc.pack" as *u8 as i64; av[4] = packpath as i64; av[5] = tokenfile as i64; av[6] = 0 71 ship_run(mgmtclient, av, out, K_MAGIC_1048576, olen) 72 if ship_contains(out, olen[0], "UPLOAD OK" as *u8) == 0 { ship_puts("[nx_ship] UPLOAD FAILED\n" as *u8); sys_write(1, out, olen[0]); sys_exit(3); return 3 } 73 74 // ---- 3. unpack into buildroot/runtime (dest=buildsrc) ---- 75 ship_puts("[nx_ship] 3/4 unpack -> buildroot/runtime\n" as *u8) 76 ship_write_body(unpackbody, "dest=buildsrc" as *u8) 77 av[1] = edge as i64; av[2] = "call" as *u8 as i64; av[3] = "POST" as *u8 as i64; av[4] = "/api/unpack" as *u8 as i64; av[5] = tokenfile as i64; av[6] = unpackbody as i64; av[7] = 0 78 ship_run(mgmtclient, av, out, K_MAGIC_1048576, olen) 79 if ship_contains(out, olen[0], "UNPACKED" as *u8) == 0 { ship_puts("[nx_ship] UNPACK FAILED\n" as *u8); sys_write(1, out, olen[0]); sys_exit(4); return 4 } 80 81 // ---- 4. build target ON THE NAS (nx_cc -> nxasm) ---- 82 ship_puts("[nx_ship] 4/4 build " as *u8); ship_puts(target); ship_puts(" on the NAS\n" as *u8) 83 let bb: *u8 = sys_mmap(256) 84 var bo: i64 = 0 85 let pfx: *u8 = "target=" as *u8 86 while pfx[bo] != (0 as u8) { bb[bo] = pfx[bo]; bo = bo + 1 } 87 var ti: i64 = 0 88 while target[ti] != (0 as u8) { bb[bo] = target[ti]; bo = bo + 1; ti = ti + 1 } 89 bb[bo] = 0 as u8 90 ship_write_body(buildbody, bb) 91 av[1] = edge as i64; av[2] = "call" as *u8 as i64; av[3] = "POST" as *u8 as i64; av[4] = "/api/build" as *u8 as i64; av[5] = tokenfile as i64; av[6] = buildbody as i64; av[7] = 0 92 ship_run(mgmtclient, av, out, K_MAGIC_1048576, olen) 93 if ship_contains(out, olen[0], "BUILT" as *u8) == 1 { 94 ship_puts("[nx_ship] SHIPPED -- " as *u8); sys_write(1, out, olen[0]); ship_puts("\n" as *u8); sys_exit(0); return 0 95 } 96 ship_puts("[nx_ship] BUILD FAILED -- " as *u8); sys_write(1, out, olen[0]); ship_puts("\n" as *u8); sys_exit(5); return 5 97}