mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
190 lines
7.2 KiB
TypeScript
190 lines
7.2 KiB
TypeScript
import { CAPABILITIES_V53 } from './pg-0054-approval-management-boundary';
|
|
import { definePostgresSqlMigration } from './sqlMigration';
|
|
|
|
export const CAPABILITIES_V54 = CAPABILITIES_V53.replace(
|
|
'"run_core":1,',
|
|
'"run_attempt_log_retention":1,"run_core":1,',
|
|
);
|
|
|
|
export const pg0055RunAttemptLogRetentionMigration =
|
|
definePostgresSqlMigration({
|
|
id: 'pg-0055-run-attempt-log-retention',
|
|
statements: [
|
|
`
|
|
CREATE TABLE "ql3"."run_attempt_log_retention_controls" (
|
|
attempt_id varchar(36) PRIMARY KEY,
|
|
project_id varchar(128) NOT NULL,
|
|
run_id varchar(36) NOT NULL,
|
|
log_artifact_id varchar(36) NOT NULL,
|
|
executor_type varchar(32) NOT NULL,
|
|
finished_at_ms bigint NOT NULL,
|
|
eligible_at_ms bigint NOT NULL,
|
|
state varchar(16) NOT NULL,
|
|
claim_owner varchar(128),
|
|
claim_token varchar(64),
|
|
claim_version integer NOT NULL DEFAULT 1,
|
|
claim_expires_at_ms bigint,
|
|
next_claim_at_ms bigint,
|
|
failure_count integer NOT NULL DEFAULT 0,
|
|
last_failure_code varchar(64),
|
|
created_at_ms bigint NOT NULL,
|
|
updated_at_ms bigint NOT NULL,
|
|
CONSTRAINT ql3_run_log_retention_control_artifact_key
|
|
UNIQUE (log_artifact_id),
|
|
CONSTRAINT ql3_run_log_retention_control_identity_check CHECK (
|
|
char_length(project_id) BETWEEN 1 AND 128
|
|
AND char_length(run_id) BETWEEN 1 AND 36
|
|
AND char_length(attempt_id) BETWEEN 1 AND 36
|
|
AND log_artifact_id ~ '^wlog-[a-f0-9]{30}$'
|
|
AND executor_type = 'remote_worker'
|
|
),
|
|
CONSTRAINT ql3_run_log_retention_control_time_check CHECK (
|
|
finished_at_ms >= 0
|
|
AND eligible_at_ms >= finished_at_ms
|
|
AND created_at_ms >= 0
|
|
AND updated_at_ms >= created_at_ms
|
|
),
|
|
CONSTRAINT ql3_run_log_retention_control_state_check
|
|
CHECK (state IN ('claimed', 'retry', 'manual')),
|
|
CONSTRAINT ql3_run_log_retention_control_claim_owner_check CHECK (
|
|
claim_owner IS NULL
|
|
OR claim_owner ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$'
|
|
),
|
|
CONSTRAINT ql3_run_log_retention_control_claim_token_check CHECK (
|
|
claim_token IS NULL
|
|
OR claim_token ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{15,63}$'
|
|
),
|
|
CONSTRAINT ql3_run_log_retention_control_claim_version_check
|
|
CHECK (claim_version BETWEEN 1 AND 2147483647),
|
|
CONSTRAINT ql3_run_log_retention_control_claim_expiry_check
|
|
CHECK (claim_expires_at_ms IS NULL OR claim_expires_at_ms >= 0),
|
|
CONSTRAINT ql3_run_log_retention_control_next_claim_check
|
|
CHECK (next_claim_at_ms IS NULL OR next_claim_at_ms >= 0),
|
|
CONSTRAINT ql3_run_log_retention_control_failure_count_check
|
|
CHECK (failure_count BETWEEN 0 AND 2147483647),
|
|
CONSTRAINT ql3_run_log_retention_control_failure_code_check CHECK (
|
|
last_failure_code IS NULL
|
|
OR last_failure_code IN (
|
|
'artifact_unavailable',
|
|
'artifact_integrity_mismatch',
|
|
'retirement_record_unavailable'
|
|
)
|
|
),
|
|
CONSTRAINT ql3_run_log_retention_control_state_shape_check CHECK (
|
|
(
|
|
state = 'claimed'
|
|
AND claim_owner IS NOT NULL
|
|
AND claim_token IS NOT NULL
|
|
AND claim_expires_at_ms IS NOT NULL
|
|
AND next_claim_at_ms IS NULL
|
|
)
|
|
OR (
|
|
state = 'retry'
|
|
AND claim_owner IS NULL
|
|
AND claim_token IS NULL
|
|
AND claim_expires_at_ms IS NULL
|
|
AND next_claim_at_ms IS NOT NULL
|
|
AND last_failure_code IS NOT NULL
|
|
)
|
|
OR (
|
|
state = 'manual'
|
|
AND claim_owner IS NULL
|
|
AND claim_token IS NULL
|
|
AND claim_expires_at_ms IS NULL
|
|
AND next_claim_at_ms IS NULL
|
|
AND last_failure_code IS NOT NULL
|
|
)
|
|
),
|
|
CONSTRAINT ql3_run_log_retention_control_attempt_fk
|
|
FOREIGN KEY (attempt_id) REFERENCES "ql3"."run_attempts" (id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT ql3_run_log_retention_control_run_fk
|
|
FOREIGN KEY (run_id) REFERENCES "ql3"."runs" (id)
|
|
ON DELETE CASCADE
|
|
)
|
|
`.trim(),
|
|
`
|
|
CREATE TABLE "ql3"."run_attempt_log_artifact_tombstones" (
|
|
log_artifact_id varchar(36) PRIMARY KEY,
|
|
project_id varchar(128) NOT NULL,
|
|
run_id varchar(36) NOT NULL,
|
|
attempt_id varchar(36) NOT NULL,
|
|
executor_type varchar(32) NOT NULL,
|
|
finished_at_ms bigint NOT NULL,
|
|
eligible_at_ms bigint NOT NULL,
|
|
retired_at_ms bigint NOT NULL,
|
|
disposition varchar(16) NOT NULL,
|
|
byte_length bigint NOT NULL,
|
|
truncated varchar(16) NOT NULL,
|
|
maximum_bytes bigint,
|
|
truncation_observed_at_ms bigint,
|
|
record_digest char(64) NOT NULL,
|
|
CONSTRAINT ql3_run_log_tombstone_attempt_key UNIQUE (attempt_id),
|
|
CONSTRAINT ql3_run_log_tombstone_identity_check CHECK (
|
|
char_length(project_id) BETWEEN 1 AND 128
|
|
AND char_length(run_id) BETWEEN 1 AND 36
|
|
AND char_length(attempt_id) BETWEEN 1 AND 36
|
|
AND log_artifact_id ~ '^wlog-[a-f0-9]{30}$'
|
|
AND executor_type = 'remote_worker'
|
|
),
|
|
CONSTRAINT ql3_run_log_tombstone_time_check CHECK (
|
|
finished_at_ms >= 0
|
|
AND eligible_at_ms >= finished_at_ms
|
|
AND retired_at_ms >= eligible_at_ms
|
|
),
|
|
CONSTRAINT ql3_run_log_tombstone_disposition_check CHECK (
|
|
disposition IN ('deleted', 'already_absent')
|
|
AND (disposition <> 'already_absent' OR byte_length = 0)
|
|
),
|
|
CONSTRAINT ql3_run_log_tombstone_size_check
|
|
CHECK (byte_length BETWEEN 0 AND 1073741824),
|
|
CONSTRAINT ql3_run_log_tombstone_truncation_check CHECK (
|
|
(
|
|
truncated = 'unknown'
|
|
AND maximum_bytes IS NULL
|
|
AND truncation_observed_at_ms IS NULL
|
|
)
|
|
OR (
|
|
truncated IN ('true', 'false')
|
|
AND maximum_bytes >= 1
|
|
AND truncation_observed_at_ms >= 0
|
|
)
|
|
),
|
|
CONSTRAINT ql3_run_log_tombstone_digest_check
|
|
CHECK (record_digest ~ '^[a-f0-9]{64}$'),
|
|
CONSTRAINT ql3_run_log_tombstone_attempt_fk
|
|
FOREIGN KEY (attempt_id) REFERENCES "ql3"."run_attempts" (id)
|
|
ON DELETE CASCADE,
|
|
CONSTRAINT ql3_run_log_tombstone_run_fk
|
|
FOREIGN KEY (run_id) REFERENCES "ql3"."runs" (id)
|
|
ON DELETE CASCADE
|
|
)
|
|
`.trim(),
|
|
`CREATE INDEX ql3_run_log_retention_retry_idx ON "ql3"."run_attempt_log_retention_controls" (next_claim_at_ms, finished_at_ms, attempt_id) WHERE state = 'retry'`,
|
|
`CREATE INDEX ql3_run_log_retention_claim_expiry_idx ON "ql3"."run_attempt_log_retention_controls" (claim_expires_at_ms, finished_at_ms, attempt_id) WHERE state = 'claimed'`,
|
|
`CREATE INDEX ql3_run_log_tombstone_retired_idx ON "ql3"."run_attempt_log_artifact_tombstones" (retired_at_ms, attempt_id)`,
|
|
`CREATE INDEX ql3_run_log_retention_candidate_idx ON "ql3"."run_attempts" (finished_at_ms, id) WHERE executor_type = 'remote_worker' AND log_artifact_id IS NOT NULL AND status IN ('succeeded', 'failed', 'cancelled', 'timed_out')`,
|
|
`GRANT SELECT, INSERT, UPDATE, DELETE ON "ql3"."run_attempt_log_retention_controls" TO ql3_runtime`,
|
|
`GRANT SELECT, INSERT ON "ql3"."run_attempt_log_artifact_tombstones" TO ql3_runtime`,
|
|
`
|
|
DO $ql3$
|
|
BEGIN
|
|
UPDATE "ql3"."schema_capabilities"
|
|
SET contract_version = 54,
|
|
migration_id = 'pg-0055-run-attempt-log-retention',
|
|
capabilities = '${CAPABILITIES_V54}'::jsonb,
|
|
updated_at_ms = floor(extract(epoch FROM transaction_timestamp()) * 1000)::bigint
|
|
WHERE contract_name = 'control-core'
|
|
AND contract_version = 53
|
|
AND migration_id = 'pg-0054-approval-management-boundary'
|
|
AND capabilities = '${CAPABILITIES_V53}'::jsonb;
|
|
IF NOT FOUND THEN
|
|
RAISE EXCEPTION 'control-core capability is not at version 53'
|
|
USING ERRCODE = 'check_violation';
|
|
END IF;
|
|
END
|
|
$ql3$
|
|
`.trim(),
|
|
],
|
|
});
|