@_xtribe/cli 1.0.0-beta.12 → 1.0.0-beta.15
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/install-tribe.js +134 -23
- package/package.json +1 -1
package/install-tribe.js
CHANGED
|
@@ -392,14 +392,43 @@ async function checkColimaRunning() {
|
|
|
392
392
|
}
|
|
393
393
|
}
|
|
394
394
|
|
|
395
|
+
async function checkColimaHasKubernetes() {
|
|
396
|
+
try {
|
|
397
|
+
const colimaPath = await findCommand('colima') || path.join(binDir, 'colima');
|
|
398
|
+
const status = execSync(`${colimaPath} status`, { encoding: 'utf8' });
|
|
399
|
+
// Check if kubernetes is mentioned in the status
|
|
400
|
+
return status.toLowerCase().includes('kubernetes');
|
|
401
|
+
} catch {
|
|
402
|
+
return false;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
395
406
|
async function startColimaWithKubernetes() {
|
|
396
407
|
const spinner = ora('Starting Colima with Kubernetes...').start();
|
|
397
408
|
|
|
398
409
|
try {
|
|
399
410
|
// Check if already running
|
|
400
411
|
if (await checkColimaRunning()) {
|
|
401
|
-
|
|
402
|
-
|
|
412
|
+
// Check if it has Kubernetes enabled
|
|
413
|
+
if (await checkColimaHasKubernetes()) {
|
|
414
|
+
spinner.succeed('Colima is already running with Kubernetes');
|
|
415
|
+
return true;
|
|
416
|
+
} else {
|
|
417
|
+
spinner.text = 'Colima is running without Kubernetes. Restarting with Kubernetes...';
|
|
418
|
+
|
|
419
|
+
// Stop existing Colima
|
|
420
|
+
const colimaPath = await findCommand('colima') || path.join(binDir, 'colima');
|
|
421
|
+
try {
|
|
422
|
+
execSync(`${colimaPath} stop`, {
|
|
423
|
+
stdio: 'pipe',
|
|
424
|
+
timeout: 30000
|
|
425
|
+
});
|
|
426
|
+
// Wait for it to fully stop
|
|
427
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
428
|
+
} catch (stopError) {
|
|
429
|
+
log.warning('Failed to stop Colima, attempting to start anyway...');
|
|
430
|
+
}
|
|
431
|
+
}
|
|
403
432
|
}
|
|
404
433
|
|
|
405
434
|
// Start Colima with Kubernetes enabled
|
|
@@ -407,9 +436,14 @@ async function startColimaWithKubernetes() {
|
|
|
407
436
|
const colimaPath = await findCommand('colima') || path.join(binDir, 'colima');
|
|
408
437
|
execSync(`${colimaPath} start --kubernetes --cpu 4 --memory 8 --disk 20`, {
|
|
409
438
|
stdio: 'pipe',
|
|
410
|
-
env: { ...process.env, PATH: `${binDir}:${process.env.PATH}` }
|
|
439
|
+
env: { ...process.env, PATH: `${binDir}:${process.env.PATH}` },
|
|
440
|
+
timeout: 300000 // 5 minute timeout for first start
|
|
411
441
|
});
|
|
412
442
|
|
|
443
|
+
// Give Colima a moment to stabilize after starting
|
|
444
|
+
spinner.text = 'Waiting for Colima to stabilize...';
|
|
445
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
446
|
+
|
|
413
447
|
// Verify it's working and set context
|
|
414
448
|
const kubectlPath = await findCommand('kubectl') || 'kubectl';
|
|
415
449
|
execSync(`${kubectlPath} version --client`, { stdio: 'ignore' });
|
|
@@ -467,28 +501,89 @@ async function deployTribeCluster() {
|
|
|
467
501
|
TRIBE_DEPLOYMENT_YAML: destYaml
|
|
468
502
|
};
|
|
469
503
|
|
|
470
|
-
// Wait for Kubernetes
|
|
471
|
-
spinner.text = 'Waiting for Kubernetes
|
|
504
|
+
// Wait for Kubernetes to be fully ready
|
|
505
|
+
spinner.text = 'Waiting for Kubernetes to be ready...';
|
|
506
|
+
const kubectlPath = await findCommand('kubectl') || 'kubectl';
|
|
472
507
|
let apiReady = false;
|
|
508
|
+
let contextSet = false;
|
|
509
|
+
|
|
510
|
+
// First, wait for the API server to be accessible
|
|
473
511
|
for (let i = 0; i < 30; i++) {
|
|
474
512
|
try {
|
|
475
|
-
|
|
476
|
-
execSync(`${kubectlPath} cluster-info`, {
|
|
477
|
-
|
|
478
|
-
env: env
|
|
513
|
+
// Try to get cluster info - this will work regardless of port
|
|
514
|
+
const clusterInfo = execSync(`${kubectlPath} cluster-info`, {
|
|
515
|
+
encoding: 'utf8',
|
|
516
|
+
env: env,
|
|
517
|
+
stdio: 'pipe'
|
|
479
518
|
});
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
519
|
+
|
|
520
|
+
// Check if we got valid cluster info
|
|
521
|
+
if (clusterInfo && clusterInfo.includes('is running at')) {
|
|
522
|
+
apiReady = true;
|
|
523
|
+
spinner.text = 'Kubernetes API server is ready';
|
|
524
|
+
|
|
525
|
+
// Extract the actual API server URL for logging
|
|
526
|
+
const urlMatch = clusterInfo.match(/is running at (https?:\/\/[^\s]+)/);
|
|
527
|
+
if (urlMatch) {
|
|
528
|
+
log.info(`Kubernetes API server: ${urlMatch[1]}`);
|
|
529
|
+
}
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
} catch (error) {
|
|
533
|
+
spinner.text = `Waiting for Kubernetes API server... (${i+1}/30)`;
|
|
484
534
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
485
535
|
}
|
|
486
536
|
}
|
|
487
537
|
|
|
488
538
|
if (!apiReady) {
|
|
489
|
-
spinner.warn('Kubernetes API server not ready
|
|
539
|
+
spinner.warn('Kubernetes API server not ready after 60 seconds');
|
|
540
|
+
log.info('Deployment may fail. You can try running "tribe start" manually later.');
|
|
541
|
+
return false;
|
|
490
542
|
}
|
|
491
543
|
|
|
544
|
+
// Set the kubectl context to colima
|
|
545
|
+
spinner.text = 'Setting kubectl context...';
|
|
546
|
+
try {
|
|
547
|
+
execSync(`${kubectlPath} config use-context colima`, {
|
|
548
|
+
stdio: 'ignore',
|
|
549
|
+
env: env
|
|
550
|
+
});
|
|
551
|
+
contextSet = true;
|
|
552
|
+
} catch {
|
|
553
|
+
log.warning('Could not set kubectl context to colima');
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
// Wait for the node to be ready
|
|
557
|
+
spinner.text = 'Waiting for Kubernetes node to be ready...';
|
|
558
|
+
let nodeReady = false;
|
|
559
|
+
for (let i = 0; i < 20; i++) {
|
|
560
|
+
try {
|
|
561
|
+
const nodeStatus = execSync(`${kubectlPath} get nodes -o jsonpath='{.items[0].status.conditions[?(@.type=="Ready")].status}'`, {
|
|
562
|
+
encoding: 'utf8',
|
|
563
|
+
env: env
|
|
564
|
+
}).trim();
|
|
565
|
+
|
|
566
|
+
if (nodeStatus === 'True') {
|
|
567
|
+
nodeReady = true;
|
|
568
|
+
spinner.text = 'Kubernetes node is ready';
|
|
569
|
+
break;
|
|
570
|
+
}
|
|
571
|
+
} catch {
|
|
572
|
+
// Node might not be registered yet
|
|
573
|
+
}
|
|
574
|
+
spinner.text = `Waiting for Kubernetes node... (${i+1}/20)`;
|
|
575
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if (!nodeReady) {
|
|
579
|
+
spinner.warn('Kubernetes node not ready after 60 seconds');
|
|
580
|
+
log.info('The cluster may still be initializing. Proceeding with deployment...');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Small delay to let everything stabilize
|
|
584
|
+
spinner.text = 'Starting TRIBE deployment...';
|
|
585
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
586
|
+
|
|
492
587
|
// Execute tribe start
|
|
493
588
|
execSync(`${tribePath} start`, {
|
|
494
589
|
stdio: 'pipe',
|
|
@@ -504,7 +599,19 @@ async function deployTribeCluster() {
|
|
|
504
599
|
} catch (error) {
|
|
505
600
|
spinner.fail('Failed to deploy TRIBE cluster');
|
|
506
601
|
log.error(error.message);
|
|
507
|
-
|
|
602
|
+
|
|
603
|
+
// Check if this is a Kubernetes connectivity issue
|
|
604
|
+
if (error.message && error.message.includes('connection refused')) {
|
|
605
|
+
log.warning('\nIt appears Kubernetes is not ready or not enabled.');
|
|
606
|
+
log.info('Troubleshooting steps:');
|
|
607
|
+
log.info('1. Check Colima status: colima status');
|
|
608
|
+
log.info('2. If running without Kubernetes, restart it:');
|
|
609
|
+
log.info(' colima stop');
|
|
610
|
+
log.info(' colima start --kubernetes');
|
|
611
|
+
log.info('3. Then run: tribe start');
|
|
612
|
+
} else {
|
|
613
|
+
log.info('You can manually deploy later with: tribe start');
|
|
614
|
+
}
|
|
508
615
|
return false;
|
|
509
616
|
}
|
|
510
617
|
}
|
|
@@ -590,14 +697,11 @@ async function main() {
|
|
|
590
697
|
console.log('\n' + chalk.bold.green('✨ TRIBE is ready!'));
|
|
591
698
|
console.log('');
|
|
592
699
|
|
|
593
|
-
//
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
console.log(' ' + chalk.gray('or restart your terminal'));
|
|
599
|
-
console.log('');
|
|
600
|
-
}
|
|
700
|
+
// Always show PATH update reminder since npx runs in a subprocess
|
|
701
|
+
log.warning('To use tribe commands, update your PATH:');
|
|
702
|
+
console.log(chalk.yellow(` source ~/.${process.env.SHELL?.includes('zsh') ? 'zshrc' : 'bashrc'}`));
|
|
703
|
+
console.log(' ' + chalk.gray('or restart your terminal'));
|
|
704
|
+
console.log('');
|
|
601
705
|
|
|
602
706
|
log.info('Quick start:');
|
|
603
707
|
console.log(' tribe # Launch interactive CLI');
|
|
@@ -618,6 +722,13 @@ async function main() {
|
|
|
618
722
|
console.log('\n' + chalk.bold.green('✨ TRIBE is ready!'));
|
|
619
723
|
log.success('Cluster is already running');
|
|
620
724
|
console.log('');
|
|
725
|
+
|
|
726
|
+
// Always show PATH update reminder since npx runs in a subprocess
|
|
727
|
+
log.warning('To use tribe commands, update your PATH:');
|
|
728
|
+
console.log(chalk.yellow(` source ~/.${process.env.SHELL?.includes('zsh') ? 'zshrc' : 'bashrc'}`));
|
|
729
|
+
console.log(' ' + chalk.gray('or restart your terminal'));
|
|
730
|
+
console.log('');
|
|
731
|
+
|
|
621
732
|
log.info('Commands:');
|
|
622
733
|
console.log(' tribe # Launch interactive CLI');
|
|
623
734
|
console.log(' tribe status # Check status');
|