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}