feat(core): Initial project scaffold and implementation: Deno CLI, ISO tooling, cloud-init generation, packaging and installer scripts
This commit is contained in:
133
ts/classes/config-manager.ts
Normal file
133
ts/classes/config-manager.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Config Manager
|
||||
* Loads and validates YAML configuration files
|
||||
*/
|
||||
|
||||
import { yaml } from '../plugins.ts';
|
||||
import { log } from '../logging.ts';
|
||||
import type { IIsoConfig } from '../interfaces/iso-config.interface.ts';
|
||||
|
||||
export class ConfigManager {
|
||||
/**
|
||||
* Load config from YAML file
|
||||
*/
|
||||
async loadFromFile(filePath: string): Promise<IIsoConfig> {
|
||||
log.info(`Loading configuration from ${filePath}...`);
|
||||
|
||||
try {
|
||||
const content = await Deno.readTextFile(filePath);
|
||||
const config = yaml.parse(content) as IIsoConfig;
|
||||
|
||||
// Validate
|
||||
this.validate(config);
|
||||
|
||||
log.success('Configuration loaded and validated');
|
||||
return config;
|
||||
} catch (err) {
|
||||
if (err instanceof Deno.errors.NotFound) {
|
||||
throw new Error(`Config file not found: ${filePath}`);
|
||||
}
|
||||
throw new Error(`Failed to load config: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate configuration
|
||||
*/
|
||||
validate(config: IIsoConfig): void {
|
||||
const errors: string[] = [];
|
||||
|
||||
// Version check
|
||||
if (!config.version) {
|
||||
errors.push('Missing required field: version');
|
||||
}
|
||||
|
||||
// ISO settings
|
||||
if (!config.iso) {
|
||||
errors.push('Missing required field: iso');
|
||||
} else {
|
||||
if (!config.iso.ubuntu_version) {
|
||||
errors.push('Missing required field: iso.ubuntu_version');
|
||||
}
|
||||
if (!config.iso.architecture || !['amd64', 'arm64'].includes(config.iso.architecture)) {
|
||||
errors.push('Invalid or missing field: iso.architecture (must be "amd64" or "arm64")');
|
||||
}
|
||||
}
|
||||
|
||||
// Output settings
|
||||
if (!config.output) {
|
||||
errors.push('Missing required field: output');
|
||||
} else {
|
||||
if (!config.output.filename) {
|
||||
errors.push('Missing required field: output.filename');
|
||||
}
|
||||
if (!config.output.path) {
|
||||
errors.push('Missing required field: output.path');
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
throw new Error(`Configuration validation failed:\n${errors.join('\n')}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a template configuration
|
||||
*/
|
||||
generateTemplate(): string {
|
||||
const template: IIsoConfig = {
|
||||
version: '1.0',
|
||||
iso: {
|
||||
ubuntu_version: '24.04',
|
||||
architecture: 'amd64',
|
||||
flavor: 'server',
|
||||
},
|
||||
output: {
|
||||
filename: 'ubuntu-custom.iso',
|
||||
path: './output',
|
||||
},
|
||||
network: {
|
||||
wifi: {
|
||||
ssid: 'MyWiFi',
|
||||
password: 'changeme',
|
||||
},
|
||||
},
|
||||
cloud_init: {
|
||||
hostname: 'ubuntu-server',
|
||||
users: [
|
||||
{
|
||||
name: 'admin',
|
||||
ssh_authorized_keys: [
|
||||
'ssh-rsa AAAAB3... your-key-here',
|
||||
],
|
||||
sudo: 'ALL=(ALL) NOPASSWD:ALL',
|
||||
shell: '/bin/bash',
|
||||
},
|
||||
],
|
||||
packages: [
|
||||
'docker.io',
|
||||
'git',
|
||||
'htop',
|
||||
],
|
||||
runcmd: [
|
||||
'systemctl enable docker',
|
||||
'systemctl start docker',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
return `# isocreator configuration file
|
||||
# Version: 1.0
|
||||
|
||||
${yaml.stringify(template)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save template to file
|
||||
*/
|
||||
async saveTemplate(filePath: string): Promise<void> {
|
||||
const template = this.generateTemplate();
|
||||
await Deno.writeTextFile(filePath, template);
|
||||
log.success(`Template saved to ${filePath}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user