Add configurable history and storage retention policies
This commit is contained in:
@@ -1,4 +1,26 @@
|
||||
export interface FleetSettings {
|
||||
provisioningKeepDays: number;
|
||||
actionKeepDays: number;
|
||||
failureKeepDays: number;
|
||||
maintenanceKeepDays: number;
|
||||
recoveryKeepDays: number;
|
||||
hostResourceKeepDays: number;
|
||||
instanceResourceKeepDays: number;
|
||||
metricsKeepDays: number;
|
||||
telemetryKeepDays: number;
|
||||
telemetryMaxPerServer: number;
|
||||
telemetryMaxTotal: number;
|
||||
matchKeepDays: number;
|
||||
betaKeepDays: number;
|
||||
fileContentKeepDays: number;
|
||||
versionKeepDays: number;
|
||||
versionKeepCount: number;
|
||||
gameFileGraceDays: number;
|
||||
gameFileKeepCount: number;
|
||||
uploadKeepDays: number;
|
||||
auditKeepDays: number;
|
||||
historyKeepCount: number;
|
||||
|
||||
deployKeepDays: number;
|
||||
observationKeepDays: number;
|
||||
restartConcurrency: number;
|
||||
@@ -14,6 +36,28 @@ export interface FleetSettings {
|
||||
}
|
||||
|
||||
export const defaultFleetSettings: FleetSettings = {
|
||||
provisioningKeepDays: 0,
|
||||
actionKeepDays: 0,
|
||||
failureKeepDays: 0,
|
||||
maintenanceKeepDays: 30,
|
||||
recoveryKeepDays: 0,
|
||||
hostResourceKeepDays: 7,
|
||||
instanceResourceKeepDays: 1,
|
||||
metricsKeepDays: 31,
|
||||
telemetryKeepDays: 7,
|
||||
telemetryMaxPerServer: 200,
|
||||
telemetryMaxTotal: 10000,
|
||||
matchKeepDays: 0,
|
||||
betaKeepDays: 0,
|
||||
fileContentKeepDays: 0,
|
||||
versionKeepDays: 0,
|
||||
versionKeepCount: 0,
|
||||
gameFileGraceDays: 0,
|
||||
gameFileKeepCount: 1,
|
||||
uploadKeepDays: 0,
|
||||
auditKeepDays: 0,
|
||||
historyKeepCount: 0,
|
||||
|
||||
deployKeepDays: 7,
|
||||
observationKeepDays: 1,
|
||||
restartConcurrency: 1,
|
||||
@@ -28,6 +72,28 @@ export const defaultFleetSettings: FleetSettings = {
|
||||
};
|
||||
|
||||
export const fleetSettingLabels: Record<keyof FleetSettings, string> = {
|
||||
provisioningKeepDays: 'Provisioning history retention',
|
||||
actionKeepDays: 'Action operation history retention',
|
||||
failureKeepDays: 'Resolved failure history retention',
|
||||
maintenanceKeepDays: 'Maintenance history retention',
|
||||
recoveryKeepDays: 'Resolved recovery incident retention',
|
||||
hostResourceKeepDays: 'Host resource history retention',
|
||||
instanceResourceKeepDays: 'Instance resource sample retention',
|
||||
metricsKeepDays: 'Fleet metrics history retention',
|
||||
telemetryKeepDays: 'Telemetry diagnostic history retention',
|
||||
telemetryMaxPerServer: 'Maximum telemetry records per server',
|
||||
telemetryMaxTotal: 'Maximum telemetry records overall',
|
||||
matchKeepDays: 'Match history retention',
|
||||
betaKeepDays: 'Completed beta history retention',
|
||||
fileContentKeepDays: 'File diffs and rollback snapshot retention',
|
||||
versionKeepDays: 'Unused artifact version retention',
|
||||
versionKeepCount: 'Minimum artifact versions to keep',
|
||||
gameFileGraceDays: 'Unused game-file grace period',
|
||||
gameFileKeepCount: 'Minimum game-file versions to keep',
|
||||
uploadKeepDays: 'Abandoned upload retention',
|
||||
auditKeepDays: 'Authentication audit history retention',
|
||||
historyKeepCount: 'Minimum history records to keep',
|
||||
|
||||
deployKeepDays: 'Campaign history retention',
|
||||
observationKeepDays: 'Routine operation history retention',
|
||||
restartConcurrency: 'Concurrent restarts',
|
||||
@@ -50,11 +116,11 @@ export function validateFleetSettings(input: unknown): FleetSettings {
|
||||
}
|
||||
for (const key of Object.keys(defaultFleetSettings) as (keyof FleetSettings)[]) {
|
||||
const value = values[key];
|
||||
const minimum = key === 'observationKeepDays' || additionalConcurrencyKeys.includes(key) ? 0 : 1;
|
||||
const minimum = settingMinimum(key);
|
||||
if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < minimum) {
|
||||
throw new Error(`${fleetSettingLabels[key]} must be ${minimum === 0 ? 'zero or a positive whole number' : 'a positive whole number'}.`);
|
||||
}
|
||||
if ((key === 'deployKeepDays' || key === 'observationKeepDays') && value > 36500) {
|
||||
if (key.endsWith('Days') && value > 36500) {
|
||||
throw new Error(`${fleetSettingLabels[key]} must be at most 36500 days.`);
|
||||
}
|
||||
}
|
||||
@@ -63,8 +129,34 @@ export function validateFleetSettings(input: unknown): FleetSettings {
|
||||
|
||||
export const additionalConcurrencyKeys: (keyof FleetSettings)[] = ["restartConcurrencyPerHost", "createConcurrencyPerHost", "destroyConcurrencyPerHost", "lifecycleConcurrency", "rebuildConcurrency", "preparationConcurrency"];
|
||||
export const concurrencyKeys: (keyof FleetSettings)[] = ['restartConcurrency', 'createConcurrency', 'destroyConcurrency', ...additionalConcurrencyKeys];
|
||||
export const retentionKeys: (keyof FleetSettings)[] = ['deployKeepDays', 'observationKeepDays'];
|
||||
export const retentionKeys: (keyof FleetSettings)[] = ['deployKeepDays', 'observationKeepDays', 'provisioningKeepDays', 'actionKeepDays', 'failureKeepDays', 'maintenanceKeepDays', 'recoveryKeepDays', 'hostResourceKeepDays', 'instanceResourceKeepDays', 'metricsKeepDays', 'telemetryKeepDays', 'telemetryMaxPerServer', 'telemetryMaxTotal', 'matchKeepDays', 'betaKeepDays', 'fileContentKeepDays', 'versionKeepDays', 'versionKeepCount', 'gameFileGraceDays', 'gameFileKeepCount', 'uploadKeepDays', 'auditKeepDays', 'historyKeepCount'];
|
||||
export function settingMinimum(key: keyof FleetSettings): number {
|
||||
return ['restartConcurrency','createConcurrency','destroyConcurrency','gameFileKeepCount'].includes(key) ? 1 : 0;
|
||||
}
|
||||
|
||||
export const settingHelp: Partial<Record<keyof FleetSettings, string>> = {
|
||||
provisioningKeepDays: 'Completed lifecycle history. Recovery, source workflows and cancellation dependencies remain protected.',
|
||||
actionKeepDays: 'Completed agent actions. Referenced commands and retry evidence remain protected. Expired actions keep compact receipts to prevent duplicate execution.',
|
||||
failureKeepDays: 'Explicitly resolved failed operations and campaigns, measured from resolution. Unresolved failures remain protected.',
|
||||
maintenanceKeepDays: 'Finished non-update maintenance. Update attempts remain durable to prevent duplicate automatic retries.',
|
||||
recoveryKeepDays: 'Resolved watchdog incidents with no unfinished recovery. Dismissed incidents remain as suppression evidence.',
|
||||
hostResourceKeepDays: 'Host CPU and memory history.',
|
||||
instanceResourceKeepDays: 'Minute resource samples. Capacity learning continues to use its independent 24-hour window.',
|
||||
metricsKeepDays: 'Historical fleet occupancy and utilization samples.',
|
||||
telemetryKeepDays: 'Raw received telemetry diagnostics. Independent of saved matches. Count limits also apply.',
|
||||
telemetryMaxPerServer: 'Count cap per server, in addition to the age limit. 0 disables this count cap.',
|
||||
telemetryMaxTotal: 'Fleet-wide count cap for telemetry diagnostics. 0 disables this count cap.',
|
||||
matchKeepDays: 'Completed and interrupted matches and player details. Expiry changes leaderboards and player totals; no lifetime aggregates are preserved.',
|
||||
betaKeepDays: 'Closed betas, revisions and test evidence, after linked campaigns and recovery work no longer need them.',
|
||||
fileContentKeepDays: 'Expired campaign file bodies are removed while summaries remain. Rollback becomes unavailable for those campaigns. Active beta snapshots remain protected.',
|
||||
versionKeepDays: 'Unused script, plugin, configuration and baseline versions. Current and referenced versions are always protected.',
|
||||
versionKeepCount: 'Keep at least this many recent versions per artifact. With no age expiry, a positive count removes older unused versions.',
|
||||
gameFileGraceDays: 'Delay removal after a version becomes superseded. Latest files, referenced versions and offline host copies remain protected. 0 adds no delay.',
|
||||
gameFileKeepCount: 'Keep this many recent published versions per game, in addition to every referenced or protected version.',
|
||||
uploadKeepDays: 'Remove incomplete browser uploads after this many days without activity. Active transfers and publication are protected.',
|
||||
auditKeepDays: 'Recorded authentication and account-administration events.',
|
||||
historyKeepCount: 'Keep at least this many recent records per history category. Does not apply to metrics, resource samples, telemetry count caps or game-file storage.',
|
||||
|
||||
restartConcurrency: 'Fleet recovery slots stay occupied until container and game health are verified.',
|
||||
createConcurrency: 'Fleet startup slots cover creation and rebuilds through health and selected-map verification.',
|
||||
destroyConcurrency: 'Fleet removals hold capacity until teardown and cleanup finish.',
|
||||
@@ -74,6 +166,6 @@ export const settingHelp: Partial<Record<keyof FleetSettings, string>> = {
|
||||
lifecycleConcurrency: 'Combined fleet limit for creates, starts, stops, restarts, rebuilds and destructions. Each workflow counts once.',
|
||||
rebuildConcurrency: 'Additional fleet limit for rebuilds, including host drain migrations.',
|
||||
preparationConcurrency: 'Maximum hosts downloading or verifying game files at once. Interrupted transfers keep their slot until reconciled.',
|
||||
deployKeepDays: 'Eligible campaign records and file diffs. Pending, failed, held and recovery-linked campaigns are protected.',
|
||||
deployKeepDays: 'Eligible campaign records and file diffs. Pending, unresolved failed, held and recovery-linked campaigns are protected.',
|
||||
observationKeepDays: 'Successful monitoring and file-read records. Failures and actions are retained. 0 keeps records indefinitely.'
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user