4runr-os 2.10.9 → 2.10.13
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/apps/gateway/dist/apps/gateway/src/db/docker-manager.d.ts +1 -0
- package/apps/gateway/dist/apps/gateway/src/db/docker-manager.d.ts.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/db/docker-manager.js +22 -2
- package/apps/gateway/dist/apps/gateway/src/db/docker-manager.js.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/db/init.d.ts.map +1 -1
- package/apps/gateway/dist/apps/gateway/src/db/init.js +8 -0
- package/apps/gateway/dist/apps/gateway/src/db/init.js.map +1 -1
- package/apps/gateway/package-lock.json +13 -13
- package/apps/gateway/src/db/docker-manager.ts +26 -3
- package/apps/gateway/src/db/init.ts +299 -289
- package/apps/gateway/src/health/index.ts +268 -268
- package/dist/boot-sequence.d.ts +24 -0
- package/dist/boot-sequence.d.ts.map +1 -0
- package/dist/boot-sequence.js +188 -0
- package/dist/boot-sequence.js.map +1 -0
- package/dist/index.js +52 -6
- package/dist/index.js.map +1 -1
- package/dist/tui-handlers.js +3 -3
- package/dist/tui-handlers.js.map +1 -1
- package/dist/version-check.d.ts.map +1 -1
- package/dist/version-check.js +71 -25
- package/dist/version-check.js.map +1 -1
- package/dist/watchdog.d.ts +13 -0
- package/dist/watchdog.d.ts.map +1 -0
- package/dist/watchdog.js +192 -0
- package/dist/watchdog.js.map +1 -0
- package/mk3-tui/src/ui/portal_monitoring.rs +259 -259
- package/package.json +2 -2
- package/prisma/schema.prisma +470 -470
- package/scripts/postinstall-gateway.js +63 -63
package/dist/watchdog.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Watchdog process that monitors 4r and cleans up Docker containers on ANY exit
|
|
3
|
+
* Runs detached and polls the parent process, stopping containers when parent dies
|
|
4
|
+
*/
|
|
5
|
+
import { execSync, spawn } from 'child_process';
|
|
6
|
+
import * as fs from 'fs';
|
|
7
|
+
import * as os from 'os';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
const WATCHDOG_PID_FILE = '4runr-watchdog.pid';
|
|
10
|
+
const PARENT_PID_FILE = '4runr-parent.pid';
|
|
11
|
+
function getWatchdogPidPath() {
|
|
12
|
+
return path.join(os.tmpdir(), WATCHDOG_PID_FILE);
|
|
13
|
+
}
|
|
14
|
+
function getParentPidPath() {
|
|
15
|
+
return path.join(os.tmpdir(), PARENT_PID_FILE);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Check if a process is running
|
|
19
|
+
*/
|
|
20
|
+
function isProcessRunning(pid) {
|
|
21
|
+
try {
|
|
22
|
+
process.kill(pid, 0); // Signal 0 just checks if process exists
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Stop Docker containers (works even if Docker compose file unavailable)
|
|
31
|
+
*/
|
|
32
|
+
function stopContainers() {
|
|
33
|
+
try {
|
|
34
|
+
if (process.platform === 'win32') {
|
|
35
|
+
execSync('docker stop 4runr-postgres 4runr-redis 2>nul', {
|
|
36
|
+
stdio: 'pipe',
|
|
37
|
+
timeout: 15000,
|
|
38
|
+
windowsHide: true,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
execSync('docker stop 4runr-postgres 4runr-redis 2>/dev/null || true', {
|
|
43
|
+
stdio: 'pipe',
|
|
44
|
+
timeout: 15000,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
// Containers might not exist or Docker unavailable
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Kill any autostarted Gateway process
|
|
54
|
+
*/
|
|
55
|
+
function killGateway() {
|
|
56
|
+
const gatewayPidPath = path.join(os.tmpdir(), '4runr-os-local-gateway.pid');
|
|
57
|
+
try {
|
|
58
|
+
if (fs.existsSync(gatewayPidPath)) {
|
|
59
|
+
const pid = parseInt(fs.readFileSync(gatewayPidPath, 'utf-8').trim(), 10);
|
|
60
|
+
if (pid > 0 && isProcessRunning(pid)) {
|
|
61
|
+
try {
|
|
62
|
+
process.kill(pid, 'SIGTERM');
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// ignore
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
fs.unlinkSync(gatewayPidPath);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// ignore
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Start watchdog process (detached, survives parent exit)
|
|
77
|
+
*/
|
|
78
|
+
export function startWatchdog(parentPid) {
|
|
79
|
+
// Kill any existing watchdog
|
|
80
|
+
const existingWatchdogPid = getWatchdogPidPath();
|
|
81
|
+
if (fs.existsSync(existingWatchdogPid)) {
|
|
82
|
+
try {
|
|
83
|
+
const pid = parseInt(fs.readFileSync(existingWatchdogPid, 'utf-8').trim(), 10);
|
|
84
|
+
if (pid > 0 && isProcessRunning(pid)) {
|
|
85
|
+
process.kill(pid, 'SIGTERM');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// ignore
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Write parent PID for watchdog to monitor
|
|
93
|
+
fs.writeFileSync(getParentPidPath(), String(parentPid), 'utf-8');
|
|
94
|
+
// Spawn detached watchdog process
|
|
95
|
+
const watchdogScript = `
|
|
96
|
+
const fs = require('fs');
|
|
97
|
+
const os = require('os');
|
|
98
|
+
const path = require('path');
|
|
99
|
+
const { execSync } = require('child_process');
|
|
100
|
+
|
|
101
|
+
const parentPidPath = path.join(os.tmpdir(), '${PARENT_PID_FILE}');
|
|
102
|
+
const watchdogPidPath = path.join(os.tmpdir(), '${WATCHDOG_PID_FILE}');
|
|
103
|
+
|
|
104
|
+
// Write our own PID
|
|
105
|
+
fs.writeFileSync(watchdogPidPath, String(process.pid), 'utf-8');
|
|
106
|
+
|
|
107
|
+
function isRunning(pid) {
|
|
108
|
+
try { process.kill(pid, 0); return true; } catch { return false; }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function cleanup() {
|
|
112
|
+
try {
|
|
113
|
+
// Kill Gateway
|
|
114
|
+
const gwPid = path.join(os.tmpdir(), '4runr-os-local-gateway.pid');
|
|
115
|
+
if (fs.existsSync(gwPid)) {
|
|
116
|
+
try {
|
|
117
|
+
const pid = parseInt(fs.readFileSync(gwPid, 'utf-8').trim(), 10);
|
|
118
|
+
if (pid > 0 && isRunning(pid)) process.kill(pid, 'SIGTERM');
|
|
119
|
+
} catch {}
|
|
120
|
+
try { fs.unlinkSync(gwPid); } catch {}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Stop Docker containers
|
|
124
|
+
try {
|
|
125
|
+
if (process.platform === 'win32') {
|
|
126
|
+
execSync('docker stop 4runr-postgres 4runr-redis 2>nul', { stdio: 'pipe', timeout: 15000, windowsHide: true });
|
|
127
|
+
} else {
|
|
128
|
+
execSync('docker stop 4runr-postgres 4runr-redis 2>/dev/null || true', { stdio: 'pipe', timeout: 15000 });
|
|
129
|
+
}
|
|
130
|
+
} catch {}
|
|
131
|
+
} catch {}
|
|
132
|
+
|
|
133
|
+
// Cleanup PID files
|
|
134
|
+
try { fs.unlinkSync(parentPidPath); } catch {}
|
|
135
|
+
try { fs.unlinkSync(watchdogPidPath); } catch {}
|
|
136
|
+
process.exit(0);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Monitor parent process
|
|
140
|
+
const parentPid = parseInt(fs.readFileSync(parentPidPath, 'utf-8').trim(), 10);
|
|
141
|
+
const interval = setInterval(() => {
|
|
142
|
+
if (!isRunning(parentPid)) {
|
|
143
|
+
clearInterval(interval);
|
|
144
|
+
cleanup();
|
|
145
|
+
}
|
|
146
|
+
}, 1000); // Check every second
|
|
147
|
+
|
|
148
|
+
// Cleanup on watchdog exit signals
|
|
149
|
+
process.on('SIGTERM', cleanup);
|
|
150
|
+
process.on('SIGINT', cleanup);
|
|
151
|
+
`;
|
|
152
|
+
const child = spawn(process.execPath, ['-e', watchdogScript], {
|
|
153
|
+
detached: true,
|
|
154
|
+
stdio: 'ignore',
|
|
155
|
+
windowsHide: true,
|
|
156
|
+
});
|
|
157
|
+
child.unref(); // Allow parent to exit independently
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Stop watchdog and cleanup (called on graceful shutdown)
|
|
161
|
+
*/
|
|
162
|
+
export function stopWatchdog() {
|
|
163
|
+
const watchdogPidPath = getWatchdogPidPath();
|
|
164
|
+
if (fs.existsSync(watchdogPidPath)) {
|
|
165
|
+
try {
|
|
166
|
+
const pid = parseInt(fs.readFileSync(watchdogPidPath, 'utf-8').trim(), 10);
|
|
167
|
+
if (pid > 0 && isProcessRunning(pid)) {
|
|
168
|
+
process.kill(pid, 'SIGTERM');
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
// ignore
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Manual cleanup since watchdog is being stopped gracefully
|
|
176
|
+
killGateway();
|
|
177
|
+
stopContainers();
|
|
178
|
+
// Cleanup PID files
|
|
179
|
+
try {
|
|
180
|
+
fs.unlinkSync(watchdogPidPath);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
// ignore
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
fs.unlinkSync(getParentPidPath());
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
// ignore
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=watchdog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watchdog.js","sourceRoot":"","sources":["../src/watchdog.ts"],"names":[],"mappings":"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"}
|