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,344 @@
|
|
|
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.parseServiceCommand = parseServiceCommand;
|
|
37
|
+
exports.createServiceDeps = createServiceDeps;
|
|
38
|
+
exports.readServiceKind = readServiceKind;
|
|
39
|
+
exports.formatSystemServiceRemoval = formatSystemServiceRemoval;
|
|
40
|
+
exports.installService = installService;
|
|
41
|
+
exports.uninstallService = uninstallService;
|
|
42
|
+
exports.runSystemStep = runSystemStep;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const commandRunner_1 = require("../selfUpdate/commandRunner");
|
|
47
|
+
const localLinkStop_1 = require("./localLinkStop");
|
|
48
|
+
const pueueDaemon_1 = require("./pueueDaemon");
|
|
49
|
+
const runnerConfig_1 = require("./runnerConfig");
|
|
50
|
+
const runnerHome_1 = require("./runnerHome");
|
|
51
|
+
const serviceCommon_1 = require("./serviceCommon");
|
|
52
|
+
const serviceUnits_1 = require("./serviceUnits");
|
|
53
|
+
/**
|
|
54
|
+
* @description `charness-runner service install|uninstall`: keep the link and Pueue running without a terminal — as the account that runs
|
|
55
|
+
* them, with the account's own rights.
|
|
56
|
+
*
|
|
57
|
+
* Linux two systemd USER units and `loginctl enable-linger` — no admin; where polkit wants one for the lingering, the one
|
|
58
|
+
* `sudo` line is printed and the units are installed all the same
|
|
59
|
+
* macOS two LaunchAgents — no admin; they run while the account is logged in (switched away included)
|
|
60
|
+
* always on (a Mac, logged out too; or Linux lingering set by an admin) is the ADMIN pairing line's work, not this command's: root must
|
|
61
|
+
* not run anything from this account's folder, so the admin line runs `adminService.ts` from a root-owned copy of the
|
|
62
|
+
* package, and that calls back into THIS program, as the account, for the account's own side (`service system-step`
|
|
63
|
+
* below). `--system` here is refused and says so.
|
|
64
|
+
*
|
|
65
|
+
* One kind at a time: installing one while the other's files exist is refused with the command that removes it. The kind is written to
|
|
66
|
+
* `~/.charness-runner/service` (one word) for `status` and for `runner.sh probe`.
|
|
67
|
+
*/
|
|
68
|
+
const markerMode = 0o644;
|
|
69
|
+
/** @description `install|uninstall [--system --user <name>]` (the pair is read only to be refused with the way that works). */
|
|
70
|
+
function parseServiceCommand(args) {
|
|
71
|
+
const [action, ...flags] = args;
|
|
72
|
+
if (action !== 'install' && action !== 'uninstall')
|
|
73
|
+
return { ok: false, error: 'service needs «install» or «uninstall»' };
|
|
74
|
+
const request = { isSystem: false, userName: null };
|
|
75
|
+
for (let index = 0; index < flags.length; index += 1) {
|
|
76
|
+
if (flags[index] === '--system') {
|
|
77
|
+
request.isSystem = true;
|
|
78
|
+
}
|
|
79
|
+
else if (flags[index] === '--user' && flags[index + 1] !== undefined) {
|
|
80
|
+
request.userName = flags[index + 1];
|
|
81
|
+
index += 1;
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
return { ok: false, error: `unknown argument: ${flags[index]}` };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (request.isSystem !== (request.userName !== null))
|
|
88
|
+
return { ok: false, error: '--system and --user <account> go together (the daemon runs as that account)' };
|
|
89
|
+
return { ok: true, action, request };
|
|
90
|
+
}
|
|
91
|
+
function createServiceDeps() {
|
|
92
|
+
return {
|
|
93
|
+
runner: commandRunner_1.runCommand,
|
|
94
|
+
platform: process.platform,
|
|
95
|
+
uid: os.userInfo().uid,
|
|
96
|
+
checkIsRunnerLink: localLinkStop_1.checkIsRunnerLinkProcess,
|
|
97
|
+
accountName: os.userInfo().username,
|
|
98
|
+
homeDir: os.homedir(),
|
|
99
|
+
nodePath: process.execPath,
|
|
100
|
+
launchDaemonsDir: '/Library/LaunchDaemons',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** @description The kind written by the last install, or `null`. */
|
|
104
|
+
function readServiceKind(paths) {
|
|
105
|
+
try {
|
|
106
|
+
const text = fs.readFileSync(paths.serviceMarker, 'utf8').trim();
|
|
107
|
+
return text === 'user-service' || text === 'system-service' ? text : null;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function getSystemdFiles(homeDir, names) {
|
|
114
|
+
const directory = path.join(homeDir, '.config', 'systemd', 'user');
|
|
115
|
+
return { directory, link: path.join(directory, names.systemdLink), pueued: path.join(directory, names.systemdPueued) };
|
|
116
|
+
}
|
|
117
|
+
function writeMarker(paths, kind) {
|
|
118
|
+
fs.mkdirSync(paths.root, { recursive: true, mode: 0o700 });
|
|
119
|
+
fs.writeFileSync(paths.serviceMarker, `${kind}\n`, { mode: markerMode });
|
|
120
|
+
}
|
|
121
|
+
const stillRunningStates = ['active', 'activating', 'reloading', 'deactivating'];
|
|
122
|
+
/**
|
|
123
|
+
* Everything that must be true BEFORE either service starts, or the services start into a mess:
|
|
124
|
+
* - the Pueue binaries exist (a unit that cannot start would restart in a loop);
|
|
125
|
+
* - no foreground `charness-runner run` is linked (two links for one runner fight for the hub's socket, and its Pueue daemon would
|
|
126
|
+
* fight the managed one for Pueue's);
|
|
127
|
+
* - a Pueue daemon that NO service owns is dealt with explicitly: while it runs jobs it is left alone and the install is refused —
|
|
128
|
+
* Pueue kills the jobs it runs when it stops — and an idle one is shut down so the managed one can take the socket;
|
|
129
|
+
* - Pueue's private configuration exists, and the service record is written, so the first start of the queue has its configuration and
|
|
130
|
+
* the link, seeing the record, waits for the service's queue instead of starting a daemon of its own.
|
|
131
|
+
* Returns the refusal, or `null` when the services may start. `hadService` tells a re-install (the daemon is the service's own then).
|
|
132
|
+
* All of it is the ACCOUNT's own doing, in the account's own tree (the always-on install reaches it through `service system-step`).
|
|
133
|
+
*/
|
|
134
|
+
async function prepareManagedStart(paths, deps, kind) {
|
|
135
|
+
const hadService = readServiceKind(paths) !== null;
|
|
136
|
+
const refuse = (...lines) => ({ refusal: (0, serviceCommon_1.fail)(...lines), hadService });
|
|
137
|
+
if (!fs.existsSync(path.join(paths.binDir, 'pueued')))
|
|
138
|
+
return refuse('Pueue is not installed for this runner yet: run `charness-runner check` (it installs it), then install the service.');
|
|
139
|
+
if (!hadService) {
|
|
140
|
+
const status = (0, runnerConfig_1.readRunnerStatus)(paths);
|
|
141
|
+
if (status !== null && deps.checkIsRunnerLink(status.pid)) {
|
|
142
|
+
return refuse(`A foreground \`charness-runner run\` is linked (pid ${status.pid}). Stop it (Ctrl-C in its terminal) and install the service again — the service takes over the link and the queue.`);
|
|
143
|
+
}
|
|
144
|
+
const queue = await (0, pueueDaemon_1.inspectPueue)(paths, deps.runner);
|
|
145
|
+
if (queue.kind === 'busy')
|
|
146
|
+
return refuse(`The Pueue queue of this runner is running ${queue.activeJobs} job(s), and a service cannot take the queue over without stopping them. Install the service when they have finished (\`pueue --config ${paths.pueueConfig} status\`).`);
|
|
147
|
+
if (queue.kind === 'unreadable')
|
|
148
|
+
return refuse('A Pueue daemon answers but its state cannot be read, so it cannot be told apart from one with running jobs. Stop it by hand and install the service again.');
|
|
149
|
+
if (queue.kind === 'idle' && !(await (0, pueueDaemon_1.shutDownPueue)(paths, deps.runner)))
|
|
150
|
+
return refuse('An idle Pueue daemon is running and did not shut down; stop it by hand and install the service again.');
|
|
151
|
+
}
|
|
152
|
+
(0, pueueDaemon_1.ensurePueueConfig)(paths);
|
|
153
|
+
writeMarker(paths, kind);
|
|
154
|
+
return { refusal: null, hadService };
|
|
155
|
+
}
|
|
156
|
+
async function stopSystemdUnits(names, deps) {
|
|
157
|
+
await deps.runner('systemctl', ['--user', 'disable', '--now', names.systemdLink, names.systemdPueued], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
158
|
+
for (const unit of [names.systemdLink, names.systemdPueued]) {
|
|
159
|
+
const state = await deps.runner('systemctl', ['--user', 'show', '-p', 'ActiveState', '--value', unit], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
160
|
+
if (!state.ok)
|
|
161
|
+
return `systemd cannot be asked whether ${unit} still runs (${state.stderr.trim().split('\n').slice(-1)[0] || 'no answer'})`;
|
|
162
|
+
if (stillRunningStates.includes(state.stdout.trim()))
|
|
163
|
+
return `${unit} is still running (${state.stdout.trim()})`;
|
|
164
|
+
}
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
async function installSystemd(paths, deps) {
|
|
168
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
169
|
+
const files = getSystemdFiles(paths.homeDir, names);
|
|
170
|
+
const { refusal, hadService } = await prepareManagedStart(paths, deps, 'user-service');
|
|
171
|
+
if (refusal !== null)
|
|
172
|
+
return refusal;
|
|
173
|
+
const previous = hadService ? (0, serviceCommon_1.readPreviousDefinitions)([files.link, files.pueued]) : [];
|
|
174
|
+
const rollBack = async (...reason) => {
|
|
175
|
+
if (hadService) {
|
|
176
|
+
// A re-install that fails must not take the working service down with it: its definitions come back, its units are not touched.
|
|
177
|
+
(0, serviceCommon_1.restorePreviousDefinitions)(previous);
|
|
178
|
+
const reloaded = await deps.runner('systemctl', ['--user', 'daemon-reload'], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
179
|
+
return (0, serviceCommon_1.fail)(...reason, reloaded.ok
|
|
180
|
+
? 'The service installed before was left as it was.'
|
|
181
|
+
: 'Its definitions are back as they were, but systemd could not be asked to read them again: run `systemctl --user daemon-reload`.');
|
|
182
|
+
}
|
|
183
|
+
await stopSystemdUnits(names, deps);
|
|
184
|
+
for (const file of [files.link, files.pueued])
|
|
185
|
+
fs.rmSync(file, { force: true });
|
|
186
|
+
await deps.runner('systemctl', ['--user', 'daemon-reload'], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
187
|
+
fs.rmSync(paths.serviceMarker, { force: true });
|
|
188
|
+
return (0, serviceCommon_1.fail)(...reason, 'Nothing was left installed.');
|
|
189
|
+
};
|
|
190
|
+
(0, serviceCommon_1.writeDefinition)(files.pueued, (0, serviceUnits_1.renderSystemdPueuedUnit)(paths));
|
|
191
|
+
(0, serviceCommon_1.writeDefinition)(files.link, (0, serviceUnits_1.renderSystemdLinkUnit)(paths, names));
|
|
192
|
+
const reload = await deps.runner('systemctl', ['--user', 'daemon-reload'], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
193
|
+
if (!reload.ok) {
|
|
194
|
+
return rollBack('systemctl --user cannot reach a user session. Log in with ssh or the console (not `su` / `sudo -u`), or `export XDG_RUNTIME_DIR=/run/user/$(id -u)`, then run this again.');
|
|
195
|
+
}
|
|
196
|
+
const enable = await deps.runner('systemctl', ['--user', 'enable', '--now', names.systemdPueued, names.systemdLink], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
197
|
+
if (!enable.ok)
|
|
198
|
+
return rollBack(`systemctl --user enable failed: ${enable.stderr.trim().split('\n').slice(-1)[0]}`);
|
|
199
|
+
const lines = [`Installed two user services: ${names.systemdLink} (the link) and ${names.systemdPueued} (the queue).`];
|
|
200
|
+
const lingering = await deps.runner('loginctl', ['show-user', deps.accountName, '-p', 'Linger'], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
201
|
+
if ((0, serviceUnits_1.parseLingerState)(lingering.stdout) === 'yes') {
|
|
202
|
+
lines.push('Lingering is on: they run without a login and start at boot.');
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
const enableLinger = await deps.runner('loginctl', ['enable-linger'], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
206
|
+
lines.push(enableLinger.ok ? 'Lingering switched on: they run without a login and start at boot.' : (0, serviceUnits_1.describeLingerRemedy)(deps.accountName));
|
|
207
|
+
}
|
|
208
|
+
return { ok: true, lines };
|
|
209
|
+
}
|
|
210
|
+
async function uninstallSystemd(paths, deps) {
|
|
211
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
212
|
+
const files = getSystemdFiles(paths.homeDir, names);
|
|
213
|
+
const reason = await stopSystemdUnits(names, deps);
|
|
214
|
+
if (reason !== null) {
|
|
215
|
+
return (0, serviceCommon_1.fail)(`The services were not removed: ${reason}.`, 'Their definitions and the record of them stay, so this can be run again; to stop them by hand: ' + `systemctl --user stop ${names.systemdLink} ${names.systemdPueued}`);
|
|
216
|
+
}
|
|
217
|
+
for (const file of [files.link, files.pueued])
|
|
218
|
+
fs.rmSync(file, { force: true });
|
|
219
|
+
await deps.runner('systemctl', ['--user', 'daemon-reload'], { timeoutMs: serviceCommon_1.commandTimeoutMs });
|
|
220
|
+
fs.rmSync(paths.serviceMarker, { force: true });
|
|
221
|
+
return { ok: true, lines: ['Removed the two user services (stopped, and checked to be stopped). Lingering is left as it was.'] };
|
|
222
|
+
}
|
|
223
|
+
const adminLineText = 'paste a fresh admin line from /runners (or `charness runners pair`) in an admin account\'s terminal on this machine';
|
|
224
|
+
async function installLaunchd(deps, paths) {
|
|
225
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
226
|
+
const files = (0, serviceCommon_1.getLaunchdFiles)(false, paths.homeDir, names, deps.launchDaemonsDir);
|
|
227
|
+
const daemonFiles = (0, serviceCommon_1.getLaunchdFiles)(true, paths.homeDir, names, deps.launchDaemonsDir);
|
|
228
|
+
if (fs.existsSync(daemonFiles.link) || fs.existsSync(daemonFiles.pueued)) {
|
|
229
|
+
return (0, serviceCommon_1.fail)('A system service (LaunchDaemon) is installed for this runner: remove it first with `charness-runner service uninstall` (it prints the admin commands).');
|
|
230
|
+
}
|
|
231
|
+
const { refusal, hadService } = await prepareManagedStart(paths, deps, 'user-service');
|
|
232
|
+
if (refusal !== null)
|
|
233
|
+
return refusal;
|
|
234
|
+
const jobs = (0, serviceUnits_1.planLaunchdJobs)(paths, names, deps.accountName, path.dirname(deps.nodePath), null);
|
|
235
|
+
const result = await (0, serviceCommon_1.installLaunchdJobs)({
|
|
236
|
+
runner: deps.runner,
|
|
237
|
+
domain: `gui/${deps.uid}`,
|
|
238
|
+
files,
|
|
239
|
+
names,
|
|
240
|
+
jobs,
|
|
241
|
+
hadService,
|
|
242
|
+
isLogDirMade: true,
|
|
243
|
+
forgetFirstInstall: () => { fs.rmSync(paths.serviceMarker, { force: true }); },
|
|
244
|
+
retryText: 'run `charness-runner service install` again.',
|
|
245
|
+
render: serviceUnits_1.renderLaunchdPlist,
|
|
246
|
+
});
|
|
247
|
+
if (!result.ok)
|
|
248
|
+
return result;
|
|
249
|
+
return { ok: true, lines: [`Installed two LaunchAgents (${names.launchdLink}, ${names.launchdPueued}): they run while ${deps.accountName} is logged in. For always-on (also logged out), an admin can ${adminLineText}.`] };
|
|
250
|
+
}
|
|
251
|
+
/** The admin's commands that remove a runner's always-on service: plain `launchctl` and `rm`, no charness code runs as root. */
|
|
252
|
+
function formatSystemServiceRemoval(paths, daemonsDir) {
|
|
253
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
254
|
+
const files = (0, serviceCommon_1.getLaunchdFiles)(true, paths.homeDir, names, daemonsDir);
|
|
255
|
+
return [
|
|
256
|
+
`sudo launchctl bootout system/${names.launchdLink}`,
|
|
257
|
+
`sudo launchctl bootout system/${names.launchdPueued}`,
|
|
258
|
+
`sudo rm ${files.link} ${files.pueued}`,
|
|
259
|
+
];
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* The runner is an always-on (system) service: only an admin can stop it, and root must not run this program to do it (see the file's
|
|
263
|
+
* head). Once the admin has run the plain commands, running this again FORGETS the service record — and only then, when both daemons are
|
|
264
|
+
* gone from launchd and from `/Library/LaunchDaemons`.
|
|
265
|
+
*/
|
|
266
|
+
async function removeSystemService(paths, deps) {
|
|
267
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
268
|
+
const files = (0, serviceCommon_1.getLaunchdFiles)(true, paths.homeDir, names, deps.launchDaemonsDir);
|
|
269
|
+
const isLoaded = async (label) => (await deps.runner('launchctl', ['print', `system/${label}`], { timeoutMs: serviceCommon_1.commandTimeoutMs })).ok;
|
|
270
|
+
const isPresent = fs.existsSync(files.link) || fs.existsSync(files.pueued) || (await isLoaded(names.launchdLink)) || (await isLoaded(names.launchdPueued));
|
|
271
|
+
if (isPresent) {
|
|
272
|
+
return (0, serviceCommon_1.fail)('This runner runs as a system service (always on), which only an admin can stop. As an admin, run:', ...formatSystemServiceRemoval(paths, deps.launchDaemonsDir).map((line) => ` ${line}`), 'then run `charness-runner service uninstall` again here, as this account: it forgets the service once they are gone.');
|
|
273
|
+
}
|
|
274
|
+
fs.rmSync(paths.serviceMarker, { force: true });
|
|
275
|
+
return { ok: true, lines: ['The always-on service is gone (stopped and removed by an admin): its record here is forgotten.'] };
|
|
276
|
+
}
|
|
277
|
+
async function uninstallLaunchd(deps, paths) {
|
|
278
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
279
|
+
const files = (0, serviceCommon_1.getLaunchdFiles)(false, paths.homeDir, names, deps.launchDaemonsDir);
|
|
280
|
+
const domain = `gui/${deps.uid}`;
|
|
281
|
+
const reason = await (0, serviceCommon_1.stopLaunchdJobs)([names.launchdLink, names.launchdPueued], domain, deps.runner);
|
|
282
|
+
if (reason !== null) {
|
|
283
|
+
return (0, serviceCommon_1.fail)(`The services were not removed: ${reason}.`, 'Their definitions and the record of them stay, so this can be run again.');
|
|
284
|
+
}
|
|
285
|
+
for (const file of [files.link, files.pueued])
|
|
286
|
+
fs.rmSync(file, { force: true });
|
|
287
|
+
fs.rmSync(paths.serviceMarker, { force: true });
|
|
288
|
+
return { ok: true, lines: ['Removed the two LaunchAgents (stopped, and checked to be stopped).'] };
|
|
289
|
+
}
|
|
290
|
+
const systemRefusal = `An always-on service is installed by an admin, through a pairing line: ${adminLineText}. It pairs a machine that is not paired yet, and for one that is, only installs the service. This command does not do it, because it would run this account's own files as root.`;
|
|
291
|
+
/** @description `service install` for `request`. */
|
|
292
|
+
async function installService(request, deps) {
|
|
293
|
+
if (deps.platform !== 'linux' && deps.platform !== 'darwin')
|
|
294
|
+
return (0, serviceCommon_1.fail)(`Services are supported on Linux (systemd) and macOS (launchd), not on ${deps.platform}.`);
|
|
295
|
+
if (request.isSystem)
|
|
296
|
+
return (0, serviceCommon_1.fail)(systemRefusal);
|
|
297
|
+
const paths = (0, runnerHome_1.getRunnerHomePaths)(deps.homeDir);
|
|
298
|
+
if ((0, runnerConfig_1.readRunnerConfig)(paths) === null)
|
|
299
|
+
return (0, serviceCommon_1.fail)('This account is not paired yet: run the line from /runners on this machine first, then install the service.');
|
|
300
|
+
if (readServiceKind(paths) === 'system-service')
|
|
301
|
+
return (0, serviceCommon_1.fail)('This runner runs as a system service already; `charness-runner service uninstall` shows how an admin removes it.');
|
|
302
|
+
return deps.platform === 'linux' ? installSystemd(paths, deps) : installLaunchd(deps, paths);
|
|
303
|
+
}
|
|
304
|
+
/** @description `service uninstall` for `request`. */
|
|
305
|
+
async function uninstallService(request, deps) {
|
|
306
|
+
if (deps.platform !== 'linux' && deps.platform !== 'darwin')
|
|
307
|
+
return (0, serviceCommon_1.fail)(`Services are supported on Linux (systemd) and macOS (launchd), not on ${deps.platform}.`);
|
|
308
|
+
if (request.isSystem)
|
|
309
|
+
return (0, serviceCommon_1.fail)('An always-on service is removed by an admin with plain `launchctl` commands (no charness program runs as root): `charness-runner service uninstall` as the account prints them.');
|
|
310
|
+
const paths = (0, runnerHome_1.getRunnerHomePaths)(deps.homeDir);
|
|
311
|
+
if (readServiceKind(paths) === 'system-service')
|
|
312
|
+
return removeSystemService(paths, deps);
|
|
313
|
+
return deps.platform === 'linux' ? uninstallSystemd(paths, deps) : uninstallLaunchd(deps, paths);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* @description `service system-step prepare|abandon` — the ACCOUNT's side of the always-on install, run by the admin step
|
|
317
|
+
* (`adminService.ts`) through `sudo -u <account>`, never by hand. `prepare` does what must be true before the daemons start (the same as a
|
|
318
|
+
* user service's install, `prepareManagedStart`, and the account must be paired and have no LaunchAgents) and answers in one JSON line;
|
|
319
|
+
* `abandon` forgets the record `prepare` wrote when the daemons could not be loaded and nothing was left installed.
|
|
320
|
+
*/
|
|
321
|
+
async function runSystemStep(step, deps) {
|
|
322
|
+
if (deps.platform !== 'darwin')
|
|
323
|
+
return { ok: false, lines: ['The always-on service is for macOS (a LaunchDaemon); a Linux account installs its own user service.'] };
|
|
324
|
+
if (deps.uid === 0)
|
|
325
|
+
return { ok: false, lines: ['This step is the account\'s own: it must not run as root.'] };
|
|
326
|
+
const paths = (0, runnerHome_1.getRunnerHomePaths)(deps.homeDir);
|
|
327
|
+
if (step === 'abandon') {
|
|
328
|
+
if (readServiceKind(paths) === 'system-service')
|
|
329
|
+
fs.rmSync(paths.serviceMarker, { force: true });
|
|
330
|
+
return { ok: true, hadService: false };
|
|
331
|
+
}
|
|
332
|
+
if (step !== 'prepare')
|
|
333
|
+
return { ok: false, lines: [`unknown step: ${step}`] };
|
|
334
|
+
if ((0, runnerConfig_1.readRunnerConfig)(paths) === null)
|
|
335
|
+
return { ok: false, lines: ['This account is not paired yet: run the line from /runners on this machine first, then install the service.'] };
|
|
336
|
+
const names = (0, serviceUnits_1.getServiceNames)(paths.root);
|
|
337
|
+
const agentFiles = (0, serviceCommon_1.getLaunchdFiles)(false, paths.homeDir, names, deps.launchDaemonsDir);
|
|
338
|
+
if (fs.existsSync(agentFiles.link) || fs.existsSync(agentFiles.pueued)) {
|
|
339
|
+
return { ok: false, lines: ['A user service (LaunchAgent) is installed for this runner: remove it first with `charness-runner service uninstall`.'] };
|
|
340
|
+
}
|
|
341
|
+
const { refusal, hadService } = await prepareManagedStart(paths, deps, 'system-service');
|
|
342
|
+
return refusal === null ? { ok: true, hadService } : { ok: false, lines: refusal.lines };
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=serviceManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceManager.js","sourceRoot":"","sources":["../../src/runnerUtility/serviceManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { RunnerHomePaths } from './runnerHome';
|
|
2
|
+
export interface ServiceNames {
|
|
3
|
+
hash: string;
|
|
4
|
+
systemdLink: string;
|
|
5
|
+
systemdPueued: string;
|
|
6
|
+
launchdLink: string;
|
|
7
|
+
launchdPueued: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function getServiceNames(stateRoot: string): ServiceNames;
|
|
10
|
+
export declare function renderSystemdLinkUnit(paths: RunnerHomePaths, names: ServiceNames): string;
|
|
11
|
+
export declare function renderSystemdPueuedUnit(paths: RunnerHomePaths): string;
|
|
12
|
+
export interface LaunchdJobSpec {
|
|
13
|
+
label: string;
|
|
14
|
+
programArguments: readonly string[];
|
|
15
|
+
/** Set for a LaunchDaemon: the account the job runs as (and the job then logs through its own shell, see {@link getLaunchdProgramArguments}). */
|
|
16
|
+
userName: string | null;
|
|
17
|
+
homeDir: string;
|
|
18
|
+
accountName: string;
|
|
19
|
+
nodeDir: string;
|
|
20
|
+
logPath: string;
|
|
21
|
+
niceness: number | null;
|
|
22
|
+
}
|
|
23
|
+
/** The program and arguments launchd starts: the job's own for a LaunchAgent, the account's shell around them for a LaunchDaemon. */
|
|
24
|
+
export declare function getLaunchdProgramArguments(spec: LaunchdJobSpec): readonly string[];
|
|
25
|
+
/** @description The property list of one launchd job. */
|
|
26
|
+
export declare function renderLaunchdPlist(spec: LaunchdJobSpec): string;
|
|
27
|
+
export interface LaunchdJobs {
|
|
28
|
+
link: LaunchdJobSpec;
|
|
29
|
+
pueued: LaunchdJobSpec;
|
|
30
|
+
}
|
|
31
|
+
/** @description The two jobs of a runner; `userName` is set for LaunchDaemons. */
|
|
32
|
+
export declare function planLaunchdJobs(paths: RunnerHomePaths, names: ServiceNames, accountName: string, nodeDir: string, userName: string | null): LaunchdJobs;
|
|
33
|
+
export type LingerState = 'yes' | 'no' | 'unknown';
|
|
34
|
+
/** @description `Linger=yes|no` out of `loginctl show-user <user> -p Linger`. */
|
|
35
|
+
export declare function parseLingerState(output: string): LingerState;
|
|
36
|
+
/** @description What to tell the operator when lingering could not be switched on by the account itself (polkit wants an admin there). */
|
|
37
|
+
export declare function describeLingerRemedy(accountName: string): string;
|
|
38
|
+
//# sourceMappingURL=serviceUnits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceUnits.d.ts","sourceRoot":"","sources":["../../src/runnerUtility/serviceUnits.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAqBpD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAS/D;AAOD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAmBzF;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAiBtE;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,iJAAiJ;IACjJ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAqBD,qIAAqI;AACrI,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,MAAM,EAAE,CAElF;AAED,yDAAyD;AACzD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAkC/D;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,cAAc,CAAC;CACxB;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,CAMvJ;AAED,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,IAAI,GAAG,SAAS,CAAC;AAEnD,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAG5D;AAED,0IAA0I;AAC1I,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE"}
|
|
@@ -0,0 +1,189 @@
|
|
|
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.getServiceNames = getServiceNames;
|
|
37
|
+
exports.renderSystemdLinkUnit = renderSystemdLinkUnit;
|
|
38
|
+
exports.renderSystemdPueuedUnit = renderSystemdPueuedUnit;
|
|
39
|
+
exports.getLaunchdProgramArguments = getLaunchdProgramArguments;
|
|
40
|
+
exports.renderLaunchdPlist = renderLaunchdPlist;
|
|
41
|
+
exports.planLaunchdJobs = planLaunchdJobs;
|
|
42
|
+
exports.parseLingerState = parseLingerState;
|
|
43
|
+
exports.describeLingerRemedy = describeLingerRemedy;
|
|
44
|
+
const crypto_1 = require("crypto");
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
/**
|
|
47
|
+
* @description The text of the two services a runner needs, pure: the LINK (`charness-runner run` through the launcher) and PUEUED (the
|
|
48
|
+
* queue — a service of its own, so a link restart or an update never touches a queued or running job). Names carry a short hash of the state
|
|
49
|
+
* folder, so a second runner on one machine (a stand-in, another account) never clashes with this one.
|
|
50
|
+
*
|
|
51
|
+
* Linux two systemd USER units (no root); `KillMode=process` on the link: stopping it ends the launcher and nothing else, and the
|
|
52
|
+
* commands it started (a lease watcher among them) see the closed pipe and finish by themselves — they are not killed with it.
|
|
53
|
+
* macOS two launchd jobs: LaunchAgents (run while the account is logged in, switched away included), or — installed by the admin pairing line
|
|
54
|
+
* (`adminService.ts`) — LaunchDaemons with `UserName=<account>` (always, also logged out; they run as that account, with no extra rights). `AbandonProcessGroup`
|
|
55
|
+
* keeps launchd from killing what the link started when the link ends. Pueue runs at `nice`, never `taskpolicy -b` (on Apple
|
|
56
|
+
* Silicon that pins jobs to the efficiency cores).
|
|
57
|
+
*/
|
|
58
|
+
const hashLength = 8;
|
|
59
|
+
const restartSeconds = 5;
|
|
60
|
+
const throttleSeconds = 10;
|
|
61
|
+
const pueuedNiceness = 10;
|
|
62
|
+
const systemPathDirs = ['/opt/homebrew/bin', '/opt/homebrew/sbin', '/usr/local/bin', '/usr/local/sbin', '/usr/bin', '/bin', '/usr/sbin', '/sbin'];
|
|
63
|
+
function getServiceNames(stateRoot) {
|
|
64
|
+
const hash = (0, crypto_1.createHash)('sha256').update(stateRoot).digest('hex').slice(0, hashLength);
|
|
65
|
+
return {
|
|
66
|
+
hash,
|
|
67
|
+
systemdLink: `charness-runner-${hash}.service`,
|
|
68
|
+
systemdPueued: `charness-runner-pueued-${hash}.service`,
|
|
69
|
+
launchdLink: `com.charness.runner.${hash}`,
|
|
70
|
+
launchdPueued: `com.charness.runner.pueued.${hash}`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** A word of an `ExecStart=` line: double-quoted, with the characters systemd would read specially escaped. */
|
|
74
|
+
function quoteSystemdWord(word) {
|
|
75
|
+
return `"${word.replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/%/g, '%%')}"`;
|
|
76
|
+
}
|
|
77
|
+
function renderSystemdLinkUnit(paths, names) {
|
|
78
|
+
return [
|
|
79
|
+
'[Unit]',
|
|
80
|
+
`Description=charness runner link (${paths.root.replace(/%/g, '%%')})`,
|
|
81
|
+
`Wants=network-online.target ${names.systemdPueued}`,
|
|
82
|
+
`After=network-online.target ${names.systemdPueued}`,
|
|
83
|
+
'',
|
|
84
|
+
'[Service]',
|
|
85
|
+
'Type=simple',
|
|
86
|
+
`ExecStart=${quoteSystemdWord(paths.launcher)} run`,
|
|
87
|
+
'Restart=always',
|
|
88
|
+
`RestartSec=${restartSeconds}`,
|
|
89
|
+
'KillMode=process',
|
|
90
|
+
'SyslogIdentifier=charness-runner',
|
|
91
|
+
'',
|
|
92
|
+
'[Install]',
|
|
93
|
+
'WantedBy=default.target',
|
|
94
|
+
'',
|
|
95
|
+
].join('\n');
|
|
96
|
+
}
|
|
97
|
+
function renderSystemdPueuedUnit(paths) {
|
|
98
|
+
return [
|
|
99
|
+
'[Unit]',
|
|
100
|
+
`Description=charness runner queue, Pueue (${paths.root.replace(/%/g, '%%')})`,
|
|
101
|
+
'',
|
|
102
|
+
'[Service]',
|
|
103
|
+
'Type=simple',
|
|
104
|
+
`ExecStart=${quoteSystemdWord(path.join(paths.binDir, 'pueued'))} --config ${quoteSystemdWord(paths.pueueConfig)}`,
|
|
105
|
+
'Restart=always',
|
|
106
|
+
`RestartSec=${restartSeconds}`,
|
|
107
|
+
`Nice=${pueuedNiceness}`,
|
|
108
|
+
'SyslogIdentifier=charness-runner-pueued',
|
|
109
|
+
'',
|
|
110
|
+
'[Install]',
|
|
111
|
+
'WantedBy=default.target',
|
|
112
|
+
'',
|
|
113
|
+
].join('\n');
|
|
114
|
+
}
|
|
115
|
+
function escapeXml(text) {
|
|
116
|
+
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* What launchd opens or enters ITSELF, as root, before it hands a LaunchDaemon to its `UserName` (whether it does so before or after the
|
|
120
|
+
* switch is not documented): none of it may be a path the account can swap for a link. So a daemon names `/dev/null` for its output, no
|
|
121
|
+
* `WorkingDirectory`, and runs its program through `sh`, which — already the account — enters the home, opens the log by `>>` and execs
|
|
122
|
+
* the program. A LaunchAgent is launchd's job in the account's own domain and needs none of this.
|
|
123
|
+
*/
|
|
124
|
+
const daemonOutputPath = '/dev/null';
|
|
125
|
+
const daemonShell = '/bin/sh';
|
|
126
|
+
/**
|
|
127
|
+
* `$0` is the log, `$1` the home, the rest the program: the account's shell makes the log's folder (it cannot be left to anyone else: a
|
|
128
|
+
* failure to open the log goes to `/dev/null`, and a job that restarts every 10 s without a word is the worst way to fail), enters the
|
|
129
|
+
* home, then execs the program with its output in the log.
|
|
130
|
+
*/
|
|
131
|
+
const daemonShellScript = 'mkdir -p "${0%/*}" && cd "$1" && shift && exec "$@" >> "$0" 2>&1';
|
|
132
|
+
/** The program and arguments launchd starts: the job's own for a LaunchAgent, the account's shell around them for a LaunchDaemon. */
|
|
133
|
+
function getLaunchdProgramArguments(spec) {
|
|
134
|
+
return spec.userName === null ? spec.programArguments : [daemonShell, '-c', daemonShellScript, spec.logPath, spec.homeDir, ...spec.programArguments];
|
|
135
|
+
}
|
|
136
|
+
/** @description The property list of one launchd job. */
|
|
137
|
+
function renderLaunchdPlist(spec) {
|
|
138
|
+
const isDaemon = spec.userName !== null;
|
|
139
|
+
const pathValue = [...new Set([path.join(spec.homeDir, '.charness-runner', 'bin'), spec.nodeDir, ...systemPathDirs])].join(':');
|
|
140
|
+
const entry = (key, value) => ` <key>${key}</key><string>${escapeXml(value)}</string>`;
|
|
141
|
+
return [
|
|
142
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
143
|
+
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">',
|
|
144
|
+
'<plist version="1.0">',
|
|
145
|
+
'<dict>',
|
|
146
|
+
` <key>Label</key><string>${escapeXml(spec.label)}</string>`,
|
|
147
|
+
' <key>ProgramArguments</key>',
|
|
148
|
+
' <array>',
|
|
149
|
+
...getLaunchdProgramArguments(spec).map((argument) => ` <string>${escapeXml(argument)}</string>`),
|
|
150
|
+
' </array>',
|
|
151
|
+
...(spec.userName === null ? [] : [` <key>UserName</key><string>${escapeXml(spec.userName)}</string>`]),
|
|
152
|
+
' <key>RunAtLoad</key><true/>',
|
|
153
|
+
' <key>KeepAlive</key><true/>',
|
|
154
|
+
` <key>ThrottleInterval</key><integer>${throttleSeconds}</integer>`,
|
|
155
|
+
' <key>AbandonProcessGroup</key><true/>',
|
|
156
|
+
...(spec.niceness === null ? [] : [` <key>Nice</key><integer>${spec.niceness}</integer>`]),
|
|
157
|
+
...(isDaemon ? [] : [` <key>WorkingDirectory</key><string>${escapeXml(spec.homeDir)}</string>`]),
|
|
158
|
+
' <key>EnvironmentVariables</key>',
|
|
159
|
+
' <dict>',
|
|
160
|
+
entry('HOME', spec.homeDir),
|
|
161
|
+
entry('USER', spec.accountName),
|
|
162
|
+
entry('LOGNAME', spec.accountName),
|
|
163
|
+
entry('PATH', pathValue),
|
|
164
|
+
' </dict>',
|
|
165
|
+
` <key>StandardOutPath</key><string>${escapeXml(isDaemon ? daemonOutputPath : spec.logPath)}</string>`,
|
|
166
|
+
` <key>StandardErrorPath</key><string>${escapeXml(isDaemon ? daemonOutputPath : spec.logPath)}</string>`,
|
|
167
|
+
'</dict>',
|
|
168
|
+
'</plist>',
|
|
169
|
+
'',
|
|
170
|
+
].join('\n');
|
|
171
|
+
}
|
|
172
|
+
/** @description The two jobs of a runner; `userName` is set for LaunchDaemons. */
|
|
173
|
+
function planLaunchdJobs(paths, names, accountName, nodeDir, userName) {
|
|
174
|
+
const common = { userName, homeDir: paths.homeDir, accountName, nodeDir };
|
|
175
|
+
return {
|
|
176
|
+
link: { ...common, label: names.launchdLink, programArguments: [paths.launcher, 'run'], logPath: path.join(paths.logsDir, 'link.log'), niceness: null },
|
|
177
|
+
pueued: { ...common, label: names.launchdPueued, programArguments: [path.join(paths.binDir, 'pueued'), '--config', paths.pueueConfig], logPath: path.join(paths.logsDir, 'pueued.log'), niceness: pueuedNiceness },
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/** @description `Linger=yes|no` out of `loginctl show-user <user> -p Linger`. */
|
|
181
|
+
function parseLingerState(output) {
|
|
182
|
+
const match = /Linger=(yes|no)/.exec(output);
|
|
183
|
+
return match === null ? 'unknown' : match[1] === 'yes' ? 'yes' : 'no';
|
|
184
|
+
}
|
|
185
|
+
/** @description What to tell the operator when lingering could not be switched on by the account itself (polkit wants an admin there). */
|
|
186
|
+
function describeLingerRemedy(accountName) {
|
|
187
|
+
return `Lingering is off, so the runner stops when ${accountName} logs out. Turn it on once, as an admin: sudo loginctl enable-linger ${accountName}`;
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=serviceUnits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceUnits.js","sourceRoot":"","sources":["../../src/runnerUtility/serviceUnits.ts"],"names":[],"mappings":"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"}
|