postgresai 0.11.0-alpha.6 → 0.11.0-alpha.7
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 +167 -3
- package/package.json +1 -1
package/bin/postgres-ai.js
CHANGED
|
@@ -191,11 +191,128 @@ program
|
|
|
191
191
|
const code = await runCompose(["run", "--rm", "sources-generator"]);
|
|
192
192
|
if (code !== 0) process.exitCode = code;
|
|
193
193
|
});
|
|
194
|
-
program
|
|
194
|
+
program
|
|
195
|
+
.command("update")
|
|
196
|
+
.description("update project")
|
|
197
|
+
.action(async () => {
|
|
198
|
+
const { exec } = require("child_process");
|
|
199
|
+
const util = require("util");
|
|
200
|
+
const execPromise = util.promisify(exec);
|
|
201
|
+
const fs = require("fs");
|
|
202
|
+
const path = require("path");
|
|
203
|
+
|
|
204
|
+
console.log("Updating PostgresAI monitoring stack...\n");
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
// Check if we're in a git repo
|
|
208
|
+
const gitDir = path.resolve(process.cwd(), ".git");
|
|
209
|
+
if (!fs.existsSync(gitDir)) {
|
|
210
|
+
console.error("Not a git repository. Cannot update.");
|
|
211
|
+
process.exitCode = 1;
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Fetch latest changes
|
|
216
|
+
console.log("Fetching latest changes...");
|
|
217
|
+
await execPromise("git fetch origin");
|
|
218
|
+
|
|
219
|
+
// Check current branch
|
|
220
|
+
const { stdout: branch } = await execPromise("git rev-parse --abbrev-ref HEAD");
|
|
221
|
+
const currentBranch = branch.trim();
|
|
222
|
+
console.log(`Current branch: ${currentBranch}`);
|
|
223
|
+
|
|
224
|
+
// Pull latest changes
|
|
225
|
+
console.log("Pulling latest changes...");
|
|
226
|
+
const { stdout: pullOut } = await execPromise("git pull origin " + currentBranch);
|
|
227
|
+
console.log(pullOut);
|
|
228
|
+
|
|
229
|
+
// Update Docker images
|
|
230
|
+
console.log("\nUpdating Docker images...");
|
|
231
|
+
const code = await runCompose(["pull"]);
|
|
232
|
+
|
|
233
|
+
if (code === 0) {
|
|
234
|
+
console.log("\n✓ Update completed successfully");
|
|
235
|
+
console.log("\nTo apply updates, restart services:");
|
|
236
|
+
console.log(" postgres-ai restart");
|
|
237
|
+
} else {
|
|
238
|
+
console.error("\n✗ Docker image update failed");
|
|
239
|
+
process.exitCode = 1;
|
|
240
|
+
}
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error(`Update failed: ${error.message}`);
|
|
243
|
+
process.exitCode = 1;
|
|
244
|
+
}
|
|
245
|
+
});
|
|
195
246
|
program
|
|
196
247
|
.command("reset [service]")
|
|
197
248
|
.description("reset all or specific service")
|
|
198
|
-
.action(
|
|
249
|
+
.action(async (service) => {
|
|
250
|
+
const readline = require("readline");
|
|
251
|
+
const rl = readline.createInterface({
|
|
252
|
+
input: process.stdin,
|
|
253
|
+
output: process.stdout,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const question = (prompt) => new Promise((resolve) => rl.question(prompt, resolve));
|
|
257
|
+
|
|
258
|
+
try {
|
|
259
|
+
if (service) {
|
|
260
|
+
// Reset specific service
|
|
261
|
+
console.log(`\nThis will stop '${service}', remove its volume, and restart it.`);
|
|
262
|
+
console.log("All data for this service will be lost!\n");
|
|
263
|
+
|
|
264
|
+
const answer = await question("Continue? (y/N): ");
|
|
265
|
+
if (answer.toLowerCase() !== "y") {
|
|
266
|
+
console.log("Cancelled");
|
|
267
|
+
rl.close();
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
console.log(`\nStopping ${service}...`);
|
|
272
|
+
await runCompose(["stop", service]);
|
|
273
|
+
|
|
274
|
+
console.log(`Removing volume for ${service}...`);
|
|
275
|
+
await runCompose(["rm", "-f", "-v", service]);
|
|
276
|
+
|
|
277
|
+
console.log(`Restarting ${service}...`);
|
|
278
|
+
const code = await runCompose(["up", "-d", service]);
|
|
279
|
+
|
|
280
|
+
if (code === 0) {
|
|
281
|
+
console.log(`\n✓ Service '${service}' has been reset`);
|
|
282
|
+
} else {
|
|
283
|
+
console.error(`\n✗ Failed to restart '${service}'`);
|
|
284
|
+
process.exitCode = 1;
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
// Reset all services
|
|
288
|
+
console.log("\nThis will stop all services and remove all data!");
|
|
289
|
+
console.log("Volumes, networks, and containers will be deleted.\n");
|
|
290
|
+
|
|
291
|
+
const answer = await question("Continue? (y/N): ");
|
|
292
|
+
if (answer.toLowerCase() !== "y") {
|
|
293
|
+
console.log("Cancelled");
|
|
294
|
+
rl.close();
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
console.log("\nStopping services and removing data...");
|
|
299
|
+
const downCode = await runCompose(["down", "-v"]);
|
|
300
|
+
|
|
301
|
+
if (downCode === 0) {
|
|
302
|
+
console.log("✓ Environment reset completed - all containers and data removed");
|
|
303
|
+
} else {
|
|
304
|
+
console.error("✗ Reset failed");
|
|
305
|
+
process.exitCode = 1;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
rl.close();
|
|
310
|
+
} catch (error) {
|
|
311
|
+
rl.close();
|
|
312
|
+
console.error(`Reset failed: ${error.message}`);
|
|
313
|
+
process.exitCode = 1;
|
|
314
|
+
}
|
|
315
|
+
});
|
|
199
316
|
program
|
|
200
317
|
.command("clean")
|
|
201
318
|
.description("cleanup artifacts")
|
|
@@ -499,7 +616,54 @@ program
|
|
|
499
616
|
program
|
|
500
617
|
.command("generate-grafana-password")
|
|
501
618
|
.description("generate Grafana password")
|
|
502
|
-
.action(
|
|
619
|
+
.action(async () => {
|
|
620
|
+
const fs = require("fs");
|
|
621
|
+
const path = require("path");
|
|
622
|
+
const { exec } = require("child_process");
|
|
623
|
+
const util = require("util");
|
|
624
|
+
const execPromise = util.promisify(exec);
|
|
625
|
+
|
|
626
|
+
const cfgPath = path.resolve(process.cwd(), ".pgwatch-config");
|
|
627
|
+
|
|
628
|
+
try {
|
|
629
|
+
// Generate secure password using openssl
|
|
630
|
+
const { stdout: password } = await execPromise(
|
|
631
|
+
"openssl rand -base64 12 | tr -d '\n'"
|
|
632
|
+
);
|
|
633
|
+
const newPassword = password.trim();
|
|
634
|
+
|
|
635
|
+
if (!newPassword) {
|
|
636
|
+
console.error("Failed to generate password");
|
|
637
|
+
process.exitCode = 1;
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// Read existing config
|
|
642
|
+
let config = "";
|
|
643
|
+
if (fs.existsSync(cfgPath)) {
|
|
644
|
+
config = fs.readFileSync(cfgPath, "utf8");
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Update or add grafana_password
|
|
648
|
+
const lines = config.split(/\r?\n/).filter((l) => !/^grafana_password=/.test(l));
|
|
649
|
+
lines.push(`grafana_password=${newPassword}`);
|
|
650
|
+
|
|
651
|
+
// Write back
|
|
652
|
+
fs.writeFileSync(cfgPath, lines.filter(Boolean).join("\n") + "\n", "utf8");
|
|
653
|
+
|
|
654
|
+
console.log("✓ New Grafana password generated and saved");
|
|
655
|
+
console.log("\nNew credentials:");
|
|
656
|
+
console.log(" URL: http://localhost:3000");
|
|
657
|
+
console.log(" Username: monitor");
|
|
658
|
+
console.log(` Password: ${newPassword}`);
|
|
659
|
+
console.log("\nRestart Grafana to apply:");
|
|
660
|
+
console.log(" postgres-ai restart grafana");
|
|
661
|
+
} catch (error) {
|
|
662
|
+
console.error(`Failed to generate password: ${error.message}`);
|
|
663
|
+
console.error("\nNote: This command requires 'openssl' to be installed");
|
|
664
|
+
process.exitCode = 1;
|
|
665
|
+
}
|
|
666
|
+
});
|
|
503
667
|
program
|
|
504
668
|
.command("show-grafana-credentials")
|
|
505
669
|
.description("show Grafana credentials")
|