feat(config): add configurable default shutdown delay for shutdown actions
This commit is contained in:
+39
-9
@@ -12,9 +12,13 @@ import { MigrationRunner } from './migrations/index.ts';
|
||||
import { formatPowerStatus, getBatteryColor, getRuntimeColor, theme } from './colors.ts';
|
||||
import type { IActionConfig } from './actions/base-action.ts';
|
||||
import { ActionManager } from './actions/index.ts';
|
||||
import { decideUpsActionExecution, type TUpsTriggerReason } from './action-orchestration.ts';
|
||||
import {
|
||||
applyDefaultShutdownDelay,
|
||||
decideUpsActionExecution,
|
||||
type TUpsTriggerReason,
|
||||
} from './action-orchestration.ts';
|
||||
import { NupstHttpServer } from './http-server.ts';
|
||||
import { NETWORK, PAUSE, THRESHOLDS, TIMING, UI } from './constants.ts';
|
||||
import { NETWORK, PAUSE, SHUTDOWN, THRESHOLDS, TIMING, UI } from './constants.ts';
|
||||
import {
|
||||
analyzeConfigReload,
|
||||
shouldRefreshPauseState,
|
||||
@@ -97,6 +101,8 @@ export interface INupstConfig {
|
||||
groups: IGroupConfig[];
|
||||
/** Check interval in milliseconds */
|
||||
checkInterval: number;
|
||||
/** Default delay in minutes for shutdown actions without an override */
|
||||
defaultShutdownDelay?: number;
|
||||
/** HTTP Server configuration */
|
||||
httpServer?: IHttpServerConfig;
|
||||
|
||||
@@ -125,6 +131,7 @@ export class NupstDaemon {
|
||||
/** Default configuration */
|
||||
private readonly DEFAULT_CONFIG: INupstConfig = {
|
||||
version: '4.3',
|
||||
defaultShutdownDelay: SHUTDOWN.DEFAULT_DELAY_MINUTES,
|
||||
upsDevices: [
|
||||
{
|
||||
id: 'default',
|
||||
@@ -155,7 +162,6 @@ export class NupstDaemon {
|
||||
battery: THRESHOLDS.DEFAULT_BATTERY_PERCENT, // Shutdown when battery below 60%
|
||||
runtime: THRESHOLDS.DEFAULT_RUNTIME_MINUTES, // Shutdown when runtime below 20 minutes
|
||||
},
|
||||
shutdownDelay: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -208,10 +214,13 @@ export class NupstDaemon {
|
||||
const migrationRunner = new MigrationRunner();
|
||||
const { config: migratedConfig, migrated } = await migrationRunner.run(parsedConfig);
|
||||
|
||||
// Save migrated config back to disk if any migrations ran
|
||||
// Cast to INupstConfig since migrations ensure the output is valid
|
||||
// Save migrated or normalized config back to disk when needed.
|
||||
// Cast to INupstConfig since migrations ensure the output is valid.
|
||||
const validConfig = migratedConfig as unknown as INupstConfig;
|
||||
if (migrated) {
|
||||
const normalizedShutdownDelay = this.normalizeShutdownDelay(validConfig.defaultShutdownDelay);
|
||||
const shouldPersistNormalizedConfig = validConfig.defaultShutdownDelay !== normalizedShutdownDelay;
|
||||
validConfig.defaultShutdownDelay = normalizedShutdownDelay;
|
||||
if (migrated || shouldPersistNormalizedConfig) {
|
||||
this.config = validConfig;
|
||||
await this.saveConfig(this.config);
|
||||
} else {
|
||||
@@ -249,6 +258,7 @@ export class NupstDaemon {
|
||||
upsDevices: config.upsDevices,
|
||||
groups: config.groups,
|
||||
checkInterval: config.checkInterval,
|
||||
defaultShutdownDelay: this.normalizeShutdownDelay(config.defaultShutdownDelay),
|
||||
...(config.httpServer ? { httpServer: config.httpServer } : {}),
|
||||
};
|
||||
|
||||
@@ -280,6 +290,22 @@ export class NupstDaemon {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
private normalizeShutdownDelay(delayMinutes: number | undefined): number {
|
||||
if (
|
||||
typeof delayMinutes !== 'number' ||
|
||||
!Number.isFinite(delayMinutes) ||
|
||||
delayMinutes < 0
|
||||
) {
|
||||
return SHUTDOWN.DEFAULT_DELAY_MINUTES;
|
||||
}
|
||||
|
||||
return delayMinutes;
|
||||
}
|
||||
|
||||
private getDefaultShutdownDelayMinutes(): number {
|
||||
return this.normalizeShutdownDelay(this.config.defaultShutdownDelay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SNMP instance
|
||||
*/
|
||||
@@ -758,7 +784,12 @@ export class NupstDaemon {
|
||||
return;
|
||||
}
|
||||
|
||||
await ActionManager.executeActions(decision.actions, decision.context);
|
||||
const actions = applyDefaultShutdownDelay(
|
||||
decision.actions,
|
||||
this.getDefaultShutdownDelayMinutes(),
|
||||
);
|
||||
|
||||
await ActionManager.executeActions(actions, decision.context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -768,8 +799,7 @@ export class NupstDaemon {
|
||||
public async initiateShutdown(reason: string): Promise<void> {
|
||||
logger.log(`Initiating system shutdown due to: ${reason}`);
|
||||
|
||||
// Set a longer delay for shutdown to allow VMs and services to close
|
||||
const shutdownDelayMinutes = 5;
|
||||
const shutdownDelayMinutes = this.getDefaultShutdownDelayMinutes();
|
||||
|
||||
try {
|
||||
await this.shutdownExecutor.scheduleShutdown(shutdownDelayMinutes);
|
||||
|
||||
Reference in New Issue
Block a user