Initial commit: Onebox v1.0.0
- Complete Deno-based architecture following nupst/spark patterns - SQLite database with full schema - Docker container management - Service orchestration (Docker + Nginx + DNS + SSL) - Registry authentication - Nginx reverse proxy configuration - Cloudflare DNS integration - Let's Encrypt SSL automation - Background daemon with metrics collection - HTTP API server - Comprehensive CLI - Cross-platform compilation setup - NPM distribution wrapper - Shell installer script Core features: - Deploy containers with single command - Automatic domain configuration - Automatic SSL certificates - Multi-registry support - Metrics and logging - Systemd integration Ready for Angular UI implementation and testing.
This commit is contained in:
220
ts/onebox.classes.onebox.ts
Normal file
220
ts/onebox.classes.onebox.ts
Normal file
@@ -0,0 +1,220 @@
|
||||
/**
|
||||
* Main Onebox coordinator class
|
||||
*
|
||||
* Coordinates all components and provides the main API
|
||||
*/
|
||||
|
||||
import { logger } from './onebox.logging.ts';
|
||||
import { OneboxDatabase } from './onebox.classes.database.ts';
|
||||
import { OneboxDockerManager } from './onebox.classes.docker.ts';
|
||||
import { OneboxServicesManager } from './onebox.classes.services.ts';
|
||||
import { OneboxRegistriesManager } from './onebox.classes.registries.ts';
|
||||
import { OneboxNginxManager } from './onebox.classes.nginx.ts';
|
||||
import { OneboxDnsManager } from './onebox.classes.dns.ts';
|
||||
import { OneboxSslManager } from './onebox.classes.ssl.ts';
|
||||
import { OneboxDaemon } from './onebox.classes.daemon.ts';
|
||||
import { OneboxHttpServer } from './onebox.classes.httpserver.ts';
|
||||
|
||||
export class Onebox {
|
||||
public database: OneboxDatabase;
|
||||
public docker: OneboxDockerManager;
|
||||
public services: OneboxServicesManager;
|
||||
public registries: OneboxRegistriesManager;
|
||||
public nginx: OneboxNginxManager;
|
||||
public dns: OneboxDnsManager;
|
||||
public ssl: OneboxSslManager;
|
||||
public daemon: OneboxDaemon;
|
||||
public httpServer: OneboxHttpServer;
|
||||
|
||||
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);
|
||||
this.nginx = new OneboxNginxManager(this);
|
||||
this.dns = new OneboxDnsManager(this);
|
||||
this.ssl = new OneboxSslManager(this);
|
||||
this.daemon = new OneboxDaemon(this);
|
||||
this.httpServer = new OneboxHttpServer(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();
|
||||
|
||||
// Initialize Nginx
|
||||
await this.nginx.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');
|
||||
}
|
||||
|
||||
// Login to all registries
|
||||
await this.registries.loginToAllRegistries();
|
||||
|
||||
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...');
|
||||
|
||||
// Hash default password 'admin'
|
||||
const passwordHash = await Deno.readTextFile('/dev/urandom').then((data) =>
|
||||
// Simple hash for now - should use bcrypt
|
||||
btoa('admin')
|
||||
);
|
||||
|
||||
await this.database.createUser({
|
||||
username: 'admin',
|
||||
passwordHash: btoa('admin'), // Simple encoding for now
|
||||
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();
|
||||
const nginxStatus = await this.nginx.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;
|
||||
|
||||
return {
|
||||
docker: {
|
||||
running: dockerRunning,
|
||||
version: dockerRunning ? await this.docker.getDockerVersion() : null,
|
||||
},
|
||||
nginx: {
|
||||
status: nginxStatus,
|
||||
installed: await this.nginx.isInstalled(),
|
||||
},
|
||||
dns: {
|
||||
configured: dnsConfigured,
|
||||
},
|
||||
ssl: {
|
||||
configured: sslConfigured,
|
||||
certbotInstalled: await this.ssl.isCertbotInstalled(),
|
||||
},
|
||||
services: {
|
||||
total: totalServices,
|
||||
running: runningServices,
|
||||
stopped: totalServices - runningServices,
|
||||
},
|
||||
};
|
||||
} 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();
|
||||
|
||||
// Close database
|
||||
this.database.close();
|
||||
|
||||
logger.success('Onebox shutdown complete');
|
||||
} catch (error) {
|
||||
logger.error(`Error during shutdown: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user