specmem-hardwicksoftware 3.5.21 → 3.5.22
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/package.json +1 -1
- package/scripts/global-postinstall.cjs +136 -49
package/package.json
CHANGED
|
@@ -274,56 +274,77 @@ function checkPostgres() {
|
|
|
274
274
|
function installPostgres() {
|
|
275
275
|
log.header('Installing PostgreSQL');
|
|
276
276
|
|
|
277
|
+
const PG_TIMEOUT = 180000; // 3 minute timeout for PG install
|
|
278
|
+
|
|
277
279
|
if (IS_MAC) {
|
|
278
280
|
log.step(1, 'Installing via Homebrew...');
|
|
279
281
|
|
|
280
282
|
// Check if Homebrew exists
|
|
281
283
|
if (!commandExists('brew')) {
|
|
282
284
|
log.info('Installing Homebrew first...');
|
|
283
|
-
run('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"');
|
|
285
|
+
run('/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"', { timeout: 300000 });
|
|
284
286
|
}
|
|
285
287
|
|
|
286
|
-
run('brew install postgresql@16');
|
|
287
|
-
run('brew services start postgresql@16');
|
|
288
|
+
run('brew install postgresql@16', { timeout: PG_TIMEOUT });
|
|
289
|
+
run('brew services start postgresql@16', { timeout: 30000 });
|
|
288
290
|
|
|
289
291
|
// Add to PATH
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
292
|
+
try {
|
|
293
|
+
const brewPrefix = execSync('brew --prefix', { encoding: 'utf8', timeout: 10000 }).trim();
|
|
294
|
+
const pgPath = `${brewPrefix}/opt/postgresql@16/bin`;
|
|
295
|
+
log.info(`Add to PATH: export PATH="${pgPath}:$PATH"`);
|
|
296
|
+
} catch (e) {}
|
|
293
297
|
|
|
294
298
|
} else if (IS_LINUX) {
|
|
295
299
|
log.step(1, 'Detecting Linux distribution...');
|
|
296
300
|
|
|
297
301
|
// Check for apt (Debian/Ubuntu)
|
|
298
302
|
if (commandExists('apt-get')) {
|
|
299
|
-
log.step(2, 'Installing via apt...');
|
|
300
|
-
run('sudo apt-get update');
|
|
301
|
-
run('sudo apt-get install -y postgresql postgresql-contrib');
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
log.step(2, 'Installing via apt (timeout: 3 min)...');
|
|
304
|
+
run('sudo apt-get update', { timeout: 60000 });
|
|
305
|
+
const result = run('sudo apt-get install -y postgresql postgresql-contrib', { timeout: PG_TIMEOUT });
|
|
306
|
+
if (!result.success) {
|
|
307
|
+
log.warn('PostgreSQL install timed out or failed');
|
|
308
|
+
log.info('Try manually: sudo apt-get install -y postgresql postgresql-contrib');
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
run('sudo systemctl start postgresql', { timeout: 30000 });
|
|
312
|
+
run('sudo systemctl enable postgresql', { timeout: 30000 });
|
|
304
313
|
}
|
|
305
314
|
// Check for yum/dnf (RHEL/CentOS/Fedora)
|
|
306
315
|
else if (commandExists('dnf')) {
|
|
307
|
-
log.step(2, 'Installing via dnf...');
|
|
308
|
-
run('sudo dnf install -y postgresql-server postgresql-contrib');
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
316
|
+
log.step(2, 'Installing via dnf (timeout: 3 min)...');
|
|
317
|
+
const result = run('sudo dnf install -y postgresql-server postgresql-contrib', { timeout: PG_TIMEOUT });
|
|
318
|
+
if (!result.success) {
|
|
319
|
+
log.warn('PostgreSQL install timed out');
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
run('sudo postgresql-setup --initdb', { timeout: 60000 });
|
|
323
|
+
run('sudo systemctl start postgresql', { timeout: 30000 });
|
|
324
|
+
run('sudo systemctl enable postgresql', { timeout: 30000 });
|
|
312
325
|
}
|
|
313
326
|
else if (commandExists('yum')) {
|
|
314
|
-
log.step(2, 'Installing via yum...');
|
|
315
|
-
run('sudo yum install -y postgresql-server postgresql-contrib');
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
327
|
+
log.step(2, 'Installing via yum (timeout: 3 min)...');
|
|
328
|
+
const result = run('sudo yum install -y postgresql-server postgresql-contrib', { timeout: PG_TIMEOUT });
|
|
329
|
+
if (!result.success) {
|
|
330
|
+
log.warn('PostgreSQL install timed out');
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
run('sudo postgresql-setup initdb', { timeout: 60000 });
|
|
334
|
+
run('sudo systemctl start postgresql', { timeout: 30000 });
|
|
335
|
+
run('sudo systemctl enable postgresql', { timeout: 30000 });
|
|
319
336
|
}
|
|
320
337
|
// Check for pacman (Arch)
|
|
321
338
|
else if (commandExists('pacman')) {
|
|
322
|
-
log.step(2, 'Installing via pacman...');
|
|
323
|
-
run('sudo pacman -S --noconfirm postgresql');
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
339
|
+
log.step(2, 'Installing via pacman (timeout: 3 min)...');
|
|
340
|
+
const result = run('sudo pacman -S --noconfirm postgresql', { timeout: PG_TIMEOUT });
|
|
341
|
+
if (!result.success) {
|
|
342
|
+
log.warn('PostgreSQL install timed out');
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
run('sudo -u postgres initdb -D /var/lib/postgres/data', { timeout: 60000 });
|
|
346
|
+
run('sudo systemctl start postgresql', { timeout: 30000 });
|
|
347
|
+
run('sudo systemctl enable postgresql', { timeout: 30000 });
|
|
327
348
|
}
|
|
328
349
|
else {
|
|
329
350
|
log.error('Could not detect package manager. Please install PostgreSQL manually.');
|
|
@@ -337,8 +358,9 @@ function installPostgres() {
|
|
|
337
358
|
return false;
|
|
338
359
|
}
|
|
339
360
|
|
|
340
|
-
// Verify installation
|
|
341
|
-
|
|
361
|
+
// Verify installation with timeout
|
|
362
|
+
log.info('Verifying PostgreSQL installation...');
|
|
363
|
+
const check = run('pg_isready', { silent: true, timeout: 10000 });
|
|
342
364
|
if (check.success) {
|
|
343
365
|
log.success('PostgreSQL installed and running!');
|
|
344
366
|
return true;
|
|
@@ -347,12 +369,23 @@ function installPostgres() {
|
|
|
347
369
|
// Try starting the service
|
|
348
370
|
log.info('Trying to start PostgreSQL service...');
|
|
349
371
|
if (IS_MAC) {
|
|
350
|
-
run('brew services start postgresql@16');
|
|
372
|
+
run('brew services start postgresql@16', { timeout: 30000 });
|
|
351
373
|
} else if (IS_LINUX) {
|
|
352
|
-
run('sudo systemctl start postgresql');
|
|
374
|
+
run('sudo systemctl start postgresql', { timeout: 30000 });
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Wait up to 30 seconds for PG to be ready
|
|
378
|
+
for (let i = 0; i < 6; i++) {
|
|
379
|
+
if (run('pg_isready', { silent: true, timeout: 5000 }).success) {
|
|
380
|
+
log.success('PostgreSQL is ready');
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
log.info('Waiting for PostgreSQL to start...');
|
|
384
|
+
run('sleep 5', { silent: true });
|
|
353
385
|
}
|
|
354
386
|
|
|
355
|
-
|
|
387
|
+
log.warn('PostgreSQL may not be fully started - continuing anyway');
|
|
388
|
+
return true; // Continue setup, might work
|
|
356
389
|
}
|
|
357
390
|
|
|
358
391
|
// ============================================================================
|
|
@@ -367,7 +400,7 @@ function checkPgvector() {
|
|
|
367
400
|
|
|
368
401
|
const result = run(
|
|
369
402
|
`sudo -u postgres psql -c "SELECT 1 FROM pg_available_extensions WHERE name = 'vector';" 2>/dev/null`,
|
|
370
|
-
{ silent: true }
|
|
403
|
+
{ silent: true, timeout: 15000 }
|
|
371
404
|
);
|
|
372
405
|
|
|
373
406
|
if (result.success && result.output && result.output.includes('1')) {
|
|
@@ -385,30 +418,33 @@ function checkPgvector() {
|
|
|
385
418
|
function installPgvector() {
|
|
386
419
|
log.header('Installing pgvector Extension');
|
|
387
420
|
|
|
421
|
+
const PGVECTOR_TIMEOUT = 120000; // 2 minute timeout
|
|
422
|
+
|
|
388
423
|
if (IS_MAC) {
|
|
389
424
|
log.step(1, 'Installing pgvector via Homebrew...');
|
|
390
|
-
run('brew install pgvector');
|
|
425
|
+
run('brew install pgvector', { timeout: PGVECTOR_TIMEOUT });
|
|
391
426
|
|
|
392
427
|
} else if (IS_LINUX) {
|
|
393
428
|
// Try apt first (Ubuntu/Debian have pgvector in repos now)
|
|
394
429
|
if (commandExists('apt-get')) {
|
|
395
|
-
log.step(1, 'Trying apt install...');
|
|
396
|
-
const aptResult = run('sudo apt-get install -y postgresql-16-pgvector 2>/dev/null || sudo apt-get install -y postgresql-pgvector 2>/dev/null', { silent: true });
|
|
430
|
+
log.step(1, 'Trying apt install (timeout: 2 min)...');
|
|
431
|
+
const aptResult = run('sudo apt-get install -y postgresql-16-pgvector 2>/dev/null || sudo apt-get install -y postgresql-pgvector 2>/dev/null', { silent: true, timeout: PGVECTOR_TIMEOUT });
|
|
397
432
|
|
|
398
433
|
if (!aptResult.success) {
|
|
399
|
-
log.step(2, 'Building pgvector from source...');
|
|
434
|
+
log.step(2, 'Building pgvector from source (timeout: 3 min)...');
|
|
400
435
|
buildPgvectorFromSource();
|
|
401
436
|
}
|
|
402
437
|
} else {
|
|
403
|
-
log.step(1, 'Building pgvector from source...');
|
|
438
|
+
log.step(1, 'Building pgvector from source (timeout: 3 min)...');
|
|
404
439
|
buildPgvectorFromSource();
|
|
405
440
|
}
|
|
406
441
|
}
|
|
407
442
|
|
|
408
|
-
// Verify
|
|
443
|
+
// Verify with timeout
|
|
444
|
+
log.info('Verifying pgvector installation...');
|
|
409
445
|
const check = run(
|
|
410
446
|
`sudo -u postgres psql -c "SELECT 1 FROM pg_available_extensions WHERE name = 'vector';" 2>/dev/null`,
|
|
411
|
-
{ silent: true }
|
|
447
|
+
{ silent: true, timeout: 15000 }
|
|
412
448
|
);
|
|
413
449
|
|
|
414
450
|
if (check.success && check.output && check.output.includes('1')) {
|
|
@@ -416,7 +452,8 @@ function installPgvector() {
|
|
|
416
452
|
return true;
|
|
417
453
|
}
|
|
418
454
|
|
|
419
|
-
log.warn('pgvector may
|
|
455
|
+
log.warn('pgvector install may have timed out - continuing anyway');
|
|
456
|
+
log.info('SpecMem can work without pgvector (reduced functionality)');
|
|
420
457
|
return false;
|
|
421
458
|
}
|
|
422
459
|
|
|
@@ -426,21 +463,33 @@ function installPgvector() {
|
|
|
426
463
|
function buildPgvectorFromSource() {
|
|
427
464
|
log.info('Building pgvector from source...');
|
|
428
465
|
|
|
466
|
+
const BUILD_TIMEOUT = 180000; // 3 minute timeout for build
|
|
467
|
+
|
|
429
468
|
// Install build dependencies
|
|
430
469
|
if (commandExists('apt-get')) {
|
|
431
|
-
run('sudo apt-get install -y build-essential git postgresql-server-dev-all');
|
|
470
|
+
run('sudo apt-get install -y build-essential git postgresql-server-dev-all', { timeout: 120000 });
|
|
432
471
|
} else if (commandExists('dnf')) {
|
|
433
|
-
run('sudo dnf install -y gcc make git postgresql-devel');
|
|
472
|
+
run('sudo dnf install -y gcc make git postgresql-devel', { timeout: 120000 });
|
|
434
473
|
} else if (commandExists('yum')) {
|
|
435
|
-
run('sudo yum install -y gcc make git postgresql-devel');
|
|
474
|
+
run('sudo yum install -y gcc make git postgresql-devel', { timeout: 120000 });
|
|
436
475
|
}
|
|
437
476
|
|
|
438
|
-
// Clone and build
|
|
477
|
+
// Clone and build with timeout
|
|
439
478
|
const tmpDir = '/tmp/pgvector-build';
|
|
440
|
-
run(`rm -rf ${tmpDir}
|
|
441
|
-
|
|
442
|
-
run(`
|
|
443
|
-
|
|
479
|
+
run(`rm -rf ${tmpDir}`, { timeout: 10000 });
|
|
480
|
+
|
|
481
|
+
const cloneResult = run(`git clone --branch v0.7.4 https://github.com/pgvector/pgvector.git ${tmpDir}`, { timeout: 60000 });
|
|
482
|
+
if (!cloneResult.success) {
|
|
483
|
+
log.warn('Failed to clone pgvector repo - skipping');
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const buildResult = run(`cd ${tmpDir} && make && sudo make install`, { timeout: BUILD_TIMEOUT });
|
|
488
|
+
if (!buildResult.success) {
|
|
489
|
+
log.warn('pgvector build timed out or failed');
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
run(`rm -rf ${tmpDir}`, { timeout: 10000 });
|
|
444
493
|
}
|
|
445
494
|
|
|
446
495
|
// ============================================================================
|
|
@@ -821,6 +870,7 @@ function installDockerLinux() {
|
|
|
821
870
|
|
|
822
871
|
/**
|
|
823
872
|
* Configure Docker for non-root usage on Linux
|
|
873
|
+
* SECURITY: Binds Docker to 127.0.0.1 only (no external access)
|
|
824
874
|
*/
|
|
825
875
|
function configureDockerLinux() {
|
|
826
876
|
log.step('→', 'Configuring Docker for non-root usage...');
|
|
@@ -830,9 +880,46 @@ function configureDockerLinux() {
|
|
|
830
880
|
// Add user to docker group
|
|
831
881
|
run(`sudo usermod -aG docker ${user}`);
|
|
832
882
|
|
|
883
|
+
// SECURITY: Configure Docker to bind to localhost only
|
|
884
|
+
log.step('→', 'Securing Docker to localhost only (127.0.0.1)...');
|
|
885
|
+
const daemonConfig = {
|
|
886
|
+
"iptables": true,
|
|
887
|
+
"ip": "127.0.0.1",
|
|
888
|
+
"ip-forward": false,
|
|
889
|
+
"userland-proxy": true,
|
|
890
|
+
"live-restore": true,
|
|
891
|
+
"log-driver": "json-file",
|
|
892
|
+
"log-opts": {
|
|
893
|
+
"max-size": "10m",
|
|
894
|
+
"max-file": "3"
|
|
895
|
+
}
|
|
896
|
+
};
|
|
897
|
+
|
|
898
|
+
try {
|
|
899
|
+
const daemonJsonPath = '/etc/docker/daemon.json';
|
|
900
|
+
run('sudo mkdir -p /etc/docker');
|
|
901
|
+
|
|
902
|
+
// Check if config exists and merge
|
|
903
|
+
let existingConfig = {};
|
|
904
|
+
if (fs.existsSync(daemonJsonPath)) {
|
|
905
|
+
try {
|
|
906
|
+
existingConfig = JSON.parse(fs.readFileSync(daemonJsonPath, 'utf8'));
|
|
907
|
+
} catch (e) {}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
const mergedConfig = { ...existingConfig, ...daemonConfig };
|
|
911
|
+
const configJson = JSON.stringify(mergedConfig, null, 2);
|
|
912
|
+
|
|
913
|
+
// Write via sudo
|
|
914
|
+
run(`echo '${configJson}' | sudo tee ${daemonJsonPath}`);
|
|
915
|
+
log.success('Docker configured for localhost-only access (127.0.0.1)');
|
|
916
|
+
} catch (e) {
|
|
917
|
+
log.warn('Could not configure Docker daemon.json - manual security review recommended');
|
|
918
|
+
}
|
|
919
|
+
|
|
833
920
|
// Enable and start Docker service
|
|
834
921
|
run('sudo systemctl enable docker');
|
|
835
|
-
run('sudo systemctl
|
|
922
|
+
run('sudo systemctl restart docker'); // Restart to apply new config
|
|
836
923
|
|
|
837
924
|
// Set up Docker to start on boot
|
|
838
925
|
run('sudo systemctl enable containerd');
|