@jmfederico/pi-web 1.202607.0 → 1.202607.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -9
- package/dist/cli.js +305 -322
- package/dist/cli.js.map +1 -1
- package/dist/client/assets/{CodeViewer-tXF3UTsY.js → CodeViewer-B4M13447.js} +1 -1
- package/dist/client/assets/{TerminalPanel-D_ihiWAt.js → TerminalPanel-Bmvj-Ecn.js} +1 -1
- package/dist/client/assets/{UnifiedDiffViewer-BziirXBJ.js → UnifiedDiffViewer-C0hygwRo.js} +1 -1
- package/dist/client/assets/index-TvPsRyS1.js +3545 -0
- package/dist/client/index.html +6 -6
- package/dist/client/manifest.webmanifest +4 -4
- package/dist/config.js +157 -2
- package/dist/config.js.map +1 -1
- package/dist/nativeServices/serviceDoctor.js +480 -0
- package/dist/nativeServices/serviceDoctor.js.map +1 -0
- package/dist/nativeServices/serviceInstall.js +35 -0
- package/dist/nativeServices/serviceInstall.js.map +1 -0
- package/dist/nativeServices/servicePlan.js +358 -0
- package/dist/nativeServices/servicePlan.js.map +1 -0
- package/dist/nativeServices/serviceProbe.js +447 -0
- package/dist/nativeServices/serviceProbe.js.map +1 -0
- package/dist/nativeServices/serviceRendering.js +122 -0
- package/dist/nativeServices/serviceRendering.js.map +1 -0
- package/dist/pi-web-plugins/updates/pi-web-plugin.js +12 -0
- package/dist/plugin-api.d.ts +2 -0
- package/dist/server/activeAgentProfileProvider.js +25 -0
- package/dist/server/activeAgentProfileProvider.js.map +1 -0
- package/dist/server/app.js +57 -16
- package/dist/server/app.js.map +1 -1
- package/dist/server/configRoutes.js +43 -9
- package/dist/server/configRoutes.js.map +1 -1
- package/dist/server/diagnostics/nodePtyNativeModule.js +36 -0
- package/dist/server/diagnostics/nodePtyNativeModule.js.map +1 -0
- package/dist/server/git/gitService.js +176 -5
- package/dist/server/git/gitService.js.map +1 -1
- package/dist/server/machines/machinePluginProxyRoutes.js +7 -4
- package/dist/server/machines/machinePluginProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineProxyRoutes.js +16 -4
- package/dist/server/machines/machineProxyRoutes.js.map +1 -1
- package/dist/server/machines/machineRoutes.js +1 -1
- package/dist/server/machines/machineRoutes.js.map +1 -1
- package/dist/server/machines/machineService.js +2 -2
- package/dist/server/machines/machineService.js.map +1 -1
- package/dist/server/piPackageRoutes.js +7 -3
- package/dist/server/piPackageRoutes.js.map +1 -1
- package/dist/server/piPackageService.js +34 -2
- package/dist/server/piPackageService.js.map +1 -1
- package/dist/server/piWebPluginService.js +48 -12
- package/dist/server/piWebPluginService.js.map +1 -1
- package/dist/server/piWebReleaseLookupCache.js +37 -0
- package/dist/server/piWebReleaseLookupCache.js.map +1 -0
- package/dist/server/piWebStatus.js +38 -39
- package/dist/server/piWebStatus.js.map +1 -1
- package/dist/server/piWebStatusCache.js +19 -6
- package/dist/server/piWebStatusCache.js.map +1 -1
- package/dist/server/realtime/sessionEventHub.js +37 -7
- package/dist/server/realtime/sessionEventHub.js.map +1 -1
- package/dist/server/sessiond/sessionDaemonStartup.js +49 -0
- package/dist/server/sessiond/sessionDaemonStartup.js.map +1 -0
- package/dist/server/sessiond.js +128 -62
- package/dist/server/sessiond.js.map +1 -1
- package/dist/server/sessions/authProviderOptions.js +30 -32
- package/dist/server/sessions/authProviderOptions.js.map +1 -1
- package/dist/server/sessions/authRoutes.js +14 -4
- package/dist/server/sessions/authRoutes.js.map +1 -1
- package/dist/server/sessions/authService.js +140 -29
- package/dist/server/sessions/authService.js.map +1 -1
- package/dist/server/sessions/globalProviderPolicy.js +98 -0
- package/dist/server/sessions/globalProviderPolicy.js.map +1 -0
- package/dist/server/sessions/modelCatalogRefresher.js +184 -0
- package/dist/server/sessions/modelCatalogRefresher.js.map +1 -0
- package/dist/server/sessions/oauthLoginFlowService.js +176 -53
- package/dist/server/sessions/oauthLoginFlowService.js.map +1 -1
- package/dist/server/sessions/piSessionManagerGateway.js +22 -21
- package/dist/server/sessions/piSessionManagerGateway.js.map +1 -1
- package/dist/server/sessions/piSessionService.js +936 -111
- package/dist/server/sessions/piSessionService.js.map +1 -1
- package/dist/server/sessions/plainTextTheme.js +112 -0
- package/dist/server/sessions/plainTextTheme.js.map +1 -0
- package/dist/server/sessions/sessionArchiveMigration.js +590 -0
- package/dist/server/sessions/sessionArchiveMigration.js.map +1 -0
- package/dist/server/sessions/sessionArchiveStore.js +7 -4
- package/dist/server/sessions/sessionArchiveStore.js.map +1 -1
- package/dist/server/sessions/sessionCommandService.js +68 -9
- package/dist/server/sessions/sessionCommandService.js.map +1 -1
- package/dist/server/sessions/sessionNotificationStore.js +484 -0
- package/dist/server/sessions/sessionNotificationStore.js.map +1 -0
- package/dist/server/sessions/sessionRoutes.js +202 -2
- package/dist/server/sessions/sessionRoutes.js.map +1 -1
- package/dist/server/sessions/sessionService.js +2 -0
- package/dist/server/sessions/sessionService.js.map +1 -0
- package/dist/server/sessions/sessionTreeProjection.js +250 -0
- package/dist/server/sessions/sessionTreeProjection.js.map +1 -0
- package/dist/server/sessions/sessionUnreadStore.js +520 -0
- package/dist/server/sessions/sessionUnreadStore.js.map +1 -0
- package/dist/server/sessions/spawnSessionTool.js +2 -2
- package/dist/server/sessions/spawnSessionTool.js.map +1 -1
- package/dist/server/sessions/spawnSubsessionTool.js +69 -31
- package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
- package/dist/server/terminals/terminalService.js +10 -4
- package/dist/server/terminals/terminalService.js.map +1 -1
- package/dist/sessiond/activeAgentProfile.js +31 -0
- package/dist/sessiond/activeAgentProfile.js.map +1 -0
- package/dist/sessiond/sessionDaemonClient.js +38 -0
- package/dist/sessiond/sessionDaemonClient.js.map +1 -1
- package/dist/shared/activeAgentProfile.js +76 -0
- package/dist/shared/activeAgentProfile.js.map +1 -0
- package/dist/shared/apiTypes.d.ts +256 -4
- package/dist/shared/apiTypes.js +12 -0
- package/dist/shared/apiTypes.js.map +1 -1
- package/dist/shared/capabilities.js +11 -0
- package/dist/shared/capabilities.js.map +1 -1
- package/dist/shared/federatedRoutes.js +12 -0
- package/dist/shared/federatedRoutes.js.map +1 -1
- package/dist/shared/piWebStatusParsing.js +6 -0
- package/dist/shared/piWebStatusParsing.js.map +1 -1
- package/docs/config.md +85 -12
- package/docs/plugins.md +29 -11
- package/install.sh +1 -1
- package/package.json +9 -8
- package/dist/client/assets/index-Brfk1lwl.js +0 -2950
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir, userInfo } from "node:os";
|
|
4
|
+
import { posix as posixPath } from "node:path";
|
|
5
|
+
import { performance } from "node:perf_hooks";
|
|
6
|
+
import { randomUUID } from "node:crypto";
|
|
7
|
+
const defaultCommandTimeoutMs = 15_000;
|
|
8
|
+
const defaultProbeTimeoutMs = 15_000;
|
|
9
|
+
const defaultPollIntervalMs = 50;
|
|
10
|
+
const maxCapturedCommandOutputBytes = 1024 * 1024;
|
|
11
|
+
const maxLaunchdProbeFileBytes = 1024 * 1024;
|
|
12
|
+
export class SystemdNativeServiceProbe {
|
|
13
|
+
constructor(dependencies) {
|
|
14
|
+
this.dependencies = dependencies;
|
|
15
|
+
}
|
|
16
|
+
async run(request) {
|
|
17
|
+
if (request.backend.kind !== "systemd") {
|
|
18
|
+
return infrastructureFailure("manager", `Systemd probe cannot validate the ${request.backend.kind} backend.`);
|
|
19
|
+
}
|
|
20
|
+
const uniqueId = safeUniqueId(this.dependencies.createUniqueId());
|
|
21
|
+
const unitName = `pi-web-authoritative-probe-${uniqueId}.service`;
|
|
22
|
+
const outputPrefix = `PI_WEB_PROBE_${uniqueId}`;
|
|
23
|
+
const command = prerequisiteProbeCommand(request.shell.name, request.prerequisites, outputPrefix);
|
|
24
|
+
const args = systemdRunArguments(request, unitName, command);
|
|
25
|
+
const result = await this.dependencies.commandRunner.run("systemd-run", args, this.dependencies.commandTimeoutMs);
|
|
26
|
+
if (result.kind === "timeout" || result.kind === "output-limit") {
|
|
27
|
+
const cleanupFailure = await this.cleanupTimedOutUnit(unitName);
|
|
28
|
+
if (cleanupFailure !== null)
|
|
29
|
+
return cleanupFailure;
|
|
30
|
+
return result.kind === "timeout"
|
|
31
|
+
? infrastructureFailure("timeout", `Timed out waiting for transient systemd unit ${unitName}.`)
|
|
32
|
+
: infrastructureFailure("manager", `Transient systemd probe ${unitName} exceeded the output limit.`);
|
|
33
|
+
}
|
|
34
|
+
if (result.kind === "spawn-failure") {
|
|
35
|
+
return infrastructureFailure("manager", `Could not start systemd-run: ${result.message}`);
|
|
36
|
+
}
|
|
37
|
+
if (result.status !== 0) {
|
|
38
|
+
return infrastructureFailure("manager", `Transient systemd probe ${unitName} failed: ${firstOutput(result.stderr, result.stdout, `exit status ${String(result.status)}`)}`);
|
|
39
|
+
}
|
|
40
|
+
return parseProbeOutput(result.stdout, request.prerequisites, outputPrefix);
|
|
41
|
+
}
|
|
42
|
+
async cleanupTimedOutUnit(unitName) {
|
|
43
|
+
const stop = await this.dependencies.commandRunner.run("systemctl", ["--user", "stop", unitName], this.dependencies.commandTimeoutMs);
|
|
44
|
+
const inspected = await this.dependencies.commandRunner.run("systemctl", ["--user", "show", unitName, "--property=LoadState", "--value"], this.dependencies.commandTimeoutMs);
|
|
45
|
+
if (inspected.kind === "completed" && inspected.status === 0 && inspected.stdout.trim() === "not-found") {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const details = [
|
|
49
|
+
`stop: ${commandFailureDetail(stop)}`,
|
|
50
|
+
`load state: ${commandFailureDetail(inspected)}`,
|
|
51
|
+
].join("; ");
|
|
52
|
+
return infrastructureFailure("cleanup", `Could not confirm cleanup of timed-out transient systemd unit ${unitName}: ${details}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export class LaunchdNativeServiceProbe {
|
|
56
|
+
constructor(dependencies) {
|
|
57
|
+
this.dependencies = dependencies;
|
|
58
|
+
}
|
|
59
|
+
async run(request) {
|
|
60
|
+
if (request.backend.kind !== "launchd") {
|
|
61
|
+
return infrastructureFailure("manager", `Launchd probe cannot validate the ${request.backend.kind} backend.`);
|
|
62
|
+
}
|
|
63
|
+
const uniqueId = safeUniqueId(this.dependencies.createUniqueId());
|
|
64
|
+
const label = `com.pi-web.authoritative-probe.${String(this.dependencies.uid)}.${uniqueId}`;
|
|
65
|
+
const domain = `gui/${String(this.dependencies.uid)}`;
|
|
66
|
+
const target = `${domain}/${label}`;
|
|
67
|
+
const outputPrefix = `PI_WEB_PROBE_${uniqueId}`;
|
|
68
|
+
let directory = null;
|
|
69
|
+
let bootstrapState = "not-loaded";
|
|
70
|
+
let result;
|
|
71
|
+
try {
|
|
72
|
+
directory = await this.dependencies.fileSystem.createTemporaryDirectory(posixPath.join(tmpdir(), "pi-web-launchd-probe-"));
|
|
73
|
+
const plistPath = posixPath.join(directory, "probe.plist");
|
|
74
|
+
const stdoutPath = posixPath.join(directory, "stdout.log");
|
|
75
|
+
const stderrPath = posixPath.join(directory, "stderr.log");
|
|
76
|
+
const pendingResultPath = posixPath.join(directory, "result.pending");
|
|
77
|
+
const resultPath = posixPath.join(directory, "result.log");
|
|
78
|
+
const command = prerequisiteProbeCommand(request.shell.name, request.prerequisites, outputPrefix, { pendingPath: pendingResultPath, completedPath: resultPath });
|
|
79
|
+
await this.dependencies.fileSystem.writeFile(plistPath, launchdProbePlist(request, label, command, stdoutPath, stderrPath), 0o600);
|
|
80
|
+
const bootstrap = await this.dependencies.commandRunner.run("launchctl", ["bootstrap", domain, plistPath], this.dependencies.commandTimeoutMs);
|
|
81
|
+
if (bootstrap.kind !== "completed" || bootstrap.status !== 0) {
|
|
82
|
+
bootstrapState = bootstrap.kind === "spawn-failure" ? "not-loaded" : "uncertain";
|
|
83
|
+
result = commandInfrastructureFailure("bootstrap launchd probe", bootstrap);
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
bootstrapState = "loaded";
|
|
87
|
+
result = await this.waitForResult(target, resultPath, request.prerequisites, outputPrefix);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
result = infrastructureFailure("manager", `Could not prepare launchd probe: ${errorMessage(error)}`);
|
|
92
|
+
}
|
|
93
|
+
const cleanupFailure = await this.cleanup(target, directory, bootstrapState);
|
|
94
|
+
return cleanupFailure ?? result;
|
|
95
|
+
}
|
|
96
|
+
async waitForResult(target, resultPath, prerequisites, outputPrefix) {
|
|
97
|
+
const deadline = this.dependencies.now() + this.dependencies.probeTimeoutMs;
|
|
98
|
+
while (this.dependencies.now() < deadline) {
|
|
99
|
+
const remainingMs = Math.max(0, deadline - this.dependencies.now());
|
|
100
|
+
const boundedRead = await readOptionalFileBounded(this.dependencies.fileSystem, resultPath, remainingMs);
|
|
101
|
+
if (boundedRead.kind === "deadline")
|
|
102
|
+
break;
|
|
103
|
+
if (boundedRead.kind === "read-failure") {
|
|
104
|
+
return infrastructureFailure("manager", `Could not read launchd probe result: ${errorMessage(boundedRead.error)}`);
|
|
105
|
+
}
|
|
106
|
+
if (boundedRead.output !== null)
|
|
107
|
+
return parseProbeOutput(boundedRead.output, prerequisites, outputPrefix);
|
|
108
|
+
const pollDelayMs = Math.min(this.dependencies.pollIntervalMs, Math.max(0, deadline - this.dependencies.now()));
|
|
109
|
+
await this.dependencies.sleep(pollDelayMs);
|
|
110
|
+
}
|
|
111
|
+
return infrastructureFailure("timeout", `Timed out waiting for launchd probe ${target}.`);
|
|
112
|
+
}
|
|
113
|
+
async cleanup(target, directory, bootstrapState) {
|
|
114
|
+
const failures = [];
|
|
115
|
+
const shouldBootout = bootstrapState !== "not-loaded";
|
|
116
|
+
if (shouldBootout) {
|
|
117
|
+
// A failed or timed-out bootstrap may still have loaded the unique label.
|
|
118
|
+
// Bootout is the only race-free cleanup; an explicit not-loaded response
|
|
119
|
+
// is success when bootstrap completion was uncertain.
|
|
120
|
+
const absenceIsSuccess = bootstrapState === "uncertain";
|
|
121
|
+
const bootout = await this.dependencies.commandRunner.run("launchctl", ["bootout", target], this.dependencies.commandTimeoutMs);
|
|
122
|
+
if ((bootout.kind !== "completed" || bootout.status !== 0)
|
|
123
|
+
&& !(absenceIsSuccess && launchdTargetNotLoaded(bootout))) {
|
|
124
|
+
failures.push(`bootout failed: ${commandFailureDetail(bootout)}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (directory !== null) {
|
|
128
|
+
try {
|
|
129
|
+
await this.dependencies.fileSystem.removeDirectory(directory);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
failures.push(`temporary-file removal failed: ${errorMessage(error)}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return failures.length === 0
|
|
136
|
+
? null
|
|
137
|
+
: infrastructureFailure("cleanup", `Launchd probe cleanup failed for ${target}: ${failures.join("; ")}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export function createNativeServiceAuthoritativeProbe() {
|
|
141
|
+
const commandRunner = new SpawnProbeCommandRunner();
|
|
142
|
+
const common = {
|
|
143
|
+
commandRunner,
|
|
144
|
+
createUniqueId: randomUUID,
|
|
145
|
+
commandTimeoutMs: defaultCommandTimeoutMs,
|
|
146
|
+
};
|
|
147
|
+
const systemd = new SystemdNativeServiceProbe(common);
|
|
148
|
+
const launchd = new LaunchdNativeServiceProbe({
|
|
149
|
+
...common,
|
|
150
|
+
fileSystem: nodeLaunchdProbeFileSystem,
|
|
151
|
+
uid: userInfo().uid,
|
|
152
|
+
now: performance.now.bind(performance),
|
|
153
|
+
sleep: (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
154
|
+
probeTimeoutMs: defaultProbeTimeoutMs,
|
|
155
|
+
pollIntervalMs: defaultPollIntervalMs,
|
|
156
|
+
});
|
|
157
|
+
return {
|
|
158
|
+
run: (request) => request.backend.kind === "systemd" ? systemd.run(request) : launchd.run(request),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
export function systemdRunArguments(request, unitName, shellCommand) {
|
|
162
|
+
return [
|
|
163
|
+
"--user",
|
|
164
|
+
"--wait",
|
|
165
|
+
"--collect",
|
|
166
|
+
"--pipe",
|
|
167
|
+
"--quiet",
|
|
168
|
+
`--unit=${unitName}`,
|
|
169
|
+
"--property=RuntimeMaxSec=15s",
|
|
170
|
+
"--property=TimeoutStopSec=5s",
|
|
171
|
+
...Object.entries(request.environment).map(([key, value]) => `--setenv=${key}=${value}`),
|
|
172
|
+
...(request.workingDirectory === null ? [] : [`--working-directory=${request.workingDirectory}`]),
|
|
173
|
+
"/usr/bin/env",
|
|
174
|
+
escapeSystemdCommandExpansion(request.shell.executable),
|
|
175
|
+
"-lc",
|
|
176
|
+
escapeSystemdCommandExpansion(shellCommand),
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
function escapeSystemdCommandExpansion(value) {
|
|
180
|
+
return value.replaceAll("$", () => "$$");
|
|
181
|
+
}
|
|
182
|
+
export function launchdProbePlist(request, label, shellCommand, stdoutPath, stderrPath) {
|
|
183
|
+
const argumentsXml = ["/usr/bin/env", request.shell.executable, "-lc", shellCommand]
|
|
184
|
+
.map((argument) => ` <string>${xmlEscape(argument)}</string>`)
|
|
185
|
+
.join("\n");
|
|
186
|
+
const environmentEntries = Object.entries(request.environment);
|
|
187
|
+
const environmentXml = environmentEntries.length === 0
|
|
188
|
+
? ""
|
|
189
|
+
: ` <key>EnvironmentVariables</key>\n <dict>\n${environmentEntries.map(([key, value]) => plistString(key, value, " ")).join("")} </dict>\n`;
|
|
190
|
+
const workingDirectoryXml = request.workingDirectory === null
|
|
191
|
+
? ""
|
|
192
|
+
: plistString("WorkingDirectory", request.workingDirectory);
|
|
193
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
194
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
195
|
+
<plist version="1.0">
|
|
196
|
+
<dict>
|
|
197
|
+
${plistString("Label", label)} <key>ProgramArguments</key>
|
|
198
|
+
<array>
|
|
199
|
+
${argumentsXml}
|
|
200
|
+
</array>
|
|
201
|
+
${workingDirectoryXml}${environmentXml} <key>RunAtLoad</key>
|
|
202
|
+
<true/>
|
|
203
|
+
<key>HardResourceLimits</key>
|
|
204
|
+
<dict>
|
|
205
|
+
<key>FileSize</key>
|
|
206
|
+
<integer>${String(maxLaunchdProbeFileBytes)}</integer>
|
|
207
|
+
</dict>
|
|
208
|
+
${plistString("StandardOutPath", stdoutPath)}${plistString("StandardErrorPath", stderrPath)}</dict>
|
|
209
|
+
</plist>
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
export class SpawnProbeCommandRunner {
|
|
213
|
+
run(command, args, timeoutMs) {
|
|
214
|
+
return new Promise((resolve) => {
|
|
215
|
+
const child = spawn(command, args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
216
|
+
let stdout = "";
|
|
217
|
+
let stderr = "";
|
|
218
|
+
let capturedBytes = 0;
|
|
219
|
+
let spawnFailure = null;
|
|
220
|
+
let settled = false;
|
|
221
|
+
const finish = (result, terminate) => {
|
|
222
|
+
if (settled)
|
|
223
|
+
return;
|
|
224
|
+
settled = true;
|
|
225
|
+
clearTimeout(timeout);
|
|
226
|
+
if (terminate) {
|
|
227
|
+
child.kill("SIGKILL");
|
|
228
|
+
child.stdout.destroy();
|
|
229
|
+
child.stderr.destroy();
|
|
230
|
+
child.unref();
|
|
231
|
+
}
|
|
232
|
+
resolve(result);
|
|
233
|
+
};
|
|
234
|
+
const capture = (stream, chunk) => {
|
|
235
|
+
if (settled)
|
|
236
|
+
return;
|
|
237
|
+
const bytes = Buffer.byteLength(chunk);
|
|
238
|
+
if (capturedBytes + bytes > maxCapturedCommandOutputBytes) {
|
|
239
|
+
finish({ kind: "output-limit", stdout, stderr }, true);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
capturedBytes += bytes;
|
|
243
|
+
if (stream === "stdout")
|
|
244
|
+
stdout += chunk;
|
|
245
|
+
else
|
|
246
|
+
stderr += chunk;
|
|
247
|
+
};
|
|
248
|
+
child.stdout.setEncoding("utf8");
|
|
249
|
+
child.stderr.setEncoding("utf8");
|
|
250
|
+
child.stdout.on("data", (chunk) => { capture("stdout", chunk); });
|
|
251
|
+
child.stderr.on("data", (chunk) => { capture("stderr", chunk); });
|
|
252
|
+
child.on("error", (error) => { spawnFailure = error.message; });
|
|
253
|
+
const timeout = setTimeout(() => {
|
|
254
|
+
finish({ kind: "timeout", stdout, stderr }, true);
|
|
255
|
+
}, timeoutMs);
|
|
256
|
+
child.on("close", (status) => {
|
|
257
|
+
if (spawnFailure !== null) {
|
|
258
|
+
finish({ kind: "spawn-failure", message: spawnFailure, stdout, stderr }, false);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
finish({ kind: "completed", status: status ?? 1, stdout, stderr }, false);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const nodeLaunchdProbeFileSystem = {
|
|
268
|
+
createTemporaryDirectory: (prefix) => mkdtemp(prefix),
|
|
269
|
+
writeFile: (path, contents, mode) => writeFile(path, contents, { encoding: "utf8", mode }),
|
|
270
|
+
readOptionalFile: async (path) => {
|
|
271
|
+
try {
|
|
272
|
+
return await readFile(path, "utf8");
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
if (isNodeErrorWithCode(error, "ENOENT"))
|
|
276
|
+
return null;
|
|
277
|
+
throw error;
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
removeDirectory: (path) => rm(path, { recursive: true, force: true }),
|
|
281
|
+
};
|
|
282
|
+
function readOptionalFileBounded(fileSystem, path, timeoutMs) {
|
|
283
|
+
return new Promise((resolve) => {
|
|
284
|
+
let settled = false;
|
|
285
|
+
const finish = (result) => {
|
|
286
|
+
if (settled)
|
|
287
|
+
return;
|
|
288
|
+
settled = true;
|
|
289
|
+
clearTimeout(timeout);
|
|
290
|
+
resolve(result);
|
|
291
|
+
};
|
|
292
|
+
const timeout = setTimeout(() => { finish({ kind: "deadline" }); }, timeoutMs);
|
|
293
|
+
void fileSystem.readOptionalFile(path).then((output) => { finish({ kind: "read", output }); }, (error) => { finish({ kind: "read-failure", error }); });
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
function prerequisiteProbeCommand(shell, prerequisites, outputPrefix, resultFiles) {
|
|
297
|
+
const markerPath = resultFiles?.pendingPath;
|
|
298
|
+
const checks = prerequisites.map((prerequisite) => {
|
|
299
|
+
const check = nativeServicePrerequisiteShellCheck(shell, prerequisite);
|
|
300
|
+
const encodedId = Buffer.from(prerequisite.id, "utf8").toString("base64");
|
|
301
|
+
const satisfied = markerCommand(shell, outputPrefix, encodedId, "satisfied", markerPath);
|
|
302
|
+
const unsatisfied = markerCommand(shell, outputPrefix, encodedId, "unsatisfied", markerPath);
|
|
303
|
+
return `${check} >/dev/null 2>&1 && ${satisfied} || ${unsatisfied}`;
|
|
304
|
+
}).join("; ") || ":";
|
|
305
|
+
if (resultFiles === undefined)
|
|
306
|
+
return checks;
|
|
307
|
+
const pending = shellQuote(shell, resultFiles.pendingPath);
|
|
308
|
+
const completed = shellQuote(shell, resultFiles.completedPath);
|
|
309
|
+
return `printf '%s' '' > ${pending}; ${checks}; /bin/mv ${pending} ${completed}`;
|
|
310
|
+
}
|
|
311
|
+
export function nativeServicePrerequisiteShellCheck(shell, prerequisite) {
|
|
312
|
+
switch (prerequisite.kind) {
|
|
313
|
+
case "command-available":
|
|
314
|
+
return externalExecutableShellCheck(shell, prerequisite.command);
|
|
315
|
+
case "node-version":
|
|
316
|
+
return externalExecutableShellCheck(shell, "node", ["-e", nodeVersionCheckScript(prerequisite.minimumVersion)]);
|
|
317
|
+
case "readable-file": {
|
|
318
|
+
const path = shellQuote(shell, prerequisite.path);
|
|
319
|
+
return `test -f ${path} && test -r ${path}`;
|
|
320
|
+
}
|
|
321
|
+
case "package-scripts": {
|
|
322
|
+
const script = "const p=require(process.argv[1]);const names=process.argv.slice(2);process.exit(names.every((name)=>typeof p.scripts?.[name]==='string')?0:1)";
|
|
323
|
+
return externalExecutableShellCheck(shell, "node", ["-e", script, prerequisite.packageJsonPath, ...prerequisite.scripts]);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
export function nodeVersionCheckScript(minimumVersion) {
|
|
328
|
+
const encodedMinimum = JSON.stringify(minimumVersion);
|
|
329
|
+
return `const version=process.argv[1]??process.versions.node;console.log(process.version);const current=version.split('.').map(Number);const minimum=${encodedMinimum}.split('.').map(Number);const length=Math.max(current.length,minimum.length);let comparison=0;for(let index=0;index<length;index+=1){const left=current[index]??0;const right=minimum[index]??0;if(left!==right){comparison=left>right?1:-1;break}}process.exit(comparison>=0?0:1)`;
|
|
330
|
+
}
|
|
331
|
+
function externalExecutableShellCheck(shell, command, arguments_ = []) {
|
|
332
|
+
const quotedCommand = shellQuote(shell, command);
|
|
333
|
+
const quotedArguments = arguments_.map((argument) => shellQuote(shell, argument)).join(" ");
|
|
334
|
+
if (shell === "fish") {
|
|
335
|
+
const invocation = quotedArguments === "" ? "" : `; and $pi_web_probe_executable[1] ${quotedArguments}`;
|
|
336
|
+
return `set -l pi_web_probe_executable (command -v ${quotedCommand}); and test (count $pi_web_probe_executable) -eq 1; and string match -q '*/*' -- $pi_web_probe_executable[1]; and test -f $pi_web_probe_executable[1]; and test -x $pi_web_probe_executable[1]${invocation}`;
|
|
337
|
+
}
|
|
338
|
+
const invocation = quotedArguments === "" ? "" : ` && "$pi_web_probe_executable" ${quotedArguments}`;
|
|
339
|
+
return `pi_web_probe_executable=$(command -v ${quotedCommand}) && case "$pi_web_probe_executable" in */*) test -f "$pi_web_probe_executable" && test -x "$pi_web_probe_executable"${invocation};; *) false;; esac`;
|
|
340
|
+
}
|
|
341
|
+
function markerCommand(shell, outputPrefix, encodedId, status, outputPath) {
|
|
342
|
+
const redirect = outputPath === undefined ? "" : ` >> ${shellQuote(shell, outputPath)}`;
|
|
343
|
+
return `printf '%s\\t%s\\t%s\\n' ${shellQuote(shell, outputPrefix)} ${shellQuote(shell, encodedId)} ${shellQuote(shell, status)}${redirect}`;
|
|
344
|
+
}
|
|
345
|
+
function parseProbeOutput(stdout, prerequisites, outputPrefix) {
|
|
346
|
+
const expected = new Map(prerequisites.map((prerequisite) => [
|
|
347
|
+
Buffer.from(prerequisite.id, "utf8").toString("base64"),
|
|
348
|
+
prerequisite,
|
|
349
|
+
]));
|
|
350
|
+
const outcomes = new Map();
|
|
351
|
+
for (const line of stdout.split(/\r?\n/u)) {
|
|
352
|
+
if (!line.startsWith(`${outputPrefix}\t`))
|
|
353
|
+
continue;
|
|
354
|
+
const fields = line.split("\t");
|
|
355
|
+
if (fields.length !== 3) {
|
|
356
|
+
return infrastructureFailure("malformed-output", "Authoritative probe returned a malformed result line.");
|
|
357
|
+
}
|
|
358
|
+
const encodedId = fields[1];
|
|
359
|
+
const status = fields[2];
|
|
360
|
+
const prerequisite = encodedId === undefined ? undefined : expected.get(encodedId);
|
|
361
|
+
if (prerequisite === undefined || (status !== "satisfied" && status !== "unsatisfied")) {
|
|
362
|
+
return infrastructureFailure("malformed-output", "Authoritative probe returned an unexpected result.");
|
|
363
|
+
}
|
|
364
|
+
if (outcomes.has(prerequisite.id)) {
|
|
365
|
+
return infrastructureFailure("malformed-output", `Authoritative probe returned duplicate outcome ${prerequisite.id}.`);
|
|
366
|
+
}
|
|
367
|
+
outcomes.set(prerequisite.id, {
|
|
368
|
+
prerequisiteId: prerequisite.id,
|
|
369
|
+
status,
|
|
370
|
+
detail: status === "satisfied" ? null : unsatisfiedDetail(prerequisite),
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
const missing = prerequisites.find((prerequisite) => !outcomes.has(prerequisite.id));
|
|
374
|
+
if (missing !== undefined) {
|
|
375
|
+
return infrastructureFailure("malformed-output", `Authoritative probe returned no outcome for ${missing.id}.`);
|
|
376
|
+
}
|
|
377
|
+
return { kind: "completed", outcomes: [...outcomes.values()] };
|
|
378
|
+
}
|
|
379
|
+
function unsatisfiedDetail(prerequisite) {
|
|
380
|
+
switch (prerequisite.kind) {
|
|
381
|
+
case "command-available":
|
|
382
|
+
return `${prerequisite.command} did not resolve to an external executable in the native service environment.`;
|
|
383
|
+
case "node-version":
|
|
384
|
+
return `node >= ${prerequisite.minimumVersion} was not available in the native service environment.`;
|
|
385
|
+
case "readable-file":
|
|
386
|
+
return `${prerequisite.path} was not a readable regular file in the native service environment.`;
|
|
387
|
+
case "package-scripts":
|
|
388
|
+
return `${prerequisite.packageJsonPath} did not provide scripts ${prerequisite.scripts.join(", ")} in the native service environment.`;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
function shellQuote(shell, value) {
|
|
392
|
+
return shell === "fish"
|
|
393
|
+
? `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`
|
|
394
|
+
: `'${value.replaceAll("'", "'\\''")}'`;
|
|
395
|
+
}
|
|
396
|
+
function safeUniqueId(value) {
|
|
397
|
+
const safe = value.toLowerCase().replaceAll(/[^a-z0-9-]/gu, "").slice(0, 48);
|
|
398
|
+
return safe === "" ? "probe" : safe;
|
|
399
|
+
}
|
|
400
|
+
function launchdTargetNotLoaded(result) {
|
|
401
|
+
if (result.kind !== "completed" || result.status === 0)
|
|
402
|
+
return false;
|
|
403
|
+
return /(?:could not find (?:specified )?service|service not found|no such process)/iu.test(`${result.stderr}\n${result.stdout}`);
|
|
404
|
+
}
|
|
405
|
+
function plistString(key, value, indent = " ") {
|
|
406
|
+
return `${indent}<key>${xmlEscape(key)}</key>\n${indent}<string>${xmlEscape(value)}</string>\n`;
|
|
407
|
+
}
|
|
408
|
+
function xmlEscape(value) {
|
|
409
|
+
return value
|
|
410
|
+
.replaceAll("&", "&")
|
|
411
|
+
.replaceAll("<", "<")
|
|
412
|
+
.replaceAll(">", ">")
|
|
413
|
+
.replaceAll('"', """)
|
|
414
|
+
.replaceAll("'", "'");
|
|
415
|
+
}
|
|
416
|
+
function commandInfrastructureFailure(action, result) {
|
|
417
|
+
if (result.kind === "timeout")
|
|
418
|
+
return infrastructureFailure("timeout", `Timed out while trying to ${action}.`);
|
|
419
|
+
return infrastructureFailure("manager", `Could not ${action}: ${commandFailureDetail(result)}`);
|
|
420
|
+
}
|
|
421
|
+
function commandFailureDetail(result) {
|
|
422
|
+
if (result.kind === "timeout")
|
|
423
|
+
return "command timed out";
|
|
424
|
+
if (result.kind === "spawn-failure")
|
|
425
|
+
return result.message;
|
|
426
|
+
if (result.kind === "output-limit")
|
|
427
|
+
return "command output exceeded the capture limit";
|
|
428
|
+
return firstOutput(result.stderr, result.stdout, `exit status ${String(result.status)}`);
|
|
429
|
+
}
|
|
430
|
+
function infrastructureFailure(reason, message) {
|
|
431
|
+
return { kind: "infrastructure-failure", reason, message };
|
|
432
|
+
}
|
|
433
|
+
function firstOutput(...values) {
|
|
434
|
+
for (const value of values) {
|
|
435
|
+
const line = value.trim().split(/\r?\n/u).find((candidate) => candidate.trim() !== "");
|
|
436
|
+
if (line !== undefined)
|
|
437
|
+
return line.trim();
|
|
438
|
+
}
|
|
439
|
+
return "no output";
|
|
440
|
+
}
|
|
441
|
+
function errorMessage(error) {
|
|
442
|
+
return error instanceof Error ? error.message : String(error);
|
|
443
|
+
}
|
|
444
|
+
function isNodeErrorWithCode(error, code) {
|
|
445
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
446
|
+
}
|
|
447
|
+
//# sourceMappingURL=serviceProbe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceProbe.js","sourceRoot":"","sources":["../../src/nativeServices/serviceProbe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { posix as posixPath } from "node:path";
|
|
2
|
+
export function renderSystemdUnit(plan, service) {
|
|
3
|
+
assertPlanService(plan, service);
|
|
4
|
+
assertBackend(plan, "systemd");
|
|
5
|
+
const workingDirectory = service.workingDirectory === null
|
|
6
|
+
? ""
|
|
7
|
+
: `WorkingDirectory=${systemdPathValue(service.workingDirectory)}\n`;
|
|
8
|
+
const restart = service.restart === "on-failure"
|
|
9
|
+
? "Restart=on-failure\nRestartSec=2\n"
|
|
10
|
+
: "Restart=no\n";
|
|
11
|
+
return `[Unit]
|
|
12
|
+
Description=${service.description}
|
|
13
|
+
${systemdDependencyLine(plan, "After", service.after)}${systemdDependencyLine(plan, "Wants", service.wants)}[Service]
|
|
14
|
+
Type=simple
|
|
15
|
+
${workingDirectory}${systemdEnvironmentLines(service.environment)}ExecStart=/usr/bin/env ${systemdExecArgument(plan.shell.executable)} -lc ${systemdExecArgument(service.shellCommand)}
|
|
16
|
+
${restart}
|
|
17
|
+
[Install]
|
|
18
|
+
WantedBy=default.target
|
|
19
|
+
`;
|
|
20
|
+
}
|
|
21
|
+
export function renderLaunchdPlist(plan, service, logDirectory) {
|
|
22
|
+
assertPlanService(plan, service);
|
|
23
|
+
assertBackend(plan, "launchd");
|
|
24
|
+
const programArguments = ["/usr/bin/env", plan.shell.executable, "-lc", service.shellCommand];
|
|
25
|
+
const workingDirectory = service.workingDirectory === null
|
|
26
|
+
? ""
|
|
27
|
+
: plistString("WorkingDirectory", service.workingDirectory);
|
|
28
|
+
const keepAlive = service.restart === "on-failure"
|
|
29
|
+
? " <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n"
|
|
30
|
+
: "";
|
|
31
|
+
const logPath = posixPath.join(logDirectory, service.manager.logName);
|
|
32
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
33
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
34
|
+
<plist version="1.0">
|
|
35
|
+
<dict>
|
|
36
|
+
${plistString("Label", service.manager.launchdLabel)}${plistProgramArguments(programArguments)}${workingDirectory}${plistEnvironment(service.environment)} <key>RunAtLoad</key>
|
|
37
|
+
<true/>
|
|
38
|
+
${keepAlive}${plistString("StandardOutPath", logPath)}${plistString("StandardErrorPath", logPath)}</dict>
|
|
39
|
+
</plist>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
function assertPlanService(plan, service) {
|
|
43
|
+
if (!plan.services.includes(service)) {
|
|
44
|
+
throw new Error(`Cannot render ${service.id}; it is not a member of the supplied native service plan.`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function assertBackend(plan, expected) {
|
|
48
|
+
if (plan.backend.kind !== expected) {
|
|
49
|
+
throw new Error(`Cannot render ${expected} service from a ${plan.backend.kind} native service plan.`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function systemdDependencyLine(plan, name, ids) {
|
|
53
|
+
if (ids.length === 0)
|
|
54
|
+
return "";
|
|
55
|
+
const names = ids.map((id) => {
|
|
56
|
+
const dependency = plan.services.find((service) => service.id === id);
|
|
57
|
+
if (dependency === undefined)
|
|
58
|
+
throw new Error(`Service ${id} is not present in the native service plan.`);
|
|
59
|
+
return dependency.manager.systemdName;
|
|
60
|
+
});
|
|
61
|
+
return `${name}=${names.join(" ")}\n`;
|
|
62
|
+
}
|
|
63
|
+
function systemdEnvironmentLines(environment) {
|
|
64
|
+
return Object.entries(environment)
|
|
65
|
+
.map(([key, value]) => `Environment=${systemdQuotedDirectiveValue(`${key}=${value}`)}\n`)
|
|
66
|
+
.join("");
|
|
67
|
+
}
|
|
68
|
+
function systemdExecArgument(value) {
|
|
69
|
+
return `"${systemdEscape(value.replaceAll("%", "%%").replaceAll("$", () => "$$"), false)}"`;
|
|
70
|
+
}
|
|
71
|
+
function systemdQuotedDirectiveValue(value) {
|
|
72
|
+
return `"${systemdEscape(value.replaceAll("%", "%%"), false)}"`;
|
|
73
|
+
}
|
|
74
|
+
function systemdPathValue(value) {
|
|
75
|
+
return systemdEscape(value.replaceAll("%", "%%"), true);
|
|
76
|
+
}
|
|
77
|
+
function systemdEscape(value, escapeSpaces) {
|
|
78
|
+
let escaped = "";
|
|
79
|
+
for (const character of value) {
|
|
80
|
+
const code = character.codePointAt(0) ?? 0;
|
|
81
|
+
if (character === "\\")
|
|
82
|
+
escaped += "\\\\";
|
|
83
|
+
else if (character === '"')
|
|
84
|
+
escaped += escapeSpaces ? "\\x22" : '\\"';
|
|
85
|
+
else if (character === "'" && escapeSpaces)
|
|
86
|
+
escaped += "\\x27";
|
|
87
|
+
else if (character === " " && escapeSpaces)
|
|
88
|
+
escaped += "\\x20";
|
|
89
|
+
else if (character === "\n")
|
|
90
|
+
escaped += "\\n";
|
|
91
|
+
else if (character === "\r")
|
|
92
|
+
escaped += "\\r";
|
|
93
|
+
else if (character === "\t")
|
|
94
|
+
escaped += "\\t";
|
|
95
|
+
else if (code < 0x20 || code === 0x7f)
|
|
96
|
+
escaped += `\\x${code.toString(16).padStart(2, "0")}`;
|
|
97
|
+
else
|
|
98
|
+
escaped += character;
|
|
99
|
+
}
|
|
100
|
+
return escaped;
|
|
101
|
+
}
|
|
102
|
+
function plistProgramArguments(arguments_) {
|
|
103
|
+
return ` <key>ProgramArguments</key>\n <array>\n${arguments_.map((argument) => ` <string>${xmlEscape(argument)}</string>`).join("\n")}\n </array>\n`;
|
|
104
|
+
}
|
|
105
|
+
function plistEnvironment(environment) {
|
|
106
|
+
const entries = Object.entries(environment);
|
|
107
|
+
if (entries.length === 0)
|
|
108
|
+
return "";
|
|
109
|
+
return ` <key>EnvironmentVariables</key>\n <dict>\n${entries.map(([key, value]) => plistString(key, value, " ")).join("")} </dict>\n`;
|
|
110
|
+
}
|
|
111
|
+
function plistString(key, value, indent = " ") {
|
|
112
|
+
return `${indent}<key>${xmlEscape(key)}</key>\n${indent}<string>${xmlEscape(value)}</string>\n`;
|
|
113
|
+
}
|
|
114
|
+
function xmlEscape(value) {
|
|
115
|
+
return value
|
|
116
|
+
.replaceAll("&", "&")
|
|
117
|
+
.replaceAll("<", "<")
|
|
118
|
+
.replaceAll(">", ">")
|
|
119
|
+
.replaceAll('"', """)
|
|
120
|
+
.replaceAll("'", "'");
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=serviceRendering.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceRendering.js","sourceRoot":"","sources":["../../src/nativeServices/serviceRendering.ts"],"names":[],"mappings":"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"}
|
|
@@ -135,6 +135,7 @@ function renderUpdatesPanel(html, terminal, state) {
|
|
|
135
135
|
<section class="updates-meta">
|
|
136
136
|
<span>Generated ${status.generatedAt}</span>
|
|
137
137
|
${status.release.latestVersion === undefined ? null : html `<span>Latest npm release ${status.release.latestVersion}</span>`}
|
|
138
|
+
${status.release.checkedAt === undefined || status.release.skipped === true ? null : html `<span>Release checked ${status.release.checkedAt}</span>`}
|
|
138
139
|
${status.release.skipped === true ? html `<span>Remote version check skipped.</span>` : null}
|
|
139
140
|
${status.release.error === undefined ? null : html `<span>Remote version check failed: ${status.release.error}</span>`}
|
|
140
141
|
</section>
|
|
@@ -146,6 +147,17 @@ const plugin = {
|
|
|
146
147
|
name: "Updates",
|
|
147
148
|
activate: ({ html, svg }) => ({
|
|
148
149
|
contributions: {
|
|
150
|
+
actions: [
|
|
151
|
+
{
|
|
152
|
+
id: "check",
|
|
153
|
+
title: "Check for PI WEB Updates",
|
|
154
|
+
description: "Bypass cached release data and check the selected machine now",
|
|
155
|
+
group: "Updates",
|
|
156
|
+
enabled: (context) => context.checkForPiWebUpdates !== undefined,
|
|
157
|
+
disabledReason: () => "Update checks require a newer PI WEB gateway",
|
|
158
|
+
run: (context) => context.checkForPiWebUpdates?.(),
|
|
159
|
+
},
|
|
160
|
+
],
|
|
149
161
|
workspacePanels: [
|
|
150
162
|
{
|
|
151
163
|
id: "workspace.updates",
|