feat(ql3): admit plugin secret action jobs

This commit is contained in:
whyour
2026-08-14 10:22:14 +08:00
parent 75dbe7a4c4
commit 7f5339e047
27 changed files with 2019 additions and 10 deletions
@@ -379,6 +379,62 @@ export class PostgresApprovedActionExecutionRepository
}
}
async listReconciliableExecutions(
query: Readonly<{
nowMs: number;
limit: number;
actionTypes: readonly string[];
}>,
): Promise<Readonly<{
executions: readonly Readonly<ApprovedActionExecutionSnapshot>[];
truncated: boolean;
}>> {
assertPageSize(query.limit);
const handledActionTypes = actionTypes(query.actionTypes);
if (!Number.isSafeInteger(query.nowMs) || query.nowMs < 0) {
throw new ApprovedActionExecutionStateConflictError();
}
if (handledActionTypes.length === 0) {
return Object.freeze({ executions: Object.freeze([]), truncated: false });
}
try {
const result = await this.pool.query<Row>(
`SELECT execution.execution_json AS "executionJson",
execution.execution_digest AS "executionDigest",
dispatch.dispatch_json AS "dispatchJson"
FROM "ql3"."approved_action_executions" AS execution
JOIN "ql3"."approved_action_dispatches" AS dispatch
ON dispatch.dispatch_id = execution.dispatch_id
WHERE dispatch.action_type = ANY($1::varchar[])
AND (
(
execution.status IN ('pending','leased','retry_wait')
AND execution.eligible_at_ms <= $2
)
OR execution.status = 'executing'
)
ORDER BY execution.updated_at_ms, execution.dispatch_id
LIMIT $3`,
[handledActionTypes, query.nowMs, query.limit + 1],
);
const truncated = result.rows.length > query.limit;
const rows = truncated ? result.rows.slice(0, query.limit) : result.rows;
return Object.freeze({
executions: Object.freeze(
rows.map((row) =>
normalizeApprovedActionExecutionSnapshot({
dispatch: parseDispatch(row),
execution: parseExecution(row),
}),
),
),
truncated,
});
} catch (error) {
throw mappedError(error);
}
}
claimExecution(
command: ClaimApprovedActionExecutionCommand,
): Promise<ClaimApprovedActionExecutionResult> {
@@ -41,6 +41,7 @@ export {
export { PostgresPluginPackageMaterializedRevisionRepository } from '../plugin-package/installation/pluginPackageMaterializedRevisionRepository';
export { PostgresApprovalRequestRepository } from '../approved-action/approvalRequestRepository';
export { PostgresApprovedActionExecutionRepository } from '../approved-action/approvedActionExecutionRepository';
export { PostgresProjectPolicyRepository } from '../security/projectPolicyRepository';
export { PostgresPluginPackageSecretBindingRepository } from '../plugin-package/installation/pluginPackageSecretBindingRepository';
export { PostgresPluginPackageSecretBindingActivationPrerequisite } from '../plugin-package/secret-binding/pluginPackageSecretBindingActivationPrerequisite';
@@ -367,11 +367,16 @@ test('Approved Action execution authority is isolated behind its explicit subpat
const runtime = require('@qinglong/cluster-postgres/runtime');
const admin = require('@qinglong/cluster-postgres/admin');
const ingress = require('@qinglong/cluster-postgres/worker-ingress');
const packageExecutor = require('@qinglong/cluster-postgres/package-executor');
const authority = require('@qinglong/cluster-postgres/approved-action-execution');
assert.equal(root.PostgresApprovedActionExecutionRepository, undefined);
assert.equal(runtime.PostgresApprovedActionExecutionRepository, undefined);
assert.equal(admin.PostgresApprovedActionExecutionRepository, undefined);
assert.equal(ingress.PostgresApprovedActionExecutionRepository, undefined);
assert.equal(
packageExecutor.PostgresApprovedActionExecutionRepository,
authority.PostgresApprovedActionExecutionRepository,
);
assert.equal(
typeof authority.PostgresApprovedActionExecutionRepository,
'function',
@@ -3581,6 +3581,22 @@ if (!migrationConnectionString) {
const executions = new PostgresApprovedActionExecutionRepository(
executorDatabase.pool,
);
const pendingSecretActions =
await executions.listReconciliableExecutions({
nowMs: claimedAtMs,
limit: 1,
actionTypes: [consumed.dispatch.action.actionType],
});
assert.equal(pendingSecretActions.truncated, false);
assert.equal(pendingSecretActions.executions.length, 1);
assert.equal(
pendingSecretActions.executions[0].dispatch.id,
consumed.dispatch.id,
);
assert.equal(
pendingSecretActions.executions[0].execution.status,
'pending',
);
const claimed = await executions.claimExecution({
dispatchId: consumed.dispatch.id,
owner: 'package_admission_dispatcher',
@@ -3598,6 +3614,22 @@ if (!migrationConnectionString) {
expectedVersion: claimed.snapshot.execution.version,
startedAtMs: admittedAtMs,
});
const executingSecretActions =
await executions.listReconciliableExecutions({
nowMs: admittedAtMs,
limit: 1,
actionTypes: [consumed.dispatch.action.actionType],
});
assert.equal(executingSecretActions.truncated, false);
assert.equal(executingSecretActions.executions.length, 1);
assert.equal(
executingSecretActions.executions[0].dispatch.id,
consumed.dispatch.id,
);
assert.equal(
executingSecretActions.executions[0].execution.status,
'executing',
);
const lock = resolvePluginPackageInstallProposal(
proposal,
consumed.dispatch,