Files
onebox/ts/classes/onebox.ts

272 lines
7.7 KiB
TypeScript
Raw Normal View History

/**
* Main Onebox coordinator class
*
* Coordinates all components and provides the main API
*/
2025-11-18 00:03:24 +00:00
import { logger } from '../logging.ts';
import { OneboxDatabase } from './database.ts';
import { OneboxDockerManager } from './docker.ts';
import { OneboxServicesManager } from './services.ts';
import { OneboxRegistriesManager } from './registries.ts';
import { OneboxReverseProxy } from './reverseproxy.ts';
import { OneboxDnsManager } from './dns.ts';
import { OneboxSslManager } from './ssl.ts';
import { OneboxDaemon } from './daemon.ts';
import { OneboxHttpServer } from './httpserver.ts';
import { CloudflareDomainSync } from './cloudflare-sync.ts';
import { CertRequirementManager } from './cert-requirement-manager.ts';
import { RegistryManager } from './registry.ts';
import { PlatformServicesManager } from './platform-services/index.ts';
export class Onebox {
public database: OneboxDatabase;
public docker: OneboxDockerManager;
public services: OneboxServicesManager;
public registries: OneboxRegistriesManager;
2025-11-18 00:03:24 +00:00
public reverseProxy: OneboxReverseProxy;
public dns: OneboxDnsManager;
public ssl: OneboxSslManager;
public daemon: OneboxDaemon;
public httpServer: OneboxHttpServer;
public cloudflareDomainSync: CloudflareDomainSync;
public certRequirementManager: CertRequirementManager;
public registry: RegistryManager;
public platformServices: PlatformServicesManager;
private initialized = false;
constructor() {
// Initialize database first
this.database = new OneboxDatabase();
// Initialize managers (passing reference to main Onebox instance)
this.docker = new OneboxDockerManager();
this.services = new OneboxServicesManager(this);
this.registries = new OneboxRegistriesManager(this);
2025-11-18 00:03:24 +00:00
this.reverseProxy = new OneboxReverseProxy(this);
this.dns = new OneboxDnsManager(this);
this.ssl = new OneboxSslManager(this);
this.daemon = new OneboxDaemon(this);
this.httpServer = new OneboxHttpServer(this);
this.registry = new RegistryManager({
dataDir: './.nogit/registry-data',
port: 4000,
baseUrl: 'localhost:5000',
});
// Initialize domain management
this.cloudflareDomainSync = new CloudflareDomainSync(this.database);
this.certRequirementManager = new CertRequirementManager(this.database, this.ssl);
// Initialize platform services manager
this.platformServices = new PlatformServicesManager(this);
}
/**
* Initialize all components
*/
async init(): Promise<void> {
try {
logger.info('Initializing Onebox...');
// Initialize database
await this.database.init();
// Ensure default admin user exists
await this.ensureDefaultUser();
// Initialize Docker
await this.docker.init();
2025-11-18 00:03:24 +00:00
// Initialize Reverse Proxy
await this.reverseProxy.init();
// Initialize DNS (non-critical)
try {
await this.dns.init();
} catch (error) {
logger.warn('DNS initialization failed - DNS features will be disabled');
}
// Initialize SSL (non-critical)
try {
await this.ssl.init();
} catch (error) {
logger.warn('SSL initialization failed - SSL features will be limited');
}
// Initialize Cloudflare domain sync (non-critical)
try {
await this.cloudflareDomainSync.init();
} catch (error) {
logger.warn('Cloudflare domain sync initialization failed - domain sync will be limited');
}
// Initialize Onebox Registry (non-critical)
try {
await this.registry.init();
} catch (error) {
logger.warn('Onebox Registry initialization failed - local registry will be disabled');
logger.warn(`Error: ${error.message}`);
}
// Initialize Platform Services (non-critical)
try {
await this.platformServices.init();
} catch (error) {
logger.warn('Platform services initialization failed - MongoDB/S3 features will be limited');
logger.warn(`Error: ${error.message}`);
}
// Login to all registries
await this.registries.loginToAllRegistries();
// Start auto-update monitoring for registry services
this.services.startAutoUpdateMonitoring();
this.initialized = true;
logger.success('Onebox initialized successfully');
} catch (error) {
logger.error(`Failed to initialize Onebox: ${error.message}`);
throw error;
}
}
/**
* Ensure default admin user exists
*/
private async ensureDefaultUser(): Promise<void> {
try {
const adminUser = this.database.getUserByUsername('admin');
if (!adminUser) {
logger.info('Creating default admin user...');
2025-11-18 00:03:24 +00:00
// Simple base64 encoding for now - should use bcrypt in production
const passwordHash = btoa('admin');
await this.database.createUser({
username: 'admin',
2025-11-18 00:03:24 +00:00
passwordHash,
role: 'admin',
createdAt: Date.now(),
updatedAt: Date.now(),
});
logger.warn('Default admin user created with username: admin, password: admin');
logger.warn('IMPORTANT: Change the default password immediately!');
}
} catch (error) {
logger.error(`Failed to create default user: ${error.message}`);
}
}
/**
* Check if Onebox is initialized
*/
isInitialized(): boolean {
return this.initialized;
}
/**
* Get system status
*/
async getSystemStatus() {
try {
const dockerRunning = await this.docker.isDockerRunning();
2025-11-18 00:03:24 +00:00
const proxyStatus = this.reverseProxy.getStatus();
const dnsConfigured = this.dns.isConfigured();
const sslConfigured = this.ssl.isConfigured();
const services = this.services.listServices();
const runningServices = services.filter((s) => s.status === 'running').length;
const totalServices = services.length;
// Get platform services status
const platformServices = this.platformServices.getAllPlatformServices();
const platformServicesStatus = platformServices.map((ps) => ({
type: ps.type,
status: ps.status,
}));
return {
docker: {
running: dockerRunning,
version: dockerRunning ? await this.docker.getDockerVersion() : null,
},
2025-11-18 00:03:24 +00:00
reverseProxy: proxyStatus,
dns: {
configured: dnsConfigured,
},
ssl: {
configured: sslConfigured,
certbotInstalled: await this.ssl.isCertbotInstalled(),
},
services: {
total: totalServices,
running: runningServices,
stopped: totalServices - runningServices,
},
platformServices: platformServicesStatus,
};
} catch (error) {
logger.error(`Failed to get system status: ${error.message}`);
throw error;
}
}
/**
* Start daemon mode
*/
async startDaemon(): Promise<void> {
await this.daemon.start();
}
/**
* Stop daemon mode
*/
async stopDaemon(): Promise<void> {
await this.daemon.stop();
}
/**
* Start HTTP server
*/
async startHttpServer(port?: number): Promise<void> {
await this.httpServer.start(port);
}
/**
* Stop HTTP server
*/
async stopHttpServer(): Promise<void> {
await this.httpServer.stop();
}
/**
* Shutdown Onebox gracefully
*/
async shutdown(): Promise<void> {
try {
logger.info('Shutting down Onebox...');
// Stop daemon if running
await this.daemon.stop();
// Stop HTTP server if running
await this.httpServer.stop();
2025-11-18 00:03:24 +00:00
// Stop reverse proxy if running
await this.reverseProxy.stop();
// Close database
this.database.close();
logger.success('Onebox shutdown complete');
} catch (error) {
logger.error(`Error during shutdown: ${error.message}`);
}
}
}