feat(migrations): add migration system for v3→v4 config format
- Create abstract BaseMigration class with order, shouldRun(), migrate() - Add MigrationRunner to execute migrations in order - Add Migration v1→v2 (snmp → upsDevices) - Add Migration v3→v4 (upsList → upsDevices) - Update INupstConfig with version field - Update loadConfig() to run migrations automatically - Update saveConfig() to ensure version field and remove legacy fields - Update Docker test scripts to use real UPS data from .nogit/env.json - Remove colors.bright (not available in @std/fmt/colors) Config migrations allow users to jump versions (e.g., v1→v4) with all intermediate migrations running automatically. Version field tracks config format for future migrations.
This commit is contained in:
52
ts/daemon.ts
52
ts/daemon.ts
@@ -6,6 +6,7 @@ import { promisify } from 'node:util';
|
||||
import { NupstSnmp } from './snmp/manager.ts';
|
||||
import type { ISnmpConfig } from './snmp/types.ts';
|
||||
import { logger } from './logger.ts';
|
||||
import { MigrationRunner } from './migrations/index.ts';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const execFileAsync = promisify(execFile);
|
||||
@@ -49,6 +50,8 @@ export interface IGroupConfig {
|
||||
* Configuration interface for the daemon
|
||||
*/
|
||||
export interface INupstConfig {
|
||||
/** Configuration format version */
|
||||
version?: string;
|
||||
/** UPS devices configuration */
|
||||
upsDevices: IUpsConfig[];
|
||||
/** Groups configuration */
|
||||
@@ -56,10 +59,12 @@ export interface INupstConfig {
|
||||
/** Check interval in milliseconds */
|
||||
checkInterval: number;
|
||||
|
||||
// Legacy fields for backward compatibility
|
||||
/** SNMP configuration settings (legacy) */
|
||||
// Legacy fields for backward compatibility (will be migrated away)
|
||||
/** UPS list (v3 format - legacy) */
|
||||
upsList?: IUpsConfig[];
|
||||
/** SNMP configuration settings (v1 format - legacy) */
|
||||
snmp?: ISnmpConfig;
|
||||
/** Threshold settings (legacy) */
|
||||
/** Threshold settings (v1 format - legacy) */
|
||||
thresholds?: {
|
||||
/** Shutdown when battery below this percentage */
|
||||
battery: number;
|
||||
@@ -91,6 +96,7 @@ export class NupstDaemon {
|
||||
|
||||
/** Default configuration */
|
||||
private readonly DEFAULT_CONFIG: INupstConfig = {
|
||||
version: '4.0',
|
||||
upsDevices: [
|
||||
{
|
||||
id: 'default',
|
||||
@@ -153,29 +159,16 @@ export class NupstDaemon {
|
||||
const configData = fs.readFileSync(this.CONFIG_PATH, 'utf8');
|
||||
const parsedConfig = JSON.parse(configData);
|
||||
|
||||
// Handle legacy configuration format
|
||||
if (!parsedConfig.upsDevices && parsedConfig.snmp) {
|
||||
// Convert legacy format to new format
|
||||
this.config = {
|
||||
upsDevices: [
|
||||
{
|
||||
id: 'default',
|
||||
name: 'Default UPS',
|
||||
snmp: parsedConfig.snmp,
|
||||
thresholds: parsedConfig.thresholds,
|
||||
groups: [],
|
||||
},
|
||||
],
|
||||
groups: [],
|
||||
checkInterval: parsedConfig.checkInterval,
|
||||
};
|
||||
// Run migrations to upgrade config format if needed
|
||||
const migrationRunner = new MigrationRunner();
|
||||
const { config: migratedConfig, migrated } = await migrationRunner.run(parsedConfig);
|
||||
|
||||
logger.log('Legacy configuration format detected. Converting to multi-UPS format.');
|
||||
|
||||
// Save the new format
|
||||
// Save migrated config back to disk if any migrations ran
|
||||
if (migrated) {
|
||||
this.config = migratedConfig;
|
||||
await this.saveConfig(this.config);
|
||||
} else {
|
||||
this.config = parsedConfig;
|
||||
this.config = migratedConfig;
|
||||
}
|
||||
|
||||
return this.config;
|
||||
@@ -202,8 +195,17 @@ export class NupstDaemon {
|
||||
if (!fs.existsSync(configDir)) {
|
||||
fs.mkdirSync(configDir, { recursive: true });
|
||||
}
|
||||
fs.writeFileSync(this.CONFIG_PATH, JSON.stringify(config, null, 2));
|
||||
this.config = config;
|
||||
|
||||
// Ensure version is always set and remove legacy fields before saving
|
||||
const configToSave: INupstConfig = {
|
||||
version: '4.0',
|
||||
upsDevices: config.upsDevices,
|
||||
groups: config.groups,
|
||||
checkInterval: config.checkInterval,
|
||||
};
|
||||
|
||||
fs.writeFileSync(this.CONFIG_PATH, JSON.stringify(configToSave, null, 2));
|
||||
this.config = configToSave;
|
||||
|
||||
console.log('┌─ Configuration Saved ─────────────────────┐');
|
||||
console.log(`│ Location: ${this.CONFIG_PATH}`);
|
||||
|
Reference in New Issue
Block a user