Files
nupst/ts/migrations/migration-v4.1-to-v4.2.ts
Juergen Kunz 8c1be6555f fix(migrations): correct migration version from v4.0-to-v4.1 to v4.1-to-v4.2
The migration was incorrectly named as v4.0→v4.1 but was actually performing
the v4.1→v4.2 migration (moving thresholds from UPS-level to action-level).
This meant users upgrading from v4.1 would not get their configs migrated.

Changes:
- Renamed migration file from migration-v4.0-to-v4.1.ts to migration-v4.1-to-v4.2.ts
- Updated class name from MigrationV4_0ToV4_1 to MigrationV4_1ToV4_2
- Updated fromVersion from '4.0' to '4.1'
- Updated toVersion from '4.1' to '4.2'
- Updated shouldRun() to check for config.version === '4.1'
- Updated all imports and exports to reference the new class name
- Updated comments and log messages to reflect v4.1→v4.2 migration
2025-10-20 12:14:02 +00:00

126 lines
3.6 KiB
TypeScript

import { BaseMigration } from './base-migration.ts';
import { logger } from '../logger.ts';
/**
* Migration from v4.1 to v4.2
*
* Major changes:
* 1. Moves thresholds from UPS level to action level
* 2. Creates default shutdown action for UPS devices that had thresholds
* 3. Adds empty actions array to UPS devices without actions
* 4. Adds empty actions array to groups
*
* Transforms v4.1 format (with UPS-level thresholds):
* {
* version: "4.1",
* upsDevices: [
* {
* id: "ups-1",
* name: "UPS 1",
* snmp: {...},
* thresholds: { battery: 60, runtime: 20 }, // UPS-level
* groups: [],
* actions: []
* }
* ]
* }
*
* To v4.2 format (with action-level thresholds):
* {
* version: "4.2",
* upsDevices: [
* {
* id: "ups-1",
* name: "UPS 1",
* snmp: {...},
* groups: [],
* actions: [ // Thresholds moved here
* {
* type: "shutdown",
* thresholds: { battery: 60, runtime: 20 },
* triggerMode: "onlyThresholds",
* shutdownDelay: 5
* }
* ]
* }
* ]
* }
*/
export class MigrationV4_1ToV4_2 extends BaseMigration {
readonly fromVersion = '4.1';
readonly toVersion = '4.2';
async shouldRun(config: any): Promise<boolean> {
// Run if config is version 4.1
if (config.version === '4.1') {
return true;
}
// Also run if config has upsDevices with thresholds at UPS level (v4.1 format)
if (config.upsDevices && config.upsDevices.length > 0) {
const firstDevice = config.upsDevices[0];
// v4.1 has thresholds at UPS level, v4.2 has them in actions
return firstDevice.thresholds !== undefined;
}
return false;
}
async migrate(config: any): Promise<any> {
logger.info(`${this.getName()}: Migrating v4.1 config to v4.2 format...`);
logger.dim(` - Moving thresholds from UPS level to action level`);
logger.dim(` - Creating default shutdown actions from existing thresholds`);
// Migrate UPS devices
const migratedDevices = (config.upsDevices || []).map((device: any) => {
const migrated: any = {
id: device.id,
name: device.name,
snmp: device.snmp,
groups: device.groups || [],
};
// If device has thresholds at UPS level, convert to shutdown action
if (device.thresholds) {
migrated.actions = [
{
type: 'shutdown',
thresholds: {
battery: device.thresholds.battery,
runtime: device.thresholds.runtime,
},
triggerMode: 'onlyThresholds', // Preserve old behavior (only on threshold violation)
shutdownDelay: 5, // Default delay
},
];
logger.dim(
`${device.name}: Created shutdown action (battery: ${device.thresholds.battery}%, runtime: ${device.thresholds.runtime}min)`,
);
} else {
// No thresholds, just add empty actions array
migrated.actions = device.actions || [];
}
return migrated;
});
// Add actions to groups
const migratedGroups = (config.groups || []).map((group: any) => ({
...group,
actions: group.actions || [],
}));
const result = {
version: this.toVersion,
upsDevices: migratedDevices,
groups: migratedGroups,
checkInterval: config.checkInterval || 30000,
};
logger.success(
`${this.getName()}: Migration complete (${migratedDevices.length} devices, ${migratedGroups.length} groups updated)`,
);
return result;
}
}