@calltelemetry/cli 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -1
- package/dist/commands/offline.d.ts.map +1 -1
- package/dist/commands/offline.js +78 -105
- package/dist/commands/offline.js.map +1 -1
- package/dist/commands/secrets.d.ts.map +1 -1
- package/dist/commands/secrets.js +12 -0
- package/dist/commands/secrets.js.map +1 -1
- package/dist/commands/self-update.d.ts +2 -3
- package/dist/commands/self-update.d.ts.map +1 -1
- package/dist/commands/self-update.js +4 -49
- package/dist/commands/self-update.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +25 -87
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/users.d.ts +3 -0
- package/dist/commands/users.d.ts.map +1 -0
- package/dist/commands/users.js +24 -0
- package/dist/commands/users.js.map +1 -0
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/auto-update.d.ts +15 -5
- package/dist/lib/auto-update.d.ts.map +1 -1
- package/dist/lib/auto-update.js +61 -25
- package/dist/lib/auto-update.js.map +1 -1
- package/dist/lib/bundle.d.ts.map +1 -1
- package/dist/lib/bundle.js +2 -9
- package/dist/lib/bundle.js.map +1 -1
- package/dist/lib/offline-steps.d.ts +33 -0
- package/dist/lib/offline-steps.d.ts.map +1 -0
- package/dist/lib/offline-steps.js +350 -0
- package/dist/lib/offline-steps.js.map +1 -0
- package/dist/lib/secrets.d.ts +14 -0
- package/dist/lib/secrets.d.ts.map +1 -1
- package/dist/lib/secrets.js +32 -0
- package/dist/lib/secrets.js.map +1 -1
- package/dist/lib/update-steps.d.ts +17 -0
- package/dist/lib/update-steps.d.ts.map +1 -0
- package/dist/lib/update-steps.js +169 -0
- package/dist/lib/update-steps.js.map +1 -0
- package/dist/lib/users.d.ts +33 -0
- package/dist/lib/users.d.ts.map +1 -0
- package/dist/lib/users.js +67 -0
- package/dist/lib/users.js.map +1 -0
- package/dist/ui/components/AppShell.d.ts +3 -1
- package/dist/ui/components/AppShell.d.ts.map +1 -1
- package/dist/ui/components/AppShell.js +5 -2
- package/dist/ui/components/AppShell.js.map +1 -1
- package/dist/ui/components/MetricsFooter.d.ts +7 -0
- package/dist/ui/components/MetricsFooter.d.ts.map +1 -0
- package/dist/ui/components/MetricsFooter.js +36 -0
- package/dist/ui/components/MetricsFooter.js.map +1 -0
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/context/MetricsContext.d.ts +7 -0
- package/dist/ui/context/MetricsContext.d.ts.map +1 -0
- package/dist/ui/context/MetricsContext.js +13 -0
- package/dist/ui/context/MetricsContext.js.map +1 -0
- package/dist/ui/views/CertsStatusView.d.ts.map +1 -1
- package/dist/ui/views/CertsStatusView.js +19 -10
- package/dist/ui/views/CertsStatusView.js.map +1 -1
- package/dist/ui/views/DbBackupView.d.ts.map +1 -1
- package/dist/ui/views/DbBackupView.js +4 -2
- package/dist/ui/views/DbBackupView.js.map +1 -1
- package/dist/ui/views/DbStatusView.d.ts.map +1 -1
- package/dist/ui/views/DbStatusView.js +3 -2
- package/dist/ui/views/DbStatusView.js.map +1 -1
- package/dist/ui/views/DiagDatabaseView.d.ts.map +1 -1
- package/dist/ui/views/DiagDatabaseView.js +39 -29
- package/dist/ui/views/DiagDatabaseView.js.map +1 -1
- package/dist/ui/views/DiagNetworkView.d.ts.map +1 -1
- package/dist/ui/views/DiagNetworkView.js +23 -14
- package/dist/ui/views/DiagNetworkView.js.map +1 -1
- package/dist/ui/views/DiagServiceView.d.ts.map +1 -1
- package/dist/ui/views/DiagServiceView.js +32 -20
- package/dist/ui/views/DiagServiceView.js.map +1 -1
- package/dist/ui/views/DockerStatusView.d.ts.map +1 -1
- package/dist/ui/views/DockerStatusView.js +5 -4
- package/dist/ui/views/DockerStatusView.js.map +1 -1
- package/dist/ui/views/MainMenu.d.ts.map +1 -1
- package/dist/ui/views/MainMenu.js +61 -10
- package/dist/ui/views/MainMenu.js.map +1 -1
- package/dist/ui/views/MigrateRunView.js +1 -1
- package/dist/ui/views/MigrateRunView.js.map +1 -1
- package/dist/ui/views/MigrateWatchView.d.ts.map +1 -1
- package/dist/ui/views/MigrateWatchView.js +2 -2
- package/dist/ui/views/MigrateWatchView.js.map +1 -1
- package/dist/ui/views/OfflineApplyView.d.ts +6 -0
- package/dist/ui/views/OfflineApplyView.d.ts.map +1 -0
- package/dist/ui/views/OfflineApplyView.js +109 -0
- package/dist/ui/views/OfflineApplyView.js.map +1 -0
- package/dist/ui/views/OfflineDownloadView.d.ts +6 -0
- package/dist/ui/views/OfflineDownloadView.d.ts.map +1 -0
- package/dist/ui/views/OfflineDownloadView.js +67 -0
- package/dist/ui/views/OfflineDownloadView.js.map +1 -0
- package/dist/ui/views/OfflineFetchView.d.ts +6 -0
- package/dist/ui/views/OfflineFetchView.d.ts.map +1 -0
- package/dist/ui/views/OfflineFetchView.js +64 -0
- package/dist/ui/views/OfflineFetchView.js.map +1 -0
- package/dist/ui/views/OfflineInspectView.d.ts +6 -0
- package/dist/ui/views/OfflineInspectView.d.ts.map +1 -0
- package/dist/ui/views/OfflineInspectView.js +65 -0
- package/dist/ui/views/OfflineInspectView.js.map +1 -0
- package/dist/ui/views/OfflineListView.d.ts.map +1 -1
- package/dist/ui/views/OfflineListView.js +2 -6
- package/dist/ui/views/OfflineListView.js.map +1 -1
- package/dist/ui/views/SecretsResetPasswordView.d.ts +11 -0
- package/dist/ui/views/SecretsResetPasswordView.d.ts.map +1 -0
- package/dist/ui/views/SecretsResetPasswordView.js +205 -0
- package/dist/ui/views/SecretsResetPasswordView.js.map +1 -0
- package/dist/ui/views/UpdateView.d.ts.map +1 -1
- package/dist/ui/views/UpdateView.js +20 -145
- package/dist/ui/views/UpdateView.js.map +1 -1
- package/dist/ui/views/UserResetPasswordView.d.ts +10 -0
- package/dist/ui/views/UserResetPasswordView.d.ts.map +1 -0
- package/dist/ui/views/UserResetPasswordView.js +220 -0
- package/dist/ui/views/UserResetPasswordView.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared offline pipeline steps consumed by both the CLI (`commands/offline.ts`)
|
|
3
|
+
* and the TUI offline views. Keeps all offline logic in one place.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync, readFileSync, statSync } from 'node:fs';
|
|
6
|
+
import { copyFile, mkdir, rm } from 'node:fs/promises';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { getPaths } from './paths.js';
|
|
9
|
+
import { exec, execRetry } from './exec.js';
|
|
10
|
+
import { composeUp } from './compose.js';
|
|
11
|
+
import { downloadBundle } from './bundle.js';
|
|
12
|
+
import { checkDiskSpace } from './system.js';
|
|
13
|
+
import { debug } from './log.js';
|
|
14
|
+
import { formatBytes } from './system.js';
|
|
15
|
+
// ─── Canonical Image Regex ──────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* Extract image names from docker-compose.yml content.
|
|
18
|
+
* Single canonical regex — replaces 3 duplicated patterns across the codebase.
|
|
19
|
+
*
|
|
20
|
+
* @param filter - 'all' returns every image, 'calltelemetry' only calltelemetry images
|
|
21
|
+
*/
|
|
22
|
+
export function extractImageNames(content, filter = 'all') {
|
|
23
|
+
const images = [];
|
|
24
|
+
for (const line of content.split('\n')) {
|
|
25
|
+
const match = line.match(/image:\s*["']?([^\s"']+)["']?/);
|
|
26
|
+
if (match) {
|
|
27
|
+
if (filter === 'calltelemetry' && !line.includes('calltelemetry'))
|
|
28
|
+
continue;
|
|
29
|
+
images.push(match[1]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return images;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate a bundle file without extracting.
|
|
36
|
+
* Checks: file exists, is a valid tar.gz, disk space for extraction.
|
|
37
|
+
*/
|
|
38
|
+
export async function validateBundle(bundlePath) {
|
|
39
|
+
if (!existsSync(bundlePath)) {
|
|
40
|
+
return { valid: false, error: `Bundle file not found: ${bundlePath}` };
|
|
41
|
+
}
|
|
42
|
+
// Check it's a valid tar.gz
|
|
43
|
+
try {
|
|
44
|
+
await exec('tar', ['-tzf', bundlePath], { stdout: 'pipe', stderr: 'pipe' });
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return { valid: false, error: 'Bundle is not a valid tar.gz archive' };
|
|
48
|
+
}
|
|
49
|
+
// Check disk space (need at least 2x bundle size for extraction)
|
|
50
|
+
const bundleSize = statSync(bundlePath).size;
|
|
51
|
+
const { installDir } = getPaths();
|
|
52
|
+
const disk = await checkDiskSpace(installDir);
|
|
53
|
+
if (!disk.ok) {
|
|
54
|
+
return { valid: false, error: `Low disk space: ${disk.freePercent}% free (need 10%+)` };
|
|
55
|
+
}
|
|
56
|
+
return { valid: true };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Inspect a bundle's contents without fully extracting.
|
|
60
|
+
* Uses tar listing + selective extract of docker-compose.yml only.
|
|
61
|
+
*/
|
|
62
|
+
export async function inspectBundle(bundlePath) {
|
|
63
|
+
const sizeBytes = statSync(bundlePath).size;
|
|
64
|
+
// List tar contents
|
|
65
|
+
const result = await exec('tar', ['-tzf', bundlePath], {
|
|
66
|
+
stdout: 'pipe',
|
|
67
|
+
stderr: 'pipe',
|
|
68
|
+
});
|
|
69
|
+
const entries = String(result.stdout ?? '').split('\n').filter(Boolean);
|
|
70
|
+
// Normalize paths (strip leading directory component to match --strip-components=1)
|
|
71
|
+
const normalized = entries.map((e) => {
|
|
72
|
+
const parts = e.split('/');
|
|
73
|
+
return parts.length > 1 ? parts.slice(1).join('/') : e;
|
|
74
|
+
}).filter(Boolean);
|
|
75
|
+
// Identify config files
|
|
76
|
+
const knownConfigs = ['docker-compose.yml', 'Caddyfile', 'cli.sh', 'nats.conf'];
|
|
77
|
+
const configFiles = knownConfigs.filter(f => normalized.some((n) => n === f || n.endsWith(`/${f}`)));
|
|
78
|
+
// Check for images.tar
|
|
79
|
+
const hasImages = normalized.some((n) => n === 'images.tar');
|
|
80
|
+
// Extract version from bundle filename
|
|
81
|
+
const versionMatch = bundlePath.match(/calltelemetry-(?:bundle|offline)-([^\s/]+?)\.tar\.gz$/);
|
|
82
|
+
const version = versionMatch ? versionMatch[1] : null;
|
|
83
|
+
// Try to extract docker-compose.yml to parse image names
|
|
84
|
+
let imageNames = [];
|
|
85
|
+
if (configFiles.includes('docker-compose.yml')) {
|
|
86
|
+
const tmpDir = `/tmp/ct-inspect-${process.pid}`;
|
|
87
|
+
try {
|
|
88
|
+
await mkdir(tmpDir, { recursive: true });
|
|
89
|
+
// Extract just docker-compose.yml
|
|
90
|
+
await exec('tar', ['-xzf', bundlePath, '-C', tmpDir, '--strip-components=1',
|
|
91
|
+
'--include=*/docker-compose.yml', '--include=docker-compose.yml'], {
|
|
92
|
+
stdout: 'pipe',
|
|
93
|
+
stderr: 'pipe',
|
|
94
|
+
});
|
|
95
|
+
const composePath = join(tmpDir, 'docker-compose.yml');
|
|
96
|
+
if (existsSync(composePath)) {
|
|
97
|
+
const content = readFileSync(composePath, 'utf-8');
|
|
98
|
+
imageNames = extractImageNames(content, 'all');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
debug('Could not extract docker-compose.yml for inspection');
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
await rm(tmpDir, { recursive: true, force: true });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Check for prometheus/grafana dirs
|
|
109
|
+
if (normalized.some((n) => n.startsWith('prometheus/')))
|
|
110
|
+
configFiles.push('prometheus/');
|
|
111
|
+
if (normalized.some((n) => n.startsWith('grafana/')))
|
|
112
|
+
configFiles.push('grafana/');
|
|
113
|
+
return {
|
|
114
|
+
version,
|
|
115
|
+
configFiles,
|
|
116
|
+
hasImages,
|
|
117
|
+
imageNames,
|
|
118
|
+
sizeBytes,
|
|
119
|
+
sizeLabel: formatBytes(sizeBytes),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// ─── Fetch Steps (config-only bundle) ───────────────────────────────────────
|
|
123
|
+
export function fetchSteps(version) {
|
|
124
|
+
return [
|
|
125
|
+
{
|
|
126
|
+
label: 'Download config bundle',
|
|
127
|
+
run: async (ctx) => {
|
|
128
|
+
const { gcsBundleBaseUrl } = getPaths();
|
|
129
|
+
ctx?.log(`Downloading from ${gcsBundleBaseUrl}/${version}/`);
|
|
130
|
+
await downloadBundle(version, { quiet: true });
|
|
131
|
+
ctx?.log('Extracted docker-compose.yml, configs, and supporting files');
|
|
132
|
+
return version;
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
label: 'Verify checksum',
|
|
137
|
+
run: async (ctx) => {
|
|
138
|
+
const { gcsBundleBaseUrl, installDir } = getPaths();
|
|
139
|
+
const bundleFile = `calltelemetry-bundle-${version}.tar.gz`;
|
|
140
|
+
const checksumUrl = `${gcsBundleBaseUrl}/${version}/${bundleFile}.sha256`;
|
|
141
|
+
try {
|
|
142
|
+
await execRetry('curl', ['-sfL', checksumUrl, '-o', `${bundleFile}.sha256`], {
|
|
143
|
+
cwd: installDir,
|
|
144
|
+
});
|
|
145
|
+
await exec('sha256sum', ['-c', `${bundleFile}.sha256`], { cwd: installDir });
|
|
146
|
+
ctx?.log('SHA256 checksum verified');
|
|
147
|
+
await rm(join(installDir, `${bundleFile}.sha256`), { force: true });
|
|
148
|
+
return 'verified';
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
ctx?.log('Checksum not available — skipped');
|
|
152
|
+
return 'skipped';
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
];
|
|
157
|
+
}
|
|
158
|
+
// ─── Download Steps (full offline bundle with Docker images) ────────────────
|
|
159
|
+
export function downloadSteps(version) {
|
|
160
|
+
const configBundle = `calltelemetry-bundle-${version}.tar.gz`;
|
|
161
|
+
const bundleDir = `calltelemetry-offline-${version}`;
|
|
162
|
+
const bundleName = `calltelemetry-offline-${version}.tar.gz`;
|
|
163
|
+
return [
|
|
164
|
+
{
|
|
165
|
+
label: 'Download config bundle',
|
|
166
|
+
run: async (ctx) => {
|
|
167
|
+
const { gcsBundleBaseUrl } = getPaths();
|
|
168
|
+
const bundleUrl = `${gcsBundleBaseUrl}/${version}/${configBundle}`;
|
|
169
|
+
ctx?.log(`Downloading from ${bundleUrl}`);
|
|
170
|
+
await execRetry('curl', ['-fsSL', bundleUrl, '-o', configBundle], {
|
|
171
|
+
retries: 2,
|
|
172
|
+
retryDelay: 3000,
|
|
173
|
+
});
|
|
174
|
+
return 'downloaded';
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
label: 'Extract config bundle',
|
|
179
|
+
run: async (ctx) => {
|
|
180
|
+
await rm(bundleDir, { recursive: true, force: true });
|
|
181
|
+
await mkdir(bundleDir, { recursive: true });
|
|
182
|
+
await exec('tar', ['-xzf', configBundle, '-C', bundleDir, '--strip-components=1']);
|
|
183
|
+
await rm(configBundle, { force: true });
|
|
184
|
+
ctx?.log(`Extracted to ${bundleDir}/`);
|
|
185
|
+
return 'extracted';
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
label: 'Pull Docker images',
|
|
190
|
+
run: async (ctx) => {
|
|
191
|
+
const composePath = join(bundleDir, 'docker-compose.yml');
|
|
192
|
+
if (!existsSync(composePath)) {
|
|
193
|
+
throw new Error('docker-compose.yml not found in bundle');
|
|
194
|
+
}
|
|
195
|
+
const content = readFileSync(composePath, 'utf-8');
|
|
196
|
+
const images = extractImageNames(content, 'all');
|
|
197
|
+
ctx?.log(`Found ${images.length} images to pull`);
|
|
198
|
+
let pulled = 0;
|
|
199
|
+
for (const img of images) {
|
|
200
|
+
ctx?.log(`Pulling ${img} (${pulled + 1}/${images.length})...`);
|
|
201
|
+
try {
|
|
202
|
+
await exec('docker', ['pull', img]);
|
|
203
|
+
pulled++;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
ctx?.log(`Warning: Failed to pull ${img}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return `${pulled}/${images.length} images pulled`;
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
label: 'Save Docker images',
|
|
214
|
+
run: async (ctx) => {
|
|
215
|
+
const composePath = join(bundleDir, 'docker-compose.yml');
|
|
216
|
+
const content = readFileSync(composePath, 'utf-8');
|
|
217
|
+
const images = extractImageNames(content, 'all');
|
|
218
|
+
ctx?.log(`Saving ${images.length} images to images.tar...`);
|
|
219
|
+
await exec('docker', ['save', ...images, '-o', join(bundleDir, 'images.tar')]);
|
|
220
|
+
const size = statSync(join(bundleDir, 'images.tar')).size;
|
|
221
|
+
return formatBytes(size);
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
label: 'Create offline archive',
|
|
226
|
+
run: async (ctx) => {
|
|
227
|
+
ctx?.log(`Archiving ${bundleDir}/ → ${bundleName}`);
|
|
228
|
+
await exec('tar', ['-czf', bundleName, bundleDir]);
|
|
229
|
+
await rm(bundleDir, { recursive: true, force: true });
|
|
230
|
+
const size = statSync(bundleName).size;
|
|
231
|
+
ctx?.log(`Archive size: ${formatBytes(size)}`);
|
|
232
|
+
return bundleName;
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
// ─── Apply Steps (install offline bundle) ───────────────────────────────────
|
|
238
|
+
export function applySteps(bundlePath) {
|
|
239
|
+
const extractDir = `offline-extract-${process.pid}`;
|
|
240
|
+
return [
|
|
241
|
+
{
|
|
242
|
+
label: 'Validate bundle',
|
|
243
|
+
run: async (ctx) => {
|
|
244
|
+
const result = await validateBundle(bundlePath);
|
|
245
|
+
if (!result.valid)
|
|
246
|
+
throw new Error(result.error);
|
|
247
|
+
const size = statSync(bundlePath).size;
|
|
248
|
+
ctx?.log(`Bundle valid: ${formatBytes(size)}`);
|
|
249
|
+
return 'valid';
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
label: 'Extract bundle',
|
|
254
|
+
run: async (ctx) => {
|
|
255
|
+
await mkdir(extractDir, { recursive: true });
|
|
256
|
+
ctx?.log(`Extracting to ${extractDir}/`);
|
|
257
|
+
await exec('tar', ['-xzf', bundlePath, '-C', extractDir, '--strip-components=1']);
|
|
258
|
+
return 'extracted';
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
label: 'Load Docker images',
|
|
263
|
+
run: async (ctx) => {
|
|
264
|
+
const imagesFile = join(extractDir, 'images.tar');
|
|
265
|
+
if (!existsSync(imagesFile)) {
|
|
266
|
+
ctx?.log('No images.tar found — config-only bundle');
|
|
267
|
+
return 'skipped';
|
|
268
|
+
}
|
|
269
|
+
const size = statSync(imagesFile).size;
|
|
270
|
+
ctx?.log(`Loading images (${formatBytes(size)})...`);
|
|
271
|
+
await exec('docker', ['load', '-i', imagesFile]);
|
|
272
|
+
return 'loaded';
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
label: 'Install configuration',
|
|
277
|
+
run: async (ctx) => {
|
|
278
|
+
const { installDir, backupDir } = getPaths();
|
|
279
|
+
await mkdir(backupDir, { recursive: true });
|
|
280
|
+
const configFiles = ['docker-compose.yml', 'Caddyfile', 'cli.sh', 'nats.conf'];
|
|
281
|
+
let installed = 0;
|
|
282
|
+
for (const file of configFiles) {
|
|
283
|
+
const src = join(extractDir, file);
|
|
284
|
+
if (!existsSync(src))
|
|
285
|
+
continue;
|
|
286
|
+
const dest = join(installDir, file);
|
|
287
|
+
if (existsSync(dest)) {
|
|
288
|
+
await copyFile(dest, join(backupDir, `${file}.backup`));
|
|
289
|
+
ctx?.log(`Backed up ${file}`);
|
|
290
|
+
}
|
|
291
|
+
await copyFile(src, dest);
|
|
292
|
+
ctx?.log(`Installed ${file}`);
|
|
293
|
+
installed++;
|
|
294
|
+
}
|
|
295
|
+
// Copy prometheus/grafana directories if present
|
|
296
|
+
const promSrc = join(extractDir, 'prometheus');
|
|
297
|
+
if (existsSync(promSrc)) {
|
|
298
|
+
const promDest = join(installDir, 'prometheus');
|
|
299
|
+
await mkdir(promDest, { recursive: true });
|
|
300
|
+
try {
|
|
301
|
+
await exec('cp', ['-r', `${promSrc}/.`, promDest]);
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
try {
|
|
305
|
+
await exec('sudo', ['cp', '-r', `${promSrc}/.`, promDest]);
|
|
306
|
+
}
|
|
307
|
+
catch { /* skip */ }
|
|
308
|
+
}
|
|
309
|
+
ctx?.log('Installed prometheus/');
|
|
310
|
+
installed++;
|
|
311
|
+
}
|
|
312
|
+
const grafanaSrc = join(extractDir, 'grafana');
|
|
313
|
+
if (existsSync(grafanaSrc)) {
|
|
314
|
+
const grafanaDest = join(installDir, 'grafana');
|
|
315
|
+
await mkdir(grafanaDest, { recursive: true });
|
|
316
|
+
try {
|
|
317
|
+
await exec('cp', ['-r', `${grafanaSrc}/.`, grafanaDest]);
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
try {
|
|
321
|
+
await exec('sudo', ['cp', '-r', `${grafanaSrc}/.`, grafanaDest]);
|
|
322
|
+
}
|
|
323
|
+
catch { /* skip */ }
|
|
324
|
+
}
|
|
325
|
+
ctx?.log('Installed grafana/');
|
|
326
|
+
installed++;
|
|
327
|
+
}
|
|
328
|
+
return `${installed} files installed`;
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
label: 'Restart services',
|
|
333
|
+
run: async (ctx) => {
|
|
334
|
+
ctx?.log('Restarting services...');
|
|
335
|
+
try {
|
|
336
|
+
await exec('systemctl', ['restart', 'docker-compose-app.service']);
|
|
337
|
+
ctx?.log('Restarted via systemctl');
|
|
338
|
+
}
|
|
339
|
+
catch {
|
|
340
|
+
ctx?.log('systemctl failed, using docker-compose up');
|
|
341
|
+
await composeUp(['-d']);
|
|
342
|
+
}
|
|
343
|
+
// Cleanup extract dir
|
|
344
|
+
await rm(extractDir, { recursive: true, force: true });
|
|
345
|
+
return 'done';
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
];
|
|
349
|
+
}
|
|
350
|
+
//# sourceMappingURL=offline-steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offline-steps.js","sourceRoot":"","sources":["../../src/lib/offline-steps.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/secrets.d.ts
CHANGED
|
@@ -35,4 +35,18 @@ export declare function writeEnvFile(values: Record<string, string>): Promise<vo
|
|
|
35
35
|
* Generate docker-compose.secrets.yml overlay file
|
|
36
36
|
*/
|
|
37
37
|
export declare function writeSecretsOverlay(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Generate a cryptographically random password (URL-safe alphanumeric).
|
|
40
|
+
*/
|
|
41
|
+
export declare function generatePassword(length?: number): string;
|
|
42
|
+
/**
|
|
43
|
+
* Change the PostgreSQL password in the running database via ALTER USER.
|
|
44
|
+
* Connects using current credentials from getSecrets().
|
|
45
|
+
*/
|
|
46
|
+
export declare function alterDbPassword(newPassword: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Update Minio password in .env/overlay and restart the Minio container.
|
|
49
|
+
* Minio reads credentials from environment variables at startup.
|
|
50
|
+
*/
|
|
51
|
+
export declare function restartMinioWithPassword(newPassword: string): Promise<void>;
|
|
38
52
|
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,CAAC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,EAOrC,CAAC;AAEF,eAAO,MAAM,aAAa,0CAA2C,CAAC;AACtE,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAwBpE;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BnD;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAMtC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBhF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAmBzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,SAAK,GAAG,MAAM,CAEpD;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjF"}
|
package/dist/lib/secrets.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
2
3
|
import { join } from 'node:path';
|
|
3
4
|
import { getPaths } from './paths.js';
|
|
4
5
|
import { writeFileSafe } from './fs.js';
|
|
6
|
+
import { composeExec, compose } from './compose.js';
|
|
5
7
|
export const SECRET_CATALOG = [
|
|
6
8
|
{ key: 'POSTGRES_PASSWORD', label: 'PostgreSQL Password', group: 'PostgreSQL', defaultValue: 'postgres', sensitive: true, required: true },
|
|
7
9
|
{ key: 'POSTGRES_USER', label: 'PostgreSQL User', group: 'PostgreSQL', defaultValue: 'calltelemetry', sensitive: false, required: true },
|
|
@@ -129,4 +131,34 @@ services:
|
|
|
129
131
|
`;
|
|
130
132
|
await writeFileSafe(secretsOverlayFile, content);
|
|
131
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Generate a cryptographically random password (URL-safe alphanumeric).
|
|
136
|
+
*/
|
|
137
|
+
export function generatePassword(length = 24) {
|
|
138
|
+
return randomBytes(length).toString('base64url').slice(0, length);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Change the PostgreSQL password in the running database via ALTER USER.
|
|
142
|
+
* Connects using current credentials from getSecrets().
|
|
143
|
+
*/
|
|
144
|
+
export async function alterDbPassword(newPassword) {
|
|
145
|
+
const secrets = getSecrets();
|
|
146
|
+
const user = secrets.POSTGRES_USER;
|
|
147
|
+
const escaped = newPassword.replace(/'/g, "''");
|
|
148
|
+
await composeExec('db', [
|
|
149
|
+
'psql', '-U', user, '-d', secrets.POSTGRES_DB,
|
|
150
|
+
'-c', `ALTER USER ${user} PASSWORD '${escaped}';`,
|
|
151
|
+
], { env: { PGPASSWORD: secrets.POSTGRES_PASSWORD }, pipe: true });
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Update Minio password in .env/overlay and restart the Minio container.
|
|
155
|
+
* Minio reads credentials from environment variables at startup.
|
|
156
|
+
*/
|
|
157
|
+
export async function restartMinioWithPassword(newPassword) {
|
|
158
|
+
const secrets = getSecrets();
|
|
159
|
+
secrets.MINIO_ROOT_PASSWORD = newPassword;
|
|
160
|
+
await writeEnvFile(secrets);
|
|
161
|
+
await writeSecretsOverlay();
|
|
162
|
+
await compose(['restart', 'minio']);
|
|
163
|
+
}
|
|
132
164
|
//# sourceMappingURL=secrets.js.map
|
package/dist/lib/secrets.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAWpD,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,EAAE,GAAG,EAAE,mBAAmB,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC1I,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;IACxI,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE;IAC/I,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;IACnH,EAAE,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE;IACnI,EAAE,GAAG,EAAE,qBAAqB,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;CAC3I,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAGtE,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5C,kCAAkC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEnE,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,SAAS;QAE3B,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE7C,wBAAwB;QACxB,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;YAC9C,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACnD,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7B,CAAC;QAED,IAAI,GAAG;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAA2B,EAAE,CAAC;IAE3C,yBAAyB;IACzB,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;IACtC,CAAC;IAED,gCAAgC;IAChC,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,kDAAkD;IAClD,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC;AACnE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC;AACpF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAA8B;IAC/D,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG;QACZ,yDAAyD;QACzD,mBAAmB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE;QAC7C,EAAE;KACH,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,MAAM,aAAa,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAClE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,EAAE,kBAAkB,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC1C,MAAM,OAAO,GAAG;;;;;;;;;;;;;;;CAejB,CAAC;IACA,MAAM,aAAa,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;AACnD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAM,GAAG,EAAE;IAC1C,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,WAAmB;IACvD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC;IACnC,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,CAAC,IAAI,EAAE;QACtB,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,WAAW;QAC7C,IAAI,EAAE,cAAc,IAAI,cAAc,OAAO,IAAI;KAClD,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AACrE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,WAAmB;IAChE,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,OAAO,CAAC,mBAAmB,GAAG,WAAW,CAAC;IAC1C,MAAM,YAAY,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,mBAAmB,EAAE,CAAC;IAC5B,MAAM,OAAO,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Minimal step context — compatible with the TUI's StepContext. */
|
|
2
|
+
export interface StepContext {
|
|
3
|
+
log: (line: string) => void;
|
|
4
|
+
}
|
|
5
|
+
/** A single pipeline step. Same shape as the TUI's Step interface. */
|
|
6
|
+
export interface UpdateStep {
|
|
7
|
+
label: string;
|
|
8
|
+
run: (ctx?: StepContext) => Promise<string | void>;
|
|
9
|
+
}
|
|
10
|
+
export declare function preflightSteps(targetVersion: string): UpdateStep[];
|
|
11
|
+
export declare function executeSteps(targetVersion: string): UpdateStep[];
|
|
12
|
+
/**
|
|
13
|
+
* Run a list of steps sequentially with console output.
|
|
14
|
+
* Used by `commands/update.ts` to run the same pipeline as the TUI.
|
|
15
|
+
*/
|
|
16
|
+
export declare function runStepsCli(steps: UpdateStep[]): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=update-steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-steps.d.ts","sourceRoot":"","sources":["../../src/lib/update-steps.ts"],"names":[],"mappings":"AAYA,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,sEAAsE;AACtE,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpD;AAID,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,EAAE,CA8BlE;AAID,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,UAAU,EAAE,CAgGhE;AAID;;;GAGG;AACH,wBAAsB,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAepE"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared update pipeline steps consumed by both the CLI (`commands/update.ts`)
|
|
3
|
+
* and the TUI (`UpdateView.tsx`). Keeps the update logic in one place.
|
|
4
|
+
*/
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { generateSelfSignedCerts } from './certs.js';
|
|
7
|
+
import { checkRam, checkDiskSpace, getDockerVersion } from './system.js';
|
|
8
|
+
import { downloadBundle, checkImageAvailabilityQuiet, extractImages } from './bundle.js';
|
|
9
|
+
import { backupCompose, applyAndRestart, postgresVersionGuard, dockerCleanup, pullImages, applyIpv6IfEnabled } from './update.js';
|
|
10
|
+
import { isVersionGte } from '../utils/version.js';
|
|
11
|
+
import { getPaths } from './paths.js';
|
|
12
|
+
// ─── Preflight Steps ────────────────────────────────────────────────────────
|
|
13
|
+
export function preflightSteps(targetVersion) {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
label: 'Check RAM',
|
|
17
|
+
run: async () => {
|
|
18
|
+
const ram = await checkRam();
|
|
19
|
+
if (isVersionGte(targetVersion, '0.8.4') && !ram.ok) {
|
|
20
|
+
throw new Error(`Insufficient RAM: ${ram.totalMb}MB (need 7168MB+)`);
|
|
21
|
+
}
|
|
22
|
+
return `${ram.totalMb} MB`;
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Check disk space',
|
|
27
|
+
run: async () => {
|
|
28
|
+
const disk = await checkDiskSpace();
|
|
29
|
+
if (!disk.ok)
|
|
30
|
+
throw new Error(`Low disk: ${disk.freePercent}% free (need 10%+)`);
|
|
31
|
+
return `${disk.freePercent}% free`;
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: 'Check Docker',
|
|
36
|
+
run: async () => {
|
|
37
|
+
const ver = await getDockerVersion();
|
|
38
|
+
if (ver === null)
|
|
39
|
+
throw new Error('Docker not found');
|
|
40
|
+
if (ver < 26)
|
|
41
|
+
return `v${ver} (upgrade recommended)`;
|
|
42
|
+
return `v${ver}`;
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
// ─── Execute Steps ──────────────────────────────────────────────────────────
|
|
48
|
+
export function executeSteps(targetVersion) {
|
|
49
|
+
const { installDir } = getPaths();
|
|
50
|
+
const tempFile = join(installDir, 'temp-docker-compose.yml');
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
label: 'Generate certificates',
|
|
54
|
+
run: async (ctx) => {
|
|
55
|
+
ctx?.log('Checking for existing certificates...');
|
|
56
|
+
await generateSelfSignedCerts();
|
|
57
|
+
return 'checked';
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
label: 'Backup current config',
|
|
62
|
+
run: async (ctx) => {
|
|
63
|
+
ctx?.log('Creating timestamped backup...');
|
|
64
|
+
const name = await backupCompose();
|
|
65
|
+
ctx?.log(`Saved: ${name}`);
|
|
66
|
+
return name;
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
label: 'Download config bundle',
|
|
71
|
+
run: async (ctx) => {
|
|
72
|
+
const { gcsBundleBaseUrl } = getPaths();
|
|
73
|
+
ctx?.log(`Downloading from ${gcsBundleBaseUrl}/${targetVersion}/`);
|
|
74
|
+
await downloadBundle(targetVersion, { quiet: true });
|
|
75
|
+
ctx?.log('Extracted docker-compose.yml, configs, and supporting files');
|
|
76
|
+
return targetVersion;
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
label: 'Check image availability',
|
|
81
|
+
run: async (ctx) => {
|
|
82
|
+
const result = await checkImageAvailabilityQuiet(tempFile);
|
|
83
|
+
for (const r of result.results) {
|
|
84
|
+
ctx?.log(`${r.available ? '✔' : '✘'} ${r.image}${r.error ? ` (${r.error})` : ''}`);
|
|
85
|
+
}
|
|
86
|
+
if (!result.available) {
|
|
87
|
+
const missing = result.results
|
|
88
|
+
.filter(r => !r.available)
|
|
89
|
+
.map(r => r.error ? `${r.image} (${r.error})` : r.image);
|
|
90
|
+
throw new Error(`Unavailable: ${missing.join(', ')}`);
|
|
91
|
+
}
|
|
92
|
+
return `${result.results.length} images verified`;
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
label: 'Pull Docker images',
|
|
97
|
+
run: async (ctx) => {
|
|
98
|
+
const images = await extractImages(tempFile);
|
|
99
|
+
ctx?.log(`Pulling ${images.length} images...`);
|
|
100
|
+
for (const img of images)
|
|
101
|
+
ctx?.log(` ${img}`);
|
|
102
|
+
const pulled = await pullImages(tempFile);
|
|
103
|
+
return `${pulled.length} images`;
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
label: 'PostgreSQL version guard',
|
|
108
|
+
run: async (ctx) => {
|
|
109
|
+
ctx?.log('Checking PostgreSQL version compatibility...');
|
|
110
|
+
const pinned = await postgresVersionGuard();
|
|
111
|
+
if (pinned)
|
|
112
|
+
ctx?.log(`Pinned to PostgreSQL ${pinned} to prevent accidental upgrade`);
|
|
113
|
+
return pinned ? `pinned to PG ${pinned}` : 'ok';
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
label: 'Apply and restart services',
|
|
118
|
+
run: async (ctx) => {
|
|
119
|
+
ctx?.log('Moving temp compose to production...');
|
|
120
|
+
await applyAndRestart();
|
|
121
|
+
ctx?.log('Services restarted');
|
|
122
|
+
return 'done';
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
label: 'Apply IPv6 configuration',
|
|
127
|
+
run: async (ctx) => {
|
|
128
|
+
const applied = await applyIpv6IfEnabled();
|
|
129
|
+
if (applied) {
|
|
130
|
+
ctx?.log('IPv6 dual-stack enabled per preferences');
|
|
131
|
+
return 'enabled';
|
|
132
|
+
}
|
|
133
|
+
return 'skipped (IPv4-only)';
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
label: 'Cleanup unused resources',
|
|
138
|
+
run: async (ctx) => {
|
|
139
|
+
ctx?.log('Running docker system prune...');
|
|
140
|
+
await dockerCleanup();
|
|
141
|
+
return 'done';
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
// ─── CLI Runner ─────────────────────────────────────────────────────────────
|
|
147
|
+
/**
|
|
148
|
+
* Run a list of steps sequentially with console output.
|
|
149
|
+
* Used by `commands/update.ts` to run the same pipeline as the TUI.
|
|
150
|
+
*/
|
|
151
|
+
export async function runStepsCli(steps) {
|
|
152
|
+
for (const step of steps) {
|
|
153
|
+
const ctx = {
|
|
154
|
+
log: (line) => console.log(` ${line}`),
|
|
155
|
+
};
|
|
156
|
+
console.log(`→ ${step.label}...`);
|
|
157
|
+
try {
|
|
158
|
+
const result = await step.run(ctx);
|
|
159
|
+
if (result)
|
|
160
|
+
console.log(` ✔ ${result}`);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
164
|
+
console.error(` ✘ ${msg}`);
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=update-steps.js.map
|