Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/lib/onboard/experimental/portable-host-preparation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,56 @@ describe("preparePortableExperimentalHost", () => {
expect(sudo).not.toHaveBeenCalled();
});

it("creates the portable network before adding its host gateway address (#9577)", () => {
const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-portable-"));
tempDirs.push(home);
let hostGatewayConfigured = false;
const commands: string[] = [];
const docker = vi.fn<(args: readonly string[], env: NodeJS.ProcessEnv) => SpawnResult>(
(args) => {
switch (args.slice(0, 2).join(" ")) {
case "--version":
return result();
case "network inspect":
return result(1);
case "network create":
commands.push("create network");
return hostGatewayConfigured
? result(125, `subnet ${PORTABLE_DOCKER_NETWORK_SUBNET} is already used on the host`)
: result();
case "inspect --format":
return result(1);
case "run -d":
return result();
default:
return result(1, `unexpected docker command: ${args.join(" ")}`);
}
},
);
const ip = vi.fn(() =>
result(
0,
hostGatewayConfigured
? `1: lo inet ${PORTABLE_HOST_GATEWAY_IP}/32 scope global lo\n`
: "1: lo inet 127.0.0.1/8 scope host lo\n",
),
);
const sudo = vi.fn(() => {
commands.push("add host gateway");
hostGatewayConfigured = true;
return result();
});

preparePortableExperimentalHost(
{ NEMOCLAW_EXPERIMENTAL_PROFILE: "portable" },
portablePreparationDeps(home, docker, { ip, sudo }),
undefined,
{ simulateExistingPortableNetwork: false },
);

expect(commands).toEqual(["create network", "add host gateway"]);
});

it("configures and verifies the portable gateway loopback alias before registry mutation (#9461)", () => {
const home = fs.mkdtempSync(path.join(os.tmpdir(), "nemoclaw-portable-"));
tempDirs.push(home);
Expand Down
9 changes: 8 additions & 1 deletion src/lib/onboard/experimental/portable-host-preparation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ function validateOwnedConfigAuthority(input: {
if (socketPath) assertOwnedDescendants(runtimeDir, path.dirname(socketPath));
}

function ensureRegistryContainer(
function ensurePortableSandboxNetwork(
env: NodeJS.ProcessEnv,
docker: NonNullable<PortableHostPreparationDeps["docker"]>,
networkName: string,
Expand All @@ -367,7 +367,13 @@ function ensureRegistryContainer(
"Creating the portable sandbox network",
);
}
}

function ensureRegistryContainer(
env: NodeJS.ProcessEnv,
docker: NonNullable<PortableHostPreparationDeps["docker"]>,
networkName: string,
): void {
const inspection = docker(
[
"inspect",
Expand Down Expand Up @@ -637,6 +643,7 @@ export function preparePortableExperimentalHost(
env: childEnv,
timeout: HOST_COMMAND_TIMEOUT_MS,
}));
ensurePortableSandboxNetwork(podmanEnv, docker, dockerNetworkName);
ensurePortableHostGatewayAlias(podmanEnv, ip, sudo);
ensureRegistryContainer(podmanEnv, docker, dockerNetworkName);
if (socketAuthority) {
Expand Down
Loading