@usine/server 0.2.1 → 0.4.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/LICENSE +661 -21
- package/README.md +54 -20
- package/dist/backend.d.ts +26 -5
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +41 -16
- package/dist/backend.js.map +1 -1
- package/dist/backup.d.ts +6 -3
- package/dist/backup.d.ts.map +1 -1
- package/dist/backup.js +26 -8
- package/dist/backup.js.map +1 -1
- package/dist/cli.d.ts +77 -11
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +280 -31
- package/dist/cli.js.map +1 -1
- package/dist/command.d.ts +22 -0
- package/dist/command.d.ts.map +1 -0
- package/dist/command.js +51 -0
- package/dist/command.js.map +1 -0
- package/dist/detach.d.ts +83 -0
- package/dist/detach.d.ts.map +1 -0
- package/dist/detach.js +320 -0
- package/dist/detach.js.map +1 -0
- package/dist/export-run.d.ts +1 -1
- package/dist/export-run.d.ts.map +1 -1
- package/dist/export-run.js +3 -3
- package/dist/export-run.js.map +1 -1
- package/dist/failure-message.d.ts +19 -0
- package/dist/failure-message.d.ts.map +1 -0
- package/dist/failure-message.js +127 -0
- package/dist/failure-message.js.map +1 -0
- package/dist/http.d.ts +14 -5
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +86 -33
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/instance/environment.d.ts +17 -0
- package/dist/instance/environment.d.ts.map +1 -0
- package/dist/instance/environment.js +51 -0
- package/dist/instance/environment.js.map +1 -0
- package/dist/instance/id.d.ts +17 -0
- package/dist/instance/id.d.ts.map +1 -0
- package/dist/instance/id.js +35 -0
- package/dist/instance/id.js.map +1 -0
- package/dist/instance/lock.d.ts +27 -0
- package/dist/instance/lock.d.ts.map +1 -0
- package/dist/instance/lock.js +127 -0
- package/dist/instance/lock.js.map +1 -0
- package/dist/instance/manifest.d.ts +52 -0
- package/dist/instance/manifest.d.ts.map +1 -0
- package/dist/instance/manifest.js +131 -0
- package/dist/instance/manifest.js.map +1 -0
- package/dist/instance/operator-api.d.ts +30 -0
- package/dist/instance/operator-api.d.ts.map +1 -0
- package/dist/instance/operator-api.js +47 -0
- package/dist/instance/operator-api.js.map +1 -0
- package/dist/instance/ports.d.ts +23 -0
- package/dist/instance/ports.d.ts.map +1 -0
- package/dist/instance/ports.js +81 -0
- package/dist/instance/ports.js.map +1 -0
- package/dist/instance/record.d.ts +82 -0
- package/dist/instance/record.d.ts.map +1 -0
- package/dist/instance/record.js +116 -0
- package/dist/instance/record.js.map +1 -0
- package/dist/instance/state.d.ts +45 -0
- package/dist/instance/state.d.ts.map +1 -0
- package/dist/instance/state.js +79 -0
- package/dist/instance/state.js.map +1 -0
- package/dist/instance/systemd.d.ts +36 -0
- package/dist/instance/systemd.d.ts.map +1 -0
- package/dist/instance/systemd.js +61 -0
- package/dist/instance/systemd.js.map +1 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +27 -0
- package/dist/logger.js.map +1 -0
- package/dist/main.js +38 -18
- package/dist/main.js.map +1 -1
- package/dist/registry.d.ts +20 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +37 -0
- package/dist/registry.js.map +1 -0
- package/dist/reload-signal.d.ts +8 -0
- package/dist/reload-signal.d.ts.map +1 -0
- package/dist/reload-signal.js +21 -0
- package/dist/reload-signal.js.map +1 -0
- package/dist/restart.d.ts +19 -0
- package/dist/restart.d.ts.map +1 -0
- package/dist/restart.js +105 -0
- package/dist/restart.js.map +1 -0
- package/dist/shutdown.d.ts +5 -2
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +11 -5
- package/dist/shutdown.js.map +1 -1
- package/dist/status.d.ts +12 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +99 -0
- package/dist/status.js.map +1 -0
- package/dist/stop.d.ts +81 -0
- package/dist/stop.d.ts.map +1 -0
- package/dist/stop.js +195 -0
- package/dist/stop.js.map +1 -0
- package/dist/system-sleep.d.ts +9 -0
- package/dist/system-sleep.d.ts.map +1 -0
- package/dist/system-sleep.js +42 -0
- package/dist/system-sleep.js.map +1 -0
- package/dist/tracing.d.ts +22 -0
- package/dist/tracing.d.ts.map +1 -0
- package/dist/tracing.js +61 -0
- package/dist/tracing.js.map +1 -0
- package/dist/up.d.ts +2 -2
- package/dist/up.d.ts.map +1 -1
- package/dist/up.js +62 -24
- package/dist/up.js.map +1 -1
- package/dist/upgrade.d.ts +58 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +237 -0
- package/dist/upgrade.js.map +1 -0
- package/dist/web/assets/CompositeItem-DU6IyNMY.js +1 -0
- package/dist/web/assets/ToolbarRootContext-Cytu6o2e.js +1 -0
- package/dist/web/assets/X.es-B7iqdxa_.js +1 -0
- package/dist/web/assets/_agent-BVKD5odk.js +1 -0
- package/dist/web/assets/_loop-BFLzamuo.js +1 -0
- package/dist/web/assets/_name-Bh4AQ9sR.js +6 -0
- package/dist/web/assets/_name-CMVsmWzq.js +1 -0
- package/dist/web/assets/_name-DCkgEma_.js +1 -0
- package/dist/web/assets/_name-Ds_pWi15.js +1 -0
- package/dist/web/assets/_number-B9aYwvcQ.js +1 -0
- package/dist/web/assets/_run-BZWt47QS.js +8 -0
- package/dist/web/assets/_worker-Dgfufm5p.js +1 -0
- package/dist/web/assets/action-rCd1FeAz.js +1 -0
- package/dist/web/assets/agents-Drbg6qpH.js +1 -0
- package/dist/web/assets/agents-_6-dEjrY.js +1 -0
- package/dist/web/assets/button-DVWXde__.js +1 -0
- package/dist/web/assets/collapsible-IOhZV1qg.js +1 -0
- package/dist/web/assets/core-wi-Hu_JV.js +12 -0
- package/dist/web/assets/drawer-BiqnR_8i.js +1 -0
- package/dist/web/assets/dropdown-menu-C9D1kRkO.js +1 -0
- package/dist/web/assets/edit-and-retry-BgOR6mvP.js +1 -0
- package/dist/web/assets/engine-javascript-D-6se_EF.js +141 -0
- package/dist/web/assets/error-alert-9tKpTE3v.js +1 -0
- package/dist/web/assets/file-error-SjG2jLJ9.js +1 -0
- package/dist/web/assets/fill-cell-ClM88KFD.js +1 -0
- package/dist/web/assets/heading-lX1a1LNN.js +1 -0
- package/dist/web/assets/index-BymNZU1Q.js +10 -0
- package/dist/web/assets/index-Dyjfp3ET.css +2 -0
- package/dist/web/assets/inter-cyrillic-ext-opsz-normal-CfYZpDVp.woff2 +0 -0
- package/dist/web/assets/inter-cyrillic-opsz-normal-BFQXbQ-f.woff2 +0 -0
- package/dist/web/assets/inter-greek-ext-opsz-normal-BmPQvyvo.woff2 +0 -0
- package/dist/web/assets/inter-greek-opsz-normal-BM0NlUE_.woff2 +0 -0
- package/dist/web/assets/inter-latin-ext-opsz-normal-DpK-iCPk.woff2 +0 -0
- package/dist/web/assets/inter-latin-opsz-normal-BwkfbSeq.woff2 +0 -0
- package/dist/web/assets/inter-vietnamese-opsz-normal-Ci9T9ieq.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/dist/web/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/dist/web/assets/label-badge-aIGT1Bry.js +1 -0
- package/dist/web/assets/list-v8WJp2Eq.js +1 -0
- package/dist/web/assets/loops-BFoFf_og.js +1 -0
- package/dist/web/assets/mark-CC3RwMy_.js +1 -0
- package/dist/web/assets/markdown-BnyfnuCL.js +29 -0
- package/dist/web/assets/matchContext-BquevSJS.js +2 -0
- package/dist/web/assets/model-BerBT6R0.js +1 -0
- package/dist/web/assets/moves-Dg9sshX5.js +1 -0
- package/dist/web/assets/overview-C_tFKGZ8.js +1 -0
- package/dist/web/assets/page-DWnGi6wA.js +301 -0
- package/dist/web/assets/project-not-found-CodaBVdu.js +1 -0
- package/dist/web/assets/pull-request-marks-DE00nqGW.js +1 -0
- package/dist/web/assets/queries-B1SHA_r4.js +1 -0
- package/dist/web/assets/reload-Dsl0zjJ7.js +1 -0
- package/dist/web/assets/repositories-BdxmD192.js +1 -0
- package/dist/web/assets/repositories-D4wYJfa_.js +1 -0
- package/dist/web/assets/route-B_gphTYG.js +1 -0
- package/dist/web/assets/route-Cc7dKnn5.js +1 -0
- package/dist/web/assets/routes-BLy5TGH_.js +65 -0
- package/dist/web/assets/run-again-BTKagSXR.js +1 -0
- package/dist/web/assets/section-B3pWIIBa.js +1 -0
- package/dist/web/assets/section-CD-MB5r3.js +1 -0
- package/dist/web/assets/section-Id99HktI.js +1 -0
- package/dist/web/assets/settings-YrDysQXW.js +1 -0
- package/dist/web/assets/slots-BraHmbNr.js +1 -0
- package/dist/web/assets/status-badge-DnvNo1tG.js +1 -0
- package/dist/web/assets/strings-CW2XaR5f.js +1 -0
- package/dist/web/assets/table-BjyI4fVI.js +1 -0
- package/dist/web/assets/tasks-DCL8kLmD.js +1 -0
- package/dist/web/assets/transcript-sxRJzx6t.js +5 -0
- package/dist/web/assets/usage-CLQJdX9-.js +1 -0
- package/dist/web/assets/use-now-0P8TUXeg.js +1 -0
- package/dist/web/assets/useAnchoredPopupScrollLock-CQ83Wy-r.js +1 -0
- package/dist/web/assets/useNavigate-BW1WdocJ.js +1 -0
- package/dist/web/assets/usePositioner-rNCxnHO-.js +1 -0
- package/dist/web/assets/useTimeout-_TcdZXP6.js +1 -0
- package/dist/web/assets/with-selector-DoElmmtd.js +1 -0
- package/dist/web/assets/workers-BH5CBOR3.js +1 -0
- package/dist/web/index.html +16 -10
- package/package.json +17 -12
- package/dist/web/assets/_name-DdyMEUN6.js +0 -6
- package/dist/web/assets/_name-eoobiMh0.js +0 -1
- package/dist/web/assets/_name-pUxlKZt5.js +0 -1
- package/dist/web/assets/badge-t7m0Vk1K.js +0 -146
- package/dist/web/assets/button-BoOukj77.js +0 -1
- package/dist/web/assets/core-CLXRiB63.js +0 -12
- package/dist/web/assets/empty-DbVYU7bi.js +0 -1
- package/dist/web/assets/engine-javascript-h-x4hGa4.js +0 -141
- package/dist/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/web/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/web/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/web/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/web/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/web/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/web/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/web/assets/index-CVBBoW6r.css +0 -2
- package/dist/web/assets/index-CsW8KcJW.js +0 -10
- package/dist/web/assets/loops-DghpuoiG.js +0 -1
- package/dist/web/assets/operator-copy-DIsVXn17.js +0 -1
- package/dist/web/assets/overview-DmCIVPwN.js +0 -1
- package/dist/web/assets/rolldown-runtime-hePW80VL.js +0 -1
- package/dist/web/assets/routes-BDyP7vCr.js +0 -1
- package/dist/web/assets/run-drawer-B-xhTXe4.js +0 -157
- package/dist/web/assets/status-badge-yblcElE0.js +0 -1
- package/dist/web/assets/table-B8cLYNvq.js +0 -1
- package/dist/web/assets/useCompositeItem-HmBmWxUW.js +0 -1
- package/dist/web/assets/with-selector-N6m4X0X_.js +0 -1
package/dist/stop.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { RunId } from "@usine/core/run";
|
|
2
|
+
import { Config, Console, Duration, Effect, Option, Schema } from "effect";
|
|
3
|
+
import { ProcessId } from "./instance/record.js";
|
|
4
|
+
import { gatewayTokenVariables, hasLiveAttempt, listRuns } from "./instance/operator-api.js";
|
|
5
|
+
import { probeInstance, processAlive, signalProcess } from "./instance/state.js";
|
|
6
|
+
import { SystemdUnit, supervisingUnit, systemctl } from "./instance/systemd.js";
|
|
7
|
+
const EXIT_POLL_INTERVAL = "200 millis";
|
|
8
|
+
/** Separates the two signals of `--force`, so that the OS doesn't merge them into one. */
|
|
9
|
+
const SECOND_SIGNAL_DELAY = "250 millis";
|
|
10
|
+
/** How long `--force` waits for the process to exit after `SIGKILL`. */
|
|
11
|
+
const KILL_EXIT_TIMEOUT = Duration.seconds(5);
|
|
12
|
+
/** The CLI command that stops the instance. */
|
|
13
|
+
export const LifecycleCommandName = Schema.Literals(["stop", "restart", "upgrade"]);
|
|
14
|
+
/** The instance process didn't exit within the timeout. Its drain continues. */
|
|
15
|
+
export class StopTimeoutError extends Schema.TaggedError("@usine/server/StopTimeoutError")("StopTimeoutError", {
|
|
16
|
+
command: LifecycleCommandName,
|
|
17
|
+
pid: ProcessId,
|
|
18
|
+
timeout: Schema.Duration,
|
|
19
|
+
/** The Runs whose Attempts were live when the stop started. */
|
|
20
|
+
runs: Schema.Array(RunId),
|
|
21
|
+
/** The systemd service that runs the instance, which `systemctl start` starts again. */
|
|
22
|
+
unit: Schema.Option(SystemdUnit),
|
|
23
|
+
}) {
|
|
24
|
+
}
|
|
25
|
+
/** The instance process still ran `timeout` after `--force` sent it `SIGKILL`. */
|
|
26
|
+
export class KillTimeoutError extends Schema.TaggedError("@usine/server/KillTimeoutError")("KillTimeoutError", {
|
|
27
|
+
command: LifecycleCommandName,
|
|
28
|
+
pid: ProcessId,
|
|
29
|
+
timeout: Schema.Duration,
|
|
30
|
+
}) {
|
|
31
|
+
}
|
|
32
|
+
/** No `usine up` runs in the instance folder. */
|
|
33
|
+
export class InstanceNotRunningError extends Schema.TaggedError("@usine/server/InstanceNotRunningError")("InstanceNotRunningError", { command: LifecycleCommandName, directory: Schema.String }) {
|
|
34
|
+
}
|
|
35
|
+
/** A process holds the instance lock without an instance record, so its launch is unknown. */
|
|
36
|
+
export class UnrecordedInstanceError extends Schema.TaggedError("@usine/server/UnrecordedInstanceError")("UnrecordedInstanceError", {
|
|
37
|
+
command: LifecycleCommandName,
|
|
38
|
+
directory: Schema.String,
|
|
39
|
+
pid: Schema.Option(ProcessId),
|
|
40
|
+
}) {
|
|
41
|
+
}
|
|
42
|
+
/** Runs have live Attempts, and the operator didn't pass `--force`. */
|
|
43
|
+
export class LiveAttemptsError extends Schema.TaggedError("@usine/server/LiveAttemptsError")("LiveAttemptsError", { command: LifecycleCommandName, runs: Schema.Array(RunId) }) {
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Neither the shell that would start the new `usine up` nor `.env` sets variables that its startup
|
|
47
|
+
* needs.
|
|
48
|
+
*/
|
|
49
|
+
export class MissingEnvironmentError extends Schema.TaggedError("@usine/server/MissingEnvironmentError")("MissingEnvironmentError", {
|
|
50
|
+
command: LifecycleCommandName,
|
|
51
|
+
variables: Schema.Array(Schema.NonEmptyString),
|
|
52
|
+
}) {
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fails with `MissingEnvironmentError` if the current `ConfigProvider` lacks a gateway admin token
|
|
56
|
+
* variable of the instance that listens on `port`. The new `usine up` inherits this process's
|
|
57
|
+
* environment and reads the instance folder's `.env`, and doesn't start without them.
|
|
58
|
+
*/
|
|
59
|
+
export const refuseMissingEnvironment = Effect.fn("Cli.refuseMissingEnvironment")(function* (command, port) {
|
|
60
|
+
const names = yield* gatewayTokenVariables(port).pipe(Effect.tapError((error) => Effect.logWarning("Could not read the gateway token variables of the instance", {
|
|
61
|
+
url: error.url,
|
|
62
|
+
reason: error.reason,
|
|
63
|
+
})), Effect.orElseSucceed(() => []));
|
|
64
|
+
const missing = [];
|
|
65
|
+
for (const name of names) {
|
|
66
|
+
const value = yield* Config.option(Config.String(name)).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
67
|
+
if (Option.isNone(value))
|
|
68
|
+
missing.push(name);
|
|
69
|
+
}
|
|
70
|
+
if (missing.length === 0)
|
|
71
|
+
return;
|
|
72
|
+
yield* Effect.logInfo("Refusing to stop the instance: the new process would lack variables", {
|
|
73
|
+
command,
|
|
74
|
+
variables: missing,
|
|
75
|
+
});
|
|
76
|
+
return yield* new MissingEnvironmentError({ command, variables: missing });
|
|
77
|
+
});
|
|
78
|
+
/** Returns the Runs with a live Attempt, or none if the operator API doesn't answer. */
|
|
79
|
+
const liveRuns = (port) => listRuns(port).pipe(Effect.map((runs) => runs.filter(hasLiveAttempt).map(({ id }) => id)), Effect.tapError((error) => Effect.logWarning("Could not list the running runs; the drain still waits for them", {
|
|
80
|
+
url: error.url,
|
|
81
|
+
reason: error.reason,
|
|
82
|
+
})), Effect.orElseSucceed(() => []));
|
|
83
|
+
/**
|
|
84
|
+
* Fails with `LiveAttemptsError` if a Run of the instance that listens on `port` has a live
|
|
85
|
+
* Attempt, unless `force` is set.
|
|
86
|
+
*/
|
|
87
|
+
export const refuseLiveAttempts = Effect.fn("Cli.refuseLiveAttempts")(function* (command, port, force) {
|
|
88
|
+
if (force)
|
|
89
|
+
return;
|
|
90
|
+
const runs = yield* liveRuns(port);
|
|
91
|
+
if (runs.length === 0)
|
|
92
|
+
return;
|
|
93
|
+
yield* Effect.logInfo("Refusing to stop the instance while runs have live attempts", {
|
|
94
|
+
command,
|
|
95
|
+
runs,
|
|
96
|
+
});
|
|
97
|
+
return yield* new LiveAttemptsError({ command, runs });
|
|
98
|
+
});
|
|
99
|
+
/** Returns `true` once the process has exited, or `false` after `timeout`. */
|
|
100
|
+
const waitForExit = (pid, timeout) => Effect.gen(function* () {
|
|
101
|
+
while (yield* processAlive(pid))
|
|
102
|
+
yield* Effect.sleep(EXIT_POLL_INTERVAL);
|
|
103
|
+
}).pipe(Effect.timeoutOption(timeout), Effect.map(Option.isSome));
|
|
104
|
+
/**
|
|
105
|
+
* Sends `SIGKILL` to a process that a forced stop didn't end within `timeout`, and waits for it to
|
|
106
|
+
* exit.
|
|
107
|
+
*/
|
|
108
|
+
const killProcess = Effect.fn("Cli.killProcess")(function* (command, pid, timeout) {
|
|
109
|
+
yield* Effect.annotateCurrentSpan({ command, pid });
|
|
110
|
+
yield* signalProcess(pid, "SIGKILL");
|
|
111
|
+
yield* Console.log(`usine (pid ${pid}) did not exit within ${Duration.format(timeout)}. Sent SIGKILL: the next start reattaches the running attempts.`);
|
|
112
|
+
if (yield* waitForExit(pid, KILL_EXIT_TIMEOUT))
|
|
113
|
+
return;
|
|
114
|
+
yield* Effect.logWarning("The instance process did not exit after SIGKILL", {
|
|
115
|
+
command,
|
|
116
|
+
pid,
|
|
117
|
+
timeoutSeconds: Duration.toSeconds(KILL_EXIT_TIMEOUT),
|
|
118
|
+
});
|
|
119
|
+
return yield* new KillTimeoutError({ command, pid, timeout: KILL_EXIT_TIMEOUT });
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* Starts the drain of the instance process and waits for the process to exit: through
|
|
123
|
+
* `systemctl stop --no-block` if `unit` runs it, so that systemd doesn't restart it, else with
|
|
124
|
+
* `SIGTERM`. With `force`, sends a second `SIGTERM`, which ends the drain without waiting for
|
|
125
|
+
* running Attempts, and sends `SIGKILL` if the process still runs after the timeout. Doesn't repeat
|
|
126
|
+
* the first signal to a process that records that it is stopping.
|
|
127
|
+
*/
|
|
128
|
+
export const stopProcess = Effect.fn("Cli.stopProcess")(function* (command, pid, record, unit, options) {
|
|
129
|
+
yield* Effect.annotateCurrentSpan({
|
|
130
|
+
command,
|
|
131
|
+
pid,
|
|
132
|
+
force: options.force,
|
|
133
|
+
unit: Option.getOrUndefined(unit),
|
|
134
|
+
});
|
|
135
|
+
const stopping = Option.exists(record, ({ stoppingSince }) => stoppingSince !== undefined);
|
|
136
|
+
const runs = Option.isSome(record) ? yield* liveRuns(record.value.launch.port) : [];
|
|
137
|
+
if (stopping) {
|
|
138
|
+
yield* Console.log(`usine (pid ${pid}) is already stopping. Waiting for it to exit.`);
|
|
139
|
+
}
|
|
140
|
+
else if (Option.isSome(unit)) {
|
|
141
|
+
yield* Console.log(`Stopping usine (pid ${pid}) with systemctl stop ${unit.value}.`);
|
|
142
|
+
yield* systemctl(unit.value, ["stop", "--no-block"]);
|
|
143
|
+
yield* Effect.logInfo("Asked systemd to stop the instance's service", {
|
|
144
|
+
command,
|
|
145
|
+
pid,
|
|
146
|
+
unit: unit.value,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
yield* Console.log(`Stopping usine (pid ${pid}).`);
|
|
151
|
+
yield* signalProcess(pid, "SIGTERM");
|
|
152
|
+
}
|
|
153
|
+
if (options.force) {
|
|
154
|
+
yield* Effect.sleep(SECOND_SIGNAL_DELAY);
|
|
155
|
+
if (yield* processAlive(pid)) {
|
|
156
|
+
yield* signalProcess(pid, "SIGTERM");
|
|
157
|
+
yield* Console.log("Sent a second SIGTERM: usine stops without waiting for running attempts, and the next start reattaches them.");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
else if (runs.length > 0) {
|
|
161
|
+
yield* Console.log(`Waiting for the running attempts of ${runs.length === 1 ? "run" : "runs"} ${runs.join(", ")} to end.`);
|
|
162
|
+
}
|
|
163
|
+
if (!(yield* waitForExit(pid, options.timeout))) {
|
|
164
|
+
yield* Effect.logWarning("The instance process did not exit before the timeout", {
|
|
165
|
+
command,
|
|
166
|
+
pid,
|
|
167
|
+
force: options.force,
|
|
168
|
+
timeoutSeconds: Duration.toSeconds(options.timeout),
|
|
169
|
+
});
|
|
170
|
+
if (!options.force) {
|
|
171
|
+
return yield* new StopTimeoutError({ command, pid, timeout: options.timeout, runs, unit });
|
|
172
|
+
}
|
|
173
|
+
yield* killProcess(command, pid, options.timeout);
|
|
174
|
+
}
|
|
175
|
+
yield* Effect.logInfo("The instance process exited", { command, pid });
|
|
176
|
+
yield* Console.log("usine stopped.");
|
|
177
|
+
});
|
|
178
|
+
/** Stops the `usine up` of the instance folder, and succeeds if none runs. */
|
|
179
|
+
export const stop = Effect.fn("Cli.stop")(function* (directory, options) {
|
|
180
|
+
const state = yield* probeInstance(directory);
|
|
181
|
+
if (state._tag === "Stopped") {
|
|
182
|
+
yield* Console.log(`usine is not running in ${directory}.`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (state._tag === "Running") {
|
|
186
|
+
const { record } = state;
|
|
187
|
+
const unit = yield* supervisingUnit(record.pid, record.systemdUnit);
|
|
188
|
+
return yield* stopProcess("stop", record.pid, Option.some(record), unit, options);
|
|
189
|
+
}
|
|
190
|
+
if (Option.isNone(state.pid)) {
|
|
191
|
+
return yield* new UnrecordedInstanceError({ command: "stop", directory, pid: state.pid });
|
|
192
|
+
}
|
|
193
|
+
return yield* stopProcess("stop", state.pid.value, Option.none(), Option.none(), options);
|
|
194
|
+
});
|
|
195
|
+
//# sourceMappingURL=stop.js.map
|
package/dist/stop.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../src/stop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE3E,OAAO,EAAuB,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEhF,MAAM,kBAAkB,GAAG,YAAY,CAAC;AACxC,0FAA0F;AAC1F,MAAM,mBAAmB,GAAG,YAAY,CAAC;AACzC,wEAAwE;AACxE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAE9C,+CAA+C;AAC/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAGpF,gFAAgF;AAChF,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,CACtD,gCAAgC,CACjC,CAAC,kBAAkB,EAAE;IACpB,OAAO,EAAE,oBAAoB;IAC7B,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,MAAM,CAAC,QAAQ;IACxB,+DAA+D;IAC/D,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IACzB,wFAAwF;IACxF,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;CACjC,CAAC;CAAG;AAEL,kFAAkF;AAClF,MAAM,OAAO,gBAAiB,SAAQ,MAAM,CAAC,WAAW,CACtD,gCAAgC,CACjC,CAAC,kBAAkB,EAAE;IACpB,OAAO,EAAE,oBAAoB;IAC7B,GAAG,EAAE,SAAS;IACd,OAAO,EAAE,MAAM,CAAC,QAAQ;CACzB,CAAC;CAAG;AAEL,iDAAiD;AACjD,MAAM,OAAO,uBAAwB,SAAQ,MAAM,CAAC,WAAW,CAC7D,uCAAuC,CACxC,CAAC,yBAAyB,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;CAAG;AAE5F,8FAA8F;AAC9F,MAAM,OAAO,uBAAwB,SAAQ,MAAM,CAAC,WAAW,CAC7D,uCAAuC,CACxC,CAAC,yBAAyB,EAAE;IAC3B,OAAO,EAAE,oBAAoB;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;CAC9B,CAAC;CAAG;AAEL,uEAAuE;AACvE,MAAM,OAAO,iBAAkB,SAAQ,MAAM,CAAC,WAAW,CACvD,iCAAiC,CAClC,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;CAAG;AAEvF;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,MAAM,CAAC,WAAW,CAC7D,uCAAuC,CACxC,CAAC,yBAAyB,EAAE;IAC3B,OAAO,EAAE,oBAAoB;IAC7B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,cAAc,CAAC;CAC/C,CAAC;CAAG;AAEL;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,QAAQ,CAAC,EACzF,OAA6B,EAC7B,IAAU;IAEV,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,IAAI,CACnD,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,MAAM,CAAC,UAAU,CAAC,4DAA4D,EAAE;QAC9E,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CACH,EACD,MAAM,CAAC,aAAa,CAAC,GAA0B,EAAE,CAAC,EAAE,CAAC,CACtD,CAAC;IACF,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC1D,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAU,CAAC,CAClD,CAAC;QACF,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IACjC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,qEAAqE,EAAE;QAC3F,OAAO;QACP,SAAS,EAAE,OAAO;KACnB,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,CAAC,IAAI,uBAAuB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AAC7E,CAAC,CAAC,CAAC;AAEH,wFAAwF;AACxF,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAE,EAAE,CAC9B,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CACjB,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EACrE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,MAAM,CAAC,UAAU,CAAC,iEAAiE,EAAE;IACnF,GAAG,EAAE,KAAK,CAAC,GAAG;IACd,MAAM,EAAE,KAAK,CAAC,MAAM;CACrB,CAAC,CACH,EACD,MAAM,CAAC,aAAa,CAAC,GAAyB,EAAE,CAAC,EAAE,CAAC,CACrD,CAAC;AAEJ;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAC7E,OAA6B,EAC7B,IAAU,EACV,KAAc;IAEd,IAAI,KAAK;QAAE,OAAO;IAClB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC9B,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,6DAA6D,EAAE;QACnF,OAAO;QACP,IAAI;KACL,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,CAAC,IAAI,iBAAiB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACzD,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,MAAM,WAAW,GAAG,CAAC,GAAc,EAAE,OAA0B,EAAE,EAAE,CACjE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;QAAE,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAEpE;;;GAGG;AACH,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,EACxD,OAA6B,EAC7B,GAAc,EACd,OAA0B;IAE1B,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACpD,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACrC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAChB,cAAc,GAAG,yBAAyB,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,iEAAiE,CACpI,CAAC;IACF,IAAI,KAAK,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,iBAAiB,CAAC;QAAE,OAAO;IACvD,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,iDAAiD,EAAE;QAC1E,OAAO;QACP,GAAG;QACH,cAAc,EAAE,QAAQ,CAAC,SAAS,CAAC,iBAAiB,CAAC;KACtD,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,CAAC,IAAI,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC,CAAC;AACnF,CAAC,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,EAC/D,OAA6B,EAC7B,GAAc,EACd,MAAqC,EACrC,IAAgC,EAChC,OAAyB;IAEzB,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC;QAChC,OAAO;QACP,GAAG;QACH,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC;KAClC,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC;IAC3F,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACpF,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,gDAAgD,CAAC,CAAC;IACxF,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,yBAAyB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACrF,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;QACrD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,8CAA8C,EAAE;YACpE,OAAO;YACP,GAAG;YACH,IAAI,EAAE,IAAI,CAAC,KAAK;SACjB,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;QACnD,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;YACrC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAChB,8GAA8G,CAC/G,CAAC;QACJ,CAAC;IACH,CAAC;SAAM,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAChB,uCAAuC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CACvG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,sDAAsD,EAAE;YAC/E,OAAO;YACP,GAAG;YACH,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC,CAAC,IAAI,gBAAgB,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD,KAAK,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,CAAC;IACD,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,6BAA6B,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;IACvE,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,EACjD,SAA4B,EAC5B,OAAyB;IAEzB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,SAAS,GAAG,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,CAAC,IAAI,uBAAuB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;AAC5F,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ChildProcessSpawner } from "effect/process";
|
|
3
|
+
/**
|
|
4
|
+
* Logs a warning if this Mac can sleep while `usine up` runs: system sleep is on, and `caffeinate`
|
|
5
|
+
* doesn't prevent it. A sleep closes the SSH connections to Workers and to the Gateway, and the
|
|
6
|
+
* orchestrator does nothing until the Mac wakes.
|
|
7
|
+
*/
|
|
8
|
+
export declare const warnIfSystemSleeps: () => Effect.Effect<void, never, ChildProcessSpawner.ChildProcessSpawner>;
|
|
9
|
+
//# sourceMappingURL=system-sleep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-sleep.d.ts","sourceRoot":"","sources":["../src/system-sleep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAgB,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AA8BnE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,2EAyB7B,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Duration, Effect, Option, Schema } from "effect";
|
|
2
|
+
import { ChildProcess, ChildProcessSpawner } from "effect/process";
|
|
3
|
+
const PMSET_TIMEOUT = Duration.seconds(5);
|
|
4
|
+
/** Matches a line such as ` sleep 1 (sleep prevented by caffeinate, powerd)`. */
|
|
5
|
+
const SLEEP_LINE = /^\s*sleep\s+(\d+)(?:\s+\(sleep prevented by ([^)]*)\))?/mu;
|
|
6
|
+
const Minutes = Schema.NumberFromString.pipe(Schema.decodeTo(Schema.Int));
|
|
7
|
+
/** Returns the `sleep` setting in `pmset -g` output, or `None` if it has no `sleep` line. */
|
|
8
|
+
const systemSleepOf = (output) => {
|
|
9
|
+
const line = SLEEP_LINE.exec(output);
|
|
10
|
+
if (line === null)
|
|
11
|
+
return Option.none();
|
|
12
|
+
return Option.map(Schema.decodeUnknownOption(Minutes)(line[1]), (minutes) => ({
|
|
13
|
+
minutes,
|
|
14
|
+
preventedBy: (line[2] ?? "")
|
|
15
|
+
.split(",")
|
|
16
|
+
.map((name) => name.trim())
|
|
17
|
+
.filter((name) => name.length > 0),
|
|
18
|
+
}));
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Logs a warning if this Mac can sleep while `usine up` runs: system sleep is on, and `caffeinate`
|
|
22
|
+
* doesn't prevent it. A sleep closes the SSH connections to Workers and to the Gateway, and the
|
|
23
|
+
* orchestrator does nothing until the Mac wakes.
|
|
24
|
+
*/
|
|
25
|
+
export const warnIfSystemSleeps = Effect.fn("Server.warnIfSystemSleeps")(function* () {
|
|
26
|
+
const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
|
|
27
|
+
const sleep = yield* spawner
|
|
28
|
+
.string(ChildProcess.make("pmset", ["-g"], { stdin: "ignore", stderr: "ignore" }))
|
|
29
|
+
.pipe(Effect.timeout(PMSET_TIMEOUT), Effect.map(systemSleepOf), Effect.tapError((cause) => Effect.logWarning("Could not read the system sleep setting with pmset", { cause })), Effect.orElseSucceed(() => Option.none()));
|
|
30
|
+
if (Option.isNone(sleep))
|
|
31
|
+
return yield* Effect.logDebug("pmset reported no system sleep setting; skipping the check");
|
|
32
|
+
const { minutes, preventedBy } = sleep.value;
|
|
33
|
+
if (minutes === 0)
|
|
34
|
+
return yield* Effect.logDebug("System sleep is off");
|
|
35
|
+
if (preventedBy.includes("caffeinate"))
|
|
36
|
+
return yield* Effect.logInfo("System sleep is on, and caffeinate prevents it", {
|
|
37
|
+
minutes,
|
|
38
|
+
preventedBy,
|
|
39
|
+
});
|
|
40
|
+
yield* Effect.logWarning("This Mac can sleep while runs are open. A sleep drops the SSH connections to workers and the gateway, and remote children must resume. Run `caffeinate -s` while runs are open, turn off sleep on AC power with `sudo pmset -c sleep 0`, or run the orchestrator on an always-on server: https://docs.usine.dev/guides/run-the-orchestrator-on-a-server/", { minutes, preventedBy });
|
|
41
|
+
});
|
|
42
|
+
//# sourceMappingURL=system-sleep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-sleep.js","sourceRoot":"","sources":["../src/system-sleep.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAU1C,kFAAkF;AAClF,MAAM,UAAU,GAAG,2DAA2D,CAAC;AAE/E,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1E,6FAA6F;AAC7F,MAAM,aAAa,GAAG,CAAC,MAAc,EAA8B,EAAE;IACnE,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC5E,OAAO;QACP,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACzB,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;aAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;KACrC,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,EAAE,CAAC,2BAA2B,CAAC,CAAC,QAAQ,CAAC;IAChF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,mBAAmB,CAAC,mBAAmB,CAAC;IAC/D,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO;SACzB,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;SACjF,IAAI,CACH,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAC7B,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,EACzB,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,MAAM,CAAC,UAAU,CAAC,oDAAoD,EAAE,EAAE,KAAK,EAAE,CAAC,CACnF,EACD,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAe,CAAC,CACvD,CAAC;IACJ,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;QACtB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,4DAA4D,CAAC,CAAC;IAC9F,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC;IAC7C,IAAI,OAAO,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IACxE,IAAI,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC;QACpC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,gDAAgD,EAAE;YAC7E,OAAO;YACP,WAAW;SACZ,CAAC,CAAC;IACL,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CACtB,0VAA0V,EAC1V,EAAE,OAAO,EAAE,WAAW,EAAE,CACzB,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Tracing } from "@usine/config/factory";
|
|
2
|
+
import { type FileSystem, Layer, Option, Schema } from "effect";
|
|
3
|
+
import { type CliVersionError } from "./cli.ts";
|
|
4
|
+
declare const ResourceAttributesError_base: Schema.Class<ResourceAttributesError, Schema.TaggedStruct<"ResourceAttributesError", {
|
|
5
|
+
readonly variable: Schema.Literal<"OTEL_RESOURCE_ATTRIBUTES">;
|
|
6
|
+
/** The parse problem, with the key at fault. */
|
|
7
|
+
readonly message: Schema.String;
|
|
8
|
+
}>, import("effect/Cause").YieldableError>;
|
|
9
|
+
/** `OTEL_RESOURCE_ATTRIBUTES` has a key or value that isn't valid percent-encoding. */
|
|
10
|
+
export declare class ResourceAttributesError extends ResourceAttributesError_base {
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Exports every ended span to `tracing.otlpUrl` as OTLP/HTTP protobuf, or keeps Effect's default
|
|
14
|
+
* tracer, which exports nothing, if `tracing` is `None`. Logs which of the two applies, and a
|
|
15
|
+
* warning for each failed export request, with the URL's origin and path only. A failed export,
|
|
16
|
+
* after up to 3 retries, drops the buffered spans and pauses export for 60 seconds. Closing the
|
|
17
|
+
* layer's scope flushes buffered spans for at most 3 seconds. Fails with
|
|
18
|
+
* `ResourceAttributesError` if `tracing` is set and `OTEL_RESOURCE_ATTRIBUTES` is malformed.
|
|
19
|
+
*/
|
|
20
|
+
export declare const tracingLayer: (tracing: Option.Option<Tracing>) => Layer.Layer<never, CliVersionError | ResourceAttributesError, FileSystem.FileSystem>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=tracing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,EACL,MAAM,EACN,MAAM,EAEP,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,KAAK,eAAe,EAAkB,MAAM,UAAU,CAAC;;;IAS9D,gDAAgD;;;AALlD,uFAAuF;AACvF,qBAAa,uBAAwB,SAAQ,4BAM3C;CAAG;AA+CL;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,YACd,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAC9B,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,eAAe,GAAG,uBAAuB,EAAE,UAAU,CAAC,UAAU,CAgClF,CAAC"}
|
package/dist/tracing.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Config, ConfigProvider, Effect, Layer, Option, Schema, SchemaTransformation, } from "effect";
|
|
2
|
+
import { FetchHttpClient, HttpClient } from "effect/http";
|
|
3
|
+
import { OtlpSerialization, OtlpTracer } from "effect/observability";
|
|
4
|
+
import { packageVersion } from "./cli.js";
|
|
5
|
+
const RESOURCE_ATTRIBUTES = "OTEL_RESOURCE_ATTRIBUTES";
|
|
6
|
+
/** `OTEL_RESOURCE_ATTRIBUTES` has a key or value that isn't valid percent-encoding. */
|
|
7
|
+
export class ResourceAttributesError extends Schema.TaggedError("@usine/server/ResourceAttributesError")("ResourceAttributesError", {
|
|
8
|
+
variable: Schema.Literal(RESOURCE_ATTRIBUTES),
|
|
9
|
+
/** The parse problem, with the key at fault. */
|
|
10
|
+
message: Schema.String,
|
|
11
|
+
}) {
|
|
12
|
+
}
|
|
13
|
+
/** Comma-separated `key=value` pairs with percent-encoded keys and values. */
|
|
14
|
+
const ResourceAttributes = Schema.String.pipe(Schema.decodeTo(Schema.Record(Schema.StringFromUriComponent, Schema.StringFromUriComponent), SchemaTransformation.splitKeyValue()));
|
|
15
|
+
/** Returns the attributes in `OTEL_RESOURCE_ATTRIBUTES`, or none if it's unset. */
|
|
16
|
+
const resourceAttributes = Effect.fn("Tracing.resourceAttributes")(function* () {
|
|
17
|
+
const refuse = (error) => new ResourceAttributesError({ variable: RESOURCE_ATTRIBUTES, message: error.message });
|
|
18
|
+
const value = yield* Config.option(Config.String(RESOURCE_ATTRIBUTES)).pipe(Effect.mapError(refuse));
|
|
19
|
+
return yield* Option.match(value, {
|
|
20
|
+
onNone: () => Effect.succeed({}),
|
|
21
|
+
onSome: (attributes) => Schema.decodeUnknownEffect(ResourceAttributes)(attributes).pipe(Effect.mapError(refuse)),
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
/** Returns the URL's origin and path, without credentials, query string, or fragment. */
|
|
25
|
+
const loggedUrl = (url) => `${url.origin}${url.pathname}`;
|
|
26
|
+
const EXPORT_FAILED = "Span export to the OTLP collector failed";
|
|
27
|
+
// The error message is left out because it repeats the request URL.
|
|
28
|
+
const exportClientLayer = (collector) => Layer.effect(HttpClient.HttpClient, Effect.map(HttpClient.HttpClient, (client) => client.pipe(HttpClient.filterStatusOk, HttpClient.tapError((error) => {
|
|
29
|
+
const failure = { otlpUrl: collector, reason: error.reason._tag };
|
|
30
|
+
return Option.match(Option.fromUndefinedOr(error.response), {
|
|
31
|
+
onNone: () => Effect.logWarning(EXPORT_FAILED, failure),
|
|
32
|
+
onSome: ({ status }) => Effect.logWarning(EXPORT_FAILED, { ...failure, status }),
|
|
33
|
+
});
|
|
34
|
+
})))).pipe(Layer.provide(FetchHttpClient.layer));
|
|
35
|
+
/**
|
|
36
|
+
* Exports every ended span to `tracing.otlpUrl` as OTLP/HTTP protobuf, or keeps Effect's default
|
|
37
|
+
* tracer, which exports nothing, if `tracing` is `None`. Logs which of the two applies, and a
|
|
38
|
+
* warning for each failed export request, with the URL's origin and path only. A failed export,
|
|
39
|
+
* after up to 3 retries, drops the buffered spans and pauses export for 60 seconds. Closing the
|
|
40
|
+
* layer's scope flushes buffered spans for at most 3 seconds. Fails with
|
|
41
|
+
* `ResourceAttributesError` if `tracing` is set and `OTEL_RESOURCE_ATTRIBUTES` is malformed.
|
|
42
|
+
*/
|
|
43
|
+
export const tracingLayer = (tracing) => Option.match(tracing, {
|
|
44
|
+
onNone: () => Layer.effectDiscard(Effect.logInfo("Span export is off; set tracing.otlp_url in usine.yaml to turn it on")),
|
|
45
|
+
onSome: ({ otlpUrl, serviceName }) => Layer.unwrap(Effect.gen(function* () {
|
|
46
|
+
const serviceVersion = yield* packageVersion();
|
|
47
|
+
const attributes = yield* resourceAttributes();
|
|
48
|
+
return OtlpTracer.layer({
|
|
49
|
+
url: otlpUrl.href,
|
|
50
|
+
resource: { serviceName, serviceVersion, attributes },
|
|
51
|
+
}).pipe(
|
|
52
|
+
// `attributes` replaces the resource's own read of OTEL_RESOURCE_ATTRIBUTES, which dies on
|
|
53
|
+
// a malformed value.
|
|
54
|
+
Layer.provide(ConfigProvider.layer(ConfigProvider.fromUnknown({}))), Layer.provide(OtlpSerialization.layerProtobuf), Layer.provide(exportClientLayer(loggedUrl(otlpUrl))), Layer.merge(Layer.effectDiscard(Effect.logInfo("Exporting spans over OTLP", {
|
|
55
|
+
otlpUrl: loggedUrl(otlpUrl),
|
|
56
|
+
serviceName,
|
|
57
|
+
serviceVersion,
|
|
58
|
+
}))));
|
|
59
|
+
})),
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=tracing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracing.js","sourceRoot":"","sources":["../src/tracing.ts"],"names":[],"mappings":"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"}
|
package/dist/up.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
import { type
|
|
3
|
-
export declare const up: (
|
|
2
|
+
import { type UpCommand, VolatileInstanceDirectoryError } from "./cli.ts";
|
|
3
|
+
export declare const up: (command: UpCommand) => Effect.Effect<never, import("@usine/github/github-app").AppAuthenticationError | import("@usine/engine/engine").AttemptCancellationError | import("./cli.ts").CliVersionError | import("@usine/executor").CredentialUnavailableError | import("@usine/durable/harness").DurableHarnessError | import("@usine/engine/engine").EnginePersistenceError | import("@usine/executor").ExecutorOperationError | import("@usine/config/file").FactoryConfigError | import("./instance/id.ts").InstanceIdError | import("./instance/lock.ts").InstanceInUseError | import("./instance/lock.ts").InstanceLockError | import("./cli.ts").PortInUseError | import("./tracing.ts").ResourceAttributesError | import("@usine/engine/engine").RunInterventionRejectedError | import("@usine/engine/engine").RunNotFoundError | import("@usine/engine/engine").RunOperationRejectedError | import("@usine/engine/engine").RunRetryBlockedError | import("./cli.ts").ServerStartError | import("@usine/orchestrator/scheduler").UnsupportedWorkerError | VolatileInstanceDirectoryError | import("@usine/executor").WorkerCapabilityError, import("effect/process/ChildProcessSpawner").ChildProcessSpawner>;
|
|
4
4
|
//# sourceMappingURL=up.d.ts.map
|
package/dist/up.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../src/up.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../src/up.ts"],"names":[],"mappings":"AAcA,OAAO,EAQL,MAAM,EAMP,MAAM,QAAQ,CAAC;AAEhB,OAAO,EAGL,KAAK,SAAS,EACd,8BAA8B,EAQ/B,MAAM,UAAU,CAAC;AAsKlB,eAAO,MAAM,EAAE,YAAa,SAAS,goCAiCwC,CAAC"}
|
package/dist/up.js
CHANGED
|
@@ -8,23 +8,35 @@ import { RunEngine, RunEngineShutdown } from "@usine/engine/engine";
|
|
|
8
8
|
import { MarcbachmannCelLayer } from "@usine/expression/marcbachmann-cel";
|
|
9
9
|
import { GitHubCredentials } from "@usine/github/github-app";
|
|
10
10
|
import { loadLocalCredentials } from "@usine/github/local-secrets";
|
|
11
|
-
import {
|
|
11
|
+
import { CurrentInstance } from "@usine/orchestrator/current-instance";
|
|
12
|
+
import { Operator, OperatorConfiguration, OperatorObservation } from "@usine/orchestrator/operator";
|
|
12
13
|
import { Orchestrator } from "@usine/orchestrator/orchestrator";
|
|
13
|
-
import { operatorObservationLayer, runtimeLayer } from "@usine/orchestrator/
|
|
14
|
-
import { Cause, Console, Context, Duration, Deferred, Effect, FileSystem, Layer, Option, Result, } from "effect";
|
|
14
|
+
import { operatorObservationLayer, runtimeLayer } from "@usine/orchestrator/runtime";
|
|
15
|
+
import { Cause, Config, Console, Context, DateTime, Duration, Deferred, Effect, FileSystem, Layer, Option, References, Result, } from "effect";
|
|
15
16
|
import { liveBackendLayer, needsSetupBackendLayer } from "./backend.js";
|
|
16
|
-
import { VolatileInstanceDirectoryError, openBrowser, serverStartError, volatileRoot, volatileRoots, } from "./cli.js";
|
|
17
|
+
import { VolatileInstanceDirectoryError, openBrowser, packageVersion, portInUse, refuseTakenPort, serverStartError, volatileRoot, volatileRoots, } from "./cli.js";
|
|
17
18
|
import { serverLayer } from "./http.js";
|
|
19
|
+
import { instanceIdOf } from "./instance/id.js";
|
|
20
|
+
import { holdInstance } from "./instance/lock.js";
|
|
21
|
+
import { InstanceRecord, ProcessId, currentLaunch, instanceFiles } from "./instance/record.js";
|
|
22
|
+
import { currentSystemService } from "./instance/systemd.js";
|
|
23
|
+
import { reloadOnHangup } from "./reload-signal.js";
|
|
18
24
|
import { withGracefulShutdown } from "./shutdown.js";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
yield*
|
|
25
|
+
import { warnIfSystemSleeps } from "./system-sleep.js";
|
|
26
|
+
import { tracingLayer } from "./tracing.js";
|
|
27
|
+
const instanceFolderLayer = InstanceFolder.layer.pipe(Layer.provide(ConfigParser.layer.pipe(Layer.provide(MarcbachmannCelLayer))), Layer.provide(NodeServices.layer));
|
|
28
|
+
/** Loads the instance folder and keeps it reloadable. Fails if `usine.yaml` is invalid. */
|
|
29
|
+
const loadInstance = Effect.fn("Server.loadInstance")(function* (directory) {
|
|
30
|
+
const context = yield* Layer.build(instanceFolderLayer);
|
|
31
|
+
const initial = yield* Context.get(context, InstanceFolder).load(directory);
|
|
32
|
+
const current = yield* Layer.build(CurrentInstance.layer(directory, initial).pipe(Layer.provide(Layer.succeedContext(context))));
|
|
33
|
+
return Context.get(current, CurrentInstance);
|
|
34
|
+
});
|
|
35
|
+
// Untraced: a span around a server that never returns would parent every request span.
|
|
36
|
+
const serve = Effect.fnUntraced(function* (options) {
|
|
37
|
+
yield* Layer.build(serverLayer(options.backend, options.webRoot, options.port, options.origin)).pipe(Effect.mapError((error) => serverStartError(options.port, error)), Effect.catchTag("PortInUseError", ({ port }) => portInUse(port)));
|
|
26
38
|
yield* Console.log(options.openSetupPage
|
|
27
|
-
? `usine is
|
|
39
|
+
? `usine is running in setup mode at ${options.url}`
|
|
28
40
|
: `usine is running at ${options.url}`);
|
|
29
41
|
if (options.openSetupPage) {
|
|
30
42
|
yield* openBrowser(options.url).pipe(Effect.tapError((error) => Effect.logWarning("The setup page could not be opened automatically", {
|
|
@@ -37,7 +49,7 @@ const serve = Effect.fn("Server.serve")(function* (options) {
|
|
|
37
49
|
});
|
|
38
50
|
const refuseVolatileInstance = Effect.fn("Server.refuseVolatileInstance")(function* (directory, allowVolatileInstance) {
|
|
39
51
|
const realDirectory = yield* Effect.flatMap(FileSystem.FileSystem, (fileSystem) => fileSystem.realPath(directory)).pipe(Effect.orElseSucceed(() => directory));
|
|
40
|
-
const roots = volatileRoots(
|
|
52
|
+
const roots = volatileRoots(yield* Effect.orDie(Config.option(Config.String("TMPDIR"))));
|
|
41
53
|
const root = Option.orElse(volatileRoot(directory, roots), () => volatileRoot(realDirectory, roots));
|
|
42
54
|
if (Option.isNone(root))
|
|
43
55
|
return;
|
|
@@ -46,10 +58,9 @@ const refuseVolatileInstance = Effect.fn("Server.refuseVolatileInstance")(functi
|
|
|
46
58
|
}
|
|
47
59
|
yield* Effect.logWarning("Instance folder sits under a volatile path; its runtime store is the only copy of run history", { instanceDirectory: directory, root: root.value });
|
|
48
60
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
yield*
|
|
52
|
-
const instance = yield* loadInstance(directory);
|
|
61
|
+
/** Serves setup mode if the GitHub App credentials are absent, otherwise runs the factory. */
|
|
62
|
+
const start = Effect.fnUntraced(function* (directory, instanceId, instances, port, origin) {
|
|
63
|
+
yield* reloadOnHangup(instances);
|
|
53
64
|
const credentials = yield* loadLocalCredentials(directory).pipe(Effect.provide(NodeServices.layer), Effect.result);
|
|
54
65
|
const webRoot = resolve(dirname(fileURLToPath(import.meta.url)), "web");
|
|
55
66
|
const url = `http://127.0.0.1:${port}`;
|
|
@@ -61,12 +72,12 @@ export const up = (port, allowVolatileInstance) => Effect.scoped(Effect.gen(func
|
|
|
61
72
|
instanceDirectory: directory,
|
|
62
73
|
});
|
|
63
74
|
const observationContext = yield* Layer.build(operatorObservationLayer(directory));
|
|
64
|
-
const backend = needsSetupBackendLayer(
|
|
65
|
-
return yield* serve({ backend, webRoot, port, url, openSetupPage: true });
|
|
75
|
+
const backend = needsSetupBackendLayer(instances, error._tag, Context.get(observationContext, OperatorObservation), Context.get(observationContext, OperatorConfiguration));
|
|
76
|
+
return yield* serve({ backend, webRoot, port, origin, url, openSetupPage: true });
|
|
66
77
|
}
|
|
67
78
|
const shutdown = yield* Deferred.make();
|
|
68
79
|
const startup = Effect.gen(function* () {
|
|
69
|
-
const runtime = runtimeLayer(directory,
|
|
80
|
+
const runtime = runtimeLayer(directory, instanceId).pipe(Layer.provide(Layer.succeed(GitHubCredentials, credentials.success)), Layer.provide(Layer.succeed(CurrentInstance, instances)));
|
|
70
81
|
const context = yield* Layer.build(runtime).pipe(Effect.provideService(RunEngineShutdown, shutdown));
|
|
71
82
|
const operator = Context.get(context, Operator);
|
|
72
83
|
const orchestrator = Context.get(context, Orchestrator);
|
|
@@ -74,18 +85,45 @@ export const up = (port, allowVolatileInstance) => Effect.scoped(Effect.gen(func
|
|
|
74
85
|
return {
|
|
75
86
|
drain: engine.drain(),
|
|
76
87
|
running: Effect.raceFirst(serve({
|
|
77
|
-
backend: liveBackendLayer(
|
|
88
|
+
backend: liveBackendLayer(instances, operator, Context.get(context, OperatorConfiguration)),
|
|
78
89
|
webRoot,
|
|
79
90
|
port,
|
|
91
|
+
origin,
|
|
80
92
|
url,
|
|
81
93
|
openSetupPage: false,
|
|
82
|
-
}), orchestrator.run
|
|
94
|
+
}), orchestrator.run.pipe(Effect.tapCause((cause) => Cause.hasInterruptsOnly(cause)
|
|
83
95
|
? Effect.void
|
|
84
96
|
: Effect.logFatal("Trigger streams stopped; shutting the server down", {
|
|
85
97
|
cause,
|
|
86
98
|
})))),
|
|
87
99
|
};
|
|
88
100
|
});
|
|
89
|
-
return yield* withGracefulShutdown(startup, shutdown,
|
|
90
|
-
|
|
101
|
+
return yield* withGracefulShutdown(startup, shutdown, Effect.map(instances.get, ({ config }) => Option.match(config.settings.maxAttemptMinutes, {
|
|
102
|
+
onNone: () => Duration.infinity,
|
|
103
|
+
onSome: Duration.minutes,
|
|
104
|
+
})));
|
|
105
|
+
});
|
|
106
|
+
export const up = (command) => Effect.scoped(Effect.gen(function* () {
|
|
107
|
+
const { port, origin } = command;
|
|
108
|
+
const directory = InstanceDirectory.make(process.cwd());
|
|
109
|
+
yield* refuseVolatileInstance(directory, command.allowVolatileInstance).pipe(Effect.provide(NodeServices.layer));
|
|
110
|
+
const record = new InstanceRecord({
|
|
111
|
+
pid: ProcessId.make(process.pid),
|
|
112
|
+
version: yield* packageVersion().pipe(Effect.provide(NodeServices.layer)),
|
|
113
|
+
startedAt: yield* DateTime.now,
|
|
114
|
+
launch: yield* currentLaunch(command),
|
|
115
|
+
systemdUnit: yield* currentSystemService().pipe(Effect.provide(NodeServices.layer)),
|
|
116
|
+
});
|
|
117
|
+
// Acquired before any store opens and released after every store closes.
|
|
118
|
+
yield* holdInstance(directory, record).pipe(Effect.provide(NodeServices.layer));
|
|
119
|
+
const instanceId = yield* instanceIdOf(instanceFiles(directory)).pipe(Effect.provide(NodeServices.layer));
|
|
120
|
+
yield* refuseTakenPort(port).pipe(Effect.provide(NodeServices.layer));
|
|
121
|
+
if (process.platform === "darwin")
|
|
122
|
+
yield* warnIfSystemSleeps().pipe(Effect.provide(NodeServices.layer));
|
|
123
|
+
const instances = yield* loadInstance(directory);
|
|
124
|
+
const { config } = yield* instances.get;
|
|
125
|
+
// Built before the runtime, so the exporter flushes the runtime's last spans when it closes.
|
|
126
|
+
const tracer = yield* Layer.build(tracingLayer(config.tracing)).pipe(Effect.provide(NodeServices.layer));
|
|
127
|
+
return yield* start(directory, instanceId, instances, port, origin).pipe(Effect.provideContext(tracer));
|
|
128
|
+
})).pipe(Effect.provideService(References.MinimumLogLevel, command.logLevel));
|
|
91
129
|
//# sourceMappingURL=up.js.map
|
package/dist/up.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"up.js","sourceRoot":"","sources":["../src/up.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"up.js","sourceRoot":"","sources":["../src/up.ts"],"names":[],"mappings":"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"}
|