Let agents idle for updates required by creation cancellation
This commit is contained in:
@@ -319,6 +319,13 @@ export function queueHostOperation(hostId: string, kind: string, payload: Record
|
||||
export function pendingHostOperations(hostId: string): HostOperation[] {
|
||||
const host = requireHost(hostId);
|
||||
if (host.mode === 'disabled' || !host.connected) return [];
|
||||
// Older agents hold activity.lock across the entire delivered batch, including
|
||||
// observations. Filtering only the unsupported cleanup can keep the updater
|
||||
// busy indefinitely. Drain the old batch by withholding ALL further work;
|
||||
// heartbeats and receipts still flow, and the new capability releases this hold.
|
||||
// This must live in the controller so the fix also works before an agent update.
|
||||
if (!host.inventory.capabilities?.includes('instance.cancel-create') && database().prepare(`SELECT 1 FROM ec_host_operations
|
||||
WHERE host_id=? AND kind='instance.cancel-create' AND state IN ('pending','accepted','running','unknown') LIMIT 1`).get(hostId)) return [];
|
||||
// Accepted/running/unknown commands keep the same immutable ID. The agent
|
||||
// consults its durable journal before acknowledging or executing a replay.
|
||||
return database().transaction(() => {
|
||||
|
||||
@@ -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 { hostAgentUpdatesEnabled } from '../../hosts.js';
|
||||
import { cancelCreation, finishCreationCancellation } from './cancel-creation.js';
|
||||
|
||||
export interface NativeSelection { hostId: string; libraryId: string; image?: string; bindAddress?: string; publicAddress?: string; publicPort?: number }
|
||||
@@ -282,8 +283,10 @@ 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?.kind === 'instance.cancel-create' && !['completed', 'failed'].includes(operation.state) && !host.inventory.capabilities?.includes('instance.cancel-create')) {
|
||||
hold(job, hostAgentUpdatesEnabled(host.inventory)
|
||||
? 'Waiting for the host agent update. New command delivery is paused so its current batch can finish and the automatic updater can run. Cleanup resumes after the updated agent connects.'
|
||||
: 'Update the host agent to support creation cancellation: rerun the current installer on this host. Automatic updates are not enabled. New command delivery is paused; 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') {
|
||||
|
||||
Reference in New Issue
Block a user