charness 3.7.0 → 3.9.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/CHANGELOG.md +36 -0
- package/DEVELOPMENT.md +8 -2
- package/README.md +5 -5
- package/SETUP.md +17 -5
- package/agent-plugin/skills/charness-manager/SKILL.md +3 -3
- package/dist/adapters/openCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/openCodeAdapter.js +2 -1
- package/dist/adapters/openCodeAdapter.js.map +1 -1
- package/dist/bot.d.ts.map +1 -1
- package/dist/bot.js +50 -9
- package/dist/bot.js.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +56 -6
- package/dist/cli.js.map +1 -1
- package/dist/configDirFile.d.ts +7 -3
- package/dist/configDirFile.d.ts.map +1 -1
- package/dist/configDirFile.js +12 -5
- package/dist/configDirFile.js.map +1 -1
- package/dist/connectors/telegram/commands/botCore.d.ts +5 -1
- package/dist/connectors/telegram/commands/botCore.d.ts.map +1 -1
- package/dist/connectors/telegram/commands/runners.d.ts +52 -0
- package/dist/connectors/telegram/commands/runners.d.ts.map +1 -0
- package/dist/connectors/telegram/commands/runners.js +524 -0
- package/dist/connectors/telegram/commands/runners.js.map +1 -0
- package/dist/connectors/telegram/runnerPairingMessages.d.ts +29 -0
- package/dist/connectors/telegram/runnerPairingMessages.d.ts.map +1 -0
- package/dist/connectors/telegram/runnerPairingMessages.js +112 -0
- package/dist/connectors/telegram/runnerPairingMessages.js.map +1 -0
- package/dist/i18n/de.d.ts.map +1 -1
- package/dist/i18n/de.js +60 -0
- package/dist/i18n/de.js.map +1 -1
- package/dist/i18n/en.d.ts.map +1 -1
- package/dist/i18n/en.js +60 -0
- package/dist/i18n/en.js.map +1 -1
- package/dist/i18n/es.d.ts.map +1 -1
- package/dist/i18n/es.js +60 -0
- package/dist/i18n/es.js.map +1 -1
- package/dist/i18n/fr.d.ts.map +1 -1
- package/dist/i18n/fr.js +60 -0
- package/dist/i18n/fr.js.map +1 -1
- package/dist/i18n/hi.d.ts.map +1 -1
- package/dist/i18n/hi.js +60 -0
- package/dist/i18n/hi.js.map +1 -1
- package/dist/i18n/ja.d.ts.map +1 -1
- package/dist/i18n/ja.js +60 -0
- package/dist/i18n/ja.js.map +1 -1
- package/dist/i18n/ka.d.ts.map +1 -1
- package/dist/i18n/ka.js +60 -0
- package/dist/i18n/ka.js.map +1 -1
- package/dist/i18n/pt.d.ts.map +1 -1
- package/dist/i18n/pt.js +60 -0
- package/dist/i18n/pt.js.map +1 -1
- package/dist/i18n/ru.d.ts.map +1 -1
- package/dist/i18n/ru.js +60 -0
- package/dist/i18n/ru.js.map +1 -1
- package/dist/i18n/uk.d.ts.map +1 -1
- package/dist/i18n/uk.js +60 -0
- package/dist/i18n/uk.js.map +1 -1
- package/dist/i18n/uz.d.ts.map +1 -1
- package/dist/i18n/uz.js +60 -0
- package/dist/i18n/uz.js.map +1 -1
- package/dist/i18n/zh.d.ts.map +1 -1
- package/dist/i18n/zh.js +60 -0
- 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/installManager.d.ts +57 -1
- package/dist/installManager.d.ts.map +1 -1
- package/dist/installManager.js +88 -10
- package/dist/installManager.js.map +1 -1
- package/dist/instanceSettings.d.ts +12 -2
- package/dist/instanceSettings.d.ts.map +1 -1
- package/dist/instanceSettings.js +17 -3
- package/dist/instanceSettings.js.map +1 -1
- package/dist/outputTrace.d.ts +6 -0
- package/dist/outputTrace.d.ts.map +1 -1
- package/dist/outputTrace.js +24 -1
- package/dist/outputTrace.js.map +1 -1
- package/dist/remoteRun/cliArgs.d.ts +2 -0
- package/dist/remoteRun/cliArgs.d.ts.map +1 -1
- package/dist/remoteRun/cliArgs.js +11 -2
- package/dist/remoteRun/cliArgs.js.map +1 -1
- package/dist/remoteRun/commands.d.ts +21 -0
- package/dist/remoteRun/commands.d.ts.map +1 -1
- package/dist/remoteRun/commands.js +38 -17
- package/dist/remoteRun/commands.js.map +1 -1
- package/dist/remoteRun/interrupts.d.ts +10 -0
- package/dist/remoteRun/interrupts.d.ts.map +1 -1
- package/dist/remoteRun/interrupts.js +43 -6
- package/dist/remoteRun/interrupts.js.map +1 -1
- package/dist/remoteRun/output.d.ts +2 -0
- package/dist/remoteRun/output.d.ts.map +1 -1
- package/dist/remoteRun/output.js +45 -0
- package/dist/remoteRun/output.js.map +1 -1
- package/dist/remoteRun/pairedRunners.d.ts +51 -0
- package/dist/remoteRun/pairedRunners.d.ts.map +1 -0
- package/dist/remoteRun/pairedRunners.js +165 -0
- package/dist/remoteRun/pairedRunners.js.map +1 -0
- package/dist/remoteRun/probe.d.ts +23 -1
- package/dist/remoteRun/probe.d.ts.map +1 -1
- package/dist/remoteRun/probe.js +45 -11
- package/dist/remoteRun/probe.js.map +1 -1
- package/dist/remoteRun/remoteRunCli.d.ts +13 -6
- package/dist/remoteRun/remoteRunCli.d.ts.map +1 -1
- package/dist/remoteRun/remoteRunCli.js +34 -59
- package/dist/remoteRun/remoteRunCli.js.map +1 -1
- package/dist/remoteRun/runnerClient.d.ts +2 -0
- package/dist/remoteRun/runnerClient.d.ts.map +1 -1
- package/dist/remoteRun/runnerClient.js +5 -1
- package/dist/remoteRun/runnerClient.js.map +1 -1
- package/dist/remoteRun/runnerSummary.d.ts +24 -0
- package/dist/remoteRun/runnerSummary.d.ts.map +1 -0
- package/dist/remoteRun/runnerSummary.js +86 -0
- package/dist/remoteRun/runnerSummary.js.map +1 -0
- package/dist/remoteRun/runnerWait.d.ts +68 -0
- package/dist/remoteRun/runnerWait.d.ts.map +1 -0
- package/dist/remoteRun/runnerWait.js +137 -0
- package/dist/remoteRun/runnerWait.js.map +1 -0
- package/dist/remoteRun/runnerWaitTiming.d.ts +16 -0
- package/dist/remoteRun/runnerWaitTiming.d.ts.map +1 -0
- package/dist/remoteRun/runnerWaitTiming.js +37 -0
- package/dist/remoteRun/runnerWaitTiming.js.map +1 -0
- package/dist/remoteRun/runners.d.ts +15 -8
- package/dist/remoteRun/runners.d.ts.map +1 -1
- package/dist/remoteRun/runners.js +59 -19
- package/dist/remoteRun/runners.js.map +1 -1
- package/dist/remoteRun/runnersCatalog.d.ts +14 -0
- package/dist/remoteRun/runnersCatalog.d.ts.map +1 -0
- package/dist/remoteRun/runnersCatalog.js +68 -0
- package/dist/remoteRun/runnersCatalog.js.map +1 -0
- package/dist/remoteRun/runnersConfig.d.ts +31 -20
- package/dist/remoteRun/runnersConfig.d.ts.map +1 -1
- package/dist/remoteRun/runnersConfig.js +14 -12
- package/dist/remoteRun/runnersConfig.js.map +1 -1
- package/dist/remoteRun/ssh.d.ts +22 -2
- package/dist/remoteRun/ssh.d.ts.map +1 -1
- package/dist/remoteRun/ssh.js +41 -7
- package/dist/remoteRun/ssh.js.map +1 -1
- package/dist/runnerUtility/adminCheck.d.ts +18 -0
- package/dist/runnerUtility/adminCheck.d.ts.map +1 -0
- package/dist/runnerUtility/adminCheck.js +69 -0
- package/dist/runnerUtility/adminCheck.js.map +1 -0
- 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/appInstall.d.ts +25 -0
- package/dist/runnerUtility/appInstall.d.ts.map +1 -0
- package/dist/runnerUtility/appInstall.js +147 -0
- package/dist/runnerUtility/appInstall.js.map +1 -0
- package/dist/runnerUtility/appUpdate.d.ts +39 -0
- package/dist/runnerUtility/appUpdate.d.ts.map +1 -0
- package/dist/runnerUtility/appUpdate.js +90 -0
- package/dist/runnerUtility/appUpdate.js.map +1 -0
- package/dist/runnerUtility/execEnv.d.ts +21 -0
- package/dist/runnerUtility/execEnv.d.ts.map +1 -0
- package/dist/runnerUtility/execEnv.js +109 -0
- package/dist/runnerUtility/execEnv.js.map +1 -0
- package/dist/runnerUtility/execSession.d.ts +13 -0
- package/dist/runnerUtility/execSession.d.ts.map +1 -0
- package/dist/runnerUtility/execSession.js +58 -0
- package/dist/runnerUtility/execSession.js.map +1 -0
- package/dist/runnerUtility/hubClient.d.ts +30 -0
- package/dist/runnerUtility/hubClient.d.ts.map +1 -0
- package/dist/runnerUtility/hubClient.js +127 -0
- package/dist/runnerUtility/hubClient.js.map +1 -0
- package/dist/runnerUtility/injectStream.d.ts +9 -0
- package/dist/runnerUtility/injectStream.d.ts.map +1 -0
- package/dist/runnerUtility/injectStream.js +12 -0
- package/dist/runnerUtility/injectStream.js.map +1 -0
- package/dist/runnerUtility/iosCheck.d.ts +62 -0
- package/dist/runnerUtility/iosCheck.d.ts.map +1 -0
- package/dist/runnerUtility/iosCheck.js +200 -0
- package/dist/runnerUtility/iosCheck.js.map +1 -0
- package/dist/runnerUtility/launcher.d.ts +5 -0
- package/dist/runnerUtility/launcher.d.ts.map +1 -0
- package/dist/runnerUtility/launcher.js +85 -0
- package/dist/runnerUtility/launcher.js.map +1 -0
- package/dist/runnerUtility/linkLoop.d.ts +39 -0
- package/dist/runnerUtility/linkLoop.d.ts.map +1 -0
- package/dist/runnerUtility/linkLoop.js +274 -0
- package/dist/runnerUtility/linkLoop.js.map +1 -0
- package/dist/runnerUtility/localLinkStop.d.ts +23 -0
- package/dist/runnerUtility/localLinkStop.d.ts.map +1 -0
- package/dist/runnerUtility/localLinkStop.js +79 -0
- package/dist/runnerUtility/localLinkStop.js.map +1 -0
- package/dist/runnerUtility/machineReport.d.ts +39 -0
- package/dist/runnerUtility/machineReport.d.ts.map +1 -0
- package/dist/runnerUtility/machineReport.js +161 -0
- package/dist/runnerUtility/machineReport.js.map +1 -0
- package/dist/runnerUtility/packageId.d.ts +5 -0
- package/dist/runnerUtility/packageId.d.ts.map +1 -0
- package/dist/runnerUtility/packageId.js +64 -0
- package/dist/runnerUtility/packageId.js.map +1 -0
- 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/pairingRecovery.d.ts +31 -0
- package/dist/runnerUtility/pairingRecovery.d.ts.map +1 -0
- package/dist/runnerUtility/pairingRecovery.js +24 -0
- package/dist/runnerUtility/pairingRecovery.js.map +1 -0
- package/dist/runnerUtility/pueueDaemon.d.ts +36 -0
- package/dist/runnerUtility/pueueDaemon.d.ts.map +1 -0
- package/dist/runnerUtility/pueueDaemon.js +165 -0
- package/dist/runnerUtility/pueueDaemon.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.d.ts +18 -0
- package/dist/runnerUtility/runnerCli.d.ts.map +1 -0
- package/dist/runnerUtility/runnerCli.js +190 -0
- package/dist/runnerUtility/runnerCli.js.map +1 -0
- package/dist/runnerUtility/runnerCommands.d.ts +76 -0
- package/dist/runnerUtility/runnerCommands.d.ts.map +1 -0
- package/dist/runnerUtility/runnerCommands.js +464 -0
- package/dist/runnerUtility/runnerCommands.js.map +1 -0
- package/dist/runnerUtility/runnerConfig.d.ts +63 -0
- package/dist/runnerUtility/runnerConfig.d.ts.map +1 -0
- package/dist/runnerUtility/runnerConfig.js +153 -0
- package/dist/runnerUtility/runnerConfig.js.map +1 -0
- package/dist/runnerUtility/runnerFlags.d.ts +9 -0
- package/dist/runnerUtility/runnerFlags.d.ts.map +1 -0
- package/dist/runnerUtility/runnerFlags.js +53 -0
- package/dist/runnerUtility/runnerFlags.js.map +1 -0
- package/dist/runnerUtility/runnerHome.d.ts +30 -0
- package/dist/runnerUtility/runnerHome.d.ts.map +1 -0
- package/dist/runnerUtility/runnerHome.js +82 -0
- package/dist/runnerUtility/runnerHome.js.map +1 -0
- package/dist/runnerUtility/runnerKeys.d.ts +11 -0
- package/dist/runnerUtility/runnerKeys.d.ts.map +1 -0
- package/dist/runnerUtility/runnerKeys.js +80 -0
- package/dist/runnerUtility/runnerKeys.js.map +1 -0
- package/dist/runnerUtility/runnerServers.d.ts +40 -0
- package/dist/runnerUtility/runnerServers.d.ts.map +1 -0
- package/dist/runnerUtility/runnerServers.js +79 -0
- package/dist/runnerUtility/runnerServers.js.map +1 -0
- 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 +51 -0
- package/dist/runnerUtility/serviceManager.d.ts.map +1 -0
- package/dist/runnerUtility/serviceManager.js +344 -0
- package/dist/runnerUtility/serviceManager.js.map +1 -0
- package/dist/runnerUtility/serviceUnits.d.ts +38 -0
- package/dist/runnerUtility/serviceUnits.d.ts.map +1 -0
- package/dist/runnerUtility/serviceUnits.js +189 -0
- package/dist/runnerUtility/serviceUnits.js.map +1 -0
- package/dist/runnerUtility/toolInstall.d.ts +95 -0
- package/dist/runnerUtility/toolInstall.d.ts.map +1 -0
- package/dist/runnerUtility/toolInstall.js +232 -0
- package/dist/runnerUtility/toolInstall.js.map +1 -0
- package/dist/runnerUtility/versionPollTiming.d.ts +16 -0
- package/dist/runnerUtility/versionPollTiming.d.ts.map +1 -0
- package/dist/runnerUtility/versionPollTiming.js +36 -0
- package/dist/runnerUtility/versionPollTiming.js.map +1 -0
- package/dist/runners/authorizedKeys.d.ts +52 -0
- package/dist/runners/authorizedKeys.d.ts.map +1 -0
- package/dist/runners/authorizedKeys.js +153 -0
- package/dist/runners/authorizedKeys.js.map +1 -0
- package/dist/runners/bootstrapLine.d.ts +13 -0
- package/dist/runners/bootstrapLine.d.ts.map +1 -0
- package/dist/runners/bootstrapLine.js +154 -0
- package/dist/runners/bootstrapLine.js.map +1 -0
- package/dist/runners/gate.d.ts +41 -0
- package/dist/runners/gate.d.ts.map +1 -0
- package/dist/runners/gate.js +225 -0
- package/dist/runners/gate.js.map +1 -0
- package/dist/runners/gateLink.d.ts +26 -0
- package/dist/runners/gateLink.d.ts.map +1 -0
- package/dist/runners/gateLink.js +240 -0
- package/dist/runners/gateLink.js.map +1 -0
- package/dist/runners/gateProtocol.d.ts +104 -0
- package/dist/runners/gateProtocol.d.ts.map +1 -0
- package/dist/runners/gateProtocol.js +151 -0
- package/dist/runners/gateProtocol.js.map +1 -0
- package/dist/runners/gateWrapper.d.ts +6 -0
- package/dist/runners/gateWrapper.d.ts.map +1 -0
- package/dist/runners/gateWrapper.js +70 -0
- package/dist/runners/gateWrapper.js.map +1 -0
- package/dist/runners/hubAddress.d.ts +33 -0
- package/dist/runners/hubAddress.d.ts.map +1 -0
- package/dist/runners/hubAddress.js +88 -0
- package/dist/runners/hubAddress.js.map +1 -0
- package/dist/runners/hubAddressCandidates.d.ts +16 -0
- package/dist/runners/hubAddressCandidates.d.ts.map +1 -0
- package/dist/runners/hubAddressCandidates.js +96 -0
- package/dist/runners/hubAddressCandidates.js.map +1 -0
- package/dist/runners/hubIds.d.ts +16 -0
- package/dist/runners/hubIds.d.ts.map +1 -0
- package/dist/runners/hubIds.js +25 -0
- package/dist/runners/hubIds.js.map +1 -0
- package/dist/runners/hubKey.d.ts +6 -0
- package/dist/runners/hubKey.d.ts.map +1 -0
- package/dist/runners/hubKey.js +78 -0
- package/dist/runners/hubKey.js.map +1 -0
- package/dist/runners/hubLock.d.ts +7 -0
- package/dist/runners/hubLock.d.ts.map +1 -0
- package/dist/runners/hubLock.js +230 -0
- package/dist/runners/hubLock.js.map +1 -0
- package/dist/runners/hubPackage.d.ts +23 -0
- package/dist/runners/hubPackage.d.ts.map +1 -0
- package/dist/runners/hubPackage.js +184 -0
- package/dist/runners/hubPackage.js.map +1 -0
- package/dist/runners/hubPairing.d.ts +70 -0
- package/dist/runners/hubPairing.d.ts.map +1 -0
- package/dist/runners/hubPairing.js +277 -0
- package/dist/runners/hubPairing.js.map +1 -0
- package/dist/runners/hubPaths.d.ts +42 -0
- package/dist/runners/hubPaths.d.ts.map +1 -0
- package/dist/runners/hubPaths.js +96 -0
- package/dist/runners/hubPaths.js.map +1 -0
- package/dist/runners/hubRegistry.d.ts +134 -0
- package/dist/runners/hubRegistry.d.ts.map +1 -0
- package/dist/runners/hubRegistry.js +256 -0
- package/dist/runners/hubRegistry.js.map +1 -0
- package/dist/runners/linkControl.d.ts +38 -0
- package/dist/runners/linkControl.d.ts.map +1 -0
- package/dist/runners/linkControl.js +171 -0
- package/dist/runners/linkControl.js.map +1 -0
- package/dist/runners/pairCode.d.ts +30 -0
- package/dist/runners/pairCode.d.ts.map +1 -0
- package/dist/runners/pairCode.js +46 -0
- package/dist/runners/pairCode.js.map +1 -0
- package/dist/runners/pairingTiming.d.ts +18 -0
- package/dist/runners/pairingTiming.d.ts.map +1 -0
- package/dist/runners/pairingTiming.js +42 -0
- package/dist/runners/pairingTiming.js.map +1 -0
- 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/runnerProxy.d.ts +9 -0
- package/dist/runners/runnerProxy.d.ts.map +1 -0
- package/dist/runners/runnerProxy.js +67 -0
- package/dist/runners/runnerProxy.js.map +1 -0
- package/dist/runners/runnerRemoval.d.ts +21 -0
- package/dist/runners/runnerRemoval.d.ts.map +1 -0
- package/dist/runners/runnerRemoval.js +94 -0
- package/dist/runners/runnerRemoval.js.map +1 -0
- 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 +25 -0
- package/dist/runners/runnersCli.d.ts.map +1 -0
- package/dist/runners/runnersCli.js +239 -0
- package/dist/runners/runnersCli.js.map +1 -0
- package/dist/runners/runnersList.d.ts +14 -0
- package/dist/runners/runnersList.d.ts.map +1 -0
- package/dist/runners/runnersList.js +51 -0
- package/dist/runners/runnersList.js.map +1 -0
- package/dist/runners/runnersOverview.d.ts +20 -0
- package/dist/runners/runnersOverview.d.ts.map +1 -0
- package/dist/runners/runnersOverview.js +56 -0
- package/dist/runners/runnersOverview.js.map +1 -0
- package/dist/runners/sshKeys.d.ts +26 -0
- package/dist/runners/sshKeys.d.ts.map +1 -0
- package/dist/runners/sshKeys.js +60 -0
- package/dist/runners/sshKeys.js.map +1 -0
- package/dist/runners/tarArchive.d.ts +20 -0
- package/dist/runners/tarArchive.d.ts.map +1 -0
- package/dist/runners/tarArchive.js +70 -0
- package/dist/runners/tarArchive.js.map +1 -0
- package/dist/scheduler/mcpSurface.d.ts +11 -5
- package/dist/scheduler/mcpSurface.d.ts.map +1 -1
- package/dist/scheduler/mcpSurface.js +59 -26
- package/dist/scheduler/mcpSurface.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/testTimings.d.ts +5 -2
- package/dist/testTimings.d.ts.map +1 -1
- package/dist/testTimings.js +10 -1
- package/dist/testTimings.js.map +1 -1
- package/dist/utils/agentEnvironment.d.ts +6 -2
- package/dist/utils/agentEnvironment.d.ts.map +1 -1
- package/dist/utils/agentEnvironment.js +13 -2
- package/dist/utils/agentEnvironment.js.map +1 -1
- package/dist/utils/runnersScreenPlan.d.ts +141 -0
- package/dist/utils/runnersScreenPlan.d.ts.map +1 -0
- package/dist/utils/runnersScreenPlan.js +272 -0
- package/dist/utils/runnersScreenPlan.js.map +1 -0
- package/package.json +5 -2
- package/remoteRun/runner.sh +81 -6
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.readLinkState = readLinkState;
|
|
37
|
+
exports.writeLinkState = writeLinkState;
|
|
38
|
+
exports.probeSocket = probeSocket;
|
|
39
|
+
exports.getRunnerLinkStatus = getRunnerLinkStatus;
|
|
40
|
+
exports.checkIsGateProcessOf = checkIsGateProcessOf;
|
|
41
|
+
exports.cutRunnerLink = cutRunnerLink;
|
|
42
|
+
exports.sweepOrphanLinkRecords = sweepOrphanLinkRecords;
|
|
43
|
+
const child_process_1 = require("child_process");
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const net = __importStar(require("net"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const zod_1 = require("zod");
|
|
48
|
+
const configDirFile_1 = require("../configDirFile");
|
|
49
|
+
const hubPaths_1 = require("./hubPaths");
|
|
50
|
+
const hubIds_1 = require("./hubIds");
|
|
51
|
+
/**
|
|
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
|
|
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
|
|
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
|
|
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}.
|
|
57
|
+
*/
|
|
58
|
+
const stateFileMode = 0o600;
|
|
59
|
+
const probeTimeoutMs = 1000;
|
|
60
|
+
const linkStateSchema = zod_1.z.strictObject({
|
|
61
|
+
pid: zod_1.z.number().int().positive(),
|
|
62
|
+
sinceMs: zod_1.z.number().int().nonnegative(),
|
|
63
|
+
lastBeatMs: zod_1.z.number().int().nonnegative(),
|
|
64
|
+
/** Set by the gate when it leaves; `null` while it holds the link. */
|
|
65
|
+
endedAtMs: zod_1.z.number().int().nonnegative().nullable(),
|
|
66
|
+
});
|
|
67
|
+
function readLinkState(dir, runnerId) {
|
|
68
|
+
try {
|
|
69
|
+
const parsed = linkStateSchema.safeParse(JSON.parse(fs.readFileSync((0, hubPaths_1.getRunnerLinkPaths)(dir, runnerId).state, 'utf8')));
|
|
70
|
+
return parsed.success ? parsed.data : null;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function writeLinkState(dir, runnerId, state) {
|
|
77
|
+
fs.mkdirSync((0, hubPaths_1.getHubFilePaths)(dir).linkDir, { recursive: true, mode: 0o700 });
|
|
78
|
+
(0, configDirFile_1.writeJsonFileAtomically)((0, hubPaths_1.getRunnerLinkPaths)(dir, runnerId).state, linkStateSchema.parse(state), stateFileMode);
|
|
79
|
+
}
|
|
80
|
+
/** @description Does anything accept a connection on the unix socket `socketPath` right now? */
|
|
81
|
+
function probeSocket(socketPath, timeoutMs = probeTimeoutMs) {
|
|
82
|
+
return new Promise((resolve) => {
|
|
83
|
+
const socket = net.connect(socketPath);
|
|
84
|
+
const settle = (isAccepted) => {
|
|
85
|
+
clearTimeout(timer);
|
|
86
|
+
socket.destroy();
|
|
87
|
+
resolve(isAccepted);
|
|
88
|
+
};
|
|
89
|
+
const timer = setTimeout(() => settle(false), timeoutMs);
|
|
90
|
+
socket.once('connect', () => settle(true));
|
|
91
|
+
socket.once('error', () => settle(false));
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async function getRunnerLinkStatus(dir, runnerId) {
|
|
95
|
+
const state = readLinkState(dir, runnerId);
|
|
96
|
+
const isOnline = await probeSocket((0, hubPaths_1.getRunnerLinkPaths)(dir, runnerId).socket);
|
|
97
|
+
return {
|
|
98
|
+
isOnline,
|
|
99
|
+
sinceMs: isOnline ? (state?.sinceMs ?? null) : null,
|
|
100
|
+
lastSeenMs: state === null ? null : (state.endedAtMs ?? state.lastBeatMs),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** @description Is `pid` a charness gate serving runner `runnerId`? (A pid in an old json may belong to anything by now.) */
|
|
104
|
+
function checkIsGateProcessOf(pid, runnerId) {
|
|
105
|
+
const listing = (0, child_process_1.spawnSync)('ps', ['-p', pid.toString(), '-o', 'command='], { encoding: 'utf8', timeout: probeTimeoutMs * 5 });
|
|
106
|
+
return listing.status === 0 && listing.stdout.includes('runner-gate') && listing.stdout.includes(` runner ${runnerId}`);
|
|
107
|
+
}
|
|
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. */
|
|
109
|
+
function cutRunnerLink(dir, runnerId) {
|
|
110
|
+
const state = readLinkState(dir, runnerId);
|
|
111
|
+
const paths = (0, hubPaths_1.getRunnerLinkPaths)(dir, runnerId);
|
|
112
|
+
fs.rmSync(paths.socket, { force: true });
|
|
113
|
+
if (state !== null && state.endedAtMs === null && checkIsGateProcessOf(state.pid, runnerId)) {
|
|
114
|
+
try {
|
|
115
|
+
process.kill(state.pid, 'SIGTERM');
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if ((0, configDirFile_1.getCaughtErrnoCode)(error) !== 'ESRCH')
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
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;
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=linkControl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linkControl.js","sourceRoot":"","sources":["../../src/runners/linkControl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* @description The pairing code: everything a runner needs to reach the hub ONCE — the address, the hub's ssh host key to pin, the
|
|
4
|
+
* account to log in as, a private key that is good for one `redeem` (and the package download), and the pairing's id. Text
|
|
5
|
+
* `cr1.<base64url of a JSON object>`; the `1` is the format version. It is a secret until it is used or has expired: it is never
|
|
6
|
+
* logged, and a decode error names a field, never a value.
|
|
7
|
+
*/
|
|
8
|
+
export declare const pairCodePrefix = "cr1.";
|
|
9
|
+
declare const pairCodePayloadSchema: z.ZodObject<{
|
|
10
|
+
host: z.ZodString;
|
|
11
|
+
port: z.ZodNumber;
|
|
12
|
+
user: z.ZodString;
|
|
13
|
+
hostKey: z.ZodString;
|
|
14
|
+
privateKey: z.ZodString;
|
|
15
|
+
pairId: z.ZodString;
|
|
16
|
+
}, z.core.$strict>;
|
|
17
|
+
/** @name PairCodePayload @description What a pairing code carries. */
|
|
18
|
+
export type PairCodePayload = z.infer<typeof pairCodePayloadSchema>;
|
|
19
|
+
export type PairCodeDecoding = {
|
|
20
|
+
ok: true;
|
|
21
|
+
payload: PairCodePayload;
|
|
22
|
+
} | {
|
|
23
|
+
ok: false;
|
|
24
|
+
error: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function encodePairCode(payload: PairCodePayload): string;
|
|
27
|
+
/** @description The payload of `code`, or why it is not one (the reason never quotes the code). */
|
|
28
|
+
export declare function decodePairCode(code: string): PairCodeDecoding;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=pairCode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairCode.d.ts","sourceRoot":"","sources":["../../src/runners/pairCode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;GAKG;AAEH,eAAO,MAAM,cAAc,SAAS,CAAC;AAIrC,QAAA,MAAM,qBAAqB;;;;;;;kBAOzB,CAAC;AAEH,sEAAsE;AACtE,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,eAAe,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErG,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAE/D;AAED,mGAAmG;AACnG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAY7D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pairCodePrefix = void 0;
|
|
4
|
+
exports.encodePairCode = encodePairCode;
|
|
5
|
+
exports.decodePairCode = decodePairCode;
|
|
6
|
+
const zod_1 = require("zod");
|
|
7
|
+
const hubIds_1 = require("./hubIds");
|
|
8
|
+
/**
|
|
9
|
+
* @description The pairing code: everything a runner needs to reach the hub ONCE — the address, the hub's ssh host key to pin, the
|
|
10
|
+
* account to log in as, a private key that is good for one `redeem` (and the package download), and the pairing's id. Text
|
|
11
|
+
* `cr1.<base64url of a JSON object>`; the `1` is the format version. It is a secret until it is used or has expired: it is never
|
|
12
|
+
* logged, and a decode error names a field, never a value.
|
|
13
|
+
*/
|
|
14
|
+
exports.pairCodePrefix = 'cr1.';
|
|
15
|
+
const maxCodeLength = 4096;
|
|
16
|
+
const privateKeyPattern = /^-----BEGIN OPENSSH PRIVATE KEY-----\n[A-Za-z0-9+/=\n]+\n-----END OPENSSH PRIVATE KEY-----\n?$/;
|
|
17
|
+
const pairCodePayloadSchema = zod_1.z.strictObject({
|
|
18
|
+
host: hubIds_1.hubHostSchema,
|
|
19
|
+
port: hubIds_1.hubPortSchema,
|
|
20
|
+
user: hubIds_1.hubSshUserSchema,
|
|
21
|
+
hostKey: hubIds_1.hubHostKeySchema,
|
|
22
|
+
privateKey: zod_1.z.string().max(2048).regex(privateKeyPattern, 'must be an OpenSSH private key'),
|
|
23
|
+
pairId: hubIds_1.hubIdSchema,
|
|
24
|
+
});
|
|
25
|
+
function encodePairCode(payload) {
|
|
26
|
+
return `${exports.pairCodePrefix}${Buffer.from(JSON.stringify(pairCodePayloadSchema.parse(payload)), 'utf8').toString('base64url')}`;
|
|
27
|
+
}
|
|
28
|
+
/** @description The payload of `code`, or why it is not one (the reason never quotes the code). */
|
|
29
|
+
function decodePairCode(code) {
|
|
30
|
+
if (!code.startsWith(exports.pairCodePrefix))
|
|
31
|
+
return { ok: false, error: `a pairing code starts with ${exports.pairCodePrefix}` };
|
|
32
|
+
if (code.length > maxCodeLength)
|
|
33
|
+
return { ok: false, error: 'the pairing code is too long' };
|
|
34
|
+
let parsedJson;
|
|
35
|
+
try {
|
|
36
|
+
parsedJson = JSON.parse(Buffer.from(code.slice(exports.pairCodePrefix.length), 'base64url').toString('utf8'));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return { ok: false, error: 'the pairing code is damaged (not a copy of the whole line?)' };
|
|
40
|
+
}
|
|
41
|
+
const parsed = pairCodePayloadSchema.safeParse(parsedJson);
|
|
42
|
+
if (parsed.success)
|
|
43
|
+
return { ok: true, payload: parsed.data };
|
|
44
|
+
return { ok: false, error: `the pairing code is damaged: ${parsed.error.issues.map((issue) => `${issue.path.join('.') || '(root)'} ${issue.message}`).join('; ')}` };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=pairCode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairCode.js","sourceRoot":"","sources":["../../src/runners/pairCode.ts"],"names":[],"mappings":";;;AA4BA,wCAEC;AAGD,wCAYC;AA7CD,6BAAwB;AACxB,qCAAyG;AAEzG;;;;;GAKG;AAEU,QAAA,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,aAAa,GAAG,IAAI,CAAC;AAC3B,MAAM,iBAAiB,GAAG,gGAAgG,CAAC;AAE3H,MAAM,qBAAqB,GAAG,OAAC,CAAC,YAAY,CAAC;IAC3C,IAAI,EAAE,sBAAa;IACnB,IAAI,EAAE,sBAAa;IACnB,IAAI,EAAE,yBAAgB;IACtB,OAAO,EAAE,yBAAgB;IACzB,UAAU,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,iBAAiB,EAAE,gCAAgC,CAAC;IAC3F,MAAM,EAAE,oBAAW;CACpB,CAAC,CAAC;AAOH,SAAgB,cAAc,CAAC,OAAwB;IACrD,OAAO,GAAG,sBAAc,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AAC/H,CAAC;AAED,mGAAmG;AACnG,SAAgB,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,sBAAc,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,sBAAc,EAAE,EAAE,CAAC;IAClH,IAAI,IAAI,CAAC,MAAM,GAAG,aAAa;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;IAC7F,IAAI,UAAkB,CAAC;IACvB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAc,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACxG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,6DAA6D,EAAE,CAAC;IAC7F,CAAC;IACD,MAAM,MAAM,GAAG,qBAAqB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gCAAgC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;AACvK,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @description How long a pairing code works. In a module of its own so the headless CLI reads it without loading the bot.
|
|
3
|
+
*
|
|
4
|
+
* The test seam `CHARNESS_TEST_TIMINGS` (`testTimings.ts`) may only SHORTEN it (key `pairingLifetimeMs`, at least
|
|
5
|
+
* {@link pairingLifetimeMinMs}: sshd's `expiry-time` has a granularity of a second). Like the remote-run lease it is read tolerantly here,
|
|
6
|
+
* because this module cannot import `testTimings.ts` (its graph reaches the bot); the boot of an instance that carries a bad value is what
|
|
7
|
+
* refuses it by name.
|
|
8
|
+
*/
|
|
9
|
+
export declare const pairingLifetimeMinutes = 10;
|
|
10
|
+
/** Production: a code works for ten minutes, once. */
|
|
11
|
+
export declare const pairingLifetimeMs: number;
|
|
12
|
+
/** sshd compares `expiry-time` in whole seconds: a shorter window would be rounding. */
|
|
13
|
+
export declare const pairingLifetimeMinMs = 5000;
|
|
14
|
+
/** @description The lifetime in force: the production one, or the seam's shorter `pairingLifetimeMs` when it is a whole number of ms within [min, production]. */
|
|
15
|
+
export declare function readPairingLifetimeMs(env: NodeJS.ProcessEnv): number;
|
|
16
|
+
/** @description «10 minutes», or «5 seconds» for a window shorter than a minute (only a test's). */
|
|
17
|
+
export declare function formatLifetime(lifetimeMs: number): string;
|
|
18
|
+
//# sourceMappingURL=pairingTiming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairingTiming.d.ts","sourceRoot":"","sources":["../../src/runners/pairingTiming.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,QAAuC,CAAC;AACtE,wFAAwF;AACxF,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAIzC,kKAAkK;AAClK,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAYpE;AAED,oGAAoG;AACpG,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @description How long a pairing code works. In a module of its own so the headless CLI reads it without loading the bot.
|
|
4
|
+
*
|
|
5
|
+
* The test seam `CHARNESS_TEST_TIMINGS` (`testTimings.ts`) may only SHORTEN it (key `pairingLifetimeMs`, at least
|
|
6
|
+
* {@link pairingLifetimeMinMs}: sshd's `expiry-time` has a granularity of a second). Like the remote-run lease it is read tolerantly here,
|
|
7
|
+
* because this module cannot import `testTimings.ts` (its graph reaches the bot); the boot of an instance that carries a bad value is what
|
|
8
|
+
* refuses it by name.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.pairingLifetimeMinMs = exports.pairingLifetimeMs = exports.pairingLifetimeMinutes = void 0;
|
|
12
|
+
exports.readPairingLifetimeMs = readPairingLifetimeMs;
|
|
13
|
+
exports.formatLifetime = formatLifetime;
|
|
14
|
+
const msPerMinute = 60 * 1000;
|
|
15
|
+
exports.pairingLifetimeMinutes = 10;
|
|
16
|
+
/** Production: a code works for ten minutes, once. */
|
|
17
|
+
exports.pairingLifetimeMs = exports.pairingLifetimeMinutes * msPerMinute;
|
|
18
|
+
/** sshd compares `expiry-time` in whole seconds: a shorter window would be rounding. */
|
|
19
|
+
exports.pairingLifetimeMinMs = 5000;
|
|
20
|
+
const testTimingsVariableName = 'CHARNESS_TEST_TIMINGS';
|
|
21
|
+
/** @description The lifetime in force: the production one, or the seam's shorter `pairingLifetimeMs` when it is a whole number of ms within [min, production]. */
|
|
22
|
+
function readPairingLifetimeMs(env) {
|
|
23
|
+
const rawTestTimings = env[testTimingsVariableName];
|
|
24
|
+
if (rawTestTimings === undefined || rawTestTimings.trim() === '')
|
|
25
|
+
return exports.pairingLifetimeMs;
|
|
26
|
+
let overrides;
|
|
27
|
+
try {
|
|
28
|
+
overrides = JSON.parse(rawTestTimings);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return exports.pairingLifetimeMs;
|
|
32
|
+
}
|
|
33
|
+
const overrideMs = overrides?.pairingLifetimeMs;
|
|
34
|
+
if (overrideMs === undefined || !Number.isInteger(overrideMs))
|
|
35
|
+
return exports.pairingLifetimeMs;
|
|
36
|
+
return overrideMs >= exports.pairingLifetimeMinMs && overrideMs <= exports.pairingLifetimeMs ? overrideMs : exports.pairingLifetimeMs;
|
|
37
|
+
}
|
|
38
|
+
/** @description «10 minutes», or «5 seconds» for a window shorter than a minute (only a test's). */
|
|
39
|
+
function formatLifetime(lifetimeMs) {
|
|
40
|
+
return lifetimeMs >= msPerMinute ? `${Math.round(lifetimeMs / msPerMinute)} minutes` : `${Math.round(lifetimeMs / 1000)} seconds`;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=pairingTiming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pairingTiming.js","sourceRoot":"","sources":["../../src/runners/pairingTiming.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAYH,sDAYC;AAGD,wCAEC;AA3BD,MAAM,WAAW,GAAG,EAAE,GAAG,IAAI,CAAC;AACjB,QAAA,sBAAsB,GAAG,EAAE,CAAC;AACzC,sDAAsD;AACzC,QAAA,iBAAiB,GAAG,8BAAsB,GAAG,WAAW,CAAC;AACtE,wFAAwF;AAC3E,QAAA,oBAAoB,GAAG,IAAI,CAAC;AAEzC,MAAM,uBAAuB,GAAG,uBAAuB,CAAC;AAExD,kKAAkK;AAClK,SAAgB,qBAAqB,CAAC,GAAsB;IAC1D,MAAM,cAAc,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC;IACpD,IAAI,cAAc,KAAK,SAAS,IAAI,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,yBAAiB,CAAC;IAC3F,IAAI,SAAgD,CAAC;IACrD,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,yBAAiB,CAAC;IAC3B,CAAC;IACD,MAAM,UAAU,GAAG,SAAS,EAAE,iBAAiB,CAAC;IAChD,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC;QAAE,OAAO,yBAAiB,CAAC;IACxF,OAAO,UAAU,IAAI,4BAAoB,IAAI,UAAU,IAAI,yBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,yBAAiB,CAAC;AAChH,CAAC;AAED,oGAAoG;AACpG,SAAgB,cAAc,CAAC,UAAkB;IAC/C,OAAO,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;AACpI,CAAC"}
|
|
@@ -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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Readable, Writable } from 'stream';
|
|
2
|
+
export interface RunnerProxyIo {
|
|
3
|
+
stdin: Readable;
|
|
4
|
+
stdout: Writable;
|
|
5
|
+
stderr: Writable;
|
|
6
|
+
}
|
|
7
|
+
/** @description Join `io` to the socket; resolves with the exit code when either side ends. */
|
|
8
|
+
export declare function runRunnerProxy(socketPath: string, io: RunnerProxyIo): Promise<number>;
|
|
9
|
+
//# sourceMappingURL=runnerProxy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerProxy.d.ts","sourceRoot":"","sources":["../../src/runners/runnerProxy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAWjD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBrF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runRunnerProxy = runRunnerProxy;
|
|
37
|
+
const net = __importStar(require("net"));
|
|
38
|
+
/**
|
|
39
|
+
* @description `charness runner-proxy <socket>` — the `ProxyCommand` of the ssh calls to a paired runner: it joins ssh's stdin and
|
|
40
|
+
* stdout to the unix socket that the runner's gate listens on (`gateLink.ts`). When nothing listens, the runner is offline: the
|
|
41
|
+
* proxy says so on stderr, which ssh shows as the reason, and exits 255 — the status ssh itself uses for a failed connection, which
|
|
42
|
+
* remote-run already treats as «the connection was lost».
|
|
43
|
+
*/
|
|
44
|
+
const connectionFailedExitCode = 255;
|
|
45
|
+
/** @description Join `io` to the socket; resolves with the exit code when either side ends. */
|
|
46
|
+
function runRunnerProxy(socketPath, io) {
|
|
47
|
+
return new Promise((resolve) => {
|
|
48
|
+
const socket = net.connect(socketPath);
|
|
49
|
+
let isConnected = false;
|
|
50
|
+
socket.once('connect', () => {
|
|
51
|
+
isConnected = true;
|
|
52
|
+
io.stdin.pipe(socket);
|
|
53
|
+
socket.pipe(io.stdout, { end: false });
|
|
54
|
+
});
|
|
55
|
+
socket.once('error', () => {
|
|
56
|
+
if (!isConnected)
|
|
57
|
+
io.stderr.write('charness runner-proxy: the runner is not connected\n');
|
|
58
|
+
socket.destroy();
|
|
59
|
+
});
|
|
60
|
+
socket.once('close', () => {
|
|
61
|
+
io.stdin.unpipe(socket);
|
|
62
|
+
resolve(isConnected ? 0 : connectionFailedExitCode);
|
|
63
|
+
});
|
|
64
|
+
io.stdin.once('end', () => socket.end());
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=runnerProxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerProxy.js","sourceRoot":"","sources":["../../src/runners/runnerProxy.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBA,wCAmBC;AAtCD,yCAA2B;AAG3B;;;;;GAKG;AAEH,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAQrC,+FAA+F;AAC/F,SAAgB,cAAc,CAAC,UAAkB,EAAE,EAAiB;IAClE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACvC,IAAI,WAAW,GAAG,KAAK,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,WAAW,GAAG,IAAI,CAAC;YACnB,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,WAAW;gBAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1F,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACxB,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { runSshCommand } from '../remoteRun/ssh';
|
|
2
|
+
import type { HubContext } from './hubPaths';
|
|
3
|
+
import { type PairedRunner } from './hubRegistry';
|
|
4
|
+
/** What became of the jobs on the removed runner: ended through the link; could not be ended from here; or the runner was offline. */
|
|
5
|
+
export type RunnerJobsStop = 'stopped' | 'failed' | 'offline';
|
|
6
|
+
export interface RunnerRemovalDeps {
|
|
7
|
+
isLinkOnline: (ctx: HubContext, runnerId: string) => Promise<boolean>;
|
|
8
|
+
runSsh: typeof runSshCommand;
|
|
9
|
+
cacheDir: string;
|
|
10
|
+
log: (line: string) => void;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* @description Remove `nameOrId`: while it is still paired, pause it and stop its jobs through the link (when it is online); then drop it
|
|
14
|
+
* 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
|
|
15
|
+
* written stops the call before the link is touched.
|
|
16
|
+
*/
|
|
17
|
+
export declare function removeRunnerAndEndItsWork(ctx: HubContext, nameOrId: string, nowMs: number, deps?: RunnerRemovalDeps): Promise<{
|
|
18
|
+
runner: PairedRunner;
|
|
19
|
+
jobs: RunnerJobsStop;
|
|
20
|
+
} | null>;
|
|
21
|
+
//# sourceMappingURL=runnerRemoval.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.removeRunnerAndEndItsWork = removeRunnerAndEndItsWork;
|
|
4
|
+
const pairedRunners_1 = require("../remoteRun/pairedRunners");
|
|
5
|
+
const ssh_1 = require("../remoteRun/ssh");
|
|
6
|
+
const runners_1 = require("../remoteRun/runners");
|
|
7
|
+
const hubPairing_1 = require("./hubPairing");
|
|
8
|
+
const hubRegistry_1 = require("./hubRegistry");
|
|
9
|
+
const linkControl_1 = require("./linkControl");
|
|
10
|
+
/**
|
|
11
|
+
* @description Removing a runner from the hub, and ending the work the hub's agents left on it. Pueue outlives any link by design, so
|
|
12
|
+
* cutting the link leaves their background jobs running on a machine that is no longer theirs. When the runner is ONLINE the hub says so
|
|
13
|
+
* itself, over the link that is still open: it runs `pueue reset --force` there (the queue's private Pueue, found from the work dir the
|
|
14
|
+
* runner reported). That is certain — unlike the runner's own inference from a refused key, which a hub with a locked home folder or a
|
|
15
|
+
* wrong file mode produces too (see `runnerUtility/linkLoop.ts`) — and it works whatever the runner's version.
|
|
16
|
+
*
|
|
17
|
+
* The ORDER matters: the gate ends a link as soon as its runner has left `paired.json`, which would cut the reset off half-way, so the
|
|
18
|
+
* runner is paused (no new job is sent to it meanwhile) and its jobs are stopped while it is still paired; only then it is removed and
|
|
19
|
+
* its link cut.
|
|
20
|
+
*/
|
|
21
|
+
const stopJobsTimeoutMs = 20 * 1000;
|
|
22
|
+
function createRemovalDeps() {
|
|
23
|
+
return {
|
|
24
|
+
isLinkOnline: async (ctx, runnerId) => (await (0, linkControl_1.getRunnerLinkStatus)(ctx.dir, runnerId)).isOnline,
|
|
25
|
+
runSsh: ssh_1.runSshCommand,
|
|
26
|
+
cacheDir: (0, ssh_1.getRemoteRunCacheDir)(),
|
|
27
|
+
log: (line) => { console.error(line); },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** Is the runner's link up? `null` when that could not be read (logged): a runner nobody can tell about is not «offline». */
|
|
31
|
+
async function checkIsLinkOnline(ctx, runner, deps) {
|
|
32
|
+
try {
|
|
33
|
+
return await deps.isLinkOnline(ctx, runner.id);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
deps.log(`runners: could not tell whether "${runner.name}" is online (${error instanceof Error ? error.message : 'unknown error'}); its jobs are not stopped from here`);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Reset the queue of a runner whose link is up. Never throws: a failure is logged and told as `failed`. */
|
|
41
|
+
async function resetQueueOverLink(ctx, runner, deps) {
|
|
42
|
+
try {
|
|
43
|
+
const config = (0, pairedRunners_1.buildPairedRunnerConfig)(runner, { hubDir: ctx.dir, nodePath: ctx.nodePath, cliPath: ctx.cliPath });
|
|
44
|
+
if (config.pueue?.bin === undefined || config.pueue.config === undefined) {
|
|
45
|
+
deps.log(`runners: cannot stop the jobs of "${runner.name}" from here: its work folder does not follow the runner utility's layout`);
|
|
46
|
+
return 'failed';
|
|
47
|
+
}
|
|
48
|
+
(0, ssh_1.ensureRemoteRunCacheDir)(deps.cacheDir);
|
|
49
|
+
// No shared connection: this one call must not leave a master behind for the link that is about to be cut.
|
|
50
|
+
const noMaster = { ...config, sshOptions: ['-o', 'ControlMaster=no', ...(config.sshOptions ?? [])] };
|
|
51
|
+
const result = await deps.runSsh({ runner: noMaster, cacheDir: deps.cacheDir, remoteCommand: (0, ssh_1.joinShellWords)([config.pueue.bin, '--config', config.pueue.config, 'reset', '--force']), timeoutMs: stopJobsTimeoutMs });
|
|
52
|
+
if (result.exitCode === 0)
|
|
53
|
+
return 'stopped';
|
|
54
|
+
deps.log(`runners: the jobs of "${runner.name}" were not stopped (${result.isTimedOut ? 'no answer in time' : `exit ${result.exitCode ?? 'none'}`})`);
|
|
55
|
+
return 'failed';
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
deps.log(`runners: could not stop the jobs of "${runner.name}" (${error instanceof Error ? error.message : 'unknown error'})`);
|
|
59
|
+
return 'failed';
|
|
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
|
+
}
|
|
71
|
+
/**
|
|
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
|
|
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
|
|
74
|
+
* written stops the call before the link is touched.
|
|
75
|
+
*/
|
|
76
|
+
async function removeRunnerAndEndItsWork(ctx, nameOrId, nowMs, deps) {
|
|
77
|
+
const resolvedDeps = deps ?? createRemovalDeps();
|
|
78
|
+
const found = (0, hubPairing_1.findPairedRunner)((0, hubRegistry_1.readPairedFile)(ctx.dir).runners, nameOrId);
|
|
79
|
+
if (found === undefined)
|
|
80
|
+
return null;
|
|
81
|
+
const isOnline = await checkIsLinkOnline(ctx, found, resolvedDeps);
|
|
82
|
+
let jobs = isOnline === null ? 'failed' : 'offline';
|
|
83
|
+
if (isOnline === true) {
|
|
84
|
+
// No agent is sent to it from now on; the reset below takes seconds.
|
|
85
|
+
await (0, hubPairing_1.setPairedRunnerPaused)(ctx, found.id, true).catch((error) => { resolvedDeps.log(`runners: could not pause "${found.name}" before stopping its jobs (${error instanceof Error ? error.message : 'unknown error'})`); });
|
|
86
|
+
jobs = await resetQueueOverLink(ctx, found, resolvedDeps);
|
|
87
|
+
}
|
|
88
|
+
const removed = await (0, hubPairing_1.removePairedRunner)(ctx, found.id, nowMs);
|
|
89
|
+
(0, linkControl_1.cutRunnerLink)(ctx.dir, found.id);
|
|
90
|
+
if (removed !== null)
|
|
91
|
+
forgetLastReport(removed, resolvedDeps);
|
|
92
|
+
return removed === null ? null : { runner: removed, jobs };
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=runnerRemoval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runnerRemoval.js","sourceRoot":"","sources":["../../src/runners/runnerRemoval.ts"],"names":[],"mappings":";;AAsFA,8DAeC;AArGD,8DAAqE;AACrE,0CAAgH;AAChH,kDAAuD;AACvD,6CAA2F;AAE3F,+CAAkE;AAClE,+CAAmE;AAEnE;;;;;;;;;;GAUG;AAEH,MAAM,iBAAiB,GAAG,EAAE,GAAG,IAAI,CAAC;AAYpC,SAAS,iBAAiB;IACxB,OAAO;QACL,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,IAAA,iCAAmB,EAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ;QAC9F,MAAM,EAAE,mBAAa;QACrB,QAAQ,EAAE,IAAA,0BAAoB,GAAE;QAChC,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,6HAA6H;AAC7H,KAAK,UAAU,iBAAiB,CAAC,GAAe,EAAE,MAAoB,EAAE,IAAuB;IAC7F,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,oCAAoC,MAAM,CAAC,IAAI,gBAAgB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,uCAAuC,CAAC,CAAC;QACzK,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,4GAA4G;AAC5G,KAAK,UAAU,kBAAkB,CAAC,GAAe,EAAE,MAAoB,EAAE,IAAuB;IAC9F,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,uCAAuB,EAAC,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAClH,IAAI,MAAM,CAAC,KAAK,EAAE,GAAG,KAAK,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACzE,IAAI,CAAC,GAAG,CAAC,qCAAqC,MAAM,CAAC,IAAI,0EAA0E,CAAC,CAAC;YACrI,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAA,6BAAuB,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvC,2GAA2G;QAC3G,MAAM,QAAQ,GAAG,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,CAAC,IAAI,EAAE,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;QACrG,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAA,oBAAc,EAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC,CAAC;QACtN,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC5C,IAAI,CAAC,GAAG,CAAC,yBAAyB,MAAM,CAAC,IAAI,uBAAuB,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,QAAQ,IAAI,MAAM,EAAE,GAAG,CAAC,CAAC;QACtJ,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,wCAAwC,MAAM,CAAC,IAAI,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC;QAC/H,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,kLAAkL;AAClL,SAAS,gBAAgB,CAAC,MAAoB,EAAE,IAAuB;IACrE,IAAI,CAAC;QACH,IAAA,yBAAe,EAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,CAAC,kDAAkD,MAAM,CAAC,IAAI,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,6DAA6D,CAAC,CAAC;IACrM,CAAC;AACH,CAAC;AAED;;;;GAIG;AACI,KAAK,UAAU,yBAAyB,CAAC,GAAe,EAAE,QAAgB,EAAE,KAAa,EAAE,IAAwB;IACxH,MAAM,YAAY,GAAG,IAAI,IAAI,iBAAiB,EAAE,CAAC;IACjD,MAAM,KAAK,GAAG,IAAA,6BAAgB,EAAC,IAAA,4BAAc,EAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC1E,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IACnE,IAAI,IAAI,GAAmB,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,qEAAqE;QACrE,MAAM,IAAA,kCAAqB,EAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,6BAA6B,KAAK,CAAC,IAAI,+BAA+B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5N,IAAI,GAAG,MAAM,kBAAkB,CAAC,GAAG,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,IAAA,+BAAkB,EAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAC/D,IAAA,2BAAa,EAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACjC,IAAI,OAAO,KAAK,IAAI;QAAE,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9D,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AAC7D,CAAC"}
|
|
@@ -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
|