Add cancellation and cleanup for native server creation
This commit is contained in:
@@ -21,6 +21,7 @@ import { sha256Buffer } from '../fleet/files.js';
|
||||
import type { StagedFileChange } from '../fleet/staged-files.js';
|
||||
import type { LaunchPreview } from '../../deployment-plan.js';
|
||||
import type { ProvisioningAction } from '../../provisioning.js';
|
||||
import { cancelCreation, finishCreationCancellation } from './cancel-creation.js';
|
||||
|
||||
export interface NativeSelection { hostId: string; libraryId: string; image?: string; bindAddress?: string; publicAddress?: string; publicPort?: number }
|
||||
type NativeRecipe = LaunchRecipe & { native?: NativeSelection };
|
||||
@@ -146,15 +147,7 @@ export function cancelQueuedNativeCreation(server: string, triggeredBy: string):
|
||||
const creation = db().prepare(`SELECT d.id FROM server_deployments d JOIN native_provisioning n ON n.deployment_id=d.id
|
||||
WHERE n.instance_id=? AND d.action='create' AND d.state='queued' AND n.operation_id IS NULL`).get(instance.id) as { id: string } | undefined;
|
||||
if (!creation) return null;
|
||||
const id = beginDeployment(server, 'destroy', triggeredBy);
|
||||
const now = new Date().toISOString();
|
||||
db().prepare("UPDATE server_deployments SET state='cancelled',finished_at=?,stage='Queued native creation cancelled',server_deleted_at=? WHERE id=?")
|
||||
.run(now, now, creation.id);
|
||||
db().prepare('UPDATE native_instances SET retired_at=? WHERE id=?').run(now, instance.id);
|
||||
releaseHostPorts(instance.id);
|
||||
deploymentStage(id, 'Cancelled queued creation; no agent mutation was submitted');
|
||||
finishDeployment(id, { ok: true });
|
||||
return id;
|
||||
return cancelCreation(creation.id, triggeredBy);
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -277,6 +270,7 @@ export async function processNativeProvisioning(eligibility: (operation: { id: s
|
||||
const activeJobs = new Map<string, Promise<void>>();
|
||||
|
||||
async function processJob(job: Job, eligibility: (job: Job) => string | null) {
|
||||
if (!stillActive(job)) return;
|
||||
let instance = nativeInstance(job.server);
|
||||
if (!instance || instance.id !== job.instance_id || (instance.generation !== job.generation && !(job.action === 'rebuild' && instance.generation === job.generation + 1))) {
|
||||
finishDeployment(job.id, { ok: false, message: 'Original instance was retired or replaced; no command was sent.' }); return;
|
||||
@@ -288,6 +282,9 @@ async function processJob(job: Job, eligibility: (job: Job) => string | null) {
|
||||
}
|
||||
if (job.operation_id) {
|
||||
const operation = getHostOperation(job.operation_id);
|
||||
if (operation?.kind === 'instance.cancel-create' && operation.state === 'pending' && !host.inventory.capabilities?.includes('instance.cancel-create')) {
|
||||
hold(job, 'Update the host agent to support creation cancellation. Creation is cancelled; cleanup and port release await the updated agent.'); return;
|
||||
}
|
||||
if (!operation || operation.state === 'unknown') { hold(job, 'Agent result is unknown. Reconciling the original operation; no replacement or repeated command will be sent.'); return; }
|
||||
if (operation.state === 'failed') {
|
||||
// The agent reports failed only when no mutation began. Ambiguous
|
||||
@@ -312,6 +309,7 @@ async function processJob(job: Job, eligibility: (job: Job) => string | null) {
|
||||
db().prepare('DELETE FROM servers WHERE name=?').run(job.server);
|
||||
recordProgress(job.id, { checkpoint: { key: 'cleanup', label: 'Instance retired and port reservations released' } });
|
||||
complete(job);
|
||||
finishCreationCancellation(job.id);
|
||||
})();
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user