postgresai 0.11.0-alpha.5 → 0.11.0-alpha.6
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/bin/postgres-ai.js +101 -2
- package/package.json +1 -1
package/bin/postgres-ai.js
CHANGED
|
@@ -196,7 +196,44 @@ program
|
|
|
196
196
|
.command("reset [service]")
|
|
197
197
|
.description("reset all or specific service")
|
|
198
198
|
.action(stub("reset"));
|
|
199
|
-
program
|
|
199
|
+
program
|
|
200
|
+
.command("clean")
|
|
201
|
+
.description("cleanup artifacts")
|
|
202
|
+
.action(async () => {
|
|
203
|
+
const { exec } = require("child_process");
|
|
204
|
+
const util = require("util");
|
|
205
|
+
const execPromise = util.promisify(exec);
|
|
206
|
+
|
|
207
|
+
console.log("Cleaning up Docker resources...\n");
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
// Remove stopped containers
|
|
211
|
+
const { stdout: containers } = await execPromise("docker ps -aq --filter 'status=exited'");
|
|
212
|
+
if (containers.trim()) {
|
|
213
|
+
await execPromise(`docker rm ${containers.trim().split('\n').join(' ')}`);
|
|
214
|
+
console.log("✓ Removed stopped containers");
|
|
215
|
+
} else {
|
|
216
|
+
console.log("✓ No stopped containers to remove");
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Remove unused volumes
|
|
220
|
+
const { stdout: volumeOut } = await execPromise("docker volume prune -f");
|
|
221
|
+
console.log("✓ Removed unused volumes");
|
|
222
|
+
|
|
223
|
+
// Remove unused networks
|
|
224
|
+
const { stdout: networkOut } = await execPromise("docker network prune -f");
|
|
225
|
+
console.log("✓ Removed unused networks");
|
|
226
|
+
|
|
227
|
+
// Remove dangling images
|
|
228
|
+
const { stdout: imageOut } = await execPromise("docker image prune -f");
|
|
229
|
+
console.log("✓ Removed dangling images");
|
|
230
|
+
|
|
231
|
+
console.log("\nCleanup completed");
|
|
232
|
+
} catch (error) {
|
|
233
|
+
console.error(`Error during cleanup: ${error.message}`);
|
|
234
|
+
process.exitCode = 1;
|
|
235
|
+
}
|
|
236
|
+
});
|
|
200
237
|
program
|
|
201
238
|
.command("shell <service>")
|
|
202
239
|
.description("open service shell")
|
|
@@ -330,7 +367,69 @@ program
|
|
|
330
367
|
program
|
|
331
368
|
.command("test-instance <name>")
|
|
332
369
|
.description("test instance connectivity")
|
|
333
|
-
.action(
|
|
370
|
+
.action(async (name) => {
|
|
371
|
+
const fs = require("fs");
|
|
372
|
+
const path = require("path");
|
|
373
|
+
const { exec } = require("child_process");
|
|
374
|
+
const util = require("util");
|
|
375
|
+
const execPromise = util.promisify(exec);
|
|
376
|
+
|
|
377
|
+
const instancesPath = path.resolve(process.cwd(), "instances.yml");
|
|
378
|
+
if (!fs.existsSync(instancesPath)) {
|
|
379
|
+
console.error("instances.yml not found");
|
|
380
|
+
process.exitCode = 1;
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const content = fs.readFileSync(instancesPath, "utf8");
|
|
385
|
+
const lines = content.split(/\r?\n/);
|
|
386
|
+
let connStr = "";
|
|
387
|
+
let foundInstance = false;
|
|
388
|
+
|
|
389
|
+
for (let i = 0; i < lines.length; i++) {
|
|
390
|
+
const nameLine = lines[i].match(/^-[\t ]*name:[\t ]*(.+)$/);
|
|
391
|
+
if (nameLine && nameLine[1].trim() === name) {
|
|
392
|
+
foundInstance = true;
|
|
393
|
+
// Look for conn_str in next lines
|
|
394
|
+
for (let j = i + 1; j < lines.length && j < i + 15; j++) {
|
|
395
|
+
const connLine = lines[j].match(/^[\t ]*conn_str:[\t ]*(.+)$/);
|
|
396
|
+
if (connLine) {
|
|
397
|
+
connStr = connLine[1].trim();
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
// Stop at next instance
|
|
401
|
+
if (lines[j].match(/^-[\t ]*name:/)) break;
|
|
402
|
+
}
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (!foundInstance) {
|
|
408
|
+
console.error(`Instance '${name}' not found`);
|
|
409
|
+
process.exitCode = 1;
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (!connStr) {
|
|
414
|
+
console.error(`Connection string not found for instance '${name}'`);
|
|
415
|
+
process.exitCode = 1;
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
console.log(`Testing connection to '${name}'...`);
|
|
420
|
+
|
|
421
|
+
try {
|
|
422
|
+
const { stdout, stderr } = await execPromise(
|
|
423
|
+
`psql "${connStr}" -c "SELECT version();" --no-psqlrc`,
|
|
424
|
+
{ timeout: 10000, env: { ...process.env, PAGER: 'cat' } }
|
|
425
|
+
);
|
|
426
|
+
console.log(`✓ Connection successful`);
|
|
427
|
+
console.log(stdout.trim());
|
|
428
|
+
} catch (error) {
|
|
429
|
+
console.error(`✗ Connection failed: ${error.message}`);
|
|
430
|
+
process.exitCode = 1;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
334
433
|
|
|
335
434
|
// API key and grafana
|
|
336
435
|
program
|