charness 3.8.0 → 3.9.1
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/CHANGELOG.md +12 -0
- package/DEVELOPMENT.md +3 -1
- package/SETUP.md +4 -3
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +12 -5
- package/dist/cli.js.map +1 -1
- package/dist/connectors/jira/inbound.d.ts +25 -1
- package/dist/connectors/jira/inbound.d.ts.map +1 -1
- package/dist/connectors/jira/inbound.js +74 -2
- package/dist/connectors/jira/inbound.js.map +1 -1
- package/dist/connectors/jira/issueContext.d.ts +11 -2
- package/dist/connectors/jira/issueContext.d.ts.map +1 -1
- package/dist/connectors/jira/issueContext.js +22 -2
- package/dist/connectors/jira/issueContext.js.map +1 -1
- package/dist/connectors/jira/prompt.d.ts +12 -2
- package/dist/connectors/jira/prompt.d.ts.map +1 -1
- package/dist/connectors/jira/prompt.js +59 -5
- package/dist/connectors/jira/prompt.js.map +1 -1
- package/dist/connectors/telegram/commands/runners.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/runners.js +64 -26
- package/dist/connectors/telegram/commands/runners.js.map +1 -1
- package/dist/connectors/telegram/runnerPairingMessages.d.ts +7 -5
- package/dist/connectors/telegram/runnerPairingMessages.d.ts.map +1 -1
- package/dist/connectors/telegram/runnerPairingMessages.js +17 -10
- package/dist/connectors/telegram/runnerPairingMessages.js.map +1 -1
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/de.js +6 -4
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +6 -4
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +6 -4
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +6 -4
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/hi.d.ts.map +1 -1
- package/dist/i18n/hi.js +6 -4
- package/dist/i18n/hi.js.map +1 -1
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ja.js +6 -4
- package/dist/i18n/ja.js.map +1 -1
- package/dist/i18n/ka.d.ts.map +1 -1
- package/dist/i18n/ka.js +6 -4
- package/dist/i18n/ka.js.map +1 -1
- package/dist/i18n/pt.d.ts.map +1 -1
- package/dist/i18n/pt.js +6 -4
- package/dist/i18n/pt.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +6 -4
- package/dist/i18n/ru.js.map +1 -1
- package/dist/i18n/uk.d.ts.map +1 -1
- package/dist/i18n/uk.js +6 -4
- package/dist/i18n/uk.js.map +1 -1
- package/dist/i18n/uz.d.ts.map +1 -1
- package/dist/i18n/uz.js +6 -4
- package/dist/i18n/uz.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +6 -4
- package/dist/i18n/zh.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/remoteRun/pairedRunners.js +1 -1
- package/dist/remoteRun/pairedRunners.js.map +1 -1
- package/dist/remoteRun/runnerSummary.js +1 -1
- package/dist/remoteRun/runnerSummary.js.map +1 -1
- package/dist/remoteRun/runners.d.ts +8 -1
- package/dist/remoteRun/runners.d.ts.map +1 -1
- package/dist/remoteRun/runners.js +14 -2
- package/dist/remoteRun/runners.js.map +1 -1
- package/dist/remoteRun/runnersConfig.d.ts +2 -0
- package/dist/remoteRun/runnersConfig.d.ts.map +1 -1
- package/dist/remoteRun/runnersConfig.js.map +1 -1
- package/dist/requests/requestHeader.d.ts +2 -1
- package/dist/requests/requestHeader.d.ts.map +1 -1
- package/dist/requests/requestHeader.js +6 -2
- package/dist/requests/requestHeader.js.map +1 -1
- package/dist/requests/storedPromptRefresh.d.ts +16 -0
- package/dist/requests/storedPromptRefresh.d.ts.map +1 -0
- package/dist/requests/storedPromptRefresh.js +36 -0
- package/dist/requests/storedPromptRefresh.js.map +1 -0
- package/dist/runnerUtility/adminCheck.d.ts +7 -0
- package/dist/runnerUtility/adminCheck.d.ts.map +1 -1
- package/dist/runnerUtility/adminCheck.js +5 -4
- package/dist/runnerUtility/adminCheck.js.map +1 -1
- package/dist/runnerUtility/adminService.d.ts +22 -0
- package/dist/runnerUtility/adminService.d.ts.map +1 -0
- package/dist/runnerUtility/adminService.js +145 -0
- package/dist/runnerUtility/adminService.js.map +1 -0
- package/dist/runnerUtility/hubClient.d.ts +2 -2
- package/dist/runnerUtility/hubClient.d.ts.map +1 -1
- package/dist/runnerUtility/hubClient.js +1 -1
- package/dist/runnerUtility/hubClient.js.map +1 -1
- package/dist/runnerUtility/linkLoop.d.ts +0 -8
- package/dist/runnerUtility/linkLoop.d.ts.map +1 -1
- package/dist/runnerUtility/linkLoop.js +3 -10
- package/dist/runnerUtility/linkLoop.js.map +1 -1
- package/dist/runnerUtility/pairArgs.d.ts +16 -0
- package/dist/runnerUtility/pairArgs.d.ts.map +1 -0
- package/dist/runnerUtility/pairArgs.js +17 -0
- package/dist/runnerUtility/pairArgs.js.map +1 -0
- package/dist/runnerUtility/rootServiceCli.d.ts +8 -0
- package/dist/runnerUtility/rootServiceCli.d.ts.map +1 -0
- package/dist/runnerUtility/rootServiceCli.js +31 -0
- package/dist/runnerUtility/rootServiceCli.js.map +1 -0
- package/dist/runnerUtility/runnerCli.js +29 -23
- package/dist/runnerUtility/runnerCli.js.map +1 -1
- package/dist/runnerUtility/runnerCommands.d.ts +13 -4
- package/dist/runnerUtility/runnerCommands.d.ts.map +1 -1
- package/dist/runnerUtility/runnerCommands.js +58 -12
- package/dist/runnerUtility/runnerCommands.js.map +1 -1
- package/dist/runnerUtility/serviceCommon.d.ts +97 -0
- package/dist/runnerUtility/serviceCommon.d.ts.map +1 -0
- package/dist/runnerUtility/serviceCommon.js +209 -0
- package/dist/runnerUtility/serviceCommon.js.map +1 -0
- package/dist/runnerUtility/serviceManager.d.ts +14 -17
- package/dist/runnerUtility/serviceManager.d.ts.map +1 -1
- package/dist/runnerUtility/serviceManager.js +132 -201
- package/dist/runnerUtility/serviceManager.js.map +1 -1
- package/dist/runnerUtility/serviceUnits.d.ts +3 -1
- package/dist/runnerUtility/serviceUnits.d.ts.map +1 -1
- package/dist/runnerUtility/serviceUnits.js +26 -6
- package/dist/runnerUtility/serviceUnits.js.map +1 -1
- package/dist/runners/bootstrapLine.d.ts +10 -1
- package/dist/runners/bootstrapLine.d.ts.map +1 -1
- package/dist/runners/bootstrapLine.js +102 -17
- package/dist/runners/bootstrapLine.js.map +1 -1
- package/dist/runners/gate.d.ts.map +1 -1
- package/dist/runners/gate.js +9 -0
- package/dist/runners/gate.js.map +1 -1
- package/dist/runners/gateProtocol.d.ts +7 -1
- package/dist/runners/gateProtocol.d.ts.map +1 -1
- package/dist/runners/gateProtocol.js +5 -3
- package/dist/runners/gateProtocol.js.map +1 -1
- package/dist/runners/hubPairing.d.ts +7 -0
- package/dist/runners/hubPairing.d.ts.map +1 -1
- package/dist/runners/hubPairing.js +16 -0
- package/dist/runners/hubPairing.js.map +1 -1
- package/dist/runners/hubPaths.d.ts +4 -0
- package/dist/runners/hubPaths.d.ts.map +1 -1
- package/dist/runners/hubPaths.js +2 -0
- package/dist/runners/hubPaths.js.map +1 -1
- package/dist/runners/hubRegistry.d.ts +23 -1
- package/dist/runners/hubRegistry.d.ts.map +1 -1
- package/dist/runners/hubRegistry.js +48 -2
- package/dist/runners/hubRegistry.js.map +1 -1
- package/dist/runners/linkControl.d.ts +12 -1
- package/dist/runners/linkControl.d.ts.map +1 -1
- package/dist/runners/linkControl.js +56 -9
- package/dist/runners/linkControl.js.map +1 -1
- package/dist/runners/removalTiming.d.ts +13 -0
- package/dist/runners/removalTiming.d.ts.map +1 -0
- package/dist/runners/removalTiming.js +17 -0
- package/dist/runners/removalTiming.js.map +1 -0
- package/dist/runners/runnerRemoval.d.ts.map +1 -1
- package/dist/runners/runnerRemoval.js +12 -0
- package/dist/runners/runnerRemoval.js.map +1 -1
- package/dist/runners/runnerServiceKind.d.ts +10 -0
- package/dist/runners/runnerServiceKind.d.ts.map +1 -0
- package/dist/runners/runnerServiceKind.js +13 -0
- package/dist/runners/runnerServiceKind.js.map +1 -0
- package/dist/runners/runnersCli.d.ts +11 -2
- package/dist/runners/runnersCli.d.ts.map +1 -1
- package/dist/runners/runnersCli.js +39 -14
- package/dist/runners/runnersCli.js.map +1 -1
- package/dist/runners/runnersList.d.ts +6 -9
- package/dist/runners/runnersList.d.ts.map +1 -1
- package/dist/runners/runnersList.js +9 -7
- package/dist/runners/runnersList.js.map +1 -1
- package/dist/runners/runnersOverview.d.ts.map +1 -1
- package/dist/runners/runnersOverview.js +2 -1
- package/dist/runners/runnersOverview.js.map +1 -1
- package/dist/selfUpdate/selfCheck.d.ts +13 -0
- package/dist/selfUpdate/selfCheck.d.ts.map +1 -1
- package/dist/selfUpdate/selfCheck.js +9 -3
- package/dist/selfUpdate/selfCheck.js.map +1 -1
- package/dist/stt/sttInstallEntry.js +7 -4
- package/dist/stt/sttInstallEntry.js.map +1 -1
- package/dist/utils/runnersScreenPlan.d.ts +18 -7
- package/dist/utils/runnersScreenPlan.d.ts.map +1 -1
- package/dist/utils/runnersScreenPlan.js +22 -7
- package/dist/utils/runnersScreenPlan.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hubPaths.d.ts","sourceRoot":"","sources":["../../src/runners/hubPaths.ts"],"names":[],"mappings":"AAeA,8GAA8G;AAC9G,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,yGAAyG;IACzG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,WAAW,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"hubPaths.d.ts","sourceRoot":"","sources":["../../src/runners/hubPaths.ts"],"names":[],"mappings":"AAeA,8GAA8G;AAC9G,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,yGAAyG;IACzG,kBAAkB,EAAE,MAAM,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,WAAW,EAAE,MAAM,CAAC;IACpB,sIAAsI;IACtI,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qHAAqH;AACrH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAOD,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,SAAS,GAAE,OAAO,CAAC,UAAU,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,UAAU,CAWvG;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAYzD;AAED,6GAA6G;AAC7G,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,CAGjF;AAED,0HAA0H;AAC1H,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D"}
|
package/dist/runners/hubPaths.js
CHANGED
|
@@ -68,12 +68,14 @@ function createHubContext(overrides = {}) {
|
|
|
68
68
|
nodePath: overrides.nodePath ?? process.execPath,
|
|
69
69
|
cliPath,
|
|
70
70
|
packageRoot: overrides.packageRoot ?? path.resolve(path.dirname(cliPath), '..'),
|
|
71
|
+
log: overrides.log ?? ((line) => { console.warn(`[runners] ${line}`); }),
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
function getHubFilePaths(dir) {
|
|
74
75
|
return {
|
|
75
76
|
paired: path.join(dir, 'paired.json'),
|
|
76
77
|
pending: path.join(dir, 'pending.json'),
|
|
78
|
+
closed: path.join(dir, 'closed.json'),
|
|
77
79
|
hubKey: path.join(dir, 'hub_ed25519'),
|
|
78
80
|
hubPublicKey: path.join(dir, 'hub_ed25519.pub'),
|
|
79
81
|
knownHosts: path.join(dir, 'known_hosts'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hubPaths.js","sourceRoot":"","sources":["../../src/runners/hubPaths.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"hubPaths.js","sourceRoot":"","sources":["../../src/runners/hubPaths.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4CA,wDAEC;AAaD,4CAWC;AAED,0CAYC;AAGD,gDAGC;AAGD,gDAEC;AA/FD,uCAAyB;AACzB,2CAA6B;AAC7B,8DAAkE;AAElE;;;;GAIG;AAEH,MAAM,cAAc,GAAG,SAAS,CAAC;AACjC,MAAM,UAAU,GAAG,MAAM,CAAC;AAC1B,MAAM,sBAAsB,GAAG,iBAAiB,CAAC;AACjD,MAAM,WAAW,GAAG,QAAQ,CAAC;AA8B7B,qHAAqH;AACrH,SAAgB,sBAAsB,CAAC,GAAW;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;AACtD,CAAC;AAOD,mGAAmG;AACnG,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;AACpD,CAAC;AAED,iGAAiG;AACjG,SAAgB,gBAAgB,CAAC,YAAwD,EAAE;IACzF,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IAClD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,IAAI,aAAa,EAAE,CAAC;IACrD,OAAO;QACL,GAAG,EAAE,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAA,oCAAoB,EAAC,OAAO,CAAC,CAAC,EAAE,cAAc,CAAC;QAC5F,kBAAkB,EAAE,SAAS,CAAC,kBAAkB,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,sBAAsB,CAAC;QAC1G,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ;QAChD,OAAO;QACP,WAAW,EAAE,SAAS,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC;QAC/E,GAAG,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,SAAgB,eAAe,CAAC,GAAW;IACzC,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC;QACrC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC;QACvC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC;QACrC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC;QACrC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC;QAC/C,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC;QACzC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;QAC5B,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;QAC/B,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,6GAA6G;AAC7G,SAAgB,kBAAkB,CAAC,GAAW,EAAE,QAAgB;IAC9D,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,QAAQ,OAAO,CAAC,EAAE,CAAC;AAC3G,CAAC;AAED,0HAA0H;AAC1H,SAAgB,kBAAkB,CAAC,QAAgB;IACjD,OAAO,mBAAmB,QAAQ,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -74,6 +74,10 @@ declare const pendingFileSchema: z.ZodObject<{
|
|
|
74
74
|
messageRef: z.ZodNullable<z.ZodString>;
|
|
75
75
|
}, z.core.$strict>>;
|
|
76
76
|
}, z.core.$strict>;
|
|
77
|
+
declare const closedCodeSchema: z.ZodObject<{
|
|
78
|
+
pairId: z.ZodString;
|
|
79
|
+
closedAtMs: z.ZodNumber;
|
|
80
|
+
}, z.core.$strict>;
|
|
77
81
|
/** @name PairedRunner @description One attached machine. */
|
|
78
82
|
export type PairedRunner = z.infer<typeof pairedRunnerSchema>;
|
|
79
83
|
/** @name PairedFile @description `paired.json`. */
|
|
@@ -82,6 +86,13 @@ export type PairedFile = z.infer<typeof pairedFileSchema>;
|
|
|
82
86
|
export type PendingPairing = z.infer<typeof pendingPairingSchema>;
|
|
83
87
|
/** @name PendingFile @description `pending.json`. */
|
|
84
88
|
export type PendingFile = z.infer<typeof pendingFileSchema>;
|
|
89
|
+
/** @name ClosedCode @description A pairing code that was closed unused, and when. */
|
|
90
|
+
export type ClosedCode = z.infer<typeof closedCodeSchema>;
|
|
91
|
+
/** @name ClosedCodesRead @description What `closed.json` holds, and — when it could not be used — why (the caller says it, once). */
|
|
92
|
+
export interface ClosedCodesRead {
|
|
93
|
+
codes: ClosedCode[];
|
|
94
|
+
problem: string | null;
|
|
95
|
+
}
|
|
85
96
|
export declare class HubRegistryError extends Error {
|
|
86
97
|
constructor(message: string);
|
|
87
98
|
}
|
|
@@ -93,6 +104,17 @@ export declare class HubDerivedFilesError extends HubRegistryError {
|
|
|
93
104
|
export declare function readPairedFile(dir: string): PairedFile;
|
|
94
105
|
/** @description `pending.json` right now (missing = no code out). */
|
|
95
106
|
export declare function readPendingFile(dir: string): PendingFile;
|
|
107
|
+
/**
|
|
108
|
+
* @description `closed.json` right now: its codes, or none — with the problem named — when it cannot be read or does not validate. A trace
|
|
109
|
+
* must never stop the caller, so unlike the registry files this does not throw; the caller says the problem once.
|
|
110
|
+
*/
|
|
111
|
+
export declare function readClosedCodes(dir: string): ClosedCodesRead;
|
|
112
|
+
/**
|
|
113
|
+
* @description Note that the code `pairId` was closed at `nowMs` (the newest {@link maxClosedCodes} are kept); the registry lock must be held. BEST
|
|
114
|
+
* EFFORT: a trace that cannot be written is said through `ctx.log` and costs only the nicer text («this line was used on a machine that was
|
|
115
|
+
* already paired» reads «expired»), never the closing it describes. A file that cannot be used is replaced.
|
|
116
|
+
*/
|
|
117
|
+
export declare function recordClosedCode(ctx: HubContext, pairId: string, nowMs: number): void;
|
|
96
118
|
/** @description Write `paired.json`; the registry lock must be held. */
|
|
97
119
|
export declare function writePairedFile(dir: string, file: PairedFile): void;
|
|
98
120
|
/** @description Write `pending.json`; the registry lock must be held. */
|
|
@@ -103,7 +125,7 @@ export declare function renderKnownHosts(runners: readonly PairedRunner[]): stri
|
|
|
103
125
|
export declare function renderManagedBlockLines(ctx: HubContext, pending: readonly PendingPairing[], runners: readonly PairedRunner[], nowMs: number): string[];
|
|
104
126
|
/**
|
|
105
127
|
* @description Bring the derived files in line with the two registry files: `known_hosts` and the `authorized_keys` block, each written
|
|
106
|
-
* only when it differs. The registry lock must be held. The block goes LAST, so a key is never allowed before the files its gate reads
|
|
128
|
+
* only when it differs, and the link files of runners that are no longer registered deleted. The registry lock must be held. The block goes LAST, so a key is never allowed before the files its gate reads
|
|
107
129
|
* are in place. The registry files are authoritative and are written BEFORE this runs; a failure here is reported as
|
|
108
130
|
* {@link HubDerivedFilesError} and mends itself, because every locked operation ends with this same call.
|
|
109
131
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hubRegistry.d.ts","sourceRoot":"","sources":["../../src/runners/hubRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAuC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"hubRegistry.d.ts","sourceRoot":"","sources":["../../src/runners/hubRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAuC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AA4BlF,yFAAyF;AACzF,eAAO,MAAM,kBAAkB,sEAAuE,CAAC;AACvG,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEpE,QAAA,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;kBAsBtB,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;kBAI3B,CAAC;AAEH,QAAA,MAAM,oBAAoB;;;;;;;;;kBAYxB,CAAC;AAEH,QAAA,MAAM,iBAAiB;;;;;;;;;;;kBAA6D,CAAC;AAErF,QAAA,MAAM,gBAAgB;;;kBAAsF,CAAC;AAK7G,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,mDAAmD;AACnD,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC1D,sEAAsE;AACtE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAClE,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,qIAAqI;AACrI,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAI5B;AAED,oIAAoI;AACpI,qBAAa,oBAAqB,SAAQ,gBAAgB;gBAC5C,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAIhD;AAqBD,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAEtD;AAED,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAExD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAO5D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CASrF;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,IAAI,CAGnE;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAGrE;AAED,qHAAqH;AACrH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,CAEzE;AAED,8HAA8H;AAC9H,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,cAAc,EAAE,EAAE,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAOtJ;AAUD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAelH"}
|
|
@@ -36,6 +36,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.HubDerivedFilesError = exports.HubRegistryError = exports.pairedFileSchema = exports.runnerServiceKinds = void 0;
|
|
37
37
|
exports.readPairedFile = readPairedFile;
|
|
38
38
|
exports.readPendingFile = readPendingFile;
|
|
39
|
+
exports.readClosedCodes = readClosedCodes;
|
|
40
|
+
exports.recordClosedCode = recordClosedCode;
|
|
39
41
|
exports.writePairedFile = writePairedFile;
|
|
40
42
|
exports.writePendingFile = writePendingFile;
|
|
41
43
|
exports.renderKnownHosts = renderKnownHosts;
|
|
@@ -49,16 +51,23 @@ const authorizedKeys_1 = require("./authorizedKeys");
|
|
|
49
51
|
const hubIds_1 = require("./hubIds");
|
|
50
52
|
const hubPaths_1 = require("./hubPaths");
|
|
51
53
|
const hubLock_1 = require("./hubLock");
|
|
54
|
+
const linkControl_1 = require("./linkControl");
|
|
52
55
|
const configDirFile_2 = require("../configDirFile");
|
|
53
56
|
const sshKeys_1 = require("./sshKeys");
|
|
54
57
|
/**
|
|
55
|
-
* @description The hub's
|
|
58
|
+
* @description The hub's registry files and what is derived from them. `paired.json` is the machines that are attached,
|
|
56
59
|
* `pending.json` the pairing codes that are out. Both are read freely (every write is a rename, a reader sees a whole file) and
|
|
57
60
|
* written only under the registry lock (`hubLock.ts`). `known_hosts` (the runners' host keys, for the ssh calls through the link)
|
|
58
61
|
* and the managed `authorized_keys` block are DERIVED from the two on every change — never edited on their own.
|
|
59
62
|
*
|
|
60
63
|
* A file that does not parse or validate stops the caller with the problem named (field and rule, no values): a registry that is
|
|
61
64
|
* silently treated as empty would be rewritten empty and lose every pairing.
|
|
65
|
+
*
|
|
66
|
+
* `closed.json` is the odd one out: a TRACE, not part of the registry's truth — the codes that were closed unused, so a code that was
|
|
67
|
+
* closed (its line was pasted for a machine that was already paired) can be told from one that ran out. Nothing depends on it for
|
|
68
|
+
* correctness, so it is read leniently (a file that cannot be used reads as none, and the problem is handed to the caller to say once) and
|
|
69
|
+
* its write never blocks the close it describes. It is a file of its own, not a field of a pending entry: the sweep drops pending entries
|
|
70
|
+
* at expiry, which would lose the trace for an instance that was down, and every reader of the pending list would have to honour it.
|
|
62
71
|
*/
|
|
63
72
|
const registryFileMode = 0o600;
|
|
64
73
|
const knownHostsMode = 0o644;
|
|
@@ -108,6 +117,10 @@ const pendingPairingSchema = zod_1.z.strictObject({
|
|
|
108
117
|
messageRef: zod_1.z.string().max(maxTextLength).nullable(),
|
|
109
118
|
});
|
|
110
119
|
const pendingFileSchema = zod_1.z.strictObject({ pending: zod_1.z.array(pendingPairingSchema) });
|
|
120
|
+
const closedCodeSchema = zod_1.z.strictObject({ pairId: hubIds_1.hubIdSchema, closedAtMs: zod_1.z.number().int().nonnegative() });
|
|
121
|
+
const closedFileSchema = zod_1.z.strictObject({ closed: zod_1.z.array(closedCodeSchema) });
|
|
122
|
+
/** The newest this many closings are kept: a closing is rare and its trace is wanted by a message that is still unsettled, so a cap is all the bound it needs. */
|
|
123
|
+
const maxClosedCodes = 50;
|
|
111
124
|
class HubRegistryError extends Error {
|
|
112
125
|
constructor(message) {
|
|
113
126
|
super(message);
|
|
@@ -153,6 +166,37 @@ function readPairedFile(dir) {
|
|
|
153
166
|
function readPendingFile(dir) {
|
|
154
167
|
return readRegistryFile((0, hubPaths_1.getHubFilePaths)(dir).pending, 'pending.json', pendingFileSchema, () => ({ pending: [] }));
|
|
155
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* @description `closed.json` right now: its codes, or none — with the problem named — when it cannot be read or does not validate. A trace
|
|
171
|
+
* must never stop the caller, so unlike the registry files this does not throw; the caller says the problem once.
|
|
172
|
+
*/
|
|
173
|
+
function readClosedCodes(dir) {
|
|
174
|
+
try {
|
|
175
|
+
return { codes: readRegistryFile((0, hubPaths_1.getHubFilePaths)(dir).closed, 'closed.json', closedFileSchema, () => ({ closed: [] })).closed, problem: null };
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
if (error instanceof HubRegistryError)
|
|
179
|
+
return { codes: [], problem: `${error.message}; the codes in it read as expired` };
|
|
180
|
+
throw error;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* @description Note that the code `pairId` was closed at `nowMs` (the newest {@link maxClosedCodes} are kept); the registry lock must be held. BEST
|
|
185
|
+
* EFFORT: a trace that cannot be written is said through `ctx.log` and costs only the nicer text («this line was used on a machine that was
|
|
186
|
+
* already paired» reads «expired»), never the closing it describes. A file that cannot be used is replaced.
|
|
187
|
+
*/
|
|
188
|
+
function recordClosedCode(ctx, pairId, nowMs) {
|
|
189
|
+
const { codes, problem } = readClosedCodes(ctx.dir);
|
|
190
|
+
if (problem !== null)
|
|
191
|
+
ctx.log(`${problem}; it is written anew`);
|
|
192
|
+
try {
|
|
193
|
+
(0, hubLock_1.ensureHubDir)(ctx.dir);
|
|
194
|
+
(0, configDirFile_1.writeJsonFileAtomically)((0, hubPaths_1.getHubFilePaths)(ctx.dir).closed, closedFileSchema.parse({ closed: [...codes.filter((entry) => entry.pairId !== pairId), { pairId, closedAtMs: nowMs }].slice(-maxClosedCodes) }), registryFileMode);
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
ctx.log(`closed.json could not be written (${(0, configDirFile_2.getCaughtErrnoCode)(error)}); the messages of the code that was just closed will read as expired`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
156
200
|
/** @description Write `paired.json`; the registry lock must be held. */
|
|
157
201
|
function writePairedFile(dir, file) {
|
|
158
202
|
(0, hubLock_1.ensureHubDir)(dir);
|
|
@@ -186,7 +230,7 @@ function readTextIfPresent(filePath) {
|
|
|
186
230
|
}
|
|
187
231
|
/**
|
|
188
232
|
* @description Bring the derived files in line with the two registry files: `known_hosts` and the `authorized_keys` block, each written
|
|
189
|
-
* only when it differs. The registry lock must be held. The block goes LAST, so a key is never allowed before the files its gate reads
|
|
233
|
+
* only when it differs, and the link files of runners that are no longer registered deleted. The registry lock must be held. The block goes LAST, so a key is never allowed before the files its gate reads
|
|
190
234
|
* are in place. The registry files are authoritative and are written BEFORE this runs; a failure here is reported as
|
|
191
235
|
* {@link HubDerivedFilesError} and mends itself, because every locked operation ends with this same call.
|
|
192
236
|
*/
|
|
@@ -206,5 +250,7 @@ function syncDerivedHubFiles(ctx, pending, paired, nowMs) {
|
|
|
206
250
|
catch (error) {
|
|
207
251
|
throw new HubDerivedFilesError('authorized_keys', (0, configDirFile_2.getCaughtErrnoCode)(error));
|
|
208
252
|
}
|
|
253
|
+
// The link files of a runner the registry does not know are leftovers: best effort, it cannot fail the operation that has already written its files.
|
|
254
|
+
(0, linkControl_1.sweepOrphanLinkRecords)(ctx.dir, paired.runners.map((runner) => runner.id), ctx.log);
|
|
209
255
|
}
|
|
210
256
|
//# sourceMappingURL=hubRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hubRegistry.js","sourceRoot":"","sources":["../../src/runners/hubRegistry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"hubRegistry.js","sourceRoot":"","sources":["../../src/runners/hubRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,18 @@ export declare function probeSocket(socketPath: string, timeoutMs?: number): Pro
|
|
|
21
21
|
export declare function getRunnerLinkStatus(dir: string, runnerId: string): Promise<RunnerLinkStatus>;
|
|
22
22
|
/** @description Is `pid` a charness gate serving runner `runnerId`? (A pid in an old json may belong to anything by now.) */
|
|
23
23
|
export declare function checkIsGateProcessOf(pid: number, runnerId: string): boolean;
|
|
24
|
-
/** @description Cut the link of a runner that was removed: no new connection reaches it, and its
|
|
24
|
+
/** @description Cut the link of a runner that was removed: no new connection reaches it, its gate leaves, and its link files are deleted. */
|
|
25
25
|
export declare function cutRunnerLink(dir: string, runnerId: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* @description Delete the link files (`<id>.json`, `<id>.sock`) of every runner that is not in `registeredRunnerIds`: a removal that was cut
|
|
28
|
+
* short, a gate that wrote its status after the removal, a runner dropped from the registry by hand. Records of a runner whose gate is still
|
|
29
|
+
* running are kept — it is on its way out, and {@link cutRunnerLink} still needs the pid to stop it.
|
|
30
|
+
*
|
|
31
|
+
* Best effort, and it NEVER throws: the registry operation that calls it has already written its files, and a folder that cannot be listed
|
|
32
|
+
* or a file that cannot be deleted is only leftover clutter, tried again by the next operation. What went wrong is handed to `onProblem`,
|
|
33
|
+
* which the caller must give (a sweep that cannot say what failed would hide exactly what it exists to report); a missing folder is not a
|
|
34
|
+
* problem: nothing was ever linked. Returns the names deleted.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sweepOrphanLinkRecords(dir: string, registeredRunnerIds: readonly string[], onProblem: (message: string) => void): string[];
|
|
26
37
|
export {};
|
|
27
38
|
//# sourceMappingURL=linkControl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linkControl.d.ts","sourceRoot":"","sources":["../../src/runners/linkControl.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"linkControl.d.ts","sourceRoot":"","sources":["../../src/runners/linkControl.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgBxB,QAAA,MAAM,eAAe;;;;;kBAMnB,CAAC;AAEH,qDAAqD;AACrD,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,yEAAyE;IACzE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAO7E;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI,CAGpF;AAED,gGAAgG;AAChG,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,GAAE,MAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,CAYpG;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAQlG;AAED,6HAA6H;AAC7H,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG3E;AAED,6IAA6I;AAC7I,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAajE;AAUD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,EAAE,CAwB1I"}
|
|
@@ -39,17 +39,21 @@ exports.probeSocket = probeSocket;
|
|
|
39
39
|
exports.getRunnerLinkStatus = getRunnerLinkStatus;
|
|
40
40
|
exports.checkIsGateProcessOf = checkIsGateProcessOf;
|
|
41
41
|
exports.cutRunnerLink = cutRunnerLink;
|
|
42
|
+
exports.sweepOrphanLinkRecords = sweepOrphanLinkRecords;
|
|
42
43
|
const child_process_1 = require("child_process");
|
|
43
44
|
const fs = __importStar(require("fs"));
|
|
44
45
|
const net = __importStar(require("net"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
45
47
|
const zod_1 = require("zod");
|
|
46
48
|
const configDirFile_1 = require("../configDirFile");
|
|
47
49
|
const hubPaths_1 = require("./hubPaths");
|
|
50
|
+
const hubIds_1 = require("./hubIds");
|
|
48
51
|
/**
|
|
49
52
|
* @description The hub's view of a runner's link: the gate that holds it writes `link/<id>.json` (its pid, since when, a heartbeat) and
|
|
50
53
|
* listens on `link/<id>.sock`. A runner is ONLINE when its socket accepts a connection; the json only says who holds the socket and
|
|
51
54
|
* when it was last seen. A removed runner's link is cut by deleting the socket (the gate notices within one check interval and
|
|
52
|
-
* leaves) and, when the recorded pid still is that runner's gate, by stopping it at once
|
|
55
|
+
* leaves) and, when the recorded pid still is that runner's gate, by stopping it at once; its two link files go with it, and any left behind
|
|
56
|
+
* for a runner the registry does not know are swept by {@link sweepOrphanLinkRecords}.
|
|
53
57
|
*/
|
|
54
58
|
const stateFileMode = 0o600;
|
|
55
59
|
const probeTimeoutMs = 1000;
|
|
@@ -101,16 +105,11 @@ function checkIsGateProcessOf(pid, runnerId) {
|
|
|
101
105
|
const listing = (0, child_process_1.spawnSync)('ps', ['-p', pid.toString(), '-o', 'command='], { encoding: 'utf8', timeout: probeTimeoutMs * 5 });
|
|
102
106
|
return listing.status === 0 && listing.stdout.includes('runner-gate') && listing.stdout.includes(` runner ${runnerId}`);
|
|
103
107
|
}
|
|
104
|
-
/** @description Cut the link of a runner that was removed: no new connection reaches it, and its
|
|
108
|
+
/** @description Cut the link of a runner that was removed: no new connection reaches it, its gate leaves, and its link files are deleted. */
|
|
105
109
|
function cutRunnerLink(dir, runnerId) {
|
|
106
110
|
const state = readLinkState(dir, runnerId);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
if ((0, configDirFile_1.getCaughtErrnoCode)(error) !== 'ENOENT')
|
|
112
|
-
throw error;
|
|
113
|
-
}
|
|
111
|
+
const paths = (0, hubPaths_1.getRunnerLinkPaths)(dir, runnerId);
|
|
112
|
+
fs.rmSync(paths.socket, { force: true });
|
|
114
113
|
if (state !== null && state.endedAtMs === null && checkIsGateProcessOf(state.pid, runnerId)) {
|
|
115
114
|
try {
|
|
116
115
|
process.kill(state.pid, 'SIGTERM');
|
|
@@ -120,5 +119,53 @@ function cutRunnerLink(dir, runnerId) {
|
|
|
120
119
|
throw error;
|
|
121
120
|
}
|
|
122
121
|
}
|
|
122
|
+
// Nobody reads the status of a runner that is gone, and a gate that leaves because of the removal writes none (`gateLink.ts`).
|
|
123
|
+
fs.rmSync(paths.state, { force: true });
|
|
124
|
+
}
|
|
125
|
+
const linkRecordExtensions = ['json', 'sock'];
|
|
126
|
+
/** @description The runner id a link file belongs to (`<id>.json`, `<id>.sock`); `null` for anything else in the folder (a temp file of an atomic write, a gate's pending socket). */
|
|
127
|
+
function getLinkRecordRunnerId(fileName) {
|
|
128
|
+
const [runnerId, extension, ...rest] = fileName.split('.');
|
|
129
|
+
return hubIds_1.hubIdPattern.test(runnerId) && linkRecordExtensions.includes(extension) && rest.length === 0 ? runnerId : null;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* @description Delete the link files (`<id>.json`, `<id>.sock`) of every runner that is not in `registeredRunnerIds`: a removal that was cut
|
|
133
|
+
* short, a gate that wrote its status after the removal, a runner dropped from the registry by hand. Records of a runner whose gate is still
|
|
134
|
+
* running are kept — it is on its way out, and {@link cutRunnerLink} still needs the pid to stop it.
|
|
135
|
+
*
|
|
136
|
+
* Best effort, and it NEVER throws: the registry operation that calls it has already written its files, and a folder that cannot be listed
|
|
137
|
+
* or a file that cannot be deleted is only leftover clutter, tried again by the next operation. What went wrong is handed to `onProblem`,
|
|
138
|
+
* which the caller must give (a sweep that cannot say what failed would hide exactly what it exists to report); a missing folder is not a
|
|
139
|
+
* problem: nothing was ever linked. Returns the names deleted.
|
|
140
|
+
*/
|
|
141
|
+
function sweepOrphanLinkRecords(dir, registeredRunnerIds, onProblem) {
|
|
142
|
+
const linkDir = (0, hubPaths_1.getHubFilePaths)(dir).linkDir;
|
|
143
|
+
let names;
|
|
144
|
+
try {
|
|
145
|
+
names = fs.readdirSync(linkDir);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
const code = (0, configDirFile_1.getCaughtErrnoCode)(error);
|
|
149
|
+
if (code !== 'ENOENT')
|
|
150
|
+
onProblem(`the link folder could not be listed (${code}); leftover link files stay until it can be`);
|
|
151
|
+
return [];
|
|
152
|
+
}
|
|
153
|
+
const deleted = [];
|
|
154
|
+
for (const name of names) {
|
|
155
|
+
const runnerId = getLinkRecordRunnerId(name);
|
|
156
|
+
if (runnerId === null || registeredRunnerIds.includes(runnerId))
|
|
157
|
+
continue;
|
|
158
|
+
const state = readLinkState(dir, runnerId);
|
|
159
|
+
if (state !== null && state.endedAtMs === null && checkIsGateProcessOf(state.pid, runnerId))
|
|
160
|
+
continue;
|
|
161
|
+
try {
|
|
162
|
+
fs.rmSync(path.join(linkDir, name), { force: true });
|
|
163
|
+
deleted.push(name);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
onProblem(`the leftover link file ${name} could not be deleted (${(0, configDirFile_1.getCaughtErrnoCode)(error)})`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return deleted;
|
|
123
170
|
}
|
|
124
171
|
//# sourceMappingURL=linkControl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linkControl.js","sourceRoot":"","sources":["../../src/runners/linkControl.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"linkControl.js","sourceRoot":"","sources":["../../src/runners/linkControl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description How long the hub must have been refusing a runner's key, without ever saying «this runner is not paired», before the runner takes
|
|
3
|
+
* the refusal for a removal worth killing its jobs for. A refused key alone is also what a hub with a locked home folder, a changed file mode or an
|
|
4
|
+
* edited sshd setting looks like, and those last hours (a night, until someone unlocks the volume); killing a long run for them is the
|
|
5
|
+
* wrong mistake. A hub that removes an ONLINE runner stops its jobs itself over the link (`runners/runnerRemoval.ts`), and a hub that can
|
|
6
|
+
* answer says so (`identity`), so this only covers a machine that was off when it was removed.
|
|
7
|
+
*
|
|
8
|
+
* The one source of the delay: the runner's link loop (`runnerUtility/linkLoop.ts`) waits this long, and the texts that tell the operator what
|
|
9
|
+
* a removal of an offline machine leaves behind (`/runners`) name the same number of hours.
|
|
10
|
+
*/
|
|
11
|
+
export declare const unconfirmedRemovalStopAfterHours = 12;
|
|
12
|
+
export declare const unconfirmedRemovalStopAfterMs: number;
|
|
13
|
+
//# sourceMappingURL=removalTiming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removalTiming.d.ts","sourceRoot":"","sources":["../../src/runners/removalTiming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,eAAO,MAAM,6BAA6B,QAA+C,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description How long the hub must have been refusing a runner's key, without ever saying «this runner is not paired», before the runner takes
|
|
4
|
+
* the refusal for a removal worth killing its jobs for. A refused key alone is also what a hub with a locked home folder, a changed file mode or an
|
|
5
|
+
* edited sshd setting looks like, and those last hours (a night, until someone unlocks the volume); killing a long run for them is the
|
|
6
|
+
* wrong mistake. A hub that removes an ONLINE runner stops its jobs itself over the link (`runners/runnerRemoval.ts`), and a hub that can
|
|
7
|
+
* answer says so (`identity`), so this only covers a machine that was off when it was removed.
|
|
8
|
+
*
|
|
9
|
+
* The one source of the delay: the runner's link loop (`runnerUtility/linkLoop.ts`) waits this long, and the texts that tell the operator what
|
|
10
|
+
* a removal of an offline machine leaves behind (`/runners`) name the same number of hours.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.unconfirmedRemovalStopAfterMs = exports.unconfirmedRemovalStopAfterHours = void 0;
|
|
14
|
+
const msPerHour = 60 * 60 * 1000;
|
|
15
|
+
exports.unconfirmedRemovalStopAfterHours = 12;
|
|
16
|
+
exports.unconfirmedRemovalStopAfterMs = exports.unconfirmedRemovalStopAfterHours * msPerHour;
|
|
17
|
+
//# sourceMappingURL=removalTiming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"removalTiming.js","sourceRoot":"","sources":["../../src/runners/removalTiming.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,MAAM,SAAS,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpB,QAAA,gCAAgC,GAAG,EAAE,CAAC;AAEtC,QAAA,6BAA6B,GAAG,wCAAgC,GAAG,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnerRemoval.d.ts","sourceRoot":"","sources":["../../src/runners/runnerRemoval.ts"],"names":[],"mappings":"AACA,OAAO,EAAiE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"runnerRemoval.d.ts","sourceRoot":"","sources":["../../src/runners/runnerRemoval.ts"],"names":[],"mappings":"AACA,OAAO,EAAiE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGhH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAiBlE,sIAAsI;AACtI,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,MAAM,EAAE,OAAO,aAAa,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAmDD;;;;GAIG;AACH,wBAAsB,yBAAyB,CAAC,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,cAAc,CAAA;CAAE,GAAG,IAAI,CAAC,CAe1L"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.removeRunnerAndEndItsWork = removeRunnerAndEndItsWork;
|
|
4
4
|
const pairedRunners_1 = require("../remoteRun/pairedRunners");
|
|
5
5
|
const ssh_1 = require("../remoteRun/ssh");
|
|
6
|
+
const runners_1 = require("../remoteRun/runners");
|
|
6
7
|
const hubPairing_1 = require("./hubPairing");
|
|
7
8
|
const hubRegistry_1 = require("./hubRegistry");
|
|
8
9
|
const linkControl_1 = require("./linkControl");
|
|
@@ -58,6 +59,15 @@ async function resetQueueOverLink(ctx, runner, deps) {
|
|
|
58
59
|
return 'failed';
|
|
59
60
|
}
|
|
60
61
|
}
|
|
62
|
+
/** The removed runner's last saved report goes with it: the name is free again, and the next machine to get it must not start with this one's report. Never fails the removal. */
|
|
63
|
+
function forgetLastReport(runner, deps) {
|
|
64
|
+
try {
|
|
65
|
+
(0, runners_1.removeLastProbe)(deps.cacheDir, runner.name);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
deps.log(`runners: could not delete the saved report of "${runner.name}" (${error instanceof Error ? error.message : 'unknown error'}); a machine paired under that name later ignores it anyway`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
61
71
|
/**
|
|
62
72
|
* @description Remove `nameOrId`: while it is still paired, pause it and stop its jobs through the link (when it is online); then drop it
|
|
63
73
|
* from the registry (its key line goes with it) and cut the link. `null` when no such runner is paired. A registry that cannot be
|
|
@@ -77,6 +87,8 @@ async function removeRunnerAndEndItsWork(ctx, nameOrId, nowMs, deps) {
|
|
|
77
87
|
}
|
|
78
88
|
const removed = await (0, hubPairing_1.removePairedRunner)(ctx, found.id, nowMs);
|
|
79
89
|
(0, linkControl_1.cutRunnerLink)(ctx.dir, found.id);
|
|
90
|
+
if (removed !== null)
|
|
91
|
+
forgetLastReport(removed, resolvedDeps);
|
|
80
92
|
return removed === null ? null : { runner: removed, jobs };
|
|
81
93
|
}
|
|
82
94
|
//# sourceMappingURL=runnerRemoval.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnerRemoval.js","sourceRoot":"","sources":["../../src/runners/runnerRemoval.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"runnerRemoval.js","sourceRoot":"","sources":["../../src/runners/runnerRemoval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RunnerProbe } from '../remoteRun/probe';
|
|
2
|
+
import type { PairedRunner, RunnerServiceKind } from './hubRegistry';
|
|
3
|
+
/**
|
|
4
|
+
* @description How a runner is kept running as it is NOW. What the machine reported in its latest probe comes first (the live one while it is
|
|
5
|
+
* online, the last snapshot for a machine that is off): the registry holds only what the runner said when it was paired — «run by hand», since
|
|
6
|
+
* `service install` comes after — and never learns of an install, an uninstall or a move to a system service. The registry's own word stands
|
|
7
|
+
* where the probe has none (never probed, or a runner too old to report it). The one rule behind `/runners` and `charness runners ls`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getCurrentServiceKind(runner: PairedRunner, probe: RunnerProbe | null): RunnerServiceKind;
|
|
10
|
+
//# sourceMappingURL=runnerServiceKind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerServiceKind.d.ts","sourceRoot":"","sources":["../../src/runners/runnerServiceKind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAErE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,GAAG,iBAAiB,CAExG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCurrentServiceKind = getCurrentServiceKind;
|
|
4
|
+
/**
|
|
5
|
+
* @description How a runner is kept running as it is NOW. What the machine reported in its latest probe comes first (the live one while it is
|
|
6
|
+
* online, the last snapshot for a machine that is off): the registry holds only what the runner said when it was paired — «run by hand», since
|
|
7
|
+
* `service install` comes after — and never learns of an install, an uninstall or a move to a system service. The registry's own word stands
|
|
8
|
+
* where the probe has none (never probed, or a runner too old to report it). The one rule behind `/runners` and `charness runners ls`.
|
|
9
|
+
*/
|
|
10
|
+
function getCurrentServiceKind(runner, probe) {
|
|
11
|
+
return probe?.serviceKind ?? runner.serviceKind;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=runnerServiceKind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerServiceKind.js","sourceRoot":"","sources":["../../src/runners/runnerServiceKind.ts"],"names":[],"mappings":";;AASA,sDAEC;AARD;;;;;GAKG;AACH,SAAgB,qBAAqB,CAAC,MAAoB,EAAE,KAAyB;IACnF,OAAO,KAAK,EAAE,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC;AAClD,CAAC"}
|
|
@@ -1,16 +1,25 @@
|
|
|
1
1
|
import type { CliIo } from '../remoteRun/output';
|
|
2
2
|
import { type HostKeyScanner } from './hubAddress';
|
|
3
3
|
import { type HubContext } from './hubPaths';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* @description `charness runners [ls | pair | remove <name> | pause <name> | resume <name>]` — the headless twin of `/runners`, for an
|
|
6
|
+
* instance without Telegram (a Jira-only one) and for the flow tests. It works on the registry of the OS user
|
|
7
|
+
* (`~/.config/charness/runners/`), loads no env file and never touches `DATA_DIR`.
|
|
8
|
+
*/
|
|
9
|
+
/** What the admin line does to the machine it is pasted on, in the words every place that offers it uses (the Telegram message has it in each language). */
|
|
10
|
+
export declare const adminLineTrustSentence = "It runs code from this charness host as root on that machine";
|
|
11
|
+
export declare const runnersUsage = "Usage:\n charness runners [ls] the machines paired as runners: online or not, OS, how they are kept running\n (as each machine last reported it; no ssh call)\n charness runners pair --host <host[:port]> [--label <text>] [--account <name>] [--wait]\n make two pairing lines (valid 10 minutes, single use, the first one used wins) to run on\n the runner machine: one for an ADMIN account there (it pairs <name>, default \"runner\", and\n installs its always-on service), one for the runner account itself;\n <host[:port]> is the address the runner dials to reach this machine's sshd;\n --wait blocks until a line is used or the code expires (a line pasted for a machine that\n was already paired ends it too, with exit 0: nothing new was paired)\n charness runners remove <name> detach a runner: its key is deleted and its link cut\n charness runners pause <name> keep a runner attached but send it no jobs\n charness runners resume <name>\n";
|
|
5
12
|
/** @description What the CLI needs from outside; tests replace the scanner, the clock and the wait. */
|
|
6
13
|
export interface RunnersCliDeps {
|
|
7
14
|
ctx: HubContext;
|
|
15
|
+
/** Where remote-run keeps the last probe snapshot of each machine: `ls` reads them (it makes no ssh call). */
|
|
16
|
+
cacheDir: string;
|
|
8
17
|
scanHostKey: HostKeyScanner;
|
|
9
18
|
now: () => number;
|
|
10
19
|
sleep: (ms: number) => Promise<void>;
|
|
11
20
|
sshUser?: string;
|
|
12
21
|
}
|
|
13
|
-
export declare function createRunnersCliDeps(io: Pick<CliIo, 'homeDir'>): RunnersCliDeps;
|
|
22
|
+
export declare function createRunnersCliDeps(io: Pick<CliIo, 'homeDir' | 'env'>): RunnersCliDeps;
|
|
14
23
|
/** @description Run the command line (the words after `runners`); resolves with the exit code. */
|
|
15
24
|
export declare function runRunnersCli(argv: readonly string[], io: CliIo, deps?: RunnersCliDeps): Promise<number>;
|
|
16
25
|
//# sourceMappingURL=runnersCli.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnersCli.d.ts","sourceRoot":"","sources":["../../src/runners/runnersCli.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"runnersCli.d.ts","sourceRoot":"","sources":["../../src/runners/runnersCli.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAIjD,OAAO,EAAiD,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAClG,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAQ/D;;;;GAIG;AAEH,4JAA4J;AAC5J,eAAO,MAAM,sBAAsB,iEAAiE,CAAC;AAMrG,eAAO,MAAM,YAAY,iyCAaxB,CAAC;AAEF,uGAAuG;AACvG,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,UAAU,CAAC;IAChB,8GAA8G;IAC9G,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,cAAc,CAAC;IAC5B,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,cAAc,CAQvF;AAkID,kGAAkG;AAClG,wBAAsB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,GAAE,cAAyC,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BxI"}
|