@intentic/machine 1.326.0 → 1.327.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +387 -33
- package/dist/commands.d.ts.map +1 -1
- package/dist/commands.js +2 -0
- package/dist/commands.js.map +1 -1
- package/dist/daemon-base.d.ts.map +1 -1
- package/dist/daemon-base.js +2 -3
- package/dist/daemon-base.js.map +1 -1
- package/dist/device/audit.d.ts +2 -0
- package/dist/device/audit.d.ts.map +1 -1
- package/dist/device/audit.js +23 -3
- package/dist/device/audit.js.map +1 -1
- package/dist/device/commands.d.ts +4 -0
- package/dist/device/commands.d.ts.map +1 -1
- package/dist/device/commands.js +7 -2
- package/dist/device/commands.js.map +1 -1
- package/dist/device/connection.d.ts +12 -1
- package/dist/device/connection.d.ts.map +1 -1
- package/dist/device/connection.js +77 -3
- package/dist/device/connection.js.map +1 -1
- package/dist/device/grant.d.ts +52 -0
- package/dist/device/grant.d.ts.map +1 -1
- package/dist/device/loopback-catch.d.ts +1 -1
- package/dist/device/loopback-catch.d.ts.map +1 -1
- package/dist/device/loopback-catch.js +5 -30
- package/dist/device/loopback-catch.js.map +1 -1
- package/dist/device/mcp.d.ts.map +1 -1
- package/dist/device/mcp.js +190 -30
- package/dist/device/mcp.js.map +1 -1
- package/dist/device/router.d.ts +52 -0
- package/dist/device/router.d.ts.map +1 -1
- package/dist/device/router.js +21 -0
- package/dist/device/router.js.map +1 -1
- package/dist/device/sandbox-rounds/auto-backup.d.ts +3 -1
- package/dist/device/sandbox-rounds/auto-backup.d.ts.map +1 -1
- package/dist/device/sandbox-rounds/auto-backup.js +14 -5
- package/dist/device/sandbox-rounds/auto-backup.js.map +1 -1
- package/dist/device/sandbox-rounds/auto-prepare.d.ts +3 -1
- package/dist/device/sandbox-rounds/auto-prepare.d.ts.map +1 -1
- package/dist/device/sandbox-rounds/auto-prepare.js +3 -3
- package/dist/device/sandbox-rounds/auto-prepare.js.map +1 -1
- package/dist/device/sandbox-rounds/in-flight.d.ts.map +1 -0
- package/dist/device/sandbox-rounds/in-flight.js.map +1 -0
- package/dist/device/sandbox-rounds/keeper.d.ts +26 -4
- package/dist/device/sandbox-rounds/keeper.d.ts.map +1 -1
- package/dist/device/sandbox-rounds/keeper.js +129 -31
- package/dist/device/sandbox-rounds/keeper.js.map +1 -1
- package/dist/device/sandbox-rounds/probation-watch.d.ts.map +1 -1
- package/dist/device/sandbox-rounds/probation-watch.js.map +1 -1
- package/dist/device/tools/android-parse.d.ts +69 -0
- package/dist/device/tools/android-parse.d.ts.map +1 -0
- package/dist/device/tools/android-parse.js +391 -0
- package/dist/device/tools/android-parse.js.map +1 -0
- package/dist/device/tools/android.d.ts +71 -0
- package/dist/device/tools/android.d.ts.map +1 -0
- package/dist/device/tools/android.js +534 -0
- package/dist/device/tools/android.js.map +1 -0
- package/dist/device/tools/apps.d.ts +3 -3
- package/dist/device/tools/apps.d.ts.map +1 -1
- package/dist/device/tools/apps.js +16 -6
- package/dist/device/tools/apps.js.map +1 -1
- package/dist/device/tools/describe.d.ts.map +1 -1
- package/dist/device/tools/describe.js +10 -5
- package/dist/device/tools/describe.js.map +1 -1
- package/dist/device/tools/device.d.ts +9 -15
- package/dist/device/tools/device.d.ts.map +1 -1
- package/dist/device/tools/device.js +34 -58
- package/dist/device/tools/device.js.map +1 -1
- package/dist/device/tools/elements.d.ts +13 -0
- package/dist/device/tools/elements.d.ts.map +1 -0
- package/dist/device/tools/elements.js +84 -0
- package/dist/device/tools/elements.js.map +1 -0
- package/dist/device/tools/ic-binary.d.ts +1 -0
- package/dist/device/tools/ic-binary.d.ts.map +1 -1
- package/dist/device/tools/ic-binary.js +40 -17
- package/dist/device/tools/ic-binary.js.map +1 -1
- package/dist/device/tools/sandboxes.d.ts +1 -1
- package/dist/device/tools/sandboxes.d.ts.map +1 -1
- package/dist/device/tools/sandboxes.js +9 -8
- package/dist/device/tools/sandboxes.js.map +1 -1
- package/dist/device/tools/shell.js +1 -1
- package/dist/device/tools/shell.js.map +1 -1
- package/dist/device/tools/view.d.ts +4 -0
- package/dist/device/tools/view.d.ts.map +1 -0
- package/dist/device/tools/view.js +4 -0
- package/dist/device/tools/view.js.map +1 -0
- package/dist/environments/children.js +1 -1
- package/dist/environments/children.js.map +1 -1
- package/dist/environments/commands.js +1 -1
- package/dist/environments/commands.js.map +1 -1
- package/dist/environments/crossing.d.ts +1 -1
- package/dist/environments/crossing.d.ts.map +1 -1
- package/dist/environments/machine.js +1 -1
- package/dist/environments/machine.js.map +1 -1
- package/dist/environments/wsl.d.ts.map +1 -0
- package/dist/environments/wsl.js.map +1 -0
- package/dist/resident.d.ts.map +1 -1
- package/dist/resident.js +14 -8
- package/dist/resident.js.map +1 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +16 -13
- package/dist/status.js.map +1 -1
- package/dist/sync/attach-commands.d.ts +39 -0
- package/dist/sync/attach-commands.d.ts.map +1 -0
- package/dist/sync/attach-commands.js +152 -0
- package/dist/sync/attach-commands.js.map +1 -0
- package/dist/sync/commands.d.ts +8 -4
- package/dist/sync/commands.d.ts.map +1 -1
- package/dist/sync/commands.js +137 -79
- package/dist/sync/commands.js.map +1 -1
- package/dist/sync/config.d.ts +43 -9
- package/dist/sync/config.d.ts.map +1 -1
- package/dist/sync/config.js +86 -41
- package/dist/sync/config.js.map +1 -1
- package/dist/sync/endpoint.d.ts +8 -1
- package/dist/sync/endpoint.d.ts.map +1 -1
- package/dist/sync/endpoint.js +41 -1
- package/dist/sync/endpoint.js.map +1 -1
- package/dist/sync/environment.d.ts +11 -0
- package/dist/sync/environment.d.ts.map +1 -0
- package/dist/sync/environment.js +48 -0
- package/dist/sync/environment.js.map +1 -0
- package/dist/sync/exec.d.ts +1 -0
- package/dist/sync/exec.d.ts.map +1 -1
- package/dist/sync/exec.js +4 -5
- package/dist/sync/exec.js.map +1 -1
- package/dist/sync/folders.d.ts +3 -2
- package/dist/sync/folders.d.ts.map +1 -1
- package/dist/sync/folders.js +55 -2
- package/dist/sync/folders.js.map +1 -1
- package/dist/sync/forget-command.d.ts +22 -0
- package/dist/sync/forget-command.d.ts.map +1 -0
- package/dist/sync/forget-command.js +95 -0
- package/dist/sync/forget-command.js.map +1 -0
- package/dist/sync/git-bridge.d.ts +6 -0
- package/dist/sync/git-bridge.d.ts.map +1 -1
- package/dist/sync/git-bridge.js +64 -1
- package/dist/sync/git-bridge.js.map +1 -1
- package/dist/sync/gone-watch.d.ts +18 -0
- package/dist/sync/gone-watch.d.ts.map +1 -0
- package/dist/sync/gone-watch.js +142 -0
- package/dist/sync/gone-watch.js.map +1 -0
- package/dist/sync/gone.d.ts +22 -0
- package/dist/sync/gone.d.ts.map +1 -0
- package/dist/sync/gone.js +60 -0
- package/dist/sync/gone.js.map +1 -0
- package/dist/sync/local-sandboxes.d.ts +6 -0
- package/dist/sync/local-sandboxes.d.ts.map +1 -0
- package/dist/sync/local-sandboxes.js +26 -0
- package/dist/sync/local-sandboxes.js.map +1 -0
- package/dist/sync/mirror.d.ts +7 -0
- package/dist/sync/mirror.d.ts.map +1 -1
- package/dist/sync/mirror.js +434 -111
- package/dist/sync/mirror.js.map +1 -1
- package/dist/sync/mutagen.d.ts +50 -18
- package/dist/sync/mutagen.d.ts.map +1 -1
- package/dist/sync/mutagen.js +294 -80
- package/dist/sync/mutagen.js.map +1 -1
- package/dist/sync/project/adopt.d.ts +18 -0
- package/dist/sync/project/adopt.d.ts.map +1 -0
- package/dist/sync/project/adopt.js +86 -0
- package/dist/sync/project/adopt.js.map +1 -0
- package/dist/sync/{project-commands.d.ts → project/project-commands.d.ts} +4 -1
- package/dist/sync/project/project-commands.d.ts.map +1 -0
- package/dist/sync/{project-commands.js → project/project-commands.js} +10 -10
- package/dist/sync/project/project-commands.js.map +1 -0
- package/dist/sync/project/project-delivery.d.ts +23 -0
- package/dist/sync/project/project-delivery.d.ts.map +1 -0
- package/dist/sync/project/project-delivery.js +315 -0
- package/dist/sync/project/project-delivery.js.map +1 -0
- package/dist/sync/{project-files.d.ts → project/project-files.d.ts} +1 -1
- package/dist/sync/project/project-files.d.ts.map +1 -0
- package/dist/sync/{project-files.js → project/project-files.js} +5 -2
- package/dist/sync/project/project-files.js.map +1 -0
- package/dist/sync/{project-local.d.ts → project/project-local.d.ts} +1 -1
- package/dist/sync/project/project-local.d.ts.map +1 -0
- package/dist/sync/{project-local.js → project/project-local.js} +1 -1
- package/dist/sync/project/project-local.js.map +1 -0
- package/dist/sync/{project-remote.d.ts → project/project-remote.d.ts} +1 -1
- package/dist/sync/project/project-remote.d.ts.map +1 -0
- package/dist/sync/{project-remote.js → project/project-remote.js} +1 -1
- package/dist/sync/project/project-remote.js.map +1 -0
- package/dist/sync/{project-transfer.d.ts → project/project-transfer.d.ts} +20 -6
- package/dist/sync/project/project-transfer.d.ts.map +1 -0
- package/dist/sync/{project-transfer.js → project/project-transfer.js} +26 -23
- package/dist/sync/project/project-transfer.js.map +1 -0
- package/dist/sync/report.d.ts.map +1 -1
- package/dist/sync/report.js +13 -7
- package/dist/sync/report.js.map +1 -1
- package/dist/sync/restore-points.d.ts +15 -11
- package/dist/sync/restore-points.d.ts.map +1 -1
- package/dist/sync/restore-points.js +25 -24
- package/dist/sync/restore-points.js.map +1 -1
- package/dist/sync/retire.d.ts +14 -0
- package/dist/sync/retire.d.ts.map +1 -0
- package/dist/sync/retire.js +66 -0
- package/dist/sync/retire.js.map +1 -0
- package/dist/sync/siblings.d.ts +27 -0
- package/dist/sync/siblings.d.ts.map +1 -0
- package/dist/sync/siblings.js +112 -0
- package/dist/sync/siblings.js.map +1 -0
- package/dist/sync/ssh.d.ts +1 -0
- package/dist/sync/ssh.d.ts.map +1 -1
- package/dist/sync/ssh.js +37 -23
- package/dist/sync/ssh.js.map +1 -1
- package/dist/sync/tunnel.d.ts +6 -2
- package/dist/sync/tunnel.d.ts.map +1 -1
- package/dist/sync/tunnel.js +45 -48
- package/dist/sync/tunnel.js.map +1 -1
- package/dist/upkeep/doctor.d.ts +5 -0
- package/dist/upkeep/doctor.d.ts.map +1 -0
- package/dist/upkeep/doctor.js +73 -0
- package/dist/upkeep/doctor.js.map +1 -0
- package/dist/upkeep/entry.d.ts +26 -0
- package/dist/upkeep/entry.d.ts.map +1 -0
- package/dist/upkeep/entry.js +2 -0
- package/dist/upkeep/entry.js.map +1 -0
- package/dist/upkeep/login.d.ts +15 -0
- package/dist/upkeep/login.d.ts.map +1 -0
- package/dist/upkeep/login.js +128 -0
- package/dist/upkeep/login.js.map +1 -0
- package/dist/upkeep/manifest.d.ts +3 -0
- package/dist/upkeep/manifest.d.ts.map +1 -0
- package/dist/upkeep/manifest.js +6 -0
- package/dist/upkeep/manifest.js.map +1 -0
- package/dist/upkeep/reconcile.d.ts +45 -0
- package/dist/upkeep/reconcile.d.ts.map +1 -0
- package/dist/upkeep/reconcile.js +159 -0
- package/dist/upkeep/reconcile.js.map +1 -0
- package/dist/upkeep/retention.d.ts +10 -0
- package/dist/upkeep/retention.d.ts.map +1 -0
- package/dist/upkeep/retention.js +71 -0
- package/dist/upkeep/retention.js.map +1 -0
- package/dist/upkeep/retired.d.ts +12 -0
- package/dist/upkeep/retired.d.ts.map +1 -0
- package/dist/upkeep/retired.js +125 -0
- package/dist/upkeep/retired.js.map +1 -0
- package/dist/upkeep/second-ic.d.ts +4 -0
- package/dist/upkeep/second-ic.d.ts.map +1 -0
- package/dist/upkeep/second-ic.js +36 -0
- package/dist/upkeep/second-ic.js.map +1 -0
- package/dist/upkeep/trash.d.ts +9 -0
- package/dist/upkeep/trash.d.ts.map +1 -0
- package/dist/upkeep/trash.js +77 -0
- package/dist/upkeep/trash.js.map +1 -0
- package/dist/watchdog.d.ts +13 -0
- package/dist/watchdog.d.ts.map +1 -0
- package/dist/watchdog.js +38 -0
- package/dist/watchdog.js.map +1 -0
- package/package.json +9 -9
- package/dist/autostart/legacy-autostart.d.ts +0 -4
- package/dist/autostart/legacy-autostart.d.ts.map +0 -1
- package/dist/autostart/legacy-autostart.js +0 -33
- package/dist/autostart/legacy-autostart.js.map +0 -1
- package/dist/device/tools/in-flight.d.ts.map +0 -1
- package/dist/device/tools/in-flight.js.map +0 -1
- package/dist/sync/project-commands.d.ts.map +0 -1
- package/dist/sync/project-commands.js.map +0 -1
- package/dist/sync/project-files.d.ts.map +0 -1
- package/dist/sync/project-files.js.map +0 -1
- package/dist/sync/project-local.d.ts.map +0 -1
- package/dist/sync/project-local.js.map +0 -1
- package/dist/sync/project-remote.d.ts.map +0 -1
- package/dist/sync/project-remote.js.map +0 -1
- package/dist/sync/project-transfer.d.ts.map +0 -1
- package/dist/sync/project-transfer.js.map +0 -1
- package/dist/wsl.d.ts.map +0 -1
- package/dist/wsl.js.map +0 -1
- /package/dist/device/{tools → sandbox-rounds}/in-flight.d.ts +0 -0
- /package/dist/device/{tools → sandbox-rounds}/in-flight.js +0 -0
- /package/dist/{wsl.d.ts → environments/wsl.d.ts} +0 -0
- /package/dist/{wsl.js → environments/wsl.js} +0 -0
|
@@ -8,7 +8,9 @@ const FIRST_TICK_MS = 20 * 60_000;
|
|
|
8
8
|
const FIRST_SPREAD_MS = 20 * 60_000;
|
|
9
9
|
const TICK_MS = 24 * 60 * 60_000;
|
|
10
10
|
const JITTER_MS = 60 * 60_000;
|
|
11
|
-
export const backupTargets = (boxes) => boxes
|
|
11
|
+
export const backupTargets = (boxes) => boxes
|
|
12
|
+
.filter((box) => box.running && box.parked !== true && !box.slug.startsWith("runner-") && box.keptElsewhere === undefined)
|
|
13
|
+
.map((box) => box.slug);
|
|
12
14
|
export const autoBackupArgs = (slug) => ["sandbox", "backup", slug, "--auto", "--json"];
|
|
13
15
|
const BackupAnswerSchema = z.object({
|
|
14
16
|
slug: z.string(),
|
|
@@ -46,6 +48,9 @@ const TidyAnswerSchema = z.object({
|
|
|
46
48
|
records: z.array(z.string()).default([]),
|
|
47
49
|
purgedFromTrash: z.array(z.string()).default([]),
|
|
48
50
|
orphanVolumes: z.array(z.string()).default([]),
|
|
51
|
+
trashedVolumeSets: z.array(z.string()).default([]),
|
|
52
|
+
danglingBuilds: z.number().default(0),
|
|
53
|
+
backups: z.array(z.object({ slug: z.string(), reason: z.string().optional() })).default([]),
|
|
49
54
|
});
|
|
50
55
|
const tidyAnswer = (line) => {
|
|
51
56
|
try {
|
|
@@ -68,11 +73,15 @@ export const tidyNews = (run) => {
|
|
|
68
73
|
}
|
|
69
74
|
const removed = [
|
|
70
75
|
answer.images.length === 0 ? undefined : plural(answer.images.length, "image"),
|
|
76
|
+
answer.danglingBuilds === 0 ? undefined : plural(answer.danglingBuilds, "leftover build"),
|
|
71
77
|
answer.records.length === 0 ? undefined : `${plural(answer.records.length, "record")} of sandboxes that are gone`,
|
|
72
78
|
answer.purgedFromTrash.length === 0 ? undefined : `${plural(answer.purgedFromTrash.length, "sandbox", "sandboxes")} from the trash`,
|
|
79
|
+
answer.backups.length === 0 ? undefined : `${plural(answer.backups.length, "stale backup")} (${answer.backups.map((backup) => backup.slug).join(", ")})`,
|
|
73
80
|
].filter((part) => part !== undefined);
|
|
74
|
-
const
|
|
75
|
-
|
|
81
|
+
const trashed = answer.trashedVolumeSets.length === 0 ? "" : `; volumes no sandbox claims moved to the trash for a week: ${answer.trashedVolumeSets.join(", ")}`;
|
|
82
|
+
const listed = answer.orphanVolumes.filter((volume) => !answer.trashedVolumeSets.some((slug) => volume.endsWith(slug)));
|
|
83
|
+
const kept = listed.length === 0 ? "" : `; volumes no sandbox claims, kept for you to decide: ${listed.join(", ")}`;
|
|
84
|
+
return `auto-tidy: ${removed.length === 0 ? "nothing to clear" : `cleared ${removed.join(", ")}`}${trashed}${kept}`;
|
|
76
85
|
};
|
|
77
86
|
export const runTidy = async (tidy, log) => {
|
|
78
87
|
try {
|
|
@@ -82,9 +91,9 @@ export const runTidy = async (tidy, log) => {
|
|
|
82
91
|
log(`auto-tidy: failed — ${errorMessage(error)}`);
|
|
83
92
|
}
|
|
84
93
|
};
|
|
85
|
-
export const startAutoBackup = (log) => {
|
|
94
|
+
export const startAutoBackup = (log, { delayMs = 0 } = {}) => {
|
|
86
95
|
const state = newBackupState();
|
|
87
|
-
return startRounds("auto-backup", log, FIRST_TICK_MS + Math.floor(Math.random() * FIRST_SPREAD_MS), () => TICK_MS + Math.floor(Math.random() * JITTER_MS), async () => {
|
|
96
|
+
return startRounds("auto-backup", log, delayMs + FIRST_TICK_MS + Math.floor(Math.random() * FIRST_SPREAD_MS), () => TICK_MS + Math.floor(Math.random() * JITTER_MS), async () => {
|
|
88
97
|
const config = await readMachineConfig();
|
|
89
98
|
if (config.sandboxBackups !== false) {
|
|
90
99
|
await runBackupRound(state, await fleet(), async (slug) => await runIc(autoBackupArgs(slug), () => undefined), log);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-backup.js","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/auto-backup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAG/C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAc,QAAQ,EAAE,aAAa,EAAgC,QAAQ,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC1H,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAQjE,MAAM,aAAa,GAAG,EAAE,GAAG,MAAM,CAAC;AAClC,MAAM,eAAe,GAAG,EAAE,GAAG,MAAM,CAAC;AAEpC,MAAM,OAAO,GAAG,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;AACjC,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"auto-backup.js","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/auto-backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,5 +8,7 @@ export declare const autoPrepareArgs: typeof icBackgroundPrepareArgs;
|
|
|
8
8
|
export type AutoPrepareState = RoundState;
|
|
9
9
|
export declare const newState: () => AutoPrepareState;
|
|
10
10
|
export declare const runTick: (state: AutoPrepareState, boxes: readonly DeviceSandbox[], prepare: (slug: string) => Promise<IcRun>, log: Log, busy?: ReadonlySet<string>) => Promise<void>;
|
|
11
|
-
export declare const startAutoPrepare: (log: Log
|
|
11
|
+
export declare const startAutoPrepare: (log: Log, { delayMs }?: {
|
|
12
|
+
readonly delayMs?: number;
|
|
13
|
+
}) => Rounds;
|
|
12
14
|
//# sourceMappingURL=auto-prepare.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-prepare.d.ts","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/auto-prepare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,KAAK,KAAK,EAA2B,KAAK,UAAU,EAAE,KAAK,MAAM,EAAyB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvI,OAAO,EAAS,uBAAuB,EAAqB,MAAM,uBAAuB,CAAC;AAa1F,OAAO,EAAE,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"auto-prepare.d.ts","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/auto-prepare.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,KAAK,KAAK,EAA2B,KAAK,UAAU,EAAE,KAAK,MAAM,EAAyB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvI,OAAO,EAAS,uBAAuB,EAAqB,MAAM,uBAAuB,CAAC;AAa1F,OAAO,EAAE,WAAW,EAAE,CAAC;AAKvB,eAAO,MAAM,cAAc,UAAW,SAAS,aAAa,EAAE,KAAG,MAAM,EAC4D,CAAC;AAGpI,eAAO,MAAM,eAAe,gCAA0B,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE1C,eAAO,MAAM,QAAQ,QAAO,gBAAmC,CAAC;AAGhE,eAAO,MAAM,OAAO,UACT,gBAAgB,SAChB,SAAS,aAAa,EAAE,WACtB,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC,OACpC,GAAG,SACF,WAAW,CAAC,MAAM,CAAC,KAC1B,OAAO,CAAC,IAAI,CAQV,CAAC;AAKN,eAAO,MAAM,gBAAgB,QAAS,GAAG,gBAAmB;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,KAAQ,MAchG,CAAC"}
|
|
@@ -5,13 +5,13 @@ const FIRST_TICK_MS = 5 * 60_000;
|
|
|
5
5
|
const TICK_MS = 6 * 60 * 60_000;
|
|
6
6
|
const JITTER_MS = 30 * 60_000;
|
|
7
7
|
export { ticksToSkip };
|
|
8
|
-
export const prepareTargets = (boxes) => boxes.filter((box) => box.running && !box.slug.startsWith("runner-")).map((box) => box.slug);
|
|
8
|
+
export const prepareTargets = (boxes) => boxes.filter((box) => box.running && !box.slug.startsWith("runner-") && box.keptElsewhere === undefined).map((box) => box.slug);
|
|
9
9
|
export const autoPrepareArgs = icBackgroundPrepareArgs;
|
|
10
10
|
export const newState = () => newRoundState();
|
|
11
11
|
export const runTick = async (state, boxes, prepare, log, busy = icInFlight) => await runRound(state, prepareTargets(boxes), { name: "auto-prepare", run: prepare, said: (slug, run) => `auto-prepare ${slug}: ${lastLine(run.output) ?? "done"}` }, log, busy);
|
|
12
|
-
export const startAutoPrepare = (log) => {
|
|
12
|
+
export const startAutoPrepare = (log, { delayMs = 0 } = {}) => {
|
|
13
13
|
const state = newState();
|
|
14
|
-
return startRounds("auto-prepare", log, FIRST_TICK_MS + Math.floor(Math.random() * JITTER_MS), () => TICK_MS + Math.floor(Math.random() * JITTER_MS), async () => {
|
|
14
|
+
return startRounds("auto-prepare", log, delayMs + FIRST_TICK_MS + Math.floor(Math.random() * JITTER_MS), () => TICK_MS + Math.floor(Math.random() * JITTER_MS), async () => {
|
|
15
15
|
if ((await readMachineConfig()).sandboxUpdates !== false) {
|
|
16
16
|
await runTick(state, await fleet(), async (slug) => await runIc(autoPrepareArgs(slug), () => undefined), log);
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-prepare.js","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/auto-prepare.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAc,QAAQ,EAAE,aAAa,EAAgC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvI,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAO1F,MAAM,aAAa,GAAG,CAAC,GAAG,MAAM,CAAC;AAEjC,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;AAEhC,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"auto-prepare.js","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/auto-prepare.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAc,QAAQ,EAAE,aAAa,EAAgC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACvI,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAO1F,MAAM,aAAa,GAAG,CAAC,GAAG,MAAM,CAAC;AAEjC,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;AAEhC,MAAM,SAAS,GAAG,EAAE,GAAG,MAAM,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,CAAC;AAKvB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAA+B,EAAY,EAAE,CACxE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAGpI,MAAM,CAAC,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAIvD,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAqB,EAAE,CAAC,aAAa,EAAE,CAAC;AAGhE,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EACxB,KAAuB,EACvB,KAA+B,EAC/B,OAAyC,EACzC,GAAQ,EACR,IAAI,GAAwB,UAAU,EACzB,EAAE,CACf,MAAM,QAAQ,CACV,KAAK,EACL,cAAc,CAAC,KAAK,CAAC,EAErB,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,gBAAgB,IAAI,KAAK,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,MAAM,EAAE,EAAE,EACtH,GAAG,EACH,IAAI,CACP,CAAC;AAKN,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAQ,EAAE,EAAE,OAAO,GAAG,CAAC,EAAE,GAAkC,EAAE,EAAU,EAAE;IACtG,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,OAAO,WAAW,CACd,cAAc,EACd,GAAG,EACH,OAAO,GAAG,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,EAC/D,GAAG,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,EACrD,KAAK,IAAI,EAAE;QAEP,IAAI,CAAC,MAAM,iBAAiB,EAAE,CAAC,CAAC,cAAc,KAAK,KAAK,EAAE,CAAC;YACvD,MAAM,OAAO,CAAC,KAAK,EAAE,MAAM,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC;QAClH,CAAC;IACL,CAAC,CACJ,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-flight.d.ts","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/in-flight.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAE1B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAGpC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,IAAI,CAAC;CAC/C;AAED,eAAO,MAAM,aAAa,QAAO,aAwBhC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-flight.js","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/in-flight.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,aAAa,GAAG,GAAkB,EAAE;IAC7C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,OAAO;QACH,KAAK;QACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACX,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAChB,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,OAAO,GAAG,EAAE;gBACR,IAAI,QAAQ,EAAE,CAAC;oBACX,OAAO;gBACX,CAAC;gBACD,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;gBACxC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;oBACX,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBACtB,OAAO;gBACX,CAAC;gBACD,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACnB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC,CAAC;QACN,CAAC;KACJ,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -33,6 +33,7 @@ declare const FixAnswerSchema: z.ZodObject<{
|
|
|
33
33
|
}, z.core.$strip>;
|
|
34
34
|
}, z.core.$strip>;
|
|
35
35
|
export type FixAnswer = z.infer<typeof FixAnswerSchema>;
|
|
36
|
+
export type FixReport = FixAnswer["report"];
|
|
36
37
|
export interface FixProgress {
|
|
37
38
|
readonly slug: string | undefined;
|
|
38
39
|
readonly doing: string | undefined;
|
|
@@ -43,9 +44,10 @@ export type FixRunReading = {
|
|
|
43
44
|
readonly unavailable: string;
|
|
44
45
|
} | {
|
|
45
46
|
readonly answers: readonly FixAnswer[];
|
|
47
|
+
readonly machine?: FixReport;
|
|
46
48
|
};
|
|
47
49
|
export declare const readFixRun: (run: IcRun) => FixRunReading;
|
|
48
|
-
export declare const settled: (answer: FixAnswer) => boolean;
|
|
50
|
+
export declare const settled: (answer: Pick<FixAnswer, "report">) => boolean;
|
|
49
51
|
export declare const verdictLine: (answer: FixAnswer) => string;
|
|
50
52
|
export declare const localSlugOf: (sandboxUrl: string, known: ReadonlySet<string>, loopback: boolean) => string | undefined;
|
|
51
53
|
export interface LinkView {
|
|
@@ -53,12 +55,25 @@ export interface LinkView {
|
|
|
53
55
|
readonly reading: LinkReading;
|
|
54
56
|
}
|
|
55
57
|
export declare const unreachableHere: (links: readonly LinkView[], known: ReadonlySet<string>, loopback: ReadonlySet<string>, now: number) => string[];
|
|
56
|
-
export
|
|
58
|
+
export interface ListedSandbox {
|
|
59
|
+
readonly slug: string;
|
|
60
|
+
readonly keptElsewhere?: string | undefined;
|
|
61
|
+
}
|
|
62
|
+
export interface KeeperScope {
|
|
63
|
+
readonly own: readonly string[];
|
|
64
|
+
readonly running: readonly string[];
|
|
65
|
+
readonly present: (slug: string) => boolean;
|
|
66
|
+
readonly elsewhere: ReadonlySet<string>;
|
|
67
|
+
}
|
|
68
|
+
export declare const keeperScope: (listed: readonly ListedSandbox[] | undefined, records: readonly string[], trashed: readonly string[] | undefined) => KeeperScope;
|
|
69
|
+
export declare const hostedSlugs: (listing: () => Promise<readonly ListedSandbox[]>, records: () => Promise<readonly string[]>) => Promise<string[]>;
|
|
70
|
+
export declare const trashedFrom: (volumes: string) => string[];
|
|
57
71
|
export interface KeeperSeams {
|
|
58
72
|
readonly enabled: () => Promise<boolean>;
|
|
59
73
|
readonly fix: (slug: string | undefined, onLine: (line: string) => void) => Promise<IcRun>;
|
|
60
|
-
readonly listing: () => Promise<readonly
|
|
74
|
+
readonly listing: () => Promise<readonly ListedSandbox[]>;
|
|
61
75
|
readonly records: () => Promise<readonly string[]>;
|
|
76
|
+
readonly trashed: () => Promise<readonly string[]>;
|
|
62
77
|
readonly swapping: () => Promise<readonly string[]>;
|
|
63
78
|
readonly links: () => readonly LinkView[];
|
|
64
79
|
readonly loopback: ReadonlySet<string>;
|
|
@@ -70,6 +85,8 @@ export interface KeeperSeams {
|
|
|
70
85
|
interface Wait {
|
|
71
86
|
readonly failures: number;
|
|
72
87
|
readonly until: number;
|
|
88
|
+
readonly failedAt?: number;
|
|
89
|
+
readonly fixedOnce?: boolean;
|
|
73
90
|
}
|
|
74
91
|
export interface KeeperState {
|
|
75
92
|
sweepDueAt: number;
|
|
@@ -77,17 +94,22 @@ export interface KeeperState {
|
|
|
77
94
|
unavailable: Wait;
|
|
78
95
|
readonly waits: Map<string, Wait>;
|
|
79
96
|
readonly said: Map<string, string>;
|
|
80
|
-
listed: readonly
|
|
97
|
+
listed: readonly ListedSandbox[] | undefined;
|
|
98
|
+
trashed: readonly string[] | undefined;
|
|
81
99
|
fixing: boolean;
|
|
82
100
|
on: boolean | undefined;
|
|
83
101
|
}
|
|
84
102
|
export declare const newKeeperState: (start: number) => KeeperState;
|
|
103
|
+
export declare const fixedClears: (wait: Pick<Wait, "failures" | "failedAt" | "fixedOnce"> | undefined, now: number) => boolean;
|
|
85
104
|
export declare const runKeeperRound: (state: KeeperState, seams: KeeperSeams, log: Log) => Promise<void>;
|
|
86
105
|
export interface KeeperWiring {
|
|
87
106
|
readonly links: () => readonly LinkView[];
|
|
88
107
|
readonly loopback: ReadonlySet<string>;
|
|
89
108
|
readonly watching: () => boolean;
|
|
90
109
|
}
|
|
110
|
+
export declare const KEEPER_HOLD: {
|
|
111
|
+
readonly moves: false;
|
|
112
|
+
};
|
|
91
113
|
export declare const keeperOn: () => Promise<boolean>;
|
|
92
114
|
export declare const machineKeeperSeams: ({ links, loopback, watching }: KeeperWiring) => KeeperSeams;
|
|
93
115
|
export declare const startKeeper: (log: Log, wiring: KeeperWiring) => Rounds;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keeper.d.ts","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/keeper.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"keeper.d.ts","sourceRoot":"","sources":["../../../src/device/sandbox-rounds/keeper.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
1
3
|
import { errorMessage } from "@intentic/base/errors";
|
|
2
4
|
import { z } from "zod";
|
|
3
5
|
import { readMachineConfig } from "../../environments/machine.js";
|
|
@@ -11,8 +13,10 @@ const LOOK_EVERY_MS = 10_000;
|
|
|
11
13
|
export const UNREACHABLE_AFTER_MS = 60_000;
|
|
12
14
|
export const FIX_DEADLINE_MS = 8 * 60_000;
|
|
13
15
|
const BACKOFF_FIRST_MS = 3 * 60_000;
|
|
14
|
-
const BACKOFF_MAX_MS =
|
|
16
|
+
const BACKOFF_MAX_MS = 20 * 60_000;
|
|
15
17
|
export const backoffMs = (failures) => (failures <= 0 ? 0 : Math.min(BACKOFF_FIRST_MS * 2 ** (failures - 1), BACKOFF_MAX_MS));
|
|
18
|
+
const REPEATED_FAILURES = 2;
|
|
19
|
+
const FAILURES_REMEMBERED_MS = 60 * 60_000;
|
|
16
20
|
export const keeperFixArgs = (slug) => ["sandbox", "fix", ...(slug === undefined ? [] : [slug]), "--auto", "--json", "--source", "agent"];
|
|
17
21
|
export const FIX_PROGRESS_PREFIX = "intentic-fix:";
|
|
18
22
|
const FixCheckSchema = z.object({
|
|
@@ -30,6 +34,7 @@ const FixReportSchema = z.object({
|
|
|
30
34
|
checks: z.array(FixCheckSchema).default([]),
|
|
31
35
|
});
|
|
32
36
|
const FixAnswerSchema = z.object({ slug: z.string(), report: FixReportSchema });
|
|
37
|
+
const FixMachineSchema = z.object({ slug: z.null(), report: FixReportSchema });
|
|
33
38
|
const FixProgressSchema = z.object({
|
|
34
39
|
slug: z.string().optional(),
|
|
35
40
|
doing: z.string().optional(),
|
|
@@ -49,12 +54,16 @@ export const fixProgress = (line) => {
|
|
|
49
54
|
const parsed = trimmed.startsWith(FIX_PROGRESS_PREFIX) ? lineAs(FixProgressSchema, trimmed.slice(FIX_PROGRESS_PREFIX.length)) : undefined;
|
|
50
55
|
return parsed === undefined ? undefined : { slug: parsed.slug, doing: parsed.report?.doing ?? parsed.doing };
|
|
51
56
|
};
|
|
52
|
-
|
|
57
|
+
const jsonLines = (output) => output
|
|
53
58
|
.split(/\r?\n/)
|
|
54
59
|
.map((line) => line.trim())
|
|
55
|
-
.filter((line) => line.startsWith("{"))
|
|
60
|
+
.filter((line) => line.startsWith("{"));
|
|
61
|
+
export const fixAnswers = (output) => jsonLines(output)
|
|
56
62
|
.map((line) => lineAs(FixAnswerSchema, line))
|
|
57
63
|
.filter((answer) => answer !== undefined);
|
|
64
|
+
const machineAnswer = (output) => jsonLines(output)
|
|
65
|
+
.map((line) => lineAs(FixMachineSchema, line)?.report)
|
|
66
|
+
.find((report) => report !== undefined);
|
|
58
67
|
const progressCount = (output) => output.split(/\r?\n/).filter((line) => fixProgress(line) !== undefined).length;
|
|
59
68
|
const refusalOf = (run) => run.output
|
|
60
69
|
.split(/\r?\n/)
|
|
@@ -64,25 +73,34 @@ const refusalOf = (run) => run.output
|
|
|
64
73
|
`ic exited with ${run.code} and said nothing`;
|
|
65
74
|
export const readFixRun = (run) => {
|
|
66
75
|
const answers = fixAnswers(run.output);
|
|
67
|
-
|
|
76
|
+
const machine = machineAnswer(run.output);
|
|
77
|
+
if (run.code !== 0 && run.timedOut !== true && answers.length === 0 && machine === undefined && progressCount(run.output) === 0) {
|
|
68
78
|
return { unavailable: refusalOf(run) };
|
|
69
79
|
}
|
|
70
|
-
return { answers };
|
|
80
|
+
return machine === undefined ? { answers } : { answers, machine };
|
|
71
81
|
};
|
|
72
|
-
|
|
82
|
+
const ELSEWHERE = "elsewhere";
|
|
83
|
+
export const settled = (answer) => answer.report.outcome === "healthy" || answer.report.outcome === "fixed" || answer.report.outcome === ELSEWHERE;
|
|
73
84
|
const EXIT_RESTART = 4;
|
|
74
85
|
const leftLine = (slug, check) => {
|
|
75
86
|
const what = `${check.label}: ${check.problem ?? check.state}`;
|
|
76
87
|
if (check.fix === "consent") {
|
|
77
|
-
return `${what} (needs your yes: \`intentic-machine sandbox fix ${slug}\`)`;
|
|
88
|
+
return `${what} (needs your yes: \`intentic-machine sandbox fix${slug === undefined ? "" : ` ${slug}`}\`)`;
|
|
78
89
|
}
|
|
79
90
|
return check.remedy === undefined ? what : `${what} (${check.remedy})`;
|
|
80
91
|
};
|
|
81
92
|
export const verdictLine = (answer) => {
|
|
93
|
+
if (answer.report.outcome === ELSEWHERE) {
|
|
94
|
+
return `keeper ${answer.slug}: ${answer.report.doing ?? "left to the other side of this computer, whose machine agent keeps it."}`;
|
|
95
|
+
}
|
|
82
96
|
const outcome = answer.report.outcome ?? answer.report.stage;
|
|
83
97
|
const left = settled(answer) ? [] : answer.report.checks.filter((check) => check.state === "fail" || check.state === "warn");
|
|
84
98
|
return `keeper ${answer.slug}: ${outcome}${left.length === 0 ? "" : ` — ${left.map((check) => leftLine(answer.slug, check)).join("; ")}`}`;
|
|
85
99
|
};
|
|
100
|
+
const machineLine = (report) => {
|
|
101
|
+
const left = report.checks.filter((check) => check.state === "fail" || check.state === "warn");
|
|
102
|
+
return `keeper: this machine: ${report.outcome ?? report.stage}${left.length === 0 ? "" : ` — ${left.map((check) => leftLine(undefined, check)).join("; ")}`}`;
|
|
103
|
+
};
|
|
86
104
|
export const localSlugOf = (sandboxUrl, known, loopback) => {
|
|
87
105
|
const slugs = pairingSlugs(sandboxUrl);
|
|
88
106
|
return slugs.find((slug) => known.has(slug)) ?? (loopback ? slugs[0] : undefined);
|
|
@@ -94,9 +112,36 @@ export const unreachableHere = (links, known, loopback, now) => links.flatMap(({
|
|
|
94
112
|
});
|
|
95
113
|
const answeringSlugs = (links) => links.filter(({ reading }) => reading.state === "open").flatMap(({ url }) => pairingSlugs(url));
|
|
96
114
|
const people = (slugs) => slugs.filter((slug) => !slug.startsWith("runner-"));
|
|
115
|
+
export const keeperScope = (listed, records, trashed) => {
|
|
116
|
+
if (listed === undefined) {
|
|
117
|
+
return { own: people(records), running: [], present: () => true, elsewhere: new Set() };
|
|
118
|
+
}
|
|
119
|
+
const containers = new Set(listed.map((row) => row.slug));
|
|
120
|
+
const binned = new Set(trashed ?? []);
|
|
121
|
+
const mine = listed.filter((row) => row.keptElsewhere === undefined).map((row) => row.slug);
|
|
122
|
+
const recordedInTrash = records.filter((slug) => !containers.has(slug) && binned.has(slug));
|
|
123
|
+
return {
|
|
124
|
+
own: people([...new Set([...mine, ...recordedInTrash])]),
|
|
125
|
+
running: people(mine),
|
|
126
|
+
present: (slug) => containers.has(slug) || binned.has(slug),
|
|
127
|
+
elsewhere: new Set(listed.filter((row) => row.keptElsewhere !== undefined).map((row) => row.slug)),
|
|
128
|
+
};
|
|
129
|
+
};
|
|
97
130
|
export const hostedSlugs = async (listing, records) => {
|
|
98
131
|
const listed = await listing().catch(() => undefined);
|
|
99
|
-
return people(listed
|
|
132
|
+
return people(listed === undefined ? await records() : listed.filter((row) => row.keptElsewhere === undefined).map((row) => row.slug));
|
|
133
|
+
};
|
|
134
|
+
export const trashedFrom = (volumes) => volumes
|
|
135
|
+
.split(/\r?\n/)
|
|
136
|
+
.map((name) => /^intentic-trashed-\d+-(.+)$/.exec(name.trim())?.[1])
|
|
137
|
+
.filter((slug) => slug !== undefined);
|
|
138
|
+
const exec = promisify(execFile);
|
|
139
|
+
const readTrashed = async () => {
|
|
140
|
+
const { stdout } = await exec("docker", ["volume", "ls", "--format", "{{.Name}}", "--filter", "name=intentic-trashed-"], {
|
|
141
|
+
timeout: 20_000,
|
|
142
|
+
windowsHide: true,
|
|
143
|
+
});
|
|
144
|
+
return trashedFrom(stdout);
|
|
100
145
|
};
|
|
101
146
|
export const newKeeperState = (start) => ({
|
|
102
147
|
sweepDueAt: start + FIRST_SWEEP_MS,
|
|
@@ -104,7 +149,8 @@ export const newKeeperState = (start) => ({
|
|
|
104
149
|
unavailable: { failures: 0, until: 0 },
|
|
105
150
|
waits: new Map(),
|
|
106
151
|
said: new Map(),
|
|
107
|
-
listed:
|
|
152
|
+
listed: undefined,
|
|
153
|
+
trashed: undefined,
|
|
108
154
|
fixing: false,
|
|
109
155
|
on: undefined,
|
|
110
156
|
});
|
|
@@ -139,27 +185,42 @@ const readSwitch = async (state, seams, log) => {
|
|
|
139
185
|
const minutes = (ms) => `${Math.round(ms / 60_000)} min`;
|
|
140
186
|
const waitAfter = (state, slug, now) => {
|
|
141
187
|
const failures = (state.waits.get(slug)?.failures ?? 0) + 1;
|
|
142
|
-
state.waits.set(slug, { failures, until: now + backoffMs(failures) });
|
|
188
|
+
state.waits.set(slug, { failures, until: now + backoffMs(failures), failedAt: now });
|
|
143
189
|
return backoffMs(failures);
|
|
144
190
|
};
|
|
191
|
+
export const fixedClears = (wait, now) => wait === undefined ||
|
|
192
|
+
wait.failures < REPEATED_FAILURES ||
|
|
193
|
+
wait.fixedOnce === true ||
|
|
194
|
+
wait.failedAt === undefined ||
|
|
195
|
+
now - wait.failedAt > FAILURES_REMEMBERED_MS;
|
|
145
196
|
const noteAnswer = (state, answer, log, now) => {
|
|
146
197
|
const line = verdictLine(answer);
|
|
147
198
|
if (settled(answer)) {
|
|
199
|
+
const held = state.waits.get(answer.slug);
|
|
200
|
+
const fixed = answer.report.outcome === "fixed";
|
|
201
|
+
if (fixed && held !== undefined && !fixedClears(held, now)) {
|
|
202
|
+
const wait = Math.max(SWEEP_EVERY_MS, backoffMs(held.failures));
|
|
203
|
+
state.waits.set(answer.slug, { ...held, until: now + wait, fixedOnce: true });
|
|
204
|
+
state.said.set(answer.slug, line);
|
|
205
|
+
log(`${line} — after ${held.failures} failures within the hour, so the next look waits ${minutes(wait)}`);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
148
208
|
state.waits.set(answer.slug, { failures: 0, until: now + SWEEP_EVERY_MS });
|
|
149
|
-
if (
|
|
209
|
+
if (fixed) {
|
|
150
210
|
state.said.set(answer.slug, line);
|
|
151
211
|
log(line);
|
|
152
212
|
}
|
|
153
213
|
else {
|
|
154
214
|
sayOnce(state, answer.slug, line, log);
|
|
155
215
|
}
|
|
156
|
-
return;
|
|
216
|
+
return true;
|
|
157
217
|
}
|
|
158
218
|
const wait = waitAfter(state, answer.slug, now);
|
|
159
219
|
if (state.said.get(answer.slug) !== line) {
|
|
160
220
|
state.said.set(answer.slug, line);
|
|
161
221
|
log(`${line} — looking again in ${minutes(wait)}`);
|
|
162
222
|
}
|
|
223
|
+
return false;
|
|
163
224
|
};
|
|
164
225
|
const noteRun = (state, run, asked, log, now) => {
|
|
165
226
|
const reading = readFixRun(run);
|
|
@@ -174,8 +235,13 @@ const noteRun = (state, run, asked, log, now) => {
|
|
|
174
235
|
}
|
|
175
236
|
state.unavailable = { failures: 0, until: 0 };
|
|
176
237
|
state.said.delete(":ic");
|
|
177
|
-
|
|
178
|
-
|
|
238
|
+
const cleared = reading.answers.map((answer) => noteAnswer(state, answer, log, now));
|
|
239
|
+
const machineSettled = reading.machine === undefined || settled({ report: reading.machine });
|
|
240
|
+
if (reading.machine !== undefined && !machineSettled) {
|
|
241
|
+
sayOnce(state, ":machine", machineLine(reading.machine), log);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
state.said.delete(":machine");
|
|
179
245
|
}
|
|
180
246
|
if (run.code === EXIT_RESTART) {
|
|
181
247
|
sayOnce(state, ":restart", "keeper: this computer needs a restart or a sign-out to finish what ic started.", log);
|
|
@@ -189,14 +255,17 @@ const noteRun = (state, run, asked, log, now) => {
|
|
|
189
255
|
state.said.delete(asked);
|
|
190
256
|
log(`keeper ${asked}: ic gave no verdict (${lastLine(run.output)?.trim() ?? "no output"}) — looking again in ${minutes(wait)}`);
|
|
191
257
|
}
|
|
192
|
-
return !unanswered &&
|
|
258
|
+
return !unanswered && machineSettled && cleared.every(Boolean);
|
|
193
259
|
};
|
|
194
260
|
const runFix = async (state, seams, slug, touches, log) => {
|
|
195
261
|
state.fixing = true;
|
|
196
|
-
const releases = touches.map((touched) => seams.hold(touched));
|
|
262
|
+
const releases = new Map(touches.map((touched) => [touched, seams.hold(touched)]));
|
|
197
263
|
const doings = new Set();
|
|
198
264
|
const onLine = (line) => {
|
|
199
265
|
const progress = fixProgress(line);
|
|
266
|
+
if (progress?.slug !== undefined && !releases.has(progress.slug)) {
|
|
267
|
+
releases.set(progress.slug, seams.hold(progress.slug));
|
|
268
|
+
}
|
|
200
269
|
const doing = progress?.doing;
|
|
201
270
|
const about = progress?.slug ?? slug;
|
|
202
271
|
const said = `keeper${about === undefined ? "" : ` ${about}`}: ${doing ?? ""}`;
|
|
@@ -212,23 +281,43 @@ const runFix = async (state, seams, slug, touches, log) => {
|
|
|
212
281
|
return { code: 127, output: errorMessage(error) };
|
|
213
282
|
}
|
|
214
283
|
finally {
|
|
215
|
-
for (const release of releases) {
|
|
284
|
+
for (const release of releases.values()) {
|
|
216
285
|
release();
|
|
217
286
|
}
|
|
218
287
|
state.fixing = false;
|
|
219
288
|
}
|
|
220
289
|
};
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
290
|
+
const relist = async (state, seams, records) => {
|
|
291
|
+
const listed = await seams.listing().catch(() => undefined);
|
|
292
|
+
if (listed === undefined) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
state.listed = listed;
|
|
296
|
+
const containers = new Set(listed.map((row) => row.slug));
|
|
297
|
+
state.trashed = records.some((slug) => !containers.has(slug)) ? await seams.trashed().catch(() => undefined) : [];
|
|
298
|
+
};
|
|
299
|
+
const sweep = async (state, seams, scope, log) => {
|
|
300
|
+
if (scope.own.length === 0) {
|
|
301
|
+
sayOnce(state, ":none", "keeper: this environment keeps no sandbox of its own, so there is nothing to sweep.", log);
|
|
302
|
+
state.sweepDueAt = seams.now() + SWEEP_EVERY_MS;
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
state.said.delete(":none");
|
|
306
|
+
const run = await runFix(state, seams, undefined, scope.running, log);
|
|
225
307
|
const now = seams.now();
|
|
226
308
|
const clean = noteRun(state, run, undefined, log, now);
|
|
227
309
|
state.sweepFailures = clean ? 0 : state.sweepFailures + 1;
|
|
228
310
|
state.sweepDueAt = now + Math.max(SWEEP_EVERY_MS, backoffMs(state.sweepFailures));
|
|
229
311
|
};
|
|
230
|
-
const dueTarget = async (state, seams, links, known, now) => {
|
|
231
|
-
const
|
|
312
|
+
const dueTarget = async (state, seams, links, known, scope, log, now) => {
|
|
313
|
+
const here = unreachableHere(links, known, seams.loopback, now).filter((slug) => {
|
|
314
|
+
if (!scope.present(slug)) {
|
|
315
|
+
sayOnce(state, slug, `keeper ${slug}: its link is down, but this engine has no container and no trash entry for it, so there is nothing here to fix.`, log);
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
return !scope.elsewhere.has(slug);
|
|
319
|
+
});
|
|
320
|
+
const candidates = here.filter((slug) => !seams.busy.has(slug) && (state.waits.get(slug)?.until ?? 0) <= now);
|
|
232
321
|
if (candidates.length === 0) {
|
|
233
322
|
return undefined;
|
|
234
323
|
}
|
|
@@ -243,30 +332,39 @@ export const runKeeperRound = async (state, seams, log) => {
|
|
|
243
332
|
for (const slug of answeringSlugs(links)) {
|
|
244
333
|
state.waits.delete(slug);
|
|
245
334
|
}
|
|
246
|
-
const
|
|
247
|
-
const
|
|
248
|
-
if (
|
|
249
|
-
await
|
|
250
|
-
|
|
335
|
+
const records = await seams.records();
|
|
336
|
+
const sweepDue = seams.now() >= state.sweepDueAt && seams.busy.size === 0;
|
|
337
|
+
if (sweepDue) {
|
|
338
|
+
await relist(state, seams, records);
|
|
339
|
+
}
|
|
340
|
+
const scope = keeperScope(state.listed, records, state.trashed);
|
|
341
|
+
if (sweepDue) {
|
|
342
|
+
await sweep(state, seams, scope, log);
|
|
343
|
+
if (scope.own.length > 0) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
251
346
|
}
|
|
252
|
-
const
|
|
347
|
+
const known = new Set([...records, ...(state.listed ?? []).map((row) => row.slug)]);
|
|
348
|
+
const target = await dueTarget(state, seams, links, known, scope, log, seams.now());
|
|
253
349
|
if (target !== undefined) {
|
|
254
350
|
const run = await runFix(state, seams, target, [target], log);
|
|
255
351
|
noteRun(state, run, target, log, seams.now());
|
|
256
352
|
}
|
|
257
353
|
};
|
|
354
|
+
export const KEEPER_HOLD = { moves: false };
|
|
258
355
|
export const keeperOn = async () => (await readMachineConfig()).sandboxKeeper !== false;
|
|
259
356
|
export const machineKeeperSeams = ({ links, loopback, watching }) => ({
|
|
260
357
|
enabled: keeperOn,
|
|
261
358
|
fix: async (slug, onLine) => await runIc(keeperFixArgs(slug), onLine, {}, { deadlineMs: FIX_DEADLINE_MS }),
|
|
262
|
-
listing: async () => (await fleet()).map((
|
|
359
|
+
listing: async () => (await fleet()).map(({ slug, keptElsewhere }) => ({ slug, keptElsewhere })),
|
|
263
360
|
records: async () => await readChannelSlugs(),
|
|
361
|
+
trashed: readTrashed,
|
|
264
362
|
swapping: async () => swapsUnderway(await readSwapRecords(), Date.now()),
|
|
265
363
|
links,
|
|
266
364
|
loopback,
|
|
267
365
|
watching,
|
|
268
366
|
busy: icInFlight,
|
|
269
|
-
hold: (slug) => holdIcFlow(slug,
|
|
367
|
+
hold: (slug) => holdIcFlow(slug, KEEPER_HOLD),
|
|
270
368
|
now: Date.now,
|
|
271
369
|
});
|
|
272
370
|
export const startKeeper = (log, wiring) => {
|