Move fleet retention and concurrency controls into Settings

Persist settings in SQLite, import legacy environment values once, and apply changes to cleanup and deployment queues without restarting.

Closes #51
This commit is contained in:
2026-09-27 16:11:45 -04:00
parent fc46cb9da4
commit 4fe8613678
20 changed files with 334 additions and 54 deletions
+17 -12
View File
@@ -438,10 +438,8 @@ describe('Provisioning ownership', () => {
describe('rollout configuration', () => {
it('honors a configured limit larger than one', async () => {
const { closeDb } = await import('../../src/lib/server/db/index.js');
closeDb();
vi.resetModules();
vi.stubEnv('DEPLOYMENT_RESTART_CONCURRENCY', '2');
const { fleetSettings, saveFleetSettings } = await import('../../src/lib/server/settings.js');
saveFleetSettings({ ...fleetSettings(), restartConcurrency: 2 });
await deployment();
const { sweep } = await import('../helpers/provisioning.js');
const { komodoRestart } = await import('../../src/lib/server/integrations/komodo.js');
@@ -451,13 +449,20 @@ describe('rollout configuration', () => {
expect(komodoRestart).toHaveBeenCalledTimes(2);
});
it.each(['0', '-1', '1.5', 'abc'])('rejects invalid concurrency %s', async (value) => {
const { closeDb } = await import('../../src/lib/server/db/index.js');
closeDb();
vi.resetModules();
vi.stubEnv('DEPLOYMENT_RESTART_CONCURRENCY', value);
await expect(import('../../src/lib/server/config.js')).rejects.toThrow(/DEPLOYMENT_RESTART_CONCURRENCY/);
vi.stubEnv('DEPLOYMENT_RESTART_CONCURRENCY', '1');
vi.resetModules();
it('holds new restarts after lowering a live limit without releasing active slots', async () => {
const { fleetSettings, saveFleetSettings } = await import('../../src/lib/server/settings.js');
const { sweep } = await import('../helpers/provisioning.js');
const { komodoRestart } = await import('../../src/lib/server/integrations/komodo.js');
saveFleetSettings({ ...fleetSettings(), restartConcurrency: 2 });
await deployment();
await sweep();
saveFleetSettings({ ...fleetSettings(), restartConcurrency: 1 });
await sweep();
expect(komodoRestart).toHaveBeenCalledTimes(2);
const { db } = await import('../../src/lib/server/db/index.js');
expect(db().prepare('SELECT server FROM restart_rollout WHERE healthy_at IS NULL').all()).toHaveLength(2);
nextTick();
await sweep();
expect(komodoRestart).toHaveBeenCalledTimes(3);
});
});