584 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			584 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import * as plugins from './mod.plugins.js';
 | 
						|
import * as helpers from './helpers.js';
 | 
						|
import { ServiceConfiguration } from './classes.serviceconfiguration.js';
 | 
						|
import { DockerContainer } from './classes.dockercontainer.js';
 | 
						|
import { logger } from '../gitzone.logging.js';
 | 
						|
 | 
						|
export class ServiceManager {
 | 
						|
  private config: ServiceConfiguration;
 | 
						|
  private docker: DockerContainer;
 | 
						|
  
 | 
						|
  constructor() {
 | 
						|
    this.config = new ServiceConfiguration();
 | 
						|
    this.docker = new DockerContainer();
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Initialize the service manager
 | 
						|
   */
 | 
						|
  public async init(): Promise<void> {
 | 
						|
    // Check Docker availability
 | 
						|
    if (!(await this.docker.checkDocker())) {
 | 
						|
      logger.log('error', 'Error: Docker is not installed. Please install Docker first.');
 | 
						|
      process.exit(1);
 | 
						|
    }
 | 
						|
    
 | 
						|
    // Load or create configuration
 | 
						|
    await this.config.loadOrCreate();
 | 
						|
    logger.log('info', `📋 Project: ${this.config.getConfig().PROJECT_NAME}`);
 | 
						|
    
 | 
						|
    // Validate and update ports if needed
 | 
						|
    await this.config.validateAndUpdatePorts();
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Start MongoDB service
 | 
						|
   */
 | 
						|
  public async startMongoDB(): Promise<void> {
 | 
						|
    logger.log('note', '📦 MongoDB:');
 | 
						|
    
 | 
						|
    const config = this.config.getConfig();
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    const directories = this.config.getDataDirectories();
 | 
						|
    
 | 
						|
    // Ensure data directory exists
 | 
						|
    await plugins.smartfile.fs.ensureDir(directories.mongo);
 | 
						|
    
 | 
						|
    const status = await this.docker.getStatus(containers.mongo);
 | 
						|
    
 | 
						|
    switch (status) {
 | 
						|
      case 'running':
 | 
						|
        logger.log('ok', '  Already running ✓');
 | 
						|
        break;
 | 
						|
        
 | 
						|
      case 'stopped':
 | 
						|
        // Check if port mapping matches config
 | 
						|
        const mongoPortMappings = await this.docker.getPortMappings(containers.mongo);
 | 
						|
        if (mongoPortMappings && mongoPortMappings['27017'] !== config.MONGODB_PORT) {
 | 
						|
          logger.log('note', '  Port configuration changed, recreating container...');
 | 
						|
          await this.docker.remove(containers.mongo, true);
 | 
						|
          // Fall through to create new container
 | 
						|
          const success = await this.docker.run({
 | 
						|
            name: containers.mongo,
 | 
						|
            image: 'mongo:7.0',
 | 
						|
            ports: {
 | 
						|
              [`0.0.0.0:${config.MONGODB_PORT}`]: '27017'
 | 
						|
            },
 | 
						|
            volumes: {
 | 
						|
              [directories.mongo]: '/data/db'
 | 
						|
            },
 | 
						|
            environment: {
 | 
						|
              MONGO_INITDB_ROOT_USERNAME: config.MONGODB_USER,
 | 
						|
              MONGO_INITDB_ROOT_PASSWORD: config.MONGODB_PASS,
 | 
						|
              MONGO_INITDB_DATABASE: config.MONGODB_NAME
 | 
						|
            },
 | 
						|
            restart: 'unless-stopped',
 | 
						|
            command: '--bind_ip_all'
 | 
						|
          });
 | 
						|
          
 | 
						|
          if (success) {
 | 
						|
            logger.log('ok', '  Recreated with new port ✓');
 | 
						|
          } else {
 | 
						|
            logger.log('error', '  Failed to recreate container');
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          // Ports match, just start the container
 | 
						|
          if (await this.docker.start(containers.mongo)) {
 | 
						|
            logger.log('ok', '  Started ✓');
 | 
						|
          } else {
 | 
						|
            logger.log('error', '  Failed to start');
 | 
						|
          }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        
 | 
						|
      case 'not_exists':
 | 
						|
        logger.log('note', '  Creating container...');
 | 
						|
        
 | 
						|
        const success = await this.docker.run({
 | 
						|
          name: containers.mongo,
 | 
						|
          image: 'mongo:7.0',
 | 
						|
          ports: {
 | 
						|
            [`0.0.0.0:${config.MONGODB_PORT}`]: '27017'
 | 
						|
          },
 | 
						|
          volumes: {
 | 
						|
            [directories.mongo]: '/data/db'
 | 
						|
          },
 | 
						|
          environment: {
 | 
						|
            MONGO_INITDB_ROOT_USERNAME: config.MONGODB_USER,
 | 
						|
            MONGO_INITDB_ROOT_PASSWORD: config.MONGODB_PASS,
 | 
						|
            MONGO_INITDB_DATABASE: config.MONGODB_NAME
 | 
						|
          },
 | 
						|
          restart: 'unless-stopped',
 | 
						|
          command: '--bind_ip_all'
 | 
						|
        });
 | 
						|
        
 | 
						|
        if (success) {
 | 
						|
          logger.log('ok', '  Created and started ✓');
 | 
						|
        } else {
 | 
						|
          logger.log('error', '  Failed to create container');
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    
 | 
						|
    logger.log('info', `  Container: ${containers.mongo}`);
 | 
						|
    logger.log('info', `  Port: ${config.MONGODB_PORT}`);
 | 
						|
    logger.log('info', `  Connection: ${this.config.getMongoConnectionString()}`);
 | 
						|
    
 | 
						|
    // Show Compass connection string
 | 
						|
    const networkIp = await helpers.getLocalNetworkIp();
 | 
						|
    const compassString = `mongodb://${config.MONGODB_USER}:${config.MONGODB_PASS}@${networkIp}:${config.MONGODB_PORT}/${config.MONGODB_NAME}?authSource=admin`;
 | 
						|
    logger.log('ok', `  Compass: ${compassString}`);
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Start MinIO service
 | 
						|
   */
 | 
						|
  public async startMinIO(): Promise<void> {
 | 
						|
    logger.log('note', '📦 S3/MinIO:');
 | 
						|
    
 | 
						|
    const config = this.config.getConfig();
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    const directories = this.config.getDataDirectories();
 | 
						|
    
 | 
						|
    // Ensure data directory exists
 | 
						|
    await plugins.smartfile.fs.ensureDir(directories.minio);
 | 
						|
    
 | 
						|
    const status = await this.docker.getStatus(containers.minio);
 | 
						|
    
 | 
						|
    switch (status) {
 | 
						|
      case 'running':
 | 
						|
        logger.log('ok', '  Already running ✓');
 | 
						|
        break;
 | 
						|
        
 | 
						|
      case 'stopped':
 | 
						|
        // Check if port mapping matches config
 | 
						|
        const minioPortMappings = await this.docker.getPortMappings(containers.minio);
 | 
						|
        if (minioPortMappings && 
 | 
						|
            (minioPortMappings['9000'] !== config.S3_PORT || 
 | 
						|
             minioPortMappings['9001'] !== config.S3_CONSOLE_PORT)) {
 | 
						|
          logger.log('note', '  Port configuration changed, recreating container...');
 | 
						|
          await this.docker.remove(containers.minio, true);
 | 
						|
          // Fall through to create new container
 | 
						|
          const success = await this.docker.run({
 | 
						|
            name: containers.minio,
 | 
						|
            image: 'minio/minio',
 | 
						|
            ports: {
 | 
						|
              [config.S3_PORT]: '9000',
 | 
						|
              [config.S3_CONSOLE_PORT]: '9001'
 | 
						|
            },
 | 
						|
            volumes: {
 | 
						|
              [directories.minio]: '/data'
 | 
						|
            },
 | 
						|
            environment: {
 | 
						|
              MINIO_ROOT_USER: config.S3_ACCESSKEY,
 | 
						|
              MINIO_ROOT_PASSWORD: config.S3_SECRETKEY
 | 
						|
            },
 | 
						|
            restart: 'unless-stopped',
 | 
						|
            command: 'server /data --console-address ":9001"'
 | 
						|
          });
 | 
						|
          
 | 
						|
          if (success) {
 | 
						|
            logger.log('ok', '  Recreated with new ports ✓');
 | 
						|
            
 | 
						|
            // Wait for MinIO to be ready
 | 
						|
            await plugins.smartdelay.delayFor(3000);
 | 
						|
            
 | 
						|
            // Create default bucket
 | 
						|
            await this.docker.exec(
 | 
						|
              containers.minio,
 | 
						|
              `mc alias set local http://localhost:9000 ${config.S3_ACCESSKEY} ${config.S3_SECRETKEY}`
 | 
						|
            );
 | 
						|
            
 | 
						|
            await this.docker.exec(
 | 
						|
              containers.minio,
 | 
						|
              `mc mb local/${config.S3_BUCKET}`
 | 
						|
            );
 | 
						|
            
 | 
						|
            logger.log('ok', `  Bucket '${config.S3_BUCKET}' created ✓`);
 | 
						|
          } else {
 | 
						|
            logger.log('error', '  Failed to recreate container');
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          // Ports match, just start the container
 | 
						|
          if (await this.docker.start(containers.minio)) {
 | 
						|
            logger.log('ok', '  Started ✓');
 | 
						|
          } else {
 | 
						|
            logger.log('error', '  Failed to start');
 | 
						|
          }
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        
 | 
						|
      case 'not_exists':
 | 
						|
        logger.log('note', '  Creating container...');
 | 
						|
        
 | 
						|
        const success = await this.docker.run({
 | 
						|
          name: containers.minio,
 | 
						|
          image: 'minio/minio',
 | 
						|
          ports: {
 | 
						|
            [config.S3_PORT]: '9000',
 | 
						|
            [config.S3_CONSOLE_PORT]: '9001'
 | 
						|
          },
 | 
						|
          volumes: {
 | 
						|
            [directories.minio]: '/data'
 | 
						|
          },
 | 
						|
          environment: {
 | 
						|
            MINIO_ROOT_USER: config.S3_ACCESSKEY,
 | 
						|
            MINIO_ROOT_PASSWORD: config.S3_SECRETKEY
 | 
						|
          },
 | 
						|
          restart: 'unless-stopped',
 | 
						|
          command: 'server /data --console-address ":9001"'
 | 
						|
        });
 | 
						|
        
 | 
						|
        if (success) {
 | 
						|
          logger.log('ok', '  Created and started ✓');
 | 
						|
          
 | 
						|
          // Wait for MinIO to be ready
 | 
						|
          await plugins.smartdelay.delayFor(3000);
 | 
						|
          
 | 
						|
          // Create default bucket
 | 
						|
          await this.docker.exec(
 | 
						|
            containers.minio,
 | 
						|
            `mc alias set local http://localhost:9000 ${config.S3_ACCESSKEY} ${config.S3_SECRETKEY}`
 | 
						|
          );
 | 
						|
          
 | 
						|
          await this.docker.exec(
 | 
						|
            containers.minio,
 | 
						|
            `mc mb local/${config.S3_BUCKET}`
 | 
						|
          );
 | 
						|
          
 | 
						|
          logger.log('ok', `  Bucket '${config.S3_BUCKET}' created ✓`);
 | 
						|
        } else {
 | 
						|
          logger.log('error', '  Failed to create container');
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    
 | 
						|
    logger.log('info', `  Container: ${containers.minio}`);
 | 
						|
    logger.log('info', `  Port: ${config.S3_PORT}`);
 | 
						|
    logger.log('info', `  Bucket: ${config.S3_BUCKET}`);
 | 
						|
    logger.log('info', `  API: http://${config.S3_HOST}:${config.S3_PORT}`);
 | 
						|
    logger.log('info', `  Console: http://${config.S3_HOST}:${config.S3_CONSOLE_PORT} (login: ${config.S3_ACCESSKEY}/***)`);
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Stop MongoDB service
 | 
						|
   */
 | 
						|
  public async stopMongoDB(): Promise<void> {
 | 
						|
    logger.log('note', '📦 MongoDB:');
 | 
						|
    
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    const status = await this.docker.getStatus(containers.mongo);
 | 
						|
    
 | 
						|
    if (status === 'running') {
 | 
						|
      if (await this.docker.stop(containers.mongo)) {
 | 
						|
        logger.log('ok', '  Stopped ✓');
 | 
						|
      } else {
 | 
						|
        logger.log('error', '  Failed to stop');
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      logger.log('note', '  Not running');
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Stop MinIO service
 | 
						|
   */
 | 
						|
  public async stopMinIO(): Promise<void> {
 | 
						|
    logger.log('note', '📦 S3/MinIO:');
 | 
						|
    
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    const status = await this.docker.getStatus(containers.minio);
 | 
						|
    
 | 
						|
    if (status === 'running') {
 | 
						|
      if (await this.docker.stop(containers.minio)) {
 | 
						|
        logger.log('ok', '  Stopped ✓');
 | 
						|
      } else {
 | 
						|
        logger.log('error', '  Failed to stop');
 | 
						|
      }
 | 
						|
    } else {
 | 
						|
      logger.log('note', '  Not running');
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Show service status
 | 
						|
   */
 | 
						|
  public async showStatus(): Promise<void> {
 | 
						|
    helpers.printHeader('Service Status');
 | 
						|
    
 | 
						|
    const config = this.config.getConfig();
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    
 | 
						|
    logger.log('info', `Project: ${config.PROJECT_NAME}`);
 | 
						|
    console.log();
 | 
						|
    
 | 
						|
    // MongoDB status
 | 
						|
    const mongoStatus = await this.docker.getStatus(containers.mongo);
 | 
						|
    switch (mongoStatus) {
 | 
						|
      case 'running':
 | 
						|
        logger.log('ok', '📦 MongoDB: 🟢 Running');
 | 
						|
        logger.log('info', `   ├─ Container: ${containers.mongo}`);
 | 
						|
        logger.log('info', `   ├─ Port: ${config.MONGODB_PORT}`);
 | 
						|
        logger.log('info', `   ├─ Connection: ${this.config.getMongoConnectionString()}`);
 | 
						|
        
 | 
						|
        // Show Compass connection string
 | 
						|
        const networkIp = await helpers.getLocalNetworkIp();
 | 
						|
        const compassString = `mongodb://${config.MONGODB_USER}:${config.MONGODB_PASS}@${networkIp}:${config.MONGODB_PORT}/${config.MONGODB_NAME}?authSource=admin`;
 | 
						|
        logger.log('ok', `   └─ Compass: ${compassString}`);
 | 
						|
        break;
 | 
						|
      case 'stopped':
 | 
						|
        logger.log('note', '📦 MongoDB: 🟡 Stopped');
 | 
						|
        logger.log('info', `   ├─ Container: ${containers.mongo}`);
 | 
						|
        logger.log('info', `   └─ Port: ${config.MONGODB_PORT}`);
 | 
						|
        break;
 | 
						|
      case 'not_exists':
 | 
						|
        logger.log('info', '📦 MongoDB: ⚪ Not installed');
 | 
						|
        // Check port availability
 | 
						|
        const mongoPort = parseInt(config.MONGODB_PORT);
 | 
						|
        const mongoAvailable = await helpers.isPortAvailable(mongoPort);
 | 
						|
        if (!mongoAvailable) {
 | 
						|
          logger.log('error', `   └─ ⚠️  Port ${mongoPort} is in use by another process`);
 | 
						|
        } else {
 | 
						|
          logger.log('info', `   └─ Port ${mongoPort} is available`);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
    
 | 
						|
    // MinIO status
 | 
						|
    const minioStatus = await this.docker.getStatus(containers.minio);
 | 
						|
    switch (minioStatus) {
 | 
						|
      case 'running':
 | 
						|
        logger.log('ok', '📦 S3/MinIO: 🟢 Running');
 | 
						|
        logger.log('info', `   ├─ Container: ${containers.minio}`);
 | 
						|
        logger.log('info', `   ├─ API: http://${config.S3_HOST}:${config.S3_PORT}`);
 | 
						|
        logger.log('info', `   ├─ Console: http://${config.S3_HOST}:${config.S3_CONSOLE_PORT}`);
 | 
						|
        logger.log('info', `   └─ Bucket: ${config.S3_BUCKET}`);
 | 
						|
        break;
 | 
						|
      case 'stopped':
 | 
						|
        logger.log('note', '📦 S3/MinIO: 🟡 Stopped');
 | 
						|
        logger.log('info', `   ├─ Container: ${containers.minio}`);
 | 
						|
        logger.log('info', `   ├─ API Port: ${config.S3_PORT}`);
 | 
						|
        logger.log('info', `   └─ Console Port: ${config.S3_CONSOLE_PORT}`);
 | 
						|
        break;
 | 
						|
      case 'not_exists':
 | 
						|
        logger.log('info', '📦 S3/MinIO: ⚪ Not installed');
 | 
						|
        // Check port availability
 | 
						|
        const s3Port = parseInt(config.S3_PORT);
 | 
						|
        const s3ConsolePort = parseInt(config.S3_CONSOLE_PORT);
 | 
						|
        const s3Available = await helpers.isPortAvailable(s3Port);
 | 
						|
        const consoleAvailable = await helpers.isPortAvailable(s3ConsolePort);
 | 
						|
        
 | 
						|
        if (!s3Available || !consoleAvailable) {
 | 
						|
          if (!s3Available) {
 | 
						|
            logger.log('error', `   ├─ ⚠️  API Port ${s3Port} is in use`);
 | 
						|
          } else {
 | 
						|
            logger.log('info', `   ├─ API Port ${s3Port} is available`);
 | 
						|
          }
 | 
						|
          if (!consoleAvailable) {
 | 
						|
            logger.log('error', `   └─ ⚠️  Console Port ${s3ConsolePort} is in use`);
 | 
						|
          } else {
 | 
						|
            logger.log('info', `   └─ Console Port ${s3ConsolePort} is available`);
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          logger.log('info', `   ├─ API Port ${s3Port} is available`);
 | 
						|
          logger.log('info', `   └─ Console Port ${s3ConsolePort} is available`);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Show configuration
 | 
						|
   */
 | 
						|
  public async showConfig(): Promise<void> {
 | 
						|
    helpers.printHeader('Current Configuration');
 | 
						|
    
 | 
						|
    const config = this.config.getConfig();
 | 
						|
    
 | 
						|
    logger.log('info', `Project: ${config.PROJECT_NAME}`);
 | 
						|
    console.log();
 | 
						|
    
 | 
						|
    logger.log('note', 'MongoDB:');
 | 
						|
    logger.log('info', `  Host: ${config.MONGODB_HOST}:${config.MONGODB_PORT}`);
 | 
						|
    logger.log('info', `  Database: ${config.MONGODB_NAME}`);
 | 
						|
    logger.log('info', `  User: ${config.MONGODB_USER}`);
 | 
						|
    logger.log('info', '  Password: ***');
 | 
						|
    logger.log('info', `  Container: ${this.config.getContainerNames().mongo}`);
 | 
						|
    logger.log('info', `  Data: ${this.config.getDataDirectories().mongo}`);
 | 
						|
    logger.log('info', `  Connection: ${this.config.getMongoConnectionString()}`);
 | 
						|
    
 | 
						|
    console.log();
 | 
						|
    logger.log('note', 'S3/MinIO:');
 | 
						|
    logger.log('info', `  Host: ${config.S3_HOST}`);
 | 
						|
    logger.log('info', `  API Port: ${config.S3_PORT}`);
 | 
						|
    logger.log('info', `  Console Port: ${config.S3_CONSOLE_PORT}`);
 | 
						|
    logger.log('info', `  Access Key: ${config.S3_ACCESSKEY}`);
 | 
						|
    logger.log('info', '  Secret Key: ***');
 | 
						|
    logger.log('info', `  Bucket: ${config.S3_BUCKET}`);
 | 
						|
    logger.log('info', `  Use SSL: ${config.S3_USESSL}`);
 | 
						|
    logger.log('info', `  Container: ${this.config.getContainerNames().minio}`);
 | 
						|
    logger.log('info', `  Data: ${this.config.getDataDirectories().minio}`);
 | 
						|
    logger.log('info', `  Endpoint: ${config.S3_ENDPOINT}`);
 | 
						|
    logger.log('info', `  Console URL: http://${config.S3_HOST}:${config.S3_CONSOLE_PORT}`);
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Show MongoDB Compass connection string
 | 
						|
   */
 | 
						|
  public async showCompassConnection(): Promise<void> {
 | 
						|
    helpers.printHeader('MongoDB Compass Connection');
 | 
						|
    
 | 
						|
    const config = this.config.getConfig();
 | 
						|
    const networkIp = await helpers.getLocalNetworkIp();
 | 
						|
    
 | 
						|
    const connectionString = `mongodb://${config.MONGODB_USER}:${config.MONGODB_PASS}@${networkIp}:${config.MONGODB_PORT}/${config.MONGODB_NAME}?authSource=admin`;
 | 
						|
    
 | 
						|
    logger.log('info', 'MongoDB Compass is a GUI tool for MongoDB. To connect:');
 | 
						|
    console.log();
 | 
						|
    logger.log('info', '1. Download MongoDB Compass from:');
 | 
						|
    logger.log('info', '   https://www.mongodb.com/products/compass');
 | 
						|
    console.log();
 | 
						|
    logger.log('info', '2. Open Compass and paste this connection string:');
 | 
						|
    logger.log('ok', `   ${connectionString}`);
 | 
						|
    console.log();
 | 
						|
    logger.log('note', 'Connection Details:');
 | 
						|
    logger.log('info', `  Network IP: ${networkIp}`);
 | 
						|
    logger.log('info', `  Port: ${config.MONGODB_PORT}`);
 | 
						|
    logger.log('info', `  Database: ${config.MONGODB_NAME}`);
 | 
						|
    logger.log('info', `  Username: ${config.MONGODB_USER}`);
 | 
						|
    logger.log('info', `  Auth Source: admin`);
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Show logs for a service
 | 
						|
   */
 | 
						|
  public async showLogs(service: string, lines: number = 20): Promise<void> {
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    
 | 
						|
    switch (service) {
 | 
						|
      case 'mongo':
 | 
						|
      case 'mongodb':
 | 
						|
        if (await this.docker.isRunning(containers.mongo)) {
 | 
						|
          helpers.printHeader(`MongoDB Logs (last ${lines} lines)`);
 | 
						|
          const logs = await this.docker.logs(containers.mongo, lines);
 | 
						|
          console.log(logs);
 | 
						|
        } else {
 | 
						|
          logger.log('note', 'MongoDB container is not running');
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        
 | 
						|
      case 'minio':
 | 
						|
      case 's3':
 | 
						|
        if (await this.docker.isRunning(containers.minio)) {
 | 
						|
          helpers.printHeader(`S3/MinIO Logs (last ${lines} lines)`);
 | 
						|
          const logs = await this.docker.logs(containers.minio, lines);
 | 
						|
          console.log(logs);
 | 
						|
        } else {
 | 
						|
          logger.log('note', 'S3/MinIO container is not running');
 | 
						|
        }
 | 
						|
        break;
 | 
						|
        
 | 
						|
      case 'all':
 | 
						|
      case '':
 | 
						|
        await this.showLogs('mongo', lines);
 | 
						|
        console.log();
 | 
						|
        await this.showLogs('minio', lines);
 | 
						|
        break;
 | 
						|
        
 | 
						|
      default:
 | 
						|
        logger.log('note', 'Usage: gitzone services logs [mongo|s3|all] [lines]');
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Remove containers
 | 
						|
   */
 | 
						|
  public async removeContainers(): Promise<void> {
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    let removed = false;
 | 
						|
    
 | 
						|
    if (await this.docker.exists(containers.mongo)) {
 | 
						|
      if (await this.docker.remove(containers.mongo, true)) {
 | 
						|
        logger.log('ok', '  MongoDB container removed ✓');
 | 
						|
        removed = true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (await this.docker.exists(containers.minio)) {
 | 
						|
      if (await this.docker.remove(containers.minio, true)) {
 | 
						|
        logger.log('ok', '  S3/MinIO container removed ✓');
 | 
						|
        removed = true;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (!removed) {
 | 
						|
      logger.log('note', '  No containers to remove');
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Clean data directories
 | 
						|
   */
 | 
						|
  public async cleanData(): Promise<void> {
 | 
						|
    const directories = this.config.getDataDirectories();
 | 
						|
    let cleaned = false;
 | 
						|
    
 | 
						|
    if (await plugins.smartfile.fs.fileExists(directories.mongo)) {
 | 
						|
      await plugins.smartfile.fs.remove(directories.mongo);
 | 
						|
      logger.log('ok', '  MongoDB data removed ✓');
 | 
						|
      cleaned = true;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (await plugins.smartfile.fs.fileExists(directories.minio)) {
 | 
						|
      await plugins.smartfile.fs.remove(directories.minio);
 | 
						|
      logger.log('ok', '  S3/MinIO data removed ✓');
 | 
						|
      cleaned = true;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (!cleaned) {
 | 
						|
      logger.log('note', '  No data to clean');
 | 
						|
    }
 | 
						|
  }
 | 
						|
  
 | 
						|
  /**
 | 
						|
   * Reconfigure services with new ports
 | 
						|
   */
 | 
						|
  public async reconfigure(): Promise<void> {
 | 
						|
    helpers.printHeader('Reconfiguring Services');
 | 
						|
    
 | 
						|
    const containers = this.config.getContainerNames();
 | 
						|
    
 | 
						|
    // Stop existing containers
 | 
						|
    logger.log('note', '🛑 Stopping existing containers...');
 | 
						|
    
 | 
						|
    if (await this.docker.exists(containers.mongo)) {
 | 
						|
      await this.docker.stop(containers.mongo);
 | 
						|
      logger.log('ok', '  MongoDB stopped ✓');
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (await this.docker.exists(containers.minio)) {
 | 
						|
      await this.docker.stop(containers.minio);
 | 
						|
      logger.log('ok', '  S3/MinIO stopped ✓');
 | 
						|
    }
 | 
						|
    
 | 
						|
    // Reconfigure ports
 | 
						|
    await this.config.reconfigurePorts();
 | 
						|
    
 | 
						|
    // Ask if user wants to restart services
 | 
						|
    const smartinteract = new plugins.smartinteract.SmartInteract();
 | 
						|
    const response = await smartinteract.askQuestion({
 | 
						|
      name: 'restart',
 | 
						|
      type: 'confirm',
 | 
						|
      message: 'Do you want to start services with new ports?',
 | 
						|
      default: true
 | 
						|
    });
 | 
						|
    
 | 
						|
    if (response.value) {
 | 
						|
      console.log();
 | 
						|
      await this.startMongoDB();
 | 
						|
      await this.startMinIO();
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |