crewly 1.20.173 → 1.20.175
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/config/skills/orchestrator/restart-crewly/SKILL.md +11 -23
- package/config/skills/orchestrator/restart-crewly/execute.sh +7 -5
- package/dist/backend/backend/src/constants.d.ts +64 -0
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +64 -0
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts +67 -0
- package/dist/backend/backend/src/controllers/system/system-control.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/system/system-control.controller.js +183 -0
- package/dist/backend/backend/src/controllers/system/system-control.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts +0 -13
- package/dist/backend/backend/src/controllers/system/system.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/system/system.controller.js +0 -87
- package/dist/backend/backend/src/controllers/system/system.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts +7 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +84 -1
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/system.routes.js +4 -2
- package/dist/backend/backend/src/routes/modules/system.routes.js.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js +7 -0
- package/dist/backend/backend/src/services/cloud/mobile-api-relay.service.js.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts +6 -0
- package/dist/backend/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js +32 -1
- package/dist/backend/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts +58 -0
- package/dist/backend/backend/src/services/system/auto-update.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.service.js +128 -52
- package/dist/backend/backend/src/services/system/auto-update.service.js.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.utils.d.ts +7 -0
- package/dist/backend/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
- package/dist/backend/backend/src/services/system/auto-update.utils.js +14 -0
- package/dist/backend/backend/src/services/system/auto-update.utils.js.map +1 -1
- package/dist/backend/backend/src/services/system/restart-replacement.d.ts +78 -0
- package/dist/backend/backend/src/services/system/restart-replacement.d.ts.map +1 -0
- package/dist/backend/backend/src/services/system/restart-replacement.js +109 -0
- package/dist/backend/backend/src/services/system/restart-replacement.js.map +1 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.d.ts +78 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.d.ts.map +1 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.js +171 -0
- package/dist/backend/backend/src/services/system/supervisor-detect.js.map +1 -0
- package/dist/backend/backend/src/services/system/system-control.service.d.ts +337 -0
- package/dist/backend/backend/src/services/system/system-control.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/system/system-control.service.js +574 -0
- package/dist/backend/backend/src/services/system/system-control.service.js.map +1 -0
- package/dist/backend/build-info.json +2 -2
- package/dist/cli/backend/src/constants.d.ts +64 -0
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +64 -0
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts +6 -0
- package/dist/cli/backend/src/services/harness/login-broker.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js +32 -1
- package/dist/cli/backend/src/services/harness/login-broker.service.js.map +1 -1
- package/dist/cli/backend/src/services/system/auto-update.utils.d.ts +7 -0
- package/dist/cli/backend/src/services/system/auto-update.utils.d.ts.map +1 -1
- package/dist/cli/backend/src/services/system/auto-update.utils.js +14 -0
- package/dist/cli/backend/src/services/system/auto-update.utils.js.map +1 -1
- package/frontend/dist/assets/{index-36e85ac8.js → index-0726afab.js} +281 -281
- package/frontend/dist/assets/{index-15501404.css → index-0c5449b5.css} +1 -1
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Who brings the backend back after it exits?
|
|
3
|
+
*
|
|
4
|
+
* The owner's Restart / Upgrade buttons must never leave a machine down, so
|
|
5
|
+
* before exiting the backend needs to know whether something will relaunch
|
|
6
|
+
* it (specs/2026-10-01-upgrade-restart-controls.md):
|
|
7
|
+
*
|
|
8
|
+
* - `crewly start` (the CLI restart loop) respawns the backend when it exits
|
|
9
|
+
* with RESTART_REQUESTED (120). That is the parent in every supported run
|
|
10
|
+
* mode: foreground, the macOS login item (`~/.crewly/crewly-start.command`),
|
|
11
|
+
* the systemd user unit (`crewly.service`) and the desktop app. The outer
|
|
12
|
+
* layer is reported too, because it decides what happens if the CLI itself
|
|
13
|
+
* dies.
|
|
14
|
+
* - PM2 restarts the app on exit by default.
|
|
15
|
+
* - A backend started some other way (directly under systemd or launchd,
|
|
16
|
+
* a bare `node dist/...`) may or may not come back; that is "unknown", and
|
|
17
|
+
* "none" when there is clearly no supervisor at all.
|
|
18
|
+
*
|
|
19
|
+
* Pure: the environment and process lookups are injected.
|
|
20
|
+
*
|
|
21
|
+
* @module services/system/supervisor-detect
|
|
22
|
+
*/
|
|
23
|
+
import { execFileSync } from 'child_process';
|
|
24
|
+
import { SYSTEM_CONTROL_CONSTANTS } from '../../constants.js';
|
|
25
|
+
import { hasRestartSupervisor, readProcessCommandLine } from './auto-update.utils.js';
|
|
26
|
+
/**
|
|
27
|
+
* Whether the environment says we run inside a systemd unit.
|
|
28
|
+
*
|
|
29
|
+
* @param env - Environment
|
|
30
|
+
* @param commandLines - Parent / grandparent command lines
|
|
31
|
+
* @returns True under systemd
|
|
32
|
+
*/
|
|
33
|
+
function isUnderSystemd(env, commandLines) {
|
|
34
|
+
if (env.INVOCATION_ID)
|
|
35
|
+
return true;
|
|
36
|
+
return commandLines.some((c) => !!c && c.includes(SYSTEM_CONTROL_CONSTANTS.SYSTEMD_UNIT));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Whether launchd started us as a job (not via Terminal). launchd sets
|
|
40
|
+
* XPC_SERVICE_NAME to the job label; shells in Terminal get `0` or an
|
|
41
|
+
* `application.*` name.
|
|
42
|
+
*
|
|
43
|
+
* @param env - Environment
|
|
44
|
+
* @param platform - Platform
|
|
45
|
+
* @returns True for a launchd job
|
|
46
|
+
*/
|
|
47
|
+
function isLaunchdJob(env, platform) {
|
|
48
|
+
if (platform !== 'darwin')
|
|
49
|
+
return false;
|
|
50
|
+
const label = env.XPC_SERVICE_NAME;
|
|
51
|
+
return !!label && label !== '0' && !label.startsWith('application.');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Work out what relaunches the backend.
|
|
55
|
+
*
|
|
56
|
+
* @param probe - Environment and process lookups
|
|
57
|
+
* @returns Supervisor info
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```ts
|
|
61
|
+
* detectSupervisor({ env: { CREWLY_RESTART_SUPERVISOR: 'cli-start', INVOCATION_ID: 'x' }, platform: 'linux',
|
|
62
|
+
* parentCommandLine: () => null, grandparentCommandLine: () => null });
|
|
63
|
+
* // { kind: 'crewly-start', outer: 'systemd', willRelaunch: 'yes', ... }
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function detectSupervisor(probe) {
|
|
67
|
+
const { env, platform } = probe;
|
|
68
|
+
let parent;
|
|
69
|
+
let grandparent;
|
|
70
|
+
const readParent = () => (parent === undefined ? (parent = probe.parentCommandLine()) : parent);
|
|
71
|
+
const readGrandparent = () => grandparent === undefined ? (grandparent = probe.grandparentCommandLine()) : grandparent;
|
|
72
|
+
const cliStart = hasRestartSupervisor(env, readParent);
|
|
73
|
+
if (cliStart) {
|
|
74
|
+
const gp = readGrandparent();
|
|
75
|
+
let outer = null;
|
|
76
|
+
if (isUnderSystemd(env, [gp]))
|
|
77
|
+
outer = 'systemd';
|
|
78
|
+
else if (gp && gp.includes(SYSTEM_CONTROL_CONSTANTS.LOGIN_WRAPPER_SCRIPT))
|
|
79
|
+
outer = 'login-wrapper';
|
|
80
|
+
else if (isLaunchdJob(env, platform))
|
|
81
|
+
outer = 'launchd';
|
|
82
|
+
const outerText = outer === 'systemd'
|
|
83
|
+
? ' systemd keeps crewly start itself running.'
|
|
84
|
+
: outer === 'login-wrapper'
|
|
85
|
+
? ` The ${SYSTEM_CONTROL_CONSTANTS.LOGIN_WRAPPER_SCRIPT} login item keeps crewly start itself running.`
|
|
86
|
+
: outer === 'launchd'
|
|
87
|
+
? ' launchd keeps crewly start itself running.'
|
|
88
|
+
: '';
|
|
89
|
+
return {
|
|
90
|
+
kind: 'crewly-start',
|
|
91
|
+
outer,
|
|
92
|
+
willRelaunch: 'yes',
|
|
93
|
+
detail: `crewly start restarts the backend when it exits.${outerText}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// PM2 (the legacy ecosystem.config.js) restarts the app on exit by default.
|
|
97
|
+
if (env.pm_id !== undefined || env.PM2_HOME !== undefined) {
|
|
98
|
+
return {
|
|
99
|
+
kind: 'pm2',
|
|
100
|
+
outer: null,
|
|
101
|
+
willRelaunch: 'yes',
|
|
102
|
+
detail: 'PM2 restarts the backend when it exits.',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const p = readParent();
|
|
106
|
+
if (isUnderSystemd(env, [p])) {
|
|
107
|
+
return {
|
|
108
|
+
kind: 'systemd',
|
|
109
|
+
outer: null,
|
|
110
|
+
willRelaunch: 'unknown',
|
|
111
|
+
detail: 'Runs directly under systemd; it comes back only if the unit has Restart= set.',
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (isLaunchdJob(env, platform)) {
|
|
115
|
+
return {
|
|
116
|
+
kind: 'launchd',
|
|
117
|
+
outer: null,
|
|
118
|
+
willRelaunch: 'unknown',
|
|
119
|
+
detail: 'Runs directly under launchd; it comes back only if the job has KeepAlive set.',
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
if (p === null) {
|
|
123
|
+
return {
|
|
124
|
+
kind: 'unknown',
|
|
125
|
+
outer: null,
|
|
126
|
+
willRelaunch: 'unknown',
|
|
127
|
+
detail: 'Could not tell what started Crewly.',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
kind: 'none',
|
|
132
|
+
outer: null,
|
|
133
|
+
willRelaunch: 'no',
|
|
134
|
+
detail: 'Nothing will relaunch Crewly on its own; a restart starts a new copy before this one exits.',
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Parent pid of a process (POSIX, via `ps`).
|
|
139
|
+
*
|
|
140
|
+
* @param pid - Process id
|
|
141
|
+
* @returns The parent pid, or null
|
|
142
|
+
*/
|
|
143
|
+
export function readParentPid(pid) {
|
|
144
|
+
if (process.platform === 'win32' || !Number.isInteger(pid) || pid <= 1)
|
|
145
|
+
return null;
|
|
146
|
+
try {
|
|
147
|
+
const out = execFileSync('ps', ['-o', 'ppid=', '-p', String(pid)], { encoding: 'utf-8', timeout: 2000 }).trim();
|
|
148
|
+
const ppid = Number.parseInt(out, 10);
|
|
149
|
+
return Number.isInteger(ppid) && ppid > 1 ? ppid : null;
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Detect the supervisor of the running process.
|
|
157
|
+
*
|
|
158
|
+
* @returns Supervisor info
|
|
159
|
+
*/
|
|
160
|
+
export function detectRunningSupervisor() {
|
|
161
|
+
return detectSupervisor({
|
|
162
|
+
env: process.env,
|
|
163
|
+
platform: process.platform,
|
|
164
|
+
parentCommandLine: () => readProcessCommandLine(process.ppid),
|
|
165
|
+
grandparentCommandLine: () => {
|
|
166
|
+
const gp = readParentPid(process.ppid);
|
|
167
|
+
return gp ? readProcessCommandLine(gp) : null;
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=supervisor-detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor-detect.js","sourceRoot":"","sources":["../../../../../../backend/src/services/system/supervisor-detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* System Control Service — the owner's Upgrade and Restart buttons.
|
|
3
|
+
*
|
|
4
|
+
* Jenkins-style "safe restart" for Crewly
|
|
5
|
+
* (specs/2026-10-01-upgrade-restart-controls.md):
|
|
6
|
+
*
|
|
7
|
+
* - **Status.** Running version, latest on npm, install kind, who relaunches
|
|
8
|
+
* the backend, agents mid-turn, and the current / last action.
|
|
9
|
+
* - **Upgrade** (`when: idle | now`). npm global installs only. It reuses the
|
|
10
|
+
* AutoUpdateService install path (same prefix, same npm, same verify), then
|
|
11
|
+
* restarts. A source checkout is refused: it is updated with git.
|
|
12
|
+
* - **Restart** (`when: idle | now`). The graceful drained shutdown, exiting
|
|
13
|
+
* with RESTART_REQUESTED. When nothing is known to relaunch the backend, a
|
|
14
|
+
* detached launcher is started first so the machine never stays down.
|
|
15
|
+
* - **When idle** waits until no agent is mid-turn, capped (30 min), then
|
|
16
|
+
* goes ahead. Asking again with `now` cuts the wait short.
|
|
17
|
+
* - **One at a time.** A second request while one is running is refused,
|
|
18
|
+
* as is any request while a shutdown is already under way.
|
|
19
|
+
* - **Survives the restart.** Progress and outcome are kept in
|
|
20
|
+
* `<crewlyHome>/system-action.json`; the next boot settles the record
|
|
21
|
+
* ("Restarted at …", "Upgraded to x.y.z", or what went wrong), so the
|
|
22
|
+
* dashboard can show it after it reconnects.
|
|
23
|
+
*
|
|
24
|
+
* All I/O goes through {@link SystemControlDeps}.
|
|
25
|
+
*
|
|
26
|
+
* @module services/system/system-control.service
|
|
27
|
+
*/
|
|
28
|
+
import { SYSTEM_CONTROL_CONSTANTS } from '../../constants.js';
|
|
29
|
+
import type { InstallAttempt } from './auto-update.service.js';
|
|
30
|
+
import type { InstallInfo } from './auto-update.utils.js';
|
|
31
|
+
import type { SupervisorInfo } from './supervisor-detect.js';
|
|
32
|
+
/** `when` choice of the buttons. */
|
|
33
|
+
export type SystemActionWhen = (typeof SYSTEM_CONTROL_CONSTANTS.WHEN_VALUES)[number];
|
|
34
|
+
/** Which button was pressed. */
|
|
35
|
+
export type SystemActionKind = 'upgrade' | 'restart';
|
|
36
|
+
/** Where an action is. */
|
|
37
|
+
export type SystemActionStatus = 'waiting-idle' | 'installing' | 'restarting' | 'completed' | 'failed' | 'interrupted';
|
|
38
|
+
/** Install kind as the dashboard sees it. */
|
|
39
|
+
export type PublicInstallKind = 'npm-global' | 'dev-checkout' | 'other';
|
|
40
|
+
/** How the backend comes back after it exits. */
|
|
41
|
+
export type RelaunchMethod = 'supervisor' | 'replacement';
|
|
42
|
+
/** One upgrade or restart, persisted across the restart. */
|
|
43
|
+
export interface SystemActionRecord {
|
|
44
|
+
id: string;
|
|
45
|
+
kind: SystemActionKind;
|
|
46
|
+
when: SystemActionWhen;
|
|
47
|
+
status: SystemActionStatus;
|
|
48
|
+
/** Who pressed it (e.g. `dashboard from 192.168.1.20`) */
|
|
49
|
+
requestedBy: string;
|
|
50
|
+
requestedAt: string;
|
|
51
|
+
updatedAt: string;
|
|
52
|
+
/** Version running when requested */
|
|
53
|
+
fromVersion: string | null;
|
|
54
|
+
/** Upgrade target */
|
|
55
|
+
toVersion: string | null;
|
|
56
|
+
/** Process that accepted the request */
|
|
57
|
+
pid: number;
|
|
58
|
+
/** How the backend is brought back */
|
|
59
|
+
relaunch: RelaunchMethod | null;
|
|
60
|
+
/** Owner-readable progress / outcome */
|
|
61
|
+
message: string;
|
|
62
|
+
/** Agents mid-turn the last time the idle wait looked */
|
|
63
|
+
waitingFor?: string[];
|
|
64
|
+
/** When the idle wait ended and why */
|
|
65
|
+
idleWaitEndedBy?: 'idle' | 'cap' | 'now';
|
|
66
|
+
/** Settled at (completed / failed / interrupted) */
|
|
67
|
+
completedAt?: string;
|
|
68
|
+
/** Version running when settled */
|
|
69
|
+
resultVersion?: string | null;
|
|
70
|
+
}
|
|
71
|
+
/** An agent mid-turn. */
|
|
72
|
+
export interface BusyAgentInfo {
|
|
73
|
+
session: string;
|
|
74
|
+
since?: string;
|
|
75
|
+
messagePreview?: string;
|
|
76
|
+
}
|
|
77
|
+
/** `GET /api/system/update-status` body. */
|
|
78
|
+
export interface UpdateStatus {
|
|
79
|
+
currentVersion: string | null;
|
|
80
|
+
latestVersion: string | null;
|
|
81
|
+
updateAvailable: boolean;
|
|
82
|
+
installKind: PublicInstallKind;
|
|
83
|
+
packageRoot: string | null;
|
|
84
|
+
/** Upgrade possible right now */
|
|
85
|
+
canUpgrade: boolean;
|
|
86
|
+
/** Why the Upgrade button is disabled (null when enabled) */
|
|
87
|
+
upgradeBlockedReason: string | null;
|
|
88
|
+
/** Restart possible right now */
|
|
89
|
+
canRestart: boolean;
|
|
90
|
+
/** Why the Restart button is disabled (null when enabled) */
|
|
91
|
+
restartBlockedReason: string | null;
|
|
92
|
+
supervisor: SupervisorInfo;
|
|
93
|
+
relaunch: RelaunchMethod;
|
|
94
|
+
/** Agents mid-turn now */
|
|
95
|
+
busyAgents: BusyAgentInfo[];
|
|
96
|
+
/** Some upgrade / restart / shutdown is under way */
|
|
97
|
+
inProgress: boolean;
|
|
98
|
+
/** Current or last action */
|
|
99
|
+
action: SystemActionRecord | null;
|
|
100
|
+
/** Changes on every boot; the dashboard uses it to see the backend came back */
|
|
101
|
+
bootId: string;
|
|
102
|
+
startedAt: string;
|
|
103
|
+
}
|
|
104
|
+
/** Refusal from a request. */
|
|
105
|
+
export interface SystemActionRefusal {
|
|
106
|
+
ok: false;
|
|
107
|
+
httpStatus: number;
|
|
108
|
+
code: string;
|
|
109
|
+
error: string;
|
|
110
|
+
}
|
|
111
|
+
/** Accepted request. */
|
|
112
|
+
export interface SystemActionAccepted {
|
|
113
|
+
ok: true;
|
|
114
|
+
action: SystemActionRecord;
|
|
115
|
+
/** True when an "idle" wait was cut short by a later "now" */
|
|
116
|
+
escalated?: boolean;
|
|
117
|
+
}
|
|
118
|
+
/** The install half the service borrows from AutoUpdateService. */
|
|
119
|
+
export interface UpgradeInstaller {
|
|
120
|
+
installVersion(version: string): Promise<InstallAttempt>;
|
|
121
|
+
writeUpgradeMarker(fromVersion: string, toVersion: string): void;
|
|
122
|
+
clearUpgradeMarker(): void;
|
|
123
|
+
isBusy(): boolean;
|
|
124
|
+
appendLogLine(line: string): void;
|
|
125
|
+
}
|
|
126
|
+
/** Minimal logger. */
|
|
127
|
+
export interface SystemControlLogger {
|
|
128
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
129
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
130
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
131
|
+
}
|
|
132
|
+
/** Everything the service touches outside itself. */
|
|
133
|
+
export interface SystemControlDeps {
|
|
134
|
+
crewlyHome: string;
|
|
135
|
+
install: InstallInfo;
|
|
136
|
+
currentVersion: string | null;
|
|
137
|
+
pid: number;
|
|
138
|
+
bootId: string;
|
|
139
|
+
startedAt: string;
|
|
140
|
+
/** Who relaunches the backend (evaluated when needed) */
|
|
141
|
+
getSupervisor: () => SupervisorInfo;
|
|
142
|
+
/** Latest version on npm, accepting a cached answer younger than maxAgeMs */
|
|
143
|
+
fetchLatestVersion: (maxAgeMs: number) => Promise<string | null>;
|
|
144
|
+
/** Agents mid-turn */
|
|
145
|
+
getBusyAgents: () => BusyAgentInfo[];
|
|
146
|
+
/** A shutdown / drain is already under way */
|
|
147
|
+
isShutdownInProgress: () => boolean;
|
|
148
|
+
/** The AutoUpdateService install path (null when it did not start) */
|
|
149
|
+
getInstaller: () => UpgradeInstaller | null;
|
|
150
|
+
/** Run the graceful drained shutdown with RESTART_REQUESTED; false when no handler */
|
|
151
|
+
requestGracefulRestart: (reason: string) => boolean;
|
|
152
|
+
/** Last resort when no graceful handler exists */
|
|
153
|
+
exit: (code: number) => void;
|
|
154
|
+
/** Start the detached launcher that brings the backend back */
|
|
155
|
+
spawnReplacement: (supervisorUnknown: boolean) => void;
|
|
156
|
+
logger: SystemControlLogger;
|
|
157
|
+
now: () => number;
|
|
158
|
+
sleep: (ms: number) => Promise<void>;
|
|
159
|
+
}
|
|
160
|
+
/** Options for the two requests. */
|
|
161
|
+
export interface SystemActionRequest {
|
|
162
|
+
when: SystemActionWhen;
|
|
163
|
+
actor: string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Map the AutoUpdate install kind onto the public one.
|
|
167
|
+
*
|
|
168
|
+
* @param install - Install info
|
|
169
|
+
* @returns Public kind
|
|
170
|
+
*/
|
|
171
|
+
export declare function toPublicInstallKind(install: InstallInfo): PublicInstallKind;
|
|
172
|
+
/**
|
|
173
|
+
* Read the persisted action record.
|
|
174
|
+
*
|
|
175
|
+
* @param file - State file
|
|
176
|
+
* @returns The record, or null when missing / malformed
|
|
177
|
+
*/
|
|
178
|
+
export declare function readActionRecord(file: string): SystemActionRecord | null;
|
|
179
|
+
/**
|
|
180
|
+
* Write the action record atomically.
|
|
181
|
+
*
|
|
182
|
+
* @param file - State file
|
|
183
|
+
* @param record - Record
|
|
184
|
+
*/
|
|
185
|
+
export declare function writeActionRecord(file: string, record: SystemActionRecord): void;
|
|
186
|
+
/**
|
|
187
|
+
* Upgrade / restart controller for the running backend.
|
|
188
|
+
*/
|
|
189
|
+
export declare class SystemControlService {
|
|
190
|
+
private readonly deps;
|
|
191
|
+
private static instance;
|
|
192
|
+
private action;
|
|
193
|
+
private readonly stateFile;
|
|
194
|
+
/** Resolves the current idle wait early ("now" pressed while waiting) */
|
|
195
|
+
private cutIdleWaitShort;
|
|
196
|
+
/**
|
|
197
|
+
* @param deps - Injected I/O
|
|
198
|
+
*/
|
|
199
|
+
constructor(deps: SystemControlDeps);
|
|
200
|
+
/**
|
|
201
|
+
* Register the process-wide instance.
|
|
202
|
+
*
|
|
203
|
+
* @param service - Instance, or null to clear
|
|
204
|
+
*/
|
|
205
|
+
static setInstance(service: SystemControlService | null): void;
|
|
206
|
+
/**
|
|
207
|
+
* The process-wide instance, when the server registered one.
|
|
208
|
+
*
|
|
209
|
+
* @returns The instance or null
|
|
210
|
+
*/
|
|
211
|
+
static getInstance(): SystemControlService | null;
|
|
212
|
+
/**
|
|
213
|
+
* Boot: settle the record a previous process left behind, so the
|
|
214
|
+
* dashboard can say "Restarted at …" / "Upgraded to x.y.z" after it
|
|
215
|
+
* reconnects.
|
|
216
|
+
*/
|
|
217
|
+
handleBoot(): void;
|
|
218
|
+
/**
|
|
219
|
+
* Whether an upgrade or restart from this process is still running.
|
|
220
|
+
*
|
|
221
|
+
* @returns True while one is
|
|
222
|
+
*/
|
|
223
|
+
isActionInProgress(): boolean;
|
|
224
|
+
/**
|
|
225
|
+
* The current or last action (this boot, or the one settled at boot).
|
|
226
|
+
*
|
|
227
|
+
* @returns The record or null
|
|
228
|
+
*/
|
|
229
|
+
getAction(): SystemActionRecord | null;
|
|
230
|
+
/**
|
|
231
|
+
* How the backend comes back after an exit.
|
|
232
|
+
*
|
|
233
|
+
* @param supervisor - Supervisor info
|
|
234
|
+
* @returns supervisor or replacement
|
|
235
|
+
*/
|
|
236
|
+
private relaunchMethod;
|
|
237
|
+
/**
|
|
238
|
+
* Status for the dashboard.
|
|
239
|
+
*
|
|
240
|
+
* @param options - `refresh` re-asks the registry when the cached answer is over a minute old
|
|
241
|
+
* @returns Status
|
|
242
|
+
*/
|
|
243
|
+
getStatus(options?: {
|
|
244
|
+
refresh?: boolean;
|
|
245
|
+
}): Promise<UpdateStatus>;
|
|
246
|
+
/**
|
|
247
|
+
* Why nothing new can start right now (null when it can).
|
|
248
|
+
*
|
|
249
|
+
* @returns Owner-readable reason or null
|
|
250
|
+
*/
|
|
251
|
+
private inProgressReason;
|
|
252
|
+
/**
|
|
253
|
+
* Busy agents, never throwing.
|
|
254
|
+
*
|
|
255
|
+
* @returns Agents mid-turn
|
|
256
|
+
*/
|
|
257
|
+
private safeBusyAgents;
|
|
258
|
+
/**
|
|
259
|
+
* Escalate a running "when idle" wait of the same kind to "now".
|
|
260
|
+
*
|
|
261
|
+
* @param kind - Requested kind
|
|
262
|
+
* @param request - Request
|
|
263
|
+
* @returns Accepted answer, or null when this is not an escalation
|
|
264
|
+
*/
|
|
265
|
+
private tryEscalate;
|
|
266
|
+
/**
|
|
267
|
+
* Refusal for "something is already running", or null.
|
|
268
|
+
*
|
|
269
|
+
* @returns Refusal or null
|
|
270
|
+
*/
|
|
271
|
+
private busyRefusal;
|
|
272
|
+
/**
|
|
273
|
+
* Owner pressed "Upgrade".
|
|
274
|
+
*
|
|
275
|
+
* @param request - When, and who
|
|
276
|
+
* @returns Accepted (work continues in the background) or a refusal
|
|
277
|
+
*/
|
|
278
|
+
requestUpgrade(request: SystemActionRequest): Promise<SystemActionAccepted | SystemActionRefusal>;
|
|
279
|
+
/**
|
|
280
|
+
* Owner pressed "Restart".
|
|
281
|
+
*
|
|
282
|
+
* @param request - When, and who
|
|
283
|
+
* @returns Accepted (work continues in the background) or a refusal
|
|
284
|
+
*/
|
|
285
|
+
requestRestart(request: SystemActionRequest): Promise<SystemActionAccepted | SystemActionRefusal>;
|
|
286
|
+
/**
|
|
287
|
+
* Create and persist a new action.
|
|
288
|
+
*
|
|
289
|
+
* @param kind - upgrade or restart
|
|
290
|
+
* @param request - Request
|
|
291
|
+
* @param toVersion - Upgrade target
|
|
292
|
+
* @returns The record
|
|
293
|
+
*/
|
|
294
|
+
private begin;
|
|
295
|
+
/**
|
|
296
|
+
* Upgrade body: (wait for idle) → install → verify → marker → restart.
|
|
297
|
+
*
|
|
298
|
+
* @param installer - AutoUpdate install path
|
|
299
|
+
* @param version - Target
|
|
300
|
+
*/
|
|
301
|
+
private runUpgrade;
|
|
302
|
+
/**
|
|
303
|
+
* Restart body: (wait for idle) → restart.
|
|
304
|
+
*/
|
|
305
|
+
private runRestart;
|
|
306
|
+
/**
|
|
307
|
+
* Make sure something brings the backend back, then run the graceful
|
|
308
|
+
* restart.
|
|
309
|
+
*
|
|
310
|
+
* @param reason - Shutdown reason (logs)
|
|
311
|
+
* @param message - Owner-readable progress
|
|
312
|
+
* @returns False when the restart could not be started
|
|
313
|
+
*/
|
|
314
|
+
private restartNow;
|
|
315
|
+
/**
|
|
316
|
+
* Wait until no agent is mid-turn, at most IDLE_WAIT_CAP_MS; a later "now"
|
|
317
|
+
* request ends the wait at once.
|
|
318
|
+
*/
|
|
319
|
+
private waitForIdle;
|
|
320
|
+
/**
|
|
321
|
+
* Mark the current action failed.
|
|
322
|
+
*
|
|
323
|
+
* @param message - Owner-readable reason
|
|
324
|
+
*/
|
|
325
|
+
private fail;
|
|
326
|
+
/**
|
|
327
|
+
* Merge a patch into the current action and persist it.
|
|
328
|
+
*
|
|
329
|
+
* @param patch - Fields to change
|
|
330
|
+
*/
|
|
331
|
+
private update;
|
|
332
|
+
/**
|
|
333
|
+
* Write the current action (best-effort).
|
|
334
|
+
*/
|
|
335
|
+
private persist;
|
|
336
|
+
}
|
|
337
|
+
//# sourceMappingURL=system-control.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-control.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/system/system-control.service.ts"],"names":[],"mappings":"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"}
|