Skip to content

Commit 437ee0a

Browse files
committed
Ensure waiting for the bridged IP after starting/resuming
1 parent a7f8f50 commit 437ee0a

File tree

6 files changed

+63
-13
lines changed

6 files changed

+63
-13
lines changed

cli.sh

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env bash
22
set -euo pipefail
3+
SCRIPT_DIR=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
34

45
code_quality() {
56
echo "Checking formatting..."
@@ -13,18 +14,18 @@ auto_fmt() {
1314
}
1415

1516
update_cache() {
16-
deno cache --lock=deno.lock ./src/deps.ts ./src/app.ts
17+
deno cache --lock=deno.lock "${SCRIPT_DIR}"/src/deps.ts "${SCRIPT_DIR}"/src/app.ts
1718
}
1819

1920
update_lock() {
2021
rm -f deno.lock
21-
deno cache --reload ./src/deps.ts ./src/app.ts
22-
deno cache ./src/deps.ts ./src/app.ts --lock ./deno.lock --lock-write
22+
deno cache --reload "${SCRIPT_DIR}"/src/deps.ts "${SCRIPT_DIR}"/src/app.ts
23+
deno cache "${SCRIPT_DIR}"/src/deps.ts "${SCRIPT_DIR}"/src/app.ts --lock ./deno.lock --lock-write
2324
}
2425

2526
run() {
2627
export JETSKI_ENABLE_STACKTRACE=${JETSKI_ENABLE_STACKTRACE:-"0"}
27-
deno run -A --check ./src/app.ts "$@"
28+
deno run -A --check "${SCRIPT_DIR}"/src/app.ts "$@"
2829
}
2930

3031
"$@"

deno.lock

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions/create.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
cyan,
55
ExitCode,
66
fsExists,
7+
gray,
78
inheritExec,
89
joinPath,
910
parseYaml,
@@ -88,8 +89,11 @@ export async function createInstance(instance: InstanceConfig) {
8889
const cloudInitConfig = createCloudInitConfig({ sshPublicKey, instance });
8990
const tempDir = await Deno.makeTempDir();
9091
const cloudInitFilePath = joinPath(tempDir, "cloud-init.yaml");
91-
ok("Generated cloud-init.yaml");
92-
ok(stringifyYaml(cloudInitConfig));
92+
log("Generated cloud-init.yaml");
93+
log(gray("--"));
94+
log(gray("# Begin cloud-init.yaml"));
95+
log(gray(stringifyYaml(cloudInitConfig)));
96+
log(gray("# End cloud-init.yaml"));
9397
await Deno.writeTextFile(cloudInitFilePath, stringifyYaml(cloudInitConfig));
9498

9599
const cloudInitLogTailingAbort = new AbortController();

src/deps.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export { parse as parseYaml, stringify as stringifyYaml } from "https://deno.lan
1818
export type { YAMLError } from "https://deno.land/[email protected]/yaml/_error.ts";
1919

2020
export { exists as fsExists } from "https://deno.land/[email protected]/fs/exists.ts";
21+
export { assertExists } from "https://deno.land/[email protected]/assert/assert_exists.ts";
2122
export { memoizePromise } from "https://deno.land/x/[email protected]/async_utils.ts";
2223

2324
export { delay } from "https://deno.land/[email protected]/async/delay.ts";

src/multipass.ts

+44-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
assertExists,
23
captureExec,
34
cyan,
45
delay,
@@ -14,7 +15,7 @@ import {
1415
validate,
1516
} from "./deps.ts";
1617
import { InstanceConfig, InstanceState, MultipassInfo } from "./types.ts";
17-
import { getSshIp, log, print } from "./utils.ts";
18+
import { getSshIp, log, ok, print } from "./utils.ts";
1819

1920
export const multipassBin = memoizePromise(() => locateMultipassBin());
2021

@@ -293,15 +294,45 @@ export async function multipassPostStart(
293294
instance: InstanceConfig,
294295
): Promise<string> {
295296
const { name, sshDirectoryPath } = instance;
296-
const { state, ipv4 } = await multipassInfo({ name });
297+
const { state } = await multipassInfo({ name });
297298

298299
if (state !== InstanceState.Running) {
299300
throw new Error(
300301
`Instance '${instance.name}' is not in 'Running' state. Current state is '${state}'`,
301302
);
302303
}
303304

304-
const ip = getSshIp(ipv4, instance.filterSshIpByCidr);
305+
let ip: string | undefined = undefined;
306+
307+
if (instance.filterSshIpByCidr) {
308+
const maxAttempts = 30;
309+
for (let i = 0; i < maxAttempts; i++) {
310+
let ipv4: string[] = [];
311+
312+
try {
313+
ipv4 = (await multipassInfo({ name })).ipv4;
314+
ip = getSshIp(ipv4, instance.filterSshIpByCidr);
315+
} catch (e) {
316+
if (i === maxAttempts - 1) {
317+
throw e;
318+
}
319+
320+
log(
321+
"Waiting for the instance's IP that matches the CIDR filter:",
322+
instance.filterSshIpByCidr,
323+
"So far got:",
324+
ipv4.length > 0 ? ipv4.join(", ") : "none",
325+
);
326+
await delay(1000);
327+
}
328+
}
329+
} else {
330+
ip = getSshIp((await multipassInfo({ name })).ipv4);
331+
}
332+
333+
assertExists(ip);
334+
335+
ok("Got instance IP", ip);
305336

306337
await multipassResolveClusterLocalDns({ ip, instance });
307338

@@ -444,6 +475,8 @@ export async function multipassRoute(
444475
`'New-NetRoute -DestinationPrefix ${cidr} -InterfaceAlias "vEthernet (Default Switch)" -NextHop ${ip}'`,
445476
],
446477
stdin: { inherit: true },
478+
stdout: { read: printOutLines((line) => `${gray("[$ New-NetRoute ]")} ${line}`) },
479+
stderr: { read: printErrLines((line) => `${gray("[$ New-NetRoute ]")} ${line}`) },
447480
});
448481
}
449482

@@ -454,25 +487,33 @@ export async function multipassRoute(
454487
`'Add-DnsClientNrptRule -Namespace ".svc.${clusterDomain}" -DnsSecEnable -NameServers "${clusterDnsIp}"'`,
455488
],
456489
stdin: { inherit: true },
490+
stdout: { read: printOutLines((line) => `${gray("[$ Add-DnsClientNrptRule ]")} ${line}`) },
491+
stderr: { read: printErrLines((line) => `${gray("[$ Add-DnsClientNrptRule ]")} ${line}`) },
457492
});
458493
} else {
459494
log("Adding routes, will require root permissions...");
460495
for (const cidr of [clusterCidr, serviceCidr]) {
461496
await inheritExec({
462497
cmd: ["sudo", "/sbin/route", "add", "-net", cidr, ip],
463498
stdin: { inherit: true },
499+
stdout: { read: printOutLines((line) => `${gray("[$ route ]")} ${line}`) },
500+
stderr: { read: printErrLines((line) => `${gray("[$ route ]")} ${line}`) },
464501
});
465502
}
466503

467504
await inheritExec({
468505
cmd: ["sudo", "mkdir", "-p", "/etc/resolver"],
506+
stdout: { read: printOutLines((line) => `${gray("[$ resolver ]")} ${line}`) },
507+
stderr: { read: printErrLines((line) => `${gray("[$ resolver ]")} ${line}`) },
469508
});
470509

471510
await inheritExec({
472511
cmd: ["sudo", "tee", `/etc/resolver/svc.${clusterDomain}`],
473512
stdin: {
474513
pipe: [`domain svc.${clusterDomain}`, `nameserver ${clusterDnsIp}`, "search_order 1", ""].join("\n"),
475514
},
515+
stdout: { read: printOutLines((line) => `${gray("[$ resolver ]")} ${line}`) },
516+
stderr: { read: printErrLines((line) => `${gray("[$ resolver ]")} ${line}`) },
476517
});
477518
}
478519
}

src/utils.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -188,19 +188,19 @@ export async function print(...params: string[]) {
188188
});
189189
}
190190

191-
export function log(...params: string[]) {
191+
export function log(...params: unknown[]) {
192192
console.error.apply(console, params);
193193
}
194194

195-
export function out(...params: string[]) {
195+
export function out(...params: unknown[]) {
196196
console.log.apply(console, params);
197197
}
198198

199-
export function ok(...params: string[]) {
199+
export function ok(...params: unknown[]) {
200200
console.error.apply(console, [green("[Success]"), ...params]);
201201
}
202202

203-
export function err(...params: string[]) {
203+
export function err(...params: unknown[]) {
204204
console.error.apply(console, [red("[Error]"), ...params]);
205205
}
206206

0 commit comments

Comments
 (0)