Merge nucleic/nimble-umber-toad-20h7 into dev
This commit is contained in:
+13
-13
@@ -30,13 +30,13 @@ internal static class Program
|
||||
private static async Task<int> Main(string[] args)
|
||||
{
|
||||
var repo = Arg(args, "--repo") ?? Directory.GetCurrentDirectory();
|
||||
var image = Arg(args, "--image") ?? "ghcr.io/abkslm/naros-agent:26.07";
|
||||
var image = Arg(args, "--image") ?? "ghcr.io/abkslm/hydrangeaos-agent:26.07";
|
||||
var container = Arg(args, "--container") ?? "nucleic-spike-c1";
|
||||
var sessionName = Arg(args, "--session-name") ?? "nucleic-spike";
|
||||
var iterations = int.TryParse(Arg(args, "--iterations"), out var n) ? n : 5;
|
||||
var broker = Arg(args, "--broker") ?? FindBroker();
|
||||
var skipRecovery = args.Contains("--no-recovery");
|
||||
// narOS runs `naros-init` as PID 1 and stays up (docs/NAROS.md). A stock image usually
|
||||
// hydrangeaOS runs `hydrangeaos-init` as PID 1 and stays up (docs/HYDRANGEAOS.md). A stock image usually
|
||||
// does not: alpine's PID 1 is /bin/sh, which exits immediately with no tty, so the
|
||||
// container is `Exited` before the first exec and every later step fails `not_running`.
|
||||
var sleepInit = args.Contains("--sleep-init");
|
||||
@@ -146,14 +146,14 @@ internal static class Program
|
||||
["hostname"] = "nucleic-spike",
|
||||
["env"] = new Dictionary<string, string> { ["NUCLEIC_SPIKE"] = "1" },
|
||||
};
|
||||
// Mirror WslcContainerEngine: narOS images carry no default CMD (wslc answers "no command
|
||||
// specified"), so the engine always names init explicitly — `naros-init` is PID 1 per
|
||||
// docs/NAROS.md §5, doing zombie reaping, signal forwarding and, with NAROS_BRIDGE=1,
|
||||
// Mirror WslcContainerEngine: hydrangeaOS images carry no default CMD (wslc answers "no command
|
||||
// specified"), so the engine always names init explicitly — `hydrangeaos-init` is PID 1 per
|
||||
// docs/HYDRANGEAOS.md §5, doing zombie reaping, signal forwarding and, with HYDRANGEAOS_BRIDGE=1,
|
||||
// supervising control-bridge.js. `--sleep-init` swaps in a keepalive for stock images that
|
||||
// have no naros-init, which is the case the engine handles with a probe (see §13.3).
|
||||
// have no hydrangeaos-init, which is the case the engine handles with a probe (see §13.3).
|
||||
create["initArgv"] = sleepInit
|
||||
? new[] { "/bin/sh", "-c", "sleep 3600" }
|
||||
: new[] { "/usr/sbin/naros-init" };
|
||||
: new[] { "/usr/sbin/hydrangeaos-init" };
|
||||
await broker.CallAsync("container.create", create);
|
||||
await broker.CallAsync("container.start", new { name = containerName });
|
||||
var state = (await broker.CallAsync("container.state", new { name = containerName }))
|
||||
@@ -164,8 +164,8 @@ internal static class Program
|
||||
// (supply a long-running init) is nothing like the remedy for a real start failure.
|
||||
if (state != "running")
|
||||
throw new InvalidOperationException(
|
||||
$"container is '{state}' immediately after start — its PID 1 exited. narOS runs "
|
||||
+ "naros-init and stays up; a stock image (alpine's PID 1 is /bin/sh) does not. "
|
||||
$"container is '{state}' immediately after start — its PID 1 exited. hydrangeaOS runs "
|
||||
+ "hydrangeaos-init and stays up; a stock image (alpine's PID 1 is /bin/sh) does not. "
|
||||
+ "Re-run with --sleep-init to give it a long-running init process.");
|
||||
|
||||
Step("exec: stdio round-trip");
|
||||
@@ -188,7 +188,7 @@ internal static class Program
|
||||
catch (BrokerError e) when (e.Kind == "unsupported")
|
||||
{
|
||||
Console.WriteLine($" REFUSED (correctly): {e.Message}");
|
||||
Console.WriteLine(" → expected on a BusyBox image; narOS ships util-linux.");
|
||||
Console.WriteLine(" → expected on a BusyBox image; hydrangeaOS ships util-linux.");
|
||||
}
|
||||
|
||||
Step("the mounted worktree");
|
||||
@@ -218,7 +218,7 @@ internal static class Program
|
||||
///
|
||||
/// Every agent session depends on this. `control-bridge.js` forwards guest loopback 9099 to
|
||||
/// `NUCLEIC_CONTROL_HOST/PORT`, which is where `MCPApprovalServer` serves approvals, the git
|
||||
/// and gh interceptor endpoints, and the nash shell reports (§5, §1.4). If the guest cannot
|
||||
/// and gh interceptor endpoints, and the hydrashell shell reports (§5, §1.4). If the guest cannot
|
||||
/// open a TCP connection to the host on that address, none of it works and no agent can run.
|
||||
///
|
||||
/// This is the reachability question in isolation: a bare TCP round trip, bound **only** to
|
||||
@@ -270,7 +270,7 @@ internal static class Program
|
||||
|
||||
try
|
||||
{
|
||||
// narOS has neither `nc` nor `wget` — it has **node**, since control-bridge.js is the
|
||||
// hydrangeaOS has neither `nc` nor `wget` — it has **node**, since control-bridge.js is the
|
||||
// real client on this path. Passed as argv with no shell, so nothing here needs
|
||||
// quoting, and the payload is a bare "PING" because the host side replies to whatever
|
||||
// it reads (no CRLF handling to get wrong).
|
||||
@@ -287,7 +287,7 @@ internal static class Program
|
||||
|
||||
// A missing client tool is NOT a blocked connection, and reporting it as one sends the
|
||||
// reader off to inspect firewall rules for no reason. An earlier version of this probe
|
||||
// did exactly that on narOS (§13.3).
|
||||
// did exactly that on hydrangeaOS (§13.3).
|
||||
if (code == 127 || output.Contains("command not found") || output.Contains("not found"))
|
||||
{
|
||||
Console.WriteLine($" INCONCLUSIVE — no usable client in this image (exit {code}): "
|
||||
|
||||
Reference in New Issue
Block a user