feat: Implement platform service providers for MinIO and MongoDB
- Added base interface and abstract class for platform service providers. - Created MinIOProvider class for S3-compatible storage with deployment, provisioning, and deprovisioning functionalities. - Implemented MongoDBProvider class for MongoDB service with similar capabilities. - Introduced error handling utilities for better error management. - Developed TokensComponent for managing registry tokens in the UI, including creation, deletion, and display of tokens.
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
* Orchestrates service deployment: Docker + Nginx + DNS + SSL
|
||||
*/
|
||||
|
||||
import type { IService, IServiceDeployOptions } from '../types.ts';
|
||||
import type { IService, IServiceDeployOptions, IPlatformRequirements } from '../types.ts';
|
||||
import { logger } from '../logging.ts';
|
||||
import { OneboxDatabase } from './database.ts';
|
||||
import { OneboxDockerManager } from './docker.ts';
|
||||
import type { PlatformServicesManager } from './platform-services/index.ts';
|
||||
|
||||
export class OneboxServicesManager {
|
||||
private oneboxRef: any; // Will be Onebox instance
|
||||
@@ -34,13 +35,9 @@ export class OneboxServicesManager {
|
||||
}
|
||||
|
||||
// Handle Onebox Registry setup
|
||||
let registryToken: string | undefined;
|
||||
let imageToPull: string;
|
||||
|
||||
if (options.useOneboxRegistry) {
|
||||
// Generate registry token
|
||||
registryToken = await this.oneboxRef.registry.createServiceToken(options.name);
|
||||
|
||||
// Use onebox registry image name
|
||||
const tag = options.registryImageTag || 'latest';
|
||||
imageToPull = this.oneboxRef.registry.getImageName(options.name, tag);
|
||||
@@ -49,6 +46,15 @@ export class OneboxServicesManager {
|
||||
imageToPull = options.image;
|
||||
}
|
||||
|
||||
// Build platform requirements
|
||||
const platformRequirements: IPlatformRequirements | undefined =
|
||||
(options.enableMongoDB || options.enableS3)
|
||||
? {
|
||||
mongodb: options.enableMongoDB,
|
||||
s3: options.enableS3,
|
||||
}
|
||||
: undefined;
|
||||
|
||||
// Create service record in database
|
||||
const service = await this.database.createService({
|
||||
name: options.name,
|
||||
@@ -63,18 +69,46 @@ export class OneboxServicesManager {
|
||||
// Onebox Registry fields
|
||||
useOneboxRegistry: options.useOneboxRegistry,
|
||||
registryRepository: options.useOneboxRegistry ? options.name : undefined,
|
||||
registryToken: registryToken,
|
||||
registryImageTag: options.registryImageTag || 'latest',
|
||||
autoUpdateOnPush: options.autoUpdateOnPush,
|
||||
// Platform requirements
|
||||
platformRequirements,
|
||||
});
|
||||
|
||||
// Provision platform resources if needed
|
||||
let platformEnvVars: Record<string, string> = {};
|
||||
if (platformRequirements) {
|
||||
try {
|
||||
logger.info(`Provisioning platform resources for service '${options.name}'...`);
|
||||
const platformServices = this.oneboxRef.platformServices as PlatformServicesManager;
|
||||
platformEnvVars = await platformServices.provisionForService(service);
|
||||
logger.success(`Platform resources provisioned for service '${options.name}'`);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to provision platform resources: ${error.message}`);
|
||||
// Clean up the service record on failure
|
||||
this.database.deleteService(service.id!);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge platform env vars with user-specified env vars (user vars take precedence)
|
||||
const mergedEnvVars = { ...platformEnvVars, ...(options.envVars || {}) };
|
||||
|
||||
// Update service with merged env vars
|
||||
if (Object.keys(platformEnvVars).length > 0) {
|
||||
this.database.updateService(service.id!, { envVars: mergedEnvVars });
|
||||
}
|
||||
|
||||
// Get updated service with merged env vars
|
||||
const serviceWithEnvVars = this.database.getServiceByName(options.name)!;
|
||||
|
||||
// Pull image (skip if using onebox registry - image might not exist yet)
|
||||
if (!options.useOneboxRegistry) {
|
||||
await this.docker.pullImage(imageToPull, options.registry);
|
||||
}
|
||||
|
||||
// Create container
|
||||
const containerID = await this.docker.createContainer(service);
|
||||
// Create container (uses the updated service with merged env vars)
|
||||
const containerID = await this.docker.createContainer(serviceWithEnvVars);
|
||||
|
||||
// Update service with container ID
|
||||
this.database.updateService(service.id!, {
|
||||
@@ -293,6 +327,19 @@ export class OneboxServicesManager {
|
||||
// as they might be used by other services or need manual cleanup
|
||||
}
|
||||
|
||||
// Cleanup platform resources (MongoDB databases, S3 buckets, etc.)
|
||||
if (service.platformRequirements) {
|
||||
try {
|
||||
logger.info(`Cleaning up platform resources for service '${name}'...`);
|
||||
const platformServices = this.oneboxRef.platformServices as PlatformServicesManager;
|
||||
await platformServices.cleanupForService(service.id!);
|
||||
logger.success(`Platform resources cleaned up for service '${name}'`);
|
||||
} catch (error) {
|
||||
logger.warn(`Failed to cleanup platform resources: ${error.message}`);
|
||||
// Continue with service deletion even if cleanup fails
|
||||
}
|
||||
}
|
||||
|
||||
// Remove from database
|
||||
this.database.deleteService(service.id!);
|
||||
|
||||
@@ -392,6 +439,28 @@ export class OneboxServicesManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get platform resources for a service
|
||||
*/
|
||||
async getServicePlatformResources(name: string) {
|
||||
try {
|
||||
const service = this.database.getServiceByName(name);
|
||||
if (!service) {
|
||||
throw new Error(`Service not found: ${name}`);
|
||||
}
|
||||
|
||||
if (!service.platformRequirements) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const platformServices = this.oneboxRef.platformServices as PlatformServicesManager;
|
||||
return await platformServices.getResourcesForService(service.id!);
|
||||
} catch (error) {
|
||||
logger.error(`Failed to get platform resources for service ${name}: ${error.message}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get service status
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user