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:
2025-10-28 13:05:42 +00:00
commit 246a6073e0
29 changed files with 5227 additions and 0 deletions

220
ts/onebox.classes.onebox.ts Normal file
View 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}`);
}
}
}