@the-librarian/cli 1.0.0-rc.27 → 1.0.0-rc.29
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/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +44 -0
- package/dist/runtime.js.map +1 -1
- package/dist/server/autoupdate.d.ts +184 -0
- package/dist/server/autoupdate.d.ts.map +1 -0
- package/dist/server/autoupdate.js +794 -0
- package/dist/server/autoupdate.js.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAmB/E,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B;AAID;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,CAAC,CAY7F;AAmXD,wBAAgB,KAAK,IAAI,MAAM,CAyB9B"}
|
package/dist/runtime.js
CHANGED
|
@@ -18,6 +18,7 @@ import { allHarnesses } from "./harnesses/index.js";
|
|
|
18
18
|
import { flagBool, flagString, parseArgs } from "./parse-args.js";
|
|
19
19
|
import { createPrompter, MissingValueError } from "./prompt.js";
|
|
20
20
|
import { runAdmin } from "./server/admin.js";
|
|
21
|
+
import { autoUpdateStatus, disableAutoUpdate, enableAutoUpdate, runAutoUpdate, uninstallAutoUpdate, } from "./server/autoupdate.js";
|
|
21
22
|
import { disableBoot, enableBoot } from "./server/boot.js";
|
|
22
23
|
import { runDown } from "./server/down.js";
|
|
23
24
|
import { serverUsage } from "./server/index.js";
|
|
@@ -184,6 +185,9 @@ async function runServerCommand(rest, options) {
|
|
|
184
185
|
if (subcommand === "disable-boot") {
|
|
185
186
|
return runServerDisableBootCommand(options);
|
|
186
187
|
}
|
|
188
|
+
if (subcommand === "autoupdate") {
|
|
189
|
+
return runServerAutoUpdateCommand(subRest, options);
|
|
190
|
+
}
|
|
187
191
|
if (subcommand === "admin") {
|
|
188
192
|
return runServerAdminCommand(subRest, options);
|
|
189
193
|
}
|
|
@@ -242,6 +246,46 @@ async function runServerDisableBootCommand(options) {
|
|
|
242
246
|
const result = await disableBoot(options.platform ? { platform: options.platform } : {});
|
|
243
247
|
return ok(result.output);
|
|
244
248
|
}
|
|
249
|
+
/**
|
|
250
|
+
* `librarian server autoupdate <enable|disable|uninstall|status> [--cadence …]`
|
|
251
|
+
* and the internal `--run` (T3). `enable` installs a host scheduler (systemd timer
|
|
252
|
+
* / cron fallback) that fires hourly and runs `--run`, plus writes enabled+cadence
|
|
253
|
+
* into the running server (so the dashboard reflects it). `disable` flips the
|
|
254
|
+
* setting off (timer stays). `uninstall` removes the timer/cron. `status` reports
|
|
255
|
+
* timer-installed + the server's enabled/cadence/last-run + up-to-date. `--run` is
|
|
256
|
+
* the wrapper the timer calls: it reads the settings from the running server,
|
|
257
|
+
* applies the due-check, and conditionally runs `server update` — FULLY fail-soft
|
|
258
|
+
* (never throws out of the timer). A real failure on the operator-facing verbs
|
|
259
|
+
* surfaces as one clean stderr line via the top-level catch.
|
|
260
|
+
*/
|
|
261
|
+
async function runServerAutoUpdateCommand(subRest, options) {
|
|
262
|
+
const { positionals, flags } = parseArgs(subRest);
|
|
263
|
+
const platformOpt = options.platform ? { platform: options.platform } : {};
|
|
264
|
+
const base = { home: options.home, dir: flagString(flags.dir), ...platformOpt };
|
|
265
|
+
// `--run` is the timer's wrapper. It is fail-soft by construction (it never
|
|
266
|
+
// throws) and always exits 0 so the timer's unit never fails; its one-line
|
|
267
|
+
// outcome is its stdout.
|
|
268
|
+
if (flagBool(flags.run)) {
|
|
269
|
+
const result = await runAutoUpdate(base);
|
|
270
|
+
return ok(result.output);
|
|
271
|
+
}
|
|
272
|
+
const [verb] = positionals;
|
|
273
|
+
if (verb === "enable") {
|
|
274
|
+
const result = await enableAutoUpdate({ ...base, cadence: flagString(flags.cadence) });
|
|
275
|
+
return ok(result.output);
|
|
276
|
+
}
|
|
277
|
+
if (verb === "disable") {
|
|
278
|
+
return ok((await disableAutoUpdate(base)).output);
|
|
279
|
+
}
|
|
280
|
+
if (verb === "uninstall") {
|
|
281
|
+
return ok((await uninstallAutoUpdate(base)).output);
|
|
282
|
+
}
|
|
283
|
+
if (verb === "status" || verb === undefined) {
|
|
284
|
+
return ok((await autoUpdateStatus(base)).output);
|
|
285
|
+
}
|
|
286
|
+
return err(`Unknown autoupdate subcommand: ${verb}\n\n` +
|
|
287
|
+
"Usage: librarian server autoupdate <enable|disable|uninstall|status> [--cadence daily|weekly]");
|
|
288
|
+
}
|
|
245
289
|
/**
|
|
246
290
|
* `librarian server admin <backup|restore|auth|rebuild> [args…]` (S7a). Runs a
|
|
247
291
|
* curated admin verb inside the running container via
|
package/dist/runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
declare const AUTOUPDATE_CADENCES: readonly ["daily", "weekly"];
|
|
2
|
+
type AutoUpdateCadence = (typeof AUTOUPDATE_CADENCES)[number];
|
|
3
|
+
/** The oneshot service unit that runs the `--run` wrapper (single instance per host). */
|
|
4
|
+
export declare const AUTOUPDATE_SERVICE_NAME = "the-librarian-autoupdate.service";
|
|
5
|
+
/** The timer unit that fires the oneshot service ~hourly. */
|
|
6
|
+
export declare const AUTOUPDATE_TIMER_NAME = "the-librarian-autoupdate.timer";
|
|
7
|
+
/** A stable marker that tags OUR crontab line, so we can find/replace/remove it idempotently. */
|
|
8
|
+
export declare const CRON_MARKER = "# the-librarian-autoupdate";
|
|
9
|
+
/**
|
|
10
|
+
* The substring every OUR systemd unit's `Description=` carries (both the service
|
|
11
|
+
* and the timer descriptions start with it). `uninstall` reads a unit file and
|
|
12
|
+
* confirms this marker BEFORE deleting it (FIX I2) — so a same-named unit a human
|
|
13
|
+
* authored is never `rm`'d out from under them.
|
|
14
|
+
*/
|
|
15
|
+
export declare const UNIT_DESCRIPTION_MARKER = "The Librarian \u2014 auto-update";
|
|
16
|
+
/** The absolute path the oneshot service is installed at (system unit, via sudo). */
|
|
17
|
+
export declare function servicePath(): string;
|
|
18
|
+
/** The absolute path the timer is installed at (system unit, via sudo). */
|
|
19
|
+
export declare function timerPath(): string;
|
|
20
|
+
/** A teaching error from autoupdate ops; the runtime renders `.message` as one stderr line. */
|
|
21
|
+
export declare class AutoUpdateError extends Error {
|
|
22
|
+
constructor(message: string);
|
|
23
|
+
}
|
|
24
|
+
export interface AutoUpdateResult {
|
|
25
|
+
/** Human-readable report for stdout. */
|
|
26
|
+
output: string;
|
|
27
|
+
}
|
|
28
|
+
export interface AutoUpdateOptions {
|
|
29
|
+
/** Platform — gates the macOS deferral + systemd-vs-cron choice. Default `process.platform`. */
|
|
30
|
+
platform?: NodeJS.Platform | undefined;
|
|
31
|
+
/** Override home (tests). Threads into `server update`/`status`. */
|
|
32
|
+
home?: string | undefined;
|
|
33
|
+
/** Deploy dir override. Default: `~/.librarian/server`. Threads into update/status. */
|
|
34
|
+
dir?: string | undefined;
|
|
35
|
+
}
|
|
36
|
+
export interface EnableOptions extends AutoUpdateOptions {
|
|
37
|
+
/** Cadence to write into the running server. Default daily. Validated daily|weekly. */
|
|
38
|
+
cadence?: string | undefined;
|
|
39
|
+
}
|
|
40
|
+
export interface RunOptions extends AutoUpdateOptions {
|
|
41
|
+
/**
|
|
42
|
+
* Sink for the wrapper's one-line log entries (the timer's journal). Defaults
|
|
43
|
+
* to a `process.stderr` writer; tests inject a recorder. Every wrapper outcome
|
|
44
|
+
* (skip / update / failure) emits exactly one line here — and the wrapper never
|
|
45
|
+
* throws, so the timer's unit always exits 0.
|
|
46
|
+
*/
|
|
47
|
+
log?: ((line: string) => void) | undefined;
|
|
48
|
+
/** Health-wait bound for the inner `server update` (small in tests). */
|
|
49
|
+
healthAttempts?: number | undefined;
|
|
50
|
+
/** Milliseconds between health polls for the inner update (0 in tests). */
|
|
51
|
+
healthIntervalMs?: number | undefined;
|
|
52
|
+
/** Injected current time for the due-check (tests). Default `new Date()`. */
|
|
53
|
+
now?: Date | undefined;
|
|
54
|
+
}
|
|
55
|
+
/** Inputs to the pure service generator (only the librarian path — NEVER a secret). */
|
|
56
|
+
export interface ServiceUnitInput {
|
|
57
|
+
/** Absolute path to the `librarian` binary the oneshot runs with `server autoupdate --run`. */
|
|
58
|
+
librarianPath: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generate the oneshot service unit text. PURE + unit-tested. Contains NO secret —
|
|
62
|
+
* it runs `librarian server autoupdate --run`, which reads the settings from the
|
|
63
|
+
* running container itself (via `docker exec`), so nothing sensitive is written
|
|
64
|
+
* into this world-readable unit file. `Type=oneshot` because the wrapper runs to
|
|
65
|
+
* completion each fire (it is the timer's job to schedule, not the service's).
|
|
66
|
+
*/
|
|
67
|
+
export declare function generateServiceUnit(input: ServiceUnitInput): string;
|
|
68
|
+
/**
|
|
69
|
+
* Generate the timer unit text. PURE + unit-tested. Fires the oneshot service
|
|
70
|
+
* roughly hourly (`OnCalendar=hourly`, with `Persistent=true` so a missed fire
|
|
71
|
+
* while the host was off runs at next boot). The FREQUENT fire is deliberate: the
|
|
72
|
+
* cadence (daily/weekly) is a due-check IN the wrapper, NOT the timer period — so
|
|
73
|
+
* the dashboard can change cadence (a setting) with no host action (spec §4). A
|
|
74
|
+
* randomized delay spreads load and avoids every host updating on the exact hour.
|
|
75
|
+
*/
|
|
76
|
+
export declare function generateTimerUnit(): string;
|
|
77
|
+
/**
|
|
78
|
+
* The crontab line for the cron fallback (systemd absent). Fires the wrapper at
|
|
79
|
+
* minute 17 of every hour (off the top-of-hour to spread load), tagged with
|
|
80
|
+
* {@link CRON_MARKER} so it can be found/replaced/removed idempotently. NO secret
|
|
81
|
+
* — same reasoning as the systemd unit (the wrapper reads settings from the
|
|
82
|
+
* container at run time).
|
|
83
|
+
*/
|
|
84
|
+
export declare function cronLine(librarianPath: string): string;
|
|
85
|
+
/** The one-line macOS-deferred notice (boot persistence + autoupdate are Linux-only for now). */
|
|
86
|
+
export declare const MACOS_NOTICE: string;
|
|
87
|
+
/** The configured auto-update state read from the running server. */
|
|
88
|
+
export interface RunningConfig {
|
|
89
|
+
enabled: boolean;
|
|
90
|
+
cadence: AutoUpdateCadence;
|
|
91
|
+
lastRunAt: string | null;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Read the auto-update config from the RUNNING server via `docker exec node -e`
|
|
95
|
+
* (the internal tRPC listener, loopback inside the container). Returns null when
|
|
96
|
+
* the container is down / the exec fails / the response is unusable — the caller
|
|
97
|
+
* treats null as "unreachable" and SKIPS (never auto-updates an unknown server).
|
|
98
|
+
* Never throws.
|
|
99
|
+
*/
|
|
100
|
+
export declare function readRunningConfig(): Promise<RunningConfig | null>;
|
|
101
|
+
/**
|
|
102
|
+
* Write the auto-update config into the RUNNING server (so the dashboard reflects
|
|
103
|
+
* the CLI's enable/cadence) via `docker exec node -e` → internal tRPC `set`.
|
|
104
|
+
* Returns true on success, false when the container is down / the write failed.
|
|
105
|
+
* Never throws — a write failure during `enable` is surfaced as a non-fatal hint
|
|
106
|
+
* (the timer is still installed; the operator can toggle from the dashboard).
|
|
107
|
+
*/
|
|
108
|
+
export declare function writeRunningConfig(input: {
|
|
109
|
+
enabled?: boolean;
|
|
110
|
+
cadence?: AutoUpdateCadence;
|
|
111
|
+
}): Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* Stamp `last_run_at` to NOW in the running server (the internal tRPC `stampRun`)
|
|
114
|
+
* after a SUCCESSFUL auto-update, so the next due-check advances by one cadence
|
|
115
|
+
* window. Returns true on success, false when the (freshly recreated) container
|
|
116
|
+
* isn't reachable yet / the call failed — a failed stamp is non-fatal (the update
|
|
117
|
+
* itself succeeded; the worst case is one extra due-check next fire). Never throws.
|
|
118
|
+
*/
|
|
119
|
+
export declare function stampRunInServer(): Promise<boolean>;
|
|
120
|
+
/**
|
|
121
|
+
* Install the host scheduler + write the enabled/cadence settings into the running
|
|
122
|
+
* server. On Linux with systemd: write the oneshot service + the .timer to
|
|
123
|
+
* `/etc/systemd/system`, `daemon-reload`, then `enable --now` the TIMER (the
|
|
124
|
+
* service is oneshot — only the timer is enabled). Idempotent: re-running rewrites
|
|
125
|
+
* the SAME unit paths and re-enables, never duplicating. Where systemd is absent:
|
|
126
|
+
* install an hourly cron line (idempotent via {@link CRON_MARKER}). On macOS: print
|
|
127
|
+
* the deferred notice and skip cleanly.
|
|
128
|
+
*
|
|
129
|
+
* The settings write (enabled=true + cadence) is best-effort: a down server is a
|
|
130
|
+
* non-fatal hint (the timer is installed; the operator toggles from the dashboard
|
|
131
|
+
* once the server is up). The timer is what makes auto-update actually happen.
|
|
132
|
+
*/
|
|
133
|
+
export declare function enableAutoUpdate(options?: EnableOptions): Promise<AutoUpdateResult>;
|
|
134
|
+
/**
|
|
135
|
+
* Disable auto-update WITHOUT removing the timer (spec §3 SC2): flip
|
|
136
|
+
* `enabled=false` in the running server so the next `--run` no-ops, leaving the
|
|
137
|
+
* timer installed. Idempotent. A down server is a teaching error (we can't flip a
|
|
138
|
+
* setting on a server we can't reach) — the operator can also toggle it off from
|
|
139
|
+
* the dashboard.
|
|
140
|
+
*/
|
|
141
|
+
export declare function disableAutoUpdate(options?: AutoUpdateOptions): Promise<AutoUpdateResult>;
|
|
142
|
+
/**
|
|
143
|
+
* Remove the host scheduler entirely (spec §3 SC2): on systemd, `disable --now`
|
|
144
|
+
* the timer (tolerating "not loaded"), remove BOTH unit files, then
|
|
145
|
+
* `daemon-reload`. Where systemd is absent, strip our tagged crontab line. Safe if
|
|
146
|
+
* already absent — idempotent, never a crash. Does NOT touch the server's
|
|
147
|
+
* `enabled` setting (the timer is gone, so it no longer matters; leaving the
|
|
148
|
+
* setting avoids a needless server round-trip on a down server). On macOS: notice.
|
|
149
|
+
*/
|
|
150
|
+
export declare function uninstallAutoUpdate(options?: AutoUpdateOptions): Promise<AutoUpdateResult>;
|
|
151
|
+
/**
|
|
152
|
+
* Report the auto-update state (spec §3 SC3): is the timer/cron installed?, the
|
|
153
|
+
* server's enabled/cadence/last-run (read from the running server), and the
|
|
154
|
+
* up-to-date badge (reusing `server status`' deployed-vs-latest render). A down
|
|
155
|
+
* server degrades the server-side fields to "unknown (server unreachable)" but
|
|
156
|
+
* still reports the host-side timer state and exits 0.
|
|
157
|
+
*/
|
|
158
|
+
export declare function autoUpdateStatus(options?: AutoUpdateOptions): Promise<AutoUpdateResult>;
|
|
159
|
+
/** The fixed lock path: `~/.librarian/server/.autoupdate.lock` (no root needed). */
|
|
160
|
+
export declare function autoUpdateLockPath(options: {
|
|
161
|
+
home?: string | undefined;
|
|
162
|
+
dir?: string | undefined;
|
|
163
|
+
}): string;
|
|
164
|
+
/**
|
|
165
|
+
* The wrapper the timer/cron fires (spec §3 SC4/SC7). Reads the auto-update
|
|
166
|
+
* settings from the RUNNING server, applies the due-check, and conditionally runs
|
|
167
|
+
* `server update`. FULLY FAIL-SOFT — it NEVER throws (the timer's unit always
|
|
168
|
+
* exits 0); every outcome is one log line:
|
|
169
|
+
*
|
|
170
|
+
* - Server UNREACHABLE → SKIP (never auto-update a server in an unknown state).
|
|
171
|
+
* - NOT (enabled && due) → SKIP (the no-op the disabled/not-due case wants).
|
|
172
|
+
* - enabled && due → run `server update`. On SUCCESS, stamp `last_run_at`
|
|
173
|
+
* (so the next due-check advances). On FAILURE (the update's own health-check
|
|
174
|
+
* rollback left the prior container running), log + do NOT stamp (so the next
|
|
175
|
+
* fire retries).
|
|
176
|
+
*
|
|
177
|
+
* The due-check is computed HOST-SIDE from the config the server returned (so the
|
|
178
|
+
* single source of truth — the core helper's logic — is mirrored here without a
|
|
179
|
+
* second round-trip): enabled AND the cadence has elapsed since `lastRunAt`
|
|
180
|
+
* (never-run → due).
|
|
181
|
+
*/
|
|
182
|
+
export declare function runAutoUpdate(options?: RunOptions): Promise<AutoUpdateResult>;
|
|
183
|
+
export {};
|
|
184
|
+
//# sourceMappingURL=autoupdate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoupdate.d.ts","sourceRoot":"","sources":["../../src/server/autoupdate.ts"],"names":[],"mappings":"AAiEA,QAAA,MAAM,mBAAmB,8BAA+B,CAAC;AACzD,KAAK,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAM9D,yFAAyF;AACzF,eAAO,MAAM,uBAAuB,qCAAqC,CAAC;AAE1E,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,mCAAmC,CAAC;AAKtE,iGAAiG;AACjG,eAAO,MAAM,WAAW,+BAA+B,CAAC;AAExD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,qCAAgC,CAAC;AAQrE,qFAAqF;AACrF,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,+FAA+F;AAC/F,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,GAAG,SAAS,CAAC;IACvC,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,uFAAuF;IACvF,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,iBAAiB;IACtD,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,UAAW,SAAQ,iBAAiB;IACnD;;;;;OAKG;IACH,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IAC3C,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,6EAA6E;IAC7E,GAAG,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;CACxB;AAID,uFAAuF;AACvF,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CA4BnE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAkB1C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAEtD;AAwCD,iGAAiG;AACjG,eAAO,MAAM,YAAY,QAG6D,CAAC;AAgDvF,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAqBvE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,iBAAiB,CAAC;CAC7B,GAAG,OAAO,CAAC,OAAO,CAAC,CASnB;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CASzD;AAiDD;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqD7F;AAgBD;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAmB3B;AAID;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAmC3B;AAkFD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAgDjG;AA+BD,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,GAAG,MAAM,CAGT;AAuFD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,aAAa,CAAC,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8EvF"}
|
|
@@ -0,0 +1,794 @@
|
|
|
1
|
+
// `librarian server autoupdate <enable|disable|uninstall|status|--run>` — the
|
|
2
|
+
// HOST half of the server auto-update feature (spec 2026-06-16-server-autoupdate
|
|
3
|
+
// T3). The server settings + admin tRPC are T1/T2; this is the scheduler that
|
|
4
|
+
// actually performs the update on the host.
|
|
5
|
+
//
|
|
6
|
+
// THE ARCHITECTURAL CONSTRAINT (spec §2). `server update` is host-level: it
|
|
7
|
+
// rebuilds the image and `docker rm`s + recreates the container. A process INSIDE
|
|
8
|
+
// the container cannot recreate its own container (no docker-socket access, by
|
|
9
|
+
// design). So the act of updating MUST run on the host. This module installs a
|
|
10
|
+
// host scheduler (a systemd timer; a cron fallback where systemd is absent) that
|
|
11
|
+
// fires frequently (~hourly) and runs `librarian server autoupdate --run`. The
|
|
12
|
+
// wrapper reads the auto-update settings from the RUNNING server, applies the
|
|
13
|
+
// due-check, and conditionally calls `server update`. The dashboard/CLI only
|
|
14
|
+
// WRITE the settings (enabled, cadence) — never the host action.
|
|
15
|
+
//
|
|
16
|
+
// HOW `--run` READS THE SETTINGS (decision). The settings live in the server's
|
|
17
|
+
// data volume, and the admin tRPC that reads them is served only on the INTERNAL
|
|
18
|
+
// listener (127.0.0.1:3840 inside the container — ADR 0008 P1/P3, no bearer
|
|
19
|
+
// gate), which is NOT published to the host. A named docker volume is not a clean
|
|
20
|
+
// host path either. So the wrapper reaches the settings the SAME way `server
|
|
21
|
+
// admin` reaches in-container state: `docker exec the-librarian node -e <script>`,
|
|
22
|
+
// where the script does a localhost `fetch` of the internal tRPC `autoupdate.get`
|
|
23
|
+
// / `autoupdate.set` from inside the container. This is the cleanest mechanism —
|
|
24
|
+
// it reuses the existing exec seam, needs no published port, and honours ADR
|
|
25
|
+
// 0008's "the socket is the gate" model (the internal listener trusts loopback).
|
|
26
|
+
//
|
|
27
|
+
// FAIL-SOFT (AGENTS.md + spec §3 SC4/SC7). The `--run` wrapper NEVER throws out of
|
|
28
|
+
// the timer: any failure (server unreachable, a non-zero update) is logged on one
|
|
29
|
+
// line and the wrapper exits 0. Server unreachable → SKIP (conservative: never
|
|
30
|
+
// auto-update a server in an unknown state). A successful update stamps
|
|
31
|
+
// `last_run_at`; a FAILED update does NOT stamp it (so the next fire retries) and
|
|
32
|
+
// relies on `server update`'s own health-check rollback to leave the prior
|
|
33
|
+
// container running.
|
|
34
|
+
//
|
|
35
|
+
// Everything privileged routes through the injectable `docker.ts` runner (the
|
|
36
|
+
// same seam boot.ts uses), so tests assert the exact systemctl/crontab/docker
|
|
37
|
+
// argv without a real systemd, cron, or docker.
|
|
38
|
+
import { closeSync, mkdirSync, mkdtempSync, openSync, readFileSync, rmSync, statSync, unlinkSync, writeFileSync, writeSync, } from "node:fs";
|
|
39
|
+
import { tmpdir } from "node:os";
|
|
40
|
+
import path from "node:path";
|
|
41
|
+
import { librarianDir } from "../paths.js";
|
|
42
|
+
import { run, which } from "./docker.js";
|
|
43
|
+
import { redactSecrets } from "./redact.js";
|
|
44
|
+
import { serverStatus } from "./status.js";
|
|
45
|
+
import { CONTAINER_NAME } from "./up.js";
|
|
46
|
+
import { runUpdate, UpdateError } from "./update.js";
|
|
47
|
+
// Cadence constants are defined LOCALLY here, NOT imported from `@librarian/core`, so
|
|
48
|
+
// the public `@the-librarian/cli` stays lightweight — `core` pulls in node-llama-cpp /
|
|
49
|
+
// the embeddings stack, which the CLI must never depend on. The server-side
|
|
50
|
+
// `autoupdate.set` tRPC (which DOES use core) is the authoritative cadence validator;
|
|
51
|
+
// this CLI-side copy is only a pre-touch UX check on `enable`. Keep in sync with
|
|
52
|
+
// `packages/core/src/server-autoupdate-config.ts`.
|
|
53
|
+
const AUTOUPDATE_CADENCES = ["daily", "weekly"];
|
|
54
|
+
const DEFAULT_AUTOUPDATE_CADENCE = "daily";
|
|
55
|
+
function isAutoUpdateCadence(value) {
|
|
56
|
+
return AUTOUPDATE_CADENCES.includes(value);
|
|
57
|
+
}
|
|
58
|
+
/** The oneshot service unit that runs the `--run` wrapper (single instance per host). */
|
|
59
|
+
export const AUTOUPDATE_SERVICE_NAME = "the-librarian-autoupdate.service";
|
|
60
|
+
/** The timer unit that fires the oneshot service ~hourly. */
|
|
61
|
+
export const AUTOUPDATE_TIMER_NAME = "the-librarian-autoupdate.timer";
|
|
62
|
+
/** The system-unit directory (a system timer fires without a login session). */
|
|
63
|
+
const SYSTEMD_SYSTEM_DIR = "/etc/systemd/system";
|
|
64
|
+
/** A stable marker that tags OUR crontab line, so we can find/replace/remove it idempotently. */
|
|
65
|
+
export const CRON_MARKER = "# the-librarian-autoupdate";
|
|
66
|
+
/**
|
|
67
|
+
* The substring every OUR systemd unit's `Description=` carries (both the service
|
|
68
|
+
* and the timer descriptions start with it). `uninstall` reads a unit file and
|
|
69
|
+
* confirms this marker BEFORE deleting it (FIX I2) — so a same-named unit a human
|
|
70
|
+
* authored is never `rm`'d out from under them.
|
|
71
|
+
*/
|
|
72
|
+
export const UNIT_DESCRIPTION_MARKER = "The Librarian — auto-update";
|
|
73
|
+
/** Fallback `librarian` path if `which librarian` can't be resolved (npm global bin). */
|
|
74
|
+
const DEFAULT_LIBRARIAN_PATH = "/usr/local/bin/librarian";
|
|
75
|
+
/** The internal tRPC listener inside the container (ADR 0008 P1 default). */
|
|
76
|
+
const INTERNAL_TRPC_URL = "http://127.0.0.1:3840/trpc";
|
|
77
|
+
/** The absolute path the oneshot service is installed at (system unit, via sudo). */
|
|
78
|
+
export function servicePath() {
|
|
79
|
+
return path.join(SYSTEMD_SYSTEM_DIR, AUTOUPDATE_SERVICE_NAME);
|
|
80
|
+
}
|
|
81
|
+
/** The absolute path the timer is installed at (system unit, via sudo). */
|
|
82
|
+
export function timerPath() {
|
|
83
|
+
return path.join(SYSTEMD_SYSTEM_DIR, AUTOUPDATE_TIMER_NAME);
|
|
84
|
+
}
|
|
85
|
+
/** A teaching error from autoupdate ops; the runtime renders `.message` as one stderr line. */
|
|
86
|
+
export class AutoUpdateError extends Error {
|
|
87
|
+
constructor(message) {
|
|
88
|
+
super(message);
|
|
89
|
+
this.name = "AutoUpdateError";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Generate the oneshot service unit text. PURE + unit-tested. Contains NO secret —
|
|
94
|
+
* it runs `librarian server autoupdate --run`, which reads the settings from the
|
|
95
|
+
* running container itself (via `docker exec`), so nothing sensitive is written
|
|
96
|
+
* into this world-readable unit file. `Type=oneshot` because the wrapper runs to
|
|
97
|
+
* completion each fire (it is the timer's job to schedule, not the service's).
|
|
98
|
+
*/
|
|
99
|
+
export function generateServiceUnit(input) {
|
|
100
|
+
const { librarianPath } = input;
|
|
101
|
+
// The path is validated whitespace/metacharacter-free before it reaches here
|
|
102
|
+
// (see `assertSafeLibrarianPath` in `enableAutoUpdate`), so a bare (unquoted)
|
|
103
|
+
// `ExecStart` token is safe — systemd splits ExecStart on whitespace.
|
|
104
|
+
return [
|
|
105
|
+
"[Unit]",
|
|
106
|
+
"Description=The Librarian — auto-update check (host-scheduled)",
|
|
107
|
+
"After=docker.service",
|
|
108
|
+
"Wants=network-online.target",
|
|
109
|
+
"",
|
|
110
|
+
"[Service]",
|
|
111
|
+
"Type=oneshot",
|
|
112
|
+
// ROOT is required (not a smell): `server update` drives the host docker
|
|
113
|
+
// daemon (build / stop / rm / run) and writes a 0600 deploy env-file under
|
|
114
|
+
// /etc — neither is reachable from an unprivileged unit. We do NOT downgrade
|
|
115
|
+
// the user; instead we add the defense-in-depth knob below.
|
|
116
|
+
// NoNewPrivileges: even running as root, forbid this oneshot from gaining
|
|
117
|
+
// ANY new privileges via setuid/setgid/capabilities on the binaries it execs
|
|
118
|
+
// (docker/git) — an auto-executing root unit should grant no more than it needs.
|
|
119
|
+
"NoNewPrivileges=true",
|
|
120
|
+
// The wrapper reads the auto-update settings from the running container and,
|
|
121
|
+
// if due, performs `server update`. It carries NO secret on this argv: the
|
|
122
|
+
// settings + the container's credentials live in the container, reached via
|
|
123
|
+
// `docker exec` at run time, not baked into this file.
|
|
124
|
+
`ExecStart=${librarianPath} server autoupdate --run`,
|
|
125
|
+
"",
|
|
126
|
+
].join("\n");
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Generate the timer unit text. PURE + unit-tested. Fires the oneshot service
|
|
130
|
+
* roughly hourly (`OnCalendar=hourly`, with `Persistent=true` so a missed fire
|
|
131
|
+
* while the host was off runs at next boot). The FREQUENT fire is deliberate: the
|
|
132
|
+
* cadence (daily/weekly) is a due-check IN the wrapper, NOT the timer period — so
|
|
133
|
+
* the dashboard can change cadence (a setting) with no host action (spec §4). A
|
|
134
|
+
* randomized delay spreads load and avoids every host updating on the exact hour.
|
|
135
|
+
*/
|
|
136
|
+
export function generateTimerUnit() {
|
|
137
|
+
return [
|
|
138
|
+
"[Unit]",
|
|
139
|
+
"Description=The Librarian — auto-update timer (fires the check hourly)",
|
|
140
|
+
"",
|
|
141
|
+
"[Timer]",
|
|
142
|
+
// Hourly poll; the cadence due-check inside the wrapper decides whether to act.
|
|
143
|
+
"OnCalendar=hourly",
|
|
144
|
+
// Run a missed fire (host was off) on next boot rather than skipping the window.
|
|
145
|
+
"Persistent=true",
|
|
146
|
+
// Spread load: fire up to 5 min after the hour rather than exactly on it.
|
|
147
|
+
"RandomizedDelaySec=300",
|
|
148
|
+
`Unit=${AUTOUPDATE_SERVICE_NAME}`,
|
|
149
|
+
"",
|
|
150
|
+
"[Install]",
|
|
151
|
+
"WantedBy=timers.target",
|
|
152
|
+
"",
|
|
153
|
+
].join("\n");
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The crontab line for the cron fallback (systemd absent). Fires the wrapper at
|
|
157
|
+
* minute 17 of every hour (off the top-of-hour to spread load), tagged with
|
|
158
|
+
* {@link CRON_MARKER} so it can be found/replaced/removed idempotently. NO secret
|
|
159
|
+
* — same reasoning as the systemd unit (the wrapper reads settings from the
|
|
160
|
+
* container at run time).
|
|
161
|
+
*/
|
|
162
|
+
export function cronLine(librarianPath) {
|
|
163
|
+
return `17 * * * * ${librarianPath} server autoupdate --run ${CRON_MARKER}`;
|
|
164
|
+
}
|
|
165
|
+
// --- librarian-path resolution -------------------------------------------
|
|
166
|
+
/**
|
|
167
|
+
* Resolve the absolute `librarian` path the scheduler invokes. Goes through the
|
|
168
|
+
* injectable runner (`which librarian`); falls back to the npm-global bin so a
|
|
169
|
+
* non-standard `which` output never breaks unit/cron generation. The path is
|
|
170
|
+
* non-secret, so a fallback is safe.
|
|
171
|
+
*/
|
|
172
|
+
async function resolveLibrarianPath() {
|
|
173
|
+
const resolved = await which("librarian");
|
|
174
|
+
return resolved && resolved.trim().length > 0 ? resolved.trim() : DEFAULT_LIBRARIAN_PATH;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Reject a `librarian` path that isn't safe to interpolate UNQUOTED into a systemd
|
|
178
|
+
* `ExecStart` / a cron line (FIX I1). systemd splits `ExecStart` on whitespace and
|
|
179
|
+
* cron passes the line to `/bin/sh`, so a path containing a space (e.g. an npm
|
|
180
|
+
* prefix under `/home/jane doe/`) or a shell metacharacter would silently break
|
|
181
|
+
* the timer — or worse, inject. Rather than wrap quoting rules around two different
|
|
182
|
+
* grammars, we REJECT at `enable` with a teaching error (the cleanest fix): the
|
|
183
|
+
* resolved binary path must contain none of these characters. The operator then
|
|
184
|
+
* symlinks/installs `librarian` to a clean path and re-runs.
|
|
185
|
+
*/
|
|
186
|
+
function assertSafeLibrarianPath(librarianPath) {
|
|
187
|
+
// Whitespace OR any shell/systemd-significant metacharacter is rejected.
|
|
188
|
+
if (/\s/.test(librarianPath) || /["'`$\\;&|<>(){}*?!#~]/.test(librarianPath)) {
|
|
189
|
+
throw new AutoUpdateError(`The resolved \`librarian\` path is not safe to schedule unquoted:\n ${librarianPath}\n\n` +
|
|
190
|
+
"It contains whitespace or a shell/systemd metacharacter, which would break the " +
|
|
191
|
+
"systemd timer's ExecStart (or the cron line). Install or symlink `librarian` to a " +
|
|
192
|
+
"path with no spaces or special characters (e.g. `/usr/local/bin/librarian`) and " +
|
|
193
|
+
"re-run `librarian server autoupdate enable`.");
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// --- platform helpers ----------------------------------------------------
|
|
197
|
+
/** The one-line macOS-deferred notice (boot persistence + autoupdate are Linux-only for now). */
|
|
198
|
+
export const MACOS_NOTICE = "Host auto-update scheduling is Linux-only for now (systemd timer / cron). " +
|
|
199
|
+
"Skipping — on macOS, run `librarian server update` manually, or schedule it " +
|
|
200
|
+
"yourself (e.g. a launchd agent / cron) to run `librarian server autoupdate --run`.";
|
|
201
|
+
/** True iff host scheduling is unsupported on this platform (macOS for now). */
|
|
202
|
+
function isUnsupportedPlatform(platform) {
|
|
203
|
+
return platform === "darwin";
|
|
204
|
+
}
|
|
205
|
+
/** True iff `systemctl` is on PATH (→ prefer the systemd timer over cron). */
|
|
206
|
+
async function hasSystemd() {
|
|
207
|
+
return (await which("systemctl")) !== null;
|
|
208
|
+
}
|
|
209
|
+
// --- the in-container settings bridge (docker exec node -e) ---------------
|
|
210
|
+
/**
|
|
211
|
+
* A tiny Node script run INSIDE the container (`docker exec the-librarian node -e
|
|
212
|
+
* <script>`) that talks to the internal tRPC listener over loopback. `op` is
|
|
213
|
+
* `get` or `set`; for `set`, `input` is the JSON body. It prints the JSON result
|
|
214
|
+
* to stdout (for `get`) or "ok" (for `set`), and exits non-zero on any failure so
|
|
215
|
+
* the host wrapper can treat an unreachable/erroring server as a skip.
|
|
216
|
+
*
|
|
217
|
+
* Built as a single-line script with no string interpolation of untrusted data
|
|
218
|
+
* (the cadence is validated daily|weekly before it reaches here; enabled is a
|
|
219
|
+
* boolean), so there's no injection surface.
|
|
220
|
+
*/
|
|
221
|
+
function bridgeScript(op, input) {
|
|
222
|
+
const base = `${INTERNAL_TRPC_URL}/autoupdate.${op}`;
|
|
223
|
+
if (op === "get") {
|
|
224
|
+
return (`fetch(${JSON.stringify(base)})` +
|
|
225
|
+
`.then(r=>r.json())` +
|
|
226
|
+
`.then(j=>{if(j.error){process.exit(3)}process.stdout.write(JSON.stringify(j.result.data))})` +
|
|
227
|
+
`.catch(()=>process.exit(2))`);
|
|
228
|
+
}
|
|
229
|
+
// POST mutations (`set` carries a JSON body; `stampRun` takes no input).
|
|
230
|
+
const bodyArg = op === "set" ? `,body:${JSON.stringify(JSON.stringify(input ?? {}))}` : "";
|
|
231
|
+
return (`fetch(${JSON.stringify(base)},{method:"POST",headers:{"content-type":"application/json"}${bodyArg}})` +
|
|
232
|
+
`.then(r=>r.json())` +
|
|
233
|
+
`.then(j=>{if(j.error){process.exit(3)}process.stdout.write("ok")})` +
|
|
234
|
+
`.catch(()=>process.exit(2))`);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Read the auto-update config from the RUNNING server via `docker exec node -e`
|
|
238
|
+
* (the internal tRPC listener, loopback inside the container). Returns null when
|
|
239
|
+
* the container is down / the exec fails / the response is unusable — the caller
|
|
240
|
+
* treats null as "unreachable" and SKIPS (never auto-updates an unknown server).
|
|
241
|
+
* Never throws.
|
|
242
|
+
*/
|
|
243
|
+
export async function readRunningConfig() {
|
|
244
|
+
const result = await run("docker", ["exec", CONTAINER_NAME, "node", "-e", bridgeScript("get")]);
|
|
245
|
+
if (result.code !== 0)
|
|
246
|
+
return null;
|
|
247
|
+
try {
|
|
248
|
+
const parsed = JSON.parse(result.stdout.trim());
|
|
249
|
+
const cadence = typeof parsed.cadence === "string" && isAutoUpdateCadence(parsed.cadence)
|
|
250
|
+
? parsed.cadence
|
|
251
|
+
: DEFAULT_AUTOUPDATE_CADENCE;
|
|
252
|
+
return {
|
|
253
|
+
enabled: parsed.enabled === true,
|
|
254
|
+
cadence,
|
|
255
|
+
lastRunAt: typeof parsed.lastRunAt === "string" ? parsed.lastRunAt : null,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Write the auto-update config into the RUNNING server (so the dashboard reflects
|
|
264
|
+
* the CLI's enable/cadence) via `docker exec node -e` → internal tRPC `set`.
|
|
265
|
+
* Returns true on success, false when the container is down / the write failed.
|
|
266
|
+
* Never throws — a write failure during `enable` is surfaced as a non-fatal hint
|
|
267
|
+
* (the timer is still installed; the operator can toggle from the dashboard).
|
|
268
|
+
*/
|
|
269
|
+
export async function writeRunningConfig(input) {
|
|
270
|
+
const result = await run("docker", [
|
|
271
|
+
"exec",
|
|
272
|
+
CONTAINER_NAME,
|
|
273
|
+
"node",
|
|
274
|
+
"-e",
|
|
275
|
+
bridgeScript("set", input),
|
|
276
|
+
]);
|
|
277
|
+
return result.code === 0;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Stamp `last_run_at` to NOW in the running server (the internal tRPC `stampRun`)
|
|
281
|
+
* after a SUCCESSFUL auto-update, so the next due-check advances by one cadence
|
|
282
|
+
* window. Returns true on success, false when the (freshly recreated) container
|
|
283
|
+
* isn't reachable yet / the call failed — a failed stamp is non-fatal (the update
|
|
284
|
+
* itself succeeded; the worst case is one extra due-check next fire). Never throws.
|
|
285
|
+
*/
|
|
286
|
+
export async function stampRunInServer() {
|
|
287
|
+
const result = await run("docker", [
|
|
288
|
+
"exec",
|
|
289
|
+
CONTAINER_NAME,
|
|
290
|
+
"node",
|
|
291
|
+
"-e",
|
|
292
|
+
bridgeScript("stampRun"),
|
|
293
|
+
]);
|
|
294
|
+
return result.code === 0;
|
|
295
|
+
}
|
|
296
|
+
// --- privileged systemd steps (every one through the injectable runner) ---
|
|
297
|
+
/** Write a unit file to the system path via temp-file + `sudo cp` + `sudo chmod 644`. */
|
|
298
|
+
async function installUnit(name, dest, unit) {
|
|
299
|
+
const dir = mkdtempSync(path.join(tmpdir(), "librarian-autoupdate-unit-"));
|
|
300
|
+
const tmp = path.join(dir, name);
|
|
301
|
+
writeFileSync(tmp, unit, "utf8");
|
|
302
|
+
try {
|
|
303
|
+
await sudoRun(["cp", tmp, dest]);
|
|
304
|
+
await sudoRun(["chmod", "644", dest]);
|
|
305
|
+
}
|
|
306
|
+
finally {
|
|
307
|
+
rmSync(dir, { recursive: true, force: true });
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/** Run `sudo systemctl <args…>`; a non-zero exit is a teaching error. */
|
|
311
|
+
async function sudoSystemctl(args) {
|
|
312
|
+
await sudoRun(["systemctl", ...args]);
|
|
313
|
+
}
|
|
314
|
+
/** Run `sudo <args…>`; a non-zero exit is a teaching error. */
|
|
315
|
+
async function sudoRun(args) {
|
|
316
|
+
const result = await run("sudo", args);
|
|
317
|
+
failIfNonZero("sudo", args, result);
|
|
318
|
+
}
|
|
319
|
+
/** True when a `systemctl disable` failure means the unit simply isn't loaded. */
|
|
320
|
+
function isUnitAbsent(stderr) {
|
|
321
|
+
return /does not exist|not loaded|no such file|not found/i.test(stderr);
|
|
322
|
+
}
|
|
323
|
+
function failIfNonZero(cmd, args, result) {
|
|
324
|
+
if (result.code === 0)
|
|
325
|
+
return;
|
|
326
|
+
const detail = result.stderr.trim() || result.stdout.trim();
|
|
327
|
+
throw new AutoUpdateError(`\`${cmd} ${args[0]}\` failed (exit ${result.code ?? "signal"})` +
|
|
328
|
+
(detail ? `:\n${detail}` : ".") +
|
|
329
|
+
"\n\nResolve the error above (you may need sudo privileges), then re-run the command.");
|
|
330
|
+
}
|
|
331
|
+
// --- enable --------------------------------------------------------------
|
|
332
|
+
/**
|
|
333
|
+
* Install the host scheduler + write the enabled/cadence settings into the running
|
|
334
|
+
* server. On Linux with systemd: write the oneshot service + the .timer to
|
|
335
|
+
* `/etc/systemd/system`, `daemon-reload`, then `enable --now` the TIMER (the
|
|
336
|
+
* service is oneshot — only the timer is enabled). Idempotent: re-running rewrites
|
|
337
|
+
* the SAME unit paths and re-enables, never duplicating. Where systemd is absent:
|
|
338
|
+
* install an hourly cron line (idempotent via {@link CRON_MARKER}). On macOS: print
|
|
339
|
+
* the deferred notice and skip cleanly.
|
|
340
|
+
*
|
|
341
|
+
* The settings write (enabled=true + cadence) is best-effort: a down server is a
|
|
342
|
+
* non-fatal hint (the timer is installed; the operator toggles from the dashboard
|
|
343
|
+
* once the server is up). The timer is what makes auto-update actually happen.
|
|
344
|
+
*/
|
|
345
|
+
export async function enableAutoUpdate(options = {}) {
|
|
346
|
+
const platform = options.platform ?? process.platform;
|
|
347
|
+
if (isUnsupportedPlatform(platform)) {
|
|
348
|
+
return { output: MACOS_NOTICE };
|
|
349
|
+
}
|
|
350
|
+
// Validate the cadence BEFORE touching the host (a bad cadence is a teaching
|
|
351
|
+
// error, not a half-installed timer). Default daily.
|
|
352
|
+
const cadence = resolveCadence(options.cadence);
|
|
353
|
+
const librarianPath = await resolveLibrarianPath();
|
|
354
|
+
// Reject a path that isn't safe to interpolate UNQUOTED into the unit/cron line
|
|
355
|
+
// BEFORE touching the host (a bad path is a teaching error, not a broken timer).
|
|
356
|
+
assertSafeLibrarianPath(librarianPath);
|
|
357
|
+
const lines = [];
|
|
358
|
+
if (await hasSystemd()) {
|
|
359
|
+
await installUnit(AUTOUPDATE_SERVICE_NAME, servicePath(), generateServiceUnit({ librarianPath }));
|
|
360
|
+
await installUnit(AUTOUPDATE_TIMER_NAME, timerPath(), generateTimerUnit());
|
|
361
|
+
// daemon-reload BEFORE enable --now so systemd sees the (possibly rewritten)
|
|
362
|
+
// units. Only the TIMER is enabled (the service is oneshot, fired by the timer).
|
|
363
|
+
await sudoSystemctl(["daemon-reload"]);
|
|
364
|
+
await sudoSystemctl(["enable", "--now", AUTOUPDATE_TIMER_NAME]);
|
|
365
|
+
lines.push(`Auto-update timer installed — ${AUTOUPDATE_TIMER_NAME} fires hourly and runs the due-check.`, ` Units: ${servicePath()} + ${timerPath()} (no secret in either file).`);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
await installCron(librarianPath);
|
|
369
|
+
lines.push("Auto-update cron entry installed — runs the due-check hourly (systemd not found).", ` Tagged \`${CRON_MARKER}\` in your crontab (remove with \`librarian server autoupdate uninstall\`).`);
|
|
370
|
+
}
|
|
371
|
+
// Write the enabled + cadence settings into the running server so the dashboard
|
|
372
|
+
// reflects them. Best-effort — a down server is a hint, not a failure.
|
|
373
|
+
const wrote = await writeRunningConfig({ enabled: true, cadence });
|
|
374
|
+
if (wrote) {
|
|
375
|
+
lines.push(`Enabled auto-update in the running server (cadence: ${cadence}).`);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
lines.push(`Could not reach the running server to set enabled/cadence (is it up?). The timer is ` +
|
|
379
|
+
`installed; enable + set the ${cadence} cadence from the dashboard, or re-run this once ` +
|
|
380
|
+
`the server is up.`);
|
|
381
|
+
}
|
|
382
|
+
return { output: lines.join("\n") };
|
|
383
|
+
}
|
|
384
|
+
/** Validate + default the cadence; a bad value is a teaching error before any host change. */
|
|
385
|
+
function resolveCadence(raw) {
|
|
386
|
+
if (raw === undefined || raw.trim().length === 0)
|
|
387
|
+
return DEFAULT_AUTOUPDATE_CADENCE;
|
|
388
|
+
const c = raw.trim();
|
|
389
|
+
if (!isAutoUpdateCadence(c)) {
|
|
390
|
+
throw new AutoUpdateError(`cadence must be one of ${AUTOUPDATE_CADENCES.join(" | ")}, got '${c}'.`);
|
|
391
|
+
}
|
|
392
|
+
return c;
|
|
393
|
+
}
|
|
394
|
+
// --- disable -------------------------------------------------------------
|
|
395
|
+
/**
|
|
396
|
+
* Disable auto-update WITHOUT removing the timer (spec §3 SC2): flip
|
|
397
|
+
* `enabled=false` in the running server so the next `--run` no-ops, leaving the
|
|
398
|
+
* timer installed. Idempotent. A down server is a teaching error (we can't flip a
|
|
399
|
+
* setting on a server we can't reach) — the operator can also toggle it off from
|
|
400
|
+
* the dashboard.
|
|
401
|
+
*/
|
|
402
|
+
export async function disableAutoUpdate(options = {}) {
|
|
403
|
+
const platform = options.platform ?? process.platform;
|
|
404
|
+
if (isUnsupportedPlatform(platform)) {
|
|
405
|
+
return { output: MACOS_NOTICE };
|
|
406
|
+
}
|
|
407
|
+
const wrote = await writeRunningConfig({ enabled: false });
|
|
408
|
+
if (!wrote) {
|
|
409
|
+
throw new AutoUpdateError("Could not reach the running server to disable auto-update. Is it up " +
|
|
410
|
+
"(`librarian server status`)? You can also toggle auto-update off from the dashboard. " +
|
|
411
|
+
"The host timer is left installed; once disabled, the next fire will no-op.");
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
output: [
|
|
415
|
+
"Auto-update disabled — the setting is off, so the next timer fire will no-op.",
|
|
416
|
+
"The host timer is left installed; remove it entirely with `librarian server autoupdate uninstall`.",
|
|
417
|
+
].join("\n"),
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
// --- uninstall -----------------------------------------------------------
|
|
421
|
+
/**
|
|
422
|
+
* Remove the host scheduler entirely (spec §3 SC2): on systemd, `disable --now`
|
|
423
|
+
* the timer (tolerating "not loaded"), remove BOTH unit files, then
|
|
424
|
+
* `daemon-reload`. Where systemd is absent, strip our tagged crontab line. Safe if
|
|
425
|
+
* already absent — idempotent, never a crash. Does NOT touch the server's
|
|
426
|
+
* `enabled` setting (the timer is gone, so it no longer matters; leaving the
|
|
427
|
+
* setting avoids a needless server round-trip on a down server). On macOS: notice.
|
|
428
|
+
*/
|
|
429
|
+
export async function uninstallAutoUpdate(options = {}) {
|
|
430
|
+
const platform = options.platform ?? process.platform;
|
|
431
|
+
if (isUnsupportedPlatform(platform)) {
|
|
432
|
+
return { output: MACOS_NOTICE };
|
|
433
|
+
}
|
|
434
|
+
if (await hasSystemd()) {
|
|
435
|
+
// disable --now the timer; tolerate "unit does not exist / not loaded".
|
|
436
|
+
const disable = await run("sudo", ["systemctl", "disable", "--now", AUTOUPDATE_TIMER_NAME]);
|
|
437
|
+
if (disable.code !== 0 && !isUnitAbsent(disable.stderr)) {
|
|
438
|
+
failIfNonZero("sudo", ["systemctl", "disable", "--now", AUTOUPDATE_TIMER_NAME], disable);
|
|
439
|
+
}
|
|
440
|
+
// Remove each unit file ONLY after confirming it's ours (FIX I2): a file with
|
|
441
|
+
// our name that a human authored (no Librarian marker) is left untouched with a
|
|
442
|
+
// warning — we never `rm` an unrelated unit out from under the operator.
|
|
443
|
+
const lines = [];
|
|
444
|
+
const removedTimer = await removeOwnedUnit(timerPath(), lines);
|
|
445
|
+
const removedService = await removeOwnedUnit(servicePath(), lines);
|
|
446
|
+
await sudoSystemctl(["daemon-reload"]);
|
|
447
|
+
lines.unshift(removedTimer || removedService
|
|
448
|
+
? "Auto-update timer removed — our unit file(s) deleted and systemd reloaded."
|
|
449
|
+
: "No Librarian auto-update unit files were removed (none of ours were present).");
|
|
450
|
+
lines.push("The server's auto-update setting is untouched; the container itself is unaffected.");
|
|
451
|
+
return { output: lines.join("\n") };
|
|
452
|
+
}
|
|
453
|
+
await removeCron();
|
|
454
|
+
return {
|
|
455
|
+
output: "Auto-update cron entry removed (systemd not found). The container itself is unaffected.",
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Remove a unit file at `unitPath` ONLY if it's ours (FIX I2). Reads it via
|
|
460
|
+
* `sudo cat` (the file is root-owned under /etc/systemd/system) and removes it
|
|
461
|
+
* iff the content carries {@link UNIT_DESCRIPTION_MARKER}. An ABSENT file is a
|
|
462
|
+
* clean no-op (idempotent). A PRESENT file that ISN'T ours is left in place and a
|
|
463
|
+
* one-line warning is appended to `notes` — we never delete an unrelated unit a
|
|
464
|
+
* human installed under the same name. Returns true iff we deleted it.
|
|
465
|
+
*/
|
|
466
|
+
async function removeOwnedUnit(unitPath, notes) {
|
|
467
|
+
const read = await run("sudo", ["cat", unitPath]);
|
|
468
|
+
if (read.code !== 0) {
|
|
469
|
+
// Non-zero `cat` → the file isn't there (already removed / never installed).
|
|
470
|
+
// Idempotent: nothing to remove, no warning.
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
if (!read.stdout.includes(UNIT_DESCRIPTION_MARKER)) {
|
|
474
|
+
notes.push(`Skipped ${unitPath} — a unit with this name exists but is NOT the Librarian ` +
|
|
475
|
+
"auto-update unit (no Librarian marker). Left it untouched; remove it yourself if intended.");
|
|
476
|
+
return false;
|
|
477
|
+
}
|
|
478
|
+
await sudoRun(["rm", "-f", unitPath]);
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
// --- cron fallback (idempotent via CRON_MARKER) --------------------------
|
|
482
|
+
/**
|
|
483
|
+
* Read the current user's crontab. `crontab -l` exits non-zero with "no crontab"
|
|
484
|
+
* when the user has none — that's an empty crontab, not an error. Returns the
|
|
485
|
+
* existing lines (never our marker line duplicated).
|
|
486
|
+
*/
|
|
487
|
+
async function readCrontab() {
|
|
488
|
+
const result = await run("crontab", ["-l"]);
|
|
489
|
+
if (result.code !== 0)
|
|
490
|
+
return []; // "no crontab for <user>" → empty
|
|
491
|
+
return result.stdout.split("\n").filter((l) => l.length > 0);
|
|
492
|
+
}
|
|
493
|
+
/** Install (or refresh) our hourly cron line idempotently — strip any prior marker line first. */
|
|
494
|
+
async function installCron(librarianPath) {
|
|
495
|
+
if ((await which("crontab")) === null) {
|
|
496
|
+
throw new AutoUpdateError("Neither systemd nor crontab was found, so there's no host scheduler to install the " +
|
|
497
|
+
"auto-update timer into. Install systemd or cron, or schedule " +
|
|
498
|
+
"`librarian server autoupdate --run` to run hourly yourself.");
|
|
499
|
+
}
|
|
500
|
+
const kept = (await readCrontab()).filter((l) => !l.includes(CRON_MARKER));
|
|
501
|
+
const next = [...kept, cronLine(librarianPath)].join("\n") + "\n";
|
|
502
|
+
await writeCrontab(next);
|
|
503
|
+
}
|
|
504
|
+
/** Remove our tagged cron line (idempotent — a crontab without it is left as-is). */
|
|
505
|
+
async function removeCron() {
|
|
506
|
+
if ((await which("crontab")) === null)
|
|
507
|
+
return; // nothing could have installed it
|
|
508
|
+
const lines = await readCrontab();
|
|
509
|
+
const kept = lines.filter((l) => !l.includes(CRON_MARKER));
|
|
510
|
+
if (kept.length === lines.length)
|
|
511
|
+
return; // our line wasn't there — nothing to do
|
|
512
|
+
await writeCrontab(kept.length > 0 ? kept.join("\n") + "\n" : "");
|
|
513
|
+
}
|
|
514
|
+
/** Write a crontab via `crontab -` (reads the new content from a temp file on stdin-substitute). */
|
|
515
|
+
async function writeCrontab(content) {
|
|
516
|
+
// `crontab <file>` installs the file as the new crontab. Write to a temp file
|
|
517
|
+
// and hand its path to crontab (the runner has no stdin pipe). NON-SECRET
|
|
518
|
+
// content (the marker line carries no token), so an ordinary temp file is fine.
|
|
519
|
+
const dir = mkdtempSync(path.join(tmpdir(), "librarian-autoupdate-cron-"));
|
|
520
|
+
const file = path.join(dir, "crontab");
|
|
521
|
+
writeFileSync(file, content, "utf8");
|
|
522
|
+
try {
|
|
523
|
+
const result = await run("crontab", [file]);
|
|
524
|
+
failIfNonZero("crontab", [file], result);
|
|
525
|
+
}
|
|
526
|
+
finally {
|
|
527
|
+
rmSync(dir, { recursive: true, force: true });
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
// --- status --------------------------------------------------------------
|
|
531
|
+
/**
|
|
532
|
+
* Report the auto-update state (spec §3 SC3): is the timer/cron installed?, the
|
|
533
|
+
* server's enabled/cadence/last-run (read from the running server), and the
|
|
534
|
+
* up-to-date badge (reusing `server status`' deployed-vs-latest render). A down
|
|
535
|
+
* server degrades the server-side fields to "unknown (server unreachable)" but
|
|
536
|
+
* still reports the host-side timer state and exits 0.
|
|
537
|
+
*/
|
|
538
|
+
export async function autoUpdateStatus(options = {}) {
|
|
539
|
+
const platform = options.platform ?? process.platform;
|
|
540
|
+
if (isUnsupportedPlatform(platform)) {
|
|
541
|
+
return { output: MACOS_NOTICE };
|
|
542
|
+
}
|
|
543
|
+
const timerInstalled = await isTimerInstalled();
|
|
544
|
+
const config = await readRunningConfig();
|
|
545
|
+
const lines = ["The Librarian auto-update:", ""];
|
|
546
|
+
lines.push(` Timer installed: ${timerInstalled ? "yes" : "no"}`);
|
|
547
|
+
if (config) {
|
|
548
|
+
lines.push(` Enabled: ${config.enabled ? "yes" : "no"}`, ` Cadence: ${config.cadence}`, ` Last auto-update: ${config.lastRunAt ?? "never"}`);
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
lines.push(" Enabled: unknown (server unreachable)", " Cadence: unknown (server unreachable)", " Last auto-update: unknown (server unreachable)");
|
|
552
|
+
}
|
|
553
|
+
// Reuse `server status` for the deployed-vs-latest badge (offline-tolerant).
|
|
554
|
+
try {
|
|
555
|
+
const status = await serverStatus({
|
|
556
|
+
...(options.home !== undefined ? { home: options.home } : {}),
|
|
557
|
+
...(options.dir !== undefined ? { dir: options.dir } : {}),
|
|
558
|
+
...(options.platform !== undefined ? { platform: options.platform } : {}),
|
|
559
|
+
});
|
|
560
|
+
lines.push("", status.output);
|
|
561
|
+
}
|
|
562
|
+
catch {
|
|
563
|
+
// A preflight failure (no docker) shouldn't crash `autoupdate status` — the
|
|
564
|
+
// host-timer state above is still useful. Note it and exit 0.
|
|
565
|
+
lines.push("", "(could not read `server status` — is docker installed/running?)");
|
|
566
|
+
}
|
|
567
|
+
if (!timerInstalled) {
|
|
568
|
+
lines.push("", "The host timer is not installed — auto-update won't run even if enabled. " +
|
|
569
|
+
"Install it with `librarian server autoupdate enable`.");
|
|
570
|
+
}
|
|
571
|
+
return { output: lines.join("\n") };
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Is the host timer installed? On systemd, `systemctl list-unit-files <timer>`
|
|
575
|
+
* lists it when the unit file exists; on a cron-only host, our tagged line is
|
|
576
|
+
* present. Both probes go through the injectable runner. Returns false on any
|
|
577
|
+
* failure (a missing scheduler → not installed).
|
|
578
|
+
*/
|
|
579
|
+
async function isTimerInstalled() {
|
|
580
|
+
if (await hasSystemd()) {
|
|
581
|
+
const result = await run("systemctl", ["list-unit-files", AUTOUPDATE_TIMER_NAME]);
|
|
582
|
+
// `list-unit-files <name>` prints the unit line when it exists; exit 0 + the
|
|
583
|
+
// name in stdout is the "installed" signal (exit code alone is unreliable
|
|
584
|
+
// across systemd versions for an absent unit).
|
|
585
|
+
return result.code === 0 && result.stdout.includes(AUTOUPDATE_TIMER_NAME);
|
|
586
|
+
}
|
|
587
|
+
if ((await which("crontab")) === null)
|
|
588
|
+
return false;
|
|
589
|
+
return (await readCrontab()).some((l) => l.includes(CRON_MARKER));
|
|
590
|
+
}
|
|
591
|
+
// --- the exclusive host lock (serialize concurrent updates, FIX C1) ------
|
|
592
|
+
/**
|
|
593
|
+
* After this many milliseconds an unrefreshed lockfile is treated as STALE and
|
|
594
|
+
* reclaimed — a crashed/killed update (the holder never released its lock) must
|
|
595
|
+
* not wedge auto-update forever. `server update` rebuilds + recreates, so a wide
|
|
596
|
+
* margin (1h) is safe: a real in-flight update is far shorter, and a lock older
|
|
597
|
+
* than this is from a dead process, not a slow one.
|
|
598
|
+
*/
|
|
599
|
+
const LOCK_STALE_MS = 60 * 60 * 1000;
|
|
600
|
+
/** The fixed lock path: `~/.librarian/server/.autoupdate.lock` (no root needed). */
|
|
601
|
+
export function autoUpdateLockPath(options) {
|
|
602
|
+
const dir = options.dir ?? path.join(librarianDir(options.home), "server");
|
|
603
|
+
return path.join(dir, ".autoupdate.lock");
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Acquire an EXCLUSIVE host lock so two timer fires (or a fire overlapping a
|
|
607
|
+
* manual `librarian server update`) can never both `docker stop`/`rm`/`run` the
|
|
608
|
+
* same container — a window with NO running container would take the server down
|
|
609
|
+
* (spec SC7). Implemented as an `O_CREAT|O_EXCL` lockfile (atomic on POSIX, no
|
|
610
|
+
* root, no external `flock`): the create succeeds for exactly one caller.
|
|
611
|
+
*
|
|
612
|
+
* Returns the held lock on success, or `null` when another update already holds
|
|
613
|
+
* it (the caller then SKIPS without stamping). A STALE lock (older than
|
|
614
|
+
* {@link LOCK_STALE_MS} — a crashed holder) is reclaimed once, then retried.
|
|
615
|
+
*
|
|
616
|
+
* FAIL-SOFT: any lock-subsystem error (a read-only FS, a permissions problem)
|
|
617
|
+
* throws here and is caught by `runAutoUpdate`'s outer guard, which logs + skips
|
|
618
|
+
* — a lock problem must never crash the timer or leave the server mid-recreate.
|
|
619
|
+
*/
|
|
620
|
+
function acquireUpdateLock(lockPath) {
|
|
621
|
+
// Best-effort: ensure the directory exists (the deploy dir normally does).
|
|
622
|
+
mkdirSync(path.dirname(lockPath), { recursive: true });
|
|
623
|
+
const tryCreate = () => {
|
|
624
|
+
let fd;
|
|
625
|
+
try {
|
|
626
|
+
// O_CREAT|O_EXCL|O_WRONLY → fails with EEXIST if the lockfile already exists.
|
|
627
|
+
fd = openSync(lockPath, "wx");
|
|
628
|
+
}
|
|
629
|
+
catch (error) {
|
|
630
|
+
if (error.code === "EEXIST")
|
|
631
|
+
return null;
|
|
632
|
+
throw error; // a real FS error → fail-soft up in runAutoUpdate
|
|
633
|
+
}
|
|
634
|
+
// Record our pid + acquisition time (debuggable; carries NO secret).
|
|
635
|
+
try {
|
|
636
|
+
writeSync(fd, `${process.pid} ${Date.now()}\n`);
|
|
637
|
+
}
|
|
638
|
+
finally {
|
|
639
|
+
closeSync(fd);
|
|
640
|
+
}
|
|
641
|
+
let released = false;
|
|
642
|
+
return {
|
|
643
|
+
release() {
|
|
644
|
+
if (released)
|
|
645
|
+
return;
|
|
646
|
+
released = true;
|
|
647
|
+
try {
|
|
648
|
+
unlinkSync(lockPath);
|
|
649
|
+
}
|
|
650
|
+
catch {
|
|
651
|
+
// Already gone (e.g. reclaimed as stale elsewhere) — nothing to do.
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
};
|
|
655
|
+
};
|
|
656
|
+
const held = tryCreate();
|
|
657
|
+
if (held)
|
|
658
|
+
return held;
|
|
659
|
+
// The lock exists. If it's STALE (a crashed holder), reclaim it ONCE and retry.
|
|
660
|
+
if (isLockStale(lockPath)) {
|
|
661
|
+
try {
|
|
662
|
+
unlinkSync(lockPath);
|
|
663
|
+
}
|
|
664
|
+
catch {
|
|
665
|
+
// Someone else reclaimed it first — fall through to a single retry anyway.
|
|
666
|
+
}
|
|
667
|
+
return tryCreate(); // null again ⇒ a live holder won the race → skip
|
|
668
|
+
}
|
|
669
|
+
return null; // a live update is in progress → skip
|
|
670
|
+
}
|
|
671
|
+
/** True iff the lockfile is older than {@link LOCK_STALE_MS} (a crashed holder). */
|
|
672
|
+
function isLockStale(lockPath) {
|
|
673
|
+
try {
|
|
674
|
+
// Prefer the timestamp written into the file; fall back to mtime.
|
|
675
|
+
const written = Number.parseInt(readFileSync(lockPath, "utf8").trim().split(/\s+/)[1] ?? "", 10);
|
|
676
|
+
const acquiredAt = Number.isFinite(written) ? written : statSync(lockPath).mtimeMs;
|
|
677
|
+
return Date.now() - acquiredAt >= LOCK_STALE_MS;
|
|
678
|
+
}
|
|
679
|
+
catch {
|
|
680
|
+
return false; // can't read it → don't reclaim (conservative: skip, don't steal)
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
// --- the `--run` wrapper (what the timer calls) --------------------------
|
|
684
|
+
/**
|
|
685
|
+
* The wrapper the timer/cron fires (spec §3 SC4/SC7). Reads the auto-update
|
|
686
|
+
* settings from the RUNNING server, applies the due-check, and conditionally runs
|
|
687
|
+
* `server update`. FULLY FAIL-SOFT — it NEVER throws (the timer's unit always
|
|
688
|
+
* exits 0); every outcome is one log line:
|
|
689
|
+
*
|
|
690
|
+
* - Server UNREACHABLE → SKIP (never auto-update a server in an unknown state).
|
|
691
|
+
* - NOT (enabled && due) → SKIP (the no-op the disabled/not-due case wants).
|
|
692
|
+
* - enabled && due → run `server update`. On SUCCESS, stamp `last_run_at`
|
|
693
|
+
* (so the next due-check advances). On FAILURE (the update's own health-check
|
|
694
|
+
* rollback left the prior container running), log + do NOT stamp (so the next
|
|
695
|
+
* fire retries).
|
|
696
|
+
*
|
|
697
|
+
* The due-check is computed HOST-SIDE from the config the server returned (so the
|
|
698
|
+
* single source of truth — the core helper's logic — is mirrored here without a
|
|
699
|
+
* second round-trip): enabled AND the cadence has elapsed since `lastRunAt`
|
|
700
|
+
* (never-run → due).
|
|
701
|
+
*/
|
|
702
|
+
export async function runAutoUpdate(options = {}) {
|
|
703
|
+
const log = options.log ?? ((line) => void process.stderr.write(`${line}\n`));
|
|
704
|
+
const now = options.now ?? new Date();
|
|
705
|
+
try {
|
|
706
|
+
const config = await readRunningConfig();
|
|
707
|
+
if (!config) {
|
|
708
|
+
const line = "autoupdate: server unreachable — skipping (won't update a server in an unknown state).";
|
|
709
|
+
log(line);
|
|
710
|
+
return { output: line };
|
|
711
|
+
}
|
|
712
|
+
if (!config.enabled) {
|
|
713
|
+
const line = "autoupdate: disabled — skipping.";
|
|
714
|
+
log(line);
|
|
715
|
+
return { output: line };
|
|
716
|
+
}
|
|
717
|
+
if (!isDue(now, config)) {
|
|
718
|
+
const line = `autoupdate: not due yet (cadence: ${config.cadence}, last run: ${config.lastRunAt ?? "never"}) — skipping.`;
|
|
719
|
+
log(line);
|
|
720
|
+
return { output: line };
|
|
721
|
+
}
|
|
722
|
+
// Due + enabled: take the EXCLUSIVE host lock before the actual update so two
|
|
723
|
+
// timer fires (or a fire overlapping a manual `server update`) can never both
|
|
724
|
+
// stop/rm/run the same container — a window with NO running container would
|
|
725
|
+
// take the server down (spec SC7). If another update already holds the lock,
|
|
726
|
+
// SKIP cleanly (do NOT stamp last_run_at — the in-flight update will stamp).
|
|
727
|
+
const lock = acquireUpdateLock(autoUpdateLockPath(options));
|
|
728
|
+
if (!lock) {
|
|
729
|
+
const line = "autoupdate: another update in progress — skipping.";
|
|
730
|
+
log(line);
|
|
731
|
+
return { output: line };
|
|
732
|
+
}
|
|
733
|
+
try {
|
|
734
|
+
const result = await runUpdate({
|
|
735
|
+
...(options.home !== undefined ? { home: options.home } : {}),
|
|
736
|
+
...(options.dir !== undefined ? { dir: options.dir } : {}),
|
|
737
|
+
...(options.healthAttempts !== undefined ? { healthAttempts: options.healthAttempts } : {}),
|
|
738
|
+
...(options.healthIntervalMs !== undefined
|
|
739
|
+
? { healthIntervalMs: options.healthIntervalMs }
|
|
740
|
+
: {}),
|
|
741
|
+
});
|
|
742
|
+
// Stamp last_run_at ONLY on success. The server was recreated, so write the
|
|
743
|
+
// stamp through the (now-fresh) container's internal tRPC. A failed stamp is
|
|
744
|
+
// logged but not fatal — the update itself succeeded.
|
|
745
|
+
const stamped = await stampRunInServer();
|
|
746
|
+
const stampNote = stamped
|
|
747
|
+
? ""
|
|
748
|
+
: " (note: could not stamp last_run_at — will re-check next fire)";
|
|
749
|
+
const line = `autoupdate: updated successfully${stampNote}.`;
|
|
750
|
+
log(line);
|
|
751
|
+
// The inner update's own output (carries an at-most-once fresh token note).
|
|
752
|
+
return { output: `${line}\n${redactSecrets(result.output)}` };
|
|
753
|
+
}
|
|
754
|
+
catch (error) {
|
|
755
|
+
// The update failed — its own health-check rollback left the prior container
|
|
756
|
+
// running. Do NOT stamp last_run_at (so the next fire retries). Log + exit 0.
|
|
757
|
+
const detail = error instanceof UpdateError || error instanceof Error
|
|
758
|
+
? redactSecrets(error.message)
|
|
759
|
+
: String(error);
|
|
760
|
+
const line = `autoupdate: update failed — left the previous server running, did NOT stamp last_run_at (will retry next fire). ${firstLine(detail)}`;
|
|
761
|
+
log(line);
|
|
762
|
+
return { output: line };
|
|
763
|
+
}
|
|
764
|
+
finally {
|
|
765
|
+
// Always release — a held lock that outlives the update would wedge the next
|
|
766
|
+
// fire until the stale-reclaim window elapses.
|
|
767
|
+
lock.release();
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
catch (error) {
|
|
771
|
+
// Belt-and-braces: ANY unexpected throw is swallowed so the timer never fails.
|
|
772
|
+
const detail = error instanceof Error ? redactSecrets(error.message) : String(error);
|
|
773
|
+
const line = `autoupdate: unexpected error — skipping (timer continues). ${firstLine(detail)}`;
|
|
774
|
+
log(line);
|
|
775
|
+
return { output: line };
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
/** The host-side due-check mirroring core's `isAutoUpdateDue` over the fetched config. */
|
|
779
|
+
function isDue(now, config) {
|
|
780
|
+
if (!config.enabled)
|
|
781
|
+
return false;
|
|
782
|
+
if (config.lastRunAt === null)
|
|
783
|
+
return true;
|
|
784
|
+
const last = new Date(config.lastRunAt);
|
|
785
|
+
if (Number.isNaN(last.getTime()))
|
|
786
|
+
return true; // corrupt → treat as never-run
|
|
787
|
+
const days = config.cadence === "weekly" ? 7 : 1;
|
|
788
|
+
return now.getTime() - last.getTime() >= days * 24 * 60 * 60 * 1000;
|
|
789
|
+
}
|
|
790
|
+
/** The first line of a (possibly multi-line) message — keeps the journal entry one line. */
|
|
791
|
+
function firstLine(text) {
|
|
792
|
+
return text.split("\n")[0] ?? "";
|
|
793
|
+
}
|
|
794
|
+
//# sourceMappingURL=autoupdate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoupdate.js","sourceRoot":"","sources":["../../src/server/autoupdate.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** The `server` subcommands, in the order they appear in the surface (§4). */
|
|
2
|
-
export declare const SERVER_SUBCOMMANDS: readonly ["up", "update", "down", "status", "logs", "enable-boot", "disable-boot", "admin"];
|
|
2
|
+
export declare const SERVER_SUBCOMMANDS: readonly ["up", "update", "down", "status", "logs", "enable-boot", "disable-boot", "autoupdate", "admin"];
|
|
3
3
|
export type ServerSubcommand = (typeof SERVER_SUBCOMMANDS)[number];
|
|
4
4
|
/** The `librarian server` command surface (spec §4). */
|
|
5
5
|
export declare function serverUsage(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAYA,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAYA,8EAA8E;AAC9E,eAAO,MAAM,kBAAkB,2GAUrB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,wDAAwD;AACxD,wBAAgB,WAAW,IAAI,MAAM,CAoBpC;AAED,gEAAgE;AAChE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,gBAAgB,CAEzE"}
|
package/dist/server/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export const SERVER_SUBCOMMANDS = [
|
|
|
18
18
|
"logs",
|
|
19
19
|
"enable-boot",
|
|
20
20
|
"disable-boot",
|
|
21
|
+
"autoupdate",
|
|
21
22
|
"admin",
|
|
22
23
|
];
|
|
23
24
|
/** The `librarian server` command surface (spec §4). */
|
|
@@ -36,6 +37,7 @@ export function serverUsage() {
|
|
|
36
37
|
" logs Tail the container logs ([-f] [--service mcp|dashboard|all])",
|
|
37
38
|
" enable-boot Start the server on boot (Linux systemd; macOS deferred)",
|
|
38
39
|
" disable-boot Reverse enable-boot",
|
|
40
|
+
" autoupdate Schedule auto-updates on the host (enable|disable|uninstall|status)",
|
|
39
41
|
" admin Run an admin command in the container (backup|restore|auth|rebuild)",
|
|
40
42
|
"",
|
|
41
43
|
"Run `librarian server <subcommand> --help` for flags (per subcommand).",
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,qBAAqB;AACrB,EAAE;AACF,6EAA6E;AAC7E,qEAAqE;AAErE,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,MAAM;IACN,aAAa;IACb,cAAc;IACd,OAAO;CACC,CAAC;AAIX,wDAAwD;AACxD,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,8CAA8C;QAC9C,EAAE;QACF,wEAAwE;QACxE,wEAAwE;QACxE,EAAE;QACF,cAAc;QACd,yEAAyE;QACzE,2EAA2E;QAC3E,mEAAmE;QACnE,sEAAsE;QACtE,8EAA8E;QAC9E,0EAA0E;QAC1E,qCAAqC;QACrC,qFAAqF;QACrF,EAAE;QACF,wEAAwE;KACzE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,EAAE;AACF,6EAA6E;AAC7E,yEAAyE;AACzE,6EAA6E;AAC7E,+EAA+E;AAC/E,8EAA8E;AAC9E,qBAAqB;AACrB,EAAE;AACF,6EAA6E;AAC7E,qEAAqE;AAErE,8EAA8E;AAC9E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,IAAI;IACJ,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,MAAM;IACN,aAAa;IACb,cAAc;IACd,YAAY;IACZ,OAAO;CACC,CAAC;AAIX,wDAAwD;AACxD,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,8CAA8C;QAC9C,EAAE;QACF,wEAAwE;QACxE,wEAAwE;QACxE,EAAE;QACF,cAAc;QACd,yEAAyE;QACzE,2EAA2E;QAC3E,mEAAmE;QACnE,sEAAsE;QACtE,8EAA8E;QAC9E,0EAA0E;QAC1E,qCAAqC;QACrC,qFAAqF;QACrF,qFAAqF;QACrF,EAAE;QACF,wEAAwE;KACzE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,OAAQ,kBAAwC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC"}
|