feat(ql3): atomically apply cluster legacy env migration

This commit is contained in:
whyour
2026-08-24 21:13:15 +08:00
parent 4abf125ce9
commit bd8678a888
23 changed files with 3372 additions and 21 deletions
@@ -358,5 +358,10 @@ export const postgresqlMainMigrationManifest: MigrationStreamManifest =
checksum:
'7cd6d993f48e7bcebcd62c93571a738d5117c9bcde33b974c5ac8962e2a03fe4',
}),
Object.freeze({
id: 'pg-0071-cluster-legacy-env-migration-applications',
checksum:
'82538b5a244011a22afad7f9c6d266a8997da538bdd2bec2ee524997c3b85996',
}),
]),
});
@@ -73,6 +73,7 @@ import { pg0067CancellationDispatchManagementMigration } from '../run-management
import { pg0068CancellationDispatchProjectKeysetMigration } from '../run-management/pg-0068-cancellation-dispatch-project-keyset';
import { pg0069WorkerSessionManagementObservationMigration } from '../remote-execution/pg-0069-worker-session-management-observation';
import { pg0070ClusterLegacyEnvMigrationPlansMigration } from '../reconciliation/pg-0070-cluster-legacy-env-migration-plans';
import { pg0071ClusterLegacyEnvMigrationApplicationsMigration } from '../reconciliation/pg-0071-cluster-legacy-env-migration-applications';
export const postgresqlMainMigrationStream: MigrationStreamDefinition<PostgresMigrationContext> =
Object.freeze({
@@ -151,5 +152,6 @@ export const postgresqlMainMigrationStream: MigrationStreamDefinition<PostgresMi
pg0068CancellationDispatchProjectKeysetMigration,
pg0069WorkerSessionManagementObservationMigration,
pg0070ClusterLegacyEnvMigrationPlansMigration,
pg0071ClusterLegacyEnvMigrationApplicationsMigration,
]),
});
@@ -0,0 +1,182 @@
import { definePostgresSqlMigration } from '../migrations/sqlMigration';
import { CAPABILITIES_V69 } from './pg-0070-cluster-legacy-env-migration-plans';
export const CAPABILITIES_V70 = CAPABILITIES_V69.replace(
'"cluster_legacy_env_migration_plan":1,',
'"cluster_legacy_env_migration_application":1,"cluster_legacy_env_migration_plan":1,',
);
export const pg0071ClusterLegacyEnvMigrationApplicationsMigration =
definePostgresSqlMigration({
id: 'pg-0071-cluster-legacy-env-migration-applications',
statements: [
`
CREATE TABLE "ql3"."cluster_legacy_env_migration_application_receipts" (
application_id varchar(128) PRIMARY KEY,
mutation_id uuid NOT NULL,
project_id varchar(128) NOT NULL,
plan_id varchar(128) NOT NULL,
plan_digest char(64) NOT NULL,
environment_bundle_ref varchar(512) NOT NULL,
task_revision_set_digest char(64) NOT NULL,
trigger_revision_set_digest char(64) NOT NULL,
task_mutation_set_digest char(64) NOT NULL,
trigger_mutation_set_digest char(64) NOT NULL,
task_count integer NOT NULL,
trigger_count integer NOT NULL,
committed_at_ms bigint NOT NULL,
receipt_digest char(64) NOT NULL,
receipt_json jsonb NOT NULL,
CONSTRAINT ql3_cluster_legacy_env_application_project_fk
FOREIGN KEY (project_id) REFERENCES "ql3"."projects" (id)
ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT ql3_cluster_legacy_env_application_plan_fk
FOREIGN KEY (plan_id) REFERENCES "ql3"."cluster_legacy_env_migration_plans" (plan_id)
ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT ql3_cluster_legacy_env_application_identity_check CHECK (
application_id ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' AND
project_id ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' AND
plan_id ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$'
),
CONSTRAINT ql3_cluster_legacy_env_application_digest_check CHECK (
plan_digest ~ '^[0-9a-f]{64}$' AND
task_revision_set_digest ~ '^[0-9a-f]{64}$' AND
trigger_revision_set_digest ~ '^[0-9a-f]{64}$' AND
task_mutation_set_digest ~ '^[0-9a-f]{64}$' AND
trigger_mutation_set_digest ~ '^[0-9a-f]{64}$' AND
receipt_digest ~ '^[0-9a-f]{64}$'
),
CONSTRAINT ql3_cluster_legacy_env_application_target_check CHECK (
environment_bundle_ref ~ '^qlsecret:v1:[A-Za-z0-9_-]+$' AND
octet_length(environment_bundle_ref) BETWEEN 14 AND 512 AND
task_count BETWEEN 1 AND 100000 AND
trigger_count BETWEEN 0 AND 500000 AND
committed_at_ms >= 0
),
CONSTRAINT ql3_cluster_legacy_env_application_json_check CHECK (
jsonb_typeof(receipt_json) = 'object' AND
octet_length(receipt_json::text) BETWEEN 2 AND 8192 AND
receipt_json = jsonb_build_object(
'schema', 'qinglong/cluster-legacy-env-migration-application-receipt@v1',
'applicationId', application_id,
'mutationId', mutation_id::text,
'projectId', project_id,
'planId', plan_id,
'planDigest', plan_digest,
'environmentBundleRef', environment_bundle_ref,
'taskRevisionSetDigest', task_revision_set_digest,
'triggerRevisionSetDigest', trigger_revision_set_digest,
'taskMutationSetDigest', task_mutation_set_digest,
'triggerMutationSetDigest', trigger_mutation_set_digest,
'taskCount', task_count,
'triggerCount', trigger_count,
'committedAtMs', committed_at_ms,
'receiptDigest', receipt_digest
)
)
)
`.trim(),
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_mutation_uidx ON "ql3"."cluster_legacy_env_migration_application_receipts" (mutation_id)`,
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_project_uidx ON "ql3"."cluster_legacy_env_migration_application_receipts" (application_id, project_id)`,
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_plan_uidx ON "ql3"."cluster_legacy_env_migration_application_receipts" (plan_id)`,
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_digest_uidx ON "ql3"."cluster_legacy_env_migration_application_receipts" (receipt_digest)`,
`CREATE INDEX ql3_cluster_legacy_env_application_project_idx ON "ql3"."cluster_legacy_env_migration_application_receipts" (project_id, committed_at_ms, application_id)`,
`
CREATE TABLE "ql3"."cluster_legacy_env_migration_application_tasks" (
application_id varchar(128) NOT NULL,
ordinal integer NOT NULL,
project_id varchar(128) NOT NULL,
task_id varchar(128) NOT NULL,
previous_revision integer NOT NULL,
previous_content_digest char(64) NOT NULL,
mutation_id uuid NOT NULL,
revision integer NOT NULL,
content_digest char(64) NOT NULL,
execution_content_digest char(64),
item_digest char(64) NOT NULL,
CONSTRAINT cluster_legacy_env_migration_application_tasks_pkey
PRIMARY KEY (application_id, ordinal),
CONSTRAINT ql3_cluster_legacy_env_application_task_receipt_fk
FOREIGN KEY (application_id, project_id)
REFERENCES "ql3"."cluster_legacy_env_migration_application_receipts"
(application_id, project_id)
ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT ql3_cluster_legacy_env_application_task_identity_check CHECK (
project_id ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' AND
char_length(task_id) BETWEEN 1 AND 128 AND task_id !~ '[[:cntrl:]]'
),
CONSTRAINT ql3_cluster_legacy_env_application_task_revision_check CHECK (
ordinal BETWEEN 0 AND 99999 AND
previous_revision BETWEEN 1 AND 2147483646 AND
revision = previous_revision + 1
),
CONSTRAINT ql3_cluster_legacy_env_application_task_digest_check CHECK (
previous_content_digest ~ '^[0-9a-f]{64}$' AND
content_digest ~ '^[0-9a-f]{64}$' AND
(execution_content_digest IS NULL OR execution_content_digest ~ '^[0-9a-f]{64}$') AND
item_digest ~ '^[0-9a-f]{64}$'
)
)
`.trim(),
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_task_uidx ON "ql3"."cluster_legacy_env_migration_application_tasks" (application_id, task_id)`,
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_task_revision_uidx ON "ql3"."cluster_legacy_env_migration_application_tasks" (application_id, project_id, task_id, revision, content_digest)`,
`
CREATE TABLE "ql3"."cluster_legacy_env_migration_application_triggers" (
application_id varchar(128) NOT NULL,
ordinal integer NOT NULL,
project_id varchar(128) NOT NULL,
trigger_id varchar(128) NOT NULL,
task_id varchar(128) NOT NULL,
previous_revision integer NOT NULL,
previous_content_digest char(64) NOT NULL,
previous_task_revision integer NOT NULL,
previous_task_content_digest char(64) NOT NULL,
mutation_id uuid NOT NULL,
revision integer NOT NULL,
content_digest char(64) NOT NULL,
task_revision integer NOT NULL,
task_content_digest char(64) NOT NULL,
item_digest char(64) NOT NULL,
CONSTRAINT cluster_legacy_env_migration_application_triggers_pkey
PRIMARY KEY (application_id, ordinal),
CONSTRAINT ql3_cluster_legacy_env_application_trigger_receipt_fk
FOREIGN KEY (application_id, project_id)
REFERENCES "ql3"."cluster_legacy_env_migration_application_receipts"
(application_id, project_id)
ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT ql3_cluster_legacy_env_application_trigger_task_fk
FOREIGN KEY (application_id, project_id, task_id, task_revision, task_content_digest)
REFERENCES "ql3"."cluster_legacy_env_migration_application_tasks"
(application_id, project_id, task_id, revision, content_digest)
ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT ql3_cluster_legacy_env_application_trigger_identity_check CHECK (
project_id ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' AND
char_length(trigger_id) BETWEEN 1 AND 128 AND trigger_id !~ '[[:cntrl:]]' AND
char_length(task_id) BETWEEN 1 AND 128 AND task_id !~ '[[:cntrl:]]'
),
CONSTRAINT ql3_cluster_legacy_env_application_trigger_revision_check CHECK (
ordinal BETWEEN 0 AND 499999 AND
previous_revision BETWEEN 1 AND 2147483646 AND
revision = previous_revision + 1 AND
previous_task_revision BETWEEN 1 AND 2147483647 AND
task_revision BETWEEN 2 AND 2147483647
),
CONSTRAINT ql3_cluster_legacy_env_application_trigger_digest_check CHECK (
previous_content_digest ~ '^[0-9a-f]{64}$' AND
previous_task_content_digest ~ '^[0-9a-f]{64}$' AND
content_digest ~ '^[0-9a-f]{64}$' AND
task_content_digest ~ '^[0-9a-f]{64}$' AND
item_digest ~ '^[0-9a-f]{64}$'
)
)
`.trim(),
`CREATE UNIQUE INDEX ql3_cluster_legacy_env_application_trigger_uidx ON "ql3"."cluster_legacy_env_migration_application_triggers" (application_id, trigger_id)`,
`REVOKE ALL ON "ql3"."cluster_legacy_env_migration_application_receipts" FROM PUBLIC`,
`REVOKE ALL ON "ql3"."cluster_legacy_env_migration_application_tasks" FROM PUBLIC`,
`REVOKE ALL ON "ql3"."cluster_legacy_env_migration_application_triggers" FROM PUBLIC`,
`GRANT SELECT, INSERT ON "ql3"."cluster_legacy_env_migration_application_receipts" TO ql3_automation_manager`,
`GRANT SELECT, INSERT ON "ql3"."cluster_legacy_env_migration_application_tasks" TO ql3_automation_manager`,
`GRANT SELECT, INSERT ON "ql3"."cluster_legacy_env_migration_application_triggers" TO ql3_automation_manager`,
`DO $ql3$ BEGIN UPDATE "ql3"."schema_capabilities" SET contract_version = 70, migration_id = 'pg-0071-cluster-legacy-env-migration-applications', capabilities = '${CAPABILITIES_V70}'::jsonb, updated_at_ms = floor(extract(epoch FROM transaction_timestamp()) * 1000)::bigint WHERE contract_name = 'control-core' AND contract_version = 69 AND migration_id = 'pg-0070-cluster-legacy-env-migration-plans' AND capabilities = '${CAPABILITIES_V69}'::jsonb; IF NOT FOUND THEN RAISE EXCEPTION 'control-core capability is not at version 69' USING ERRCODE = 'check_violation'; END IF; END $ql3$`,
],
});
@@ -180,6 +180,213 @@ export const clusterLegacyEnvMigrationPlans = ql3Schema.table(
],
);
export const clusterLegacyEnvMigrationApplicationReceipts = ql3Schema.table(
'cluster_legacy_env_migration_application_receipts',
{
applicationId: varchar('application_id', { length: 128 }).primaryKey(),
mutationId: uuid('mutation_id').notNull(),
projectId: varchar('project_id', { length: 128 }).notNull(),
planId: varchar('plan_id', { length: 128 }).notNull(),
planDigest: char('plan_digest', { length: 64 }).notNull(),
environmentBundleRef: varchar('environment_bundle_ref', {
length: 512,
}).notNull(),
taskRevisionSetDigest: char('task_revision_set_digest', {
length: 64,
}).notNull(),
triggerRevisionSetDigest: char('trigger_revision_set_digest', {
length: 64,
}).notNull(),
taskMutationSetDigest: char('task_mutation_set_digest', {
length: 64,
}).notNull(),
triggerMutationSetDigest: char('trigger_mutation_set_digest', {
length: 64,
}).notNull(),
taskCount: integer('task_count').notNull(),
triggerCount: integer('trigger_count').notNull(),
committedAtMs: bigint('committed_at_ms', { mode: 'number' }).notNull(),
receiptDigest: char('receipt_digest', { length: 64 }).notNull(),
receiptJson: jsonb('receipt_json')
.$type<Record<string, unknown>>()
.notNull(),
},
(table) => [
foreignKey({
name: 'ql3_cluster_legacy_env_application_project_fk',
columns: [table.projectId],
foreignColumns: [projects.id],
}).onDelete('restrict'),
foreignKey({
name: 'ql3_cluster_legacy_env_application_plan_fk',
columns: [table.planId],
foreignColumns: [clusterLegacyEnvMigrationPlans.planId],
}).onDelete('restrict'),
check(
'ql3_cluster_legacy_env_application_identity_check',
sql`${table.applicationId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' and ${table.projectId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' and ${table.planId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$'`,
),
check(
'ql3_cluster_legacy_env_application_digest_check',
sql`${table.planDigest} ~ '^[0-9a-f]{64}$' and ${table.taskRevisionSetDigest} ~ '^[0-9a-f]{64}$' and ${table.triggerRevisionSetDigest} ~ '^[0-9a-f]{64}$' and ${table.taskMutationSetDigest} ~ '^[0-9a-f]{64}$' and ${table.triggerMutationSetDigest} ~ '^[0-9a-f]{64}$' and ${table.receiptDigest} ~ '^[0-9a-f]{64}$'`,
),
check(
'ql3_cluster_legacy_env_application_target_check',
sql`${table.environmentBundleRef} ~ '^qlsecret:v1:[A-Za-z0-9_-]+$' and octet_length(${table.environmentBundleRef}) between 14 and 512 and ${table.taskCount} between 1 and 100000 and ${table.triggerCount} between 0 and 500000 and ${table.committedAtMs} >= 0`,
),
check(
'ql3_cluster_legacy_env_application_json_check',
sql`jsonb_typeof(${table.receiptJson}) = 'object' and octet_length(${table.receiptJson}::text) between 2 and 8192 and ${table.receiptJson} = jsonb_build_object('schema', 'qinglong/cluster-legacy-env-migration-application-receipt@v1', 'applicationId', ${table.applicationId}, 'mutationId', ${table.mutationId}::text, 'projectId', ${table.projectId}, 'planId', ${table.planId}, 'planDigest', ${table.planDigest}, 'environmentBundleRef', ${table.environmentBundleRef}, 'taskRevisionSetDigest', ${table.taskRevisionSetDigest}, 'triggerRevisionSetDigest', ${table.triggerRevisionSetDigest}, 'taskMutationSetDigest', ${table.taskMutationSetDigest}, 'triggerMutationSetDigest', ${table.triggerMutationSetDigest}, 'taskCount', ${table.taskCount}, 'triggerCount', ${table.triggerCount}, 'committedAtMs', ${table.committedAtMs}, 'receiptDigest', ${table.receiptDigest})`,
),
uniqueIndex('ql3_cluster_legacy_env_application_mutation_uidx').on(
table.mutationId,
),
uniqueIndex('ql3_cluster_legacy_env_application_project_uidx').on(
table.applicationId,
table.projectId,
),
uniqueIndex('ql3_cluster_legacy_env_application_plan_uidx').on(
table.planId,
),
uniqueIndex('ql3_cluster_legacy_env_application_digest_uidx').on(
table.receiptDigest,
),
index('ql3_cluster_legacy_env_application_project_idx').on(
table.projectId,
table.committedAtMs,
table.applicationId,
),
],
);
export const clusterLegacyEnvMigrationApplicationTasks = ql3Schema.table(
'cluster_legacy_env_migration_application_tasks',
{
applicationId: varchar('application_id', { length: 128 }).notNull(),
ordinal: integer('ordinal').notNull(),
projectId: varchar('project_id', { length: 128 }).notNull(),
taskId: varchar('task_id', { length: 128 }).notNull(),
previousRevision: integer('previous_revision').notNull(),
previousContentDigest: char('previous_content_digest', {
length: 64,
}).notNull(),
mutationId: uuid('mutation_id').notNull(),
revision: integer('revision').notNull(),
contentDigest: char('content_digest', { length: 64 }).notNull(),
executionContentDigest: char('execution_content_digest', { length: 64 }),
itemDigest: char('item_digest', { length: 64 }).notNull(),
},
(table) => [
primaryKey({
name: 'cluster_legacy_env_migration_application_tasks_pkey',
columns: [table.applicationId, table.ordinal],
}),
foreignKey({
name: 'ql3_cluster_legacy_env_application_task_receipt_fk',
columns: [table.applicationId, table.projectId],
foreignColumns: [
clusterLegacyEnvMigrationApplicationReceipts.applicationId,
clusterLegacyEnvMigrationApplicationReceipts.projectId,
],
}).onDelete('restrict'),
check(
'ql3_cluster_legacy_env_application_task_identity_check',
sql`${table.projectId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' and char_length(${table.taskId}) between 1 and 128 and ${table.taskId} !~ '[[:cntrl:]]'`,
),
check(
'ql3_cluster_legacy_env_application_task_revision_check',
sql`${table.ordinal} between 0 and 99999 and ${table.previousRevision} between 1 and 2147483646 and ${table.revision} = ${table.previousRevision} + 1`,
),
check(
'ql3_cluster_legacy_env_application_task_digest_check',
sql`${table.previousContentDigest} ~ '^[0-9a-f]{64}$' and ${table.contentDigest} ~ '^[0-9a-f]{64}$' and (${table.executionContentDigest} is null or ${table.executionContentDigest} ~ '^[0-9a-f]{64}$') and ${table.itemDigest} ~ '^[0-9a-f]{64}$'`,
),
uniqueIndex('ql3_cluster_legacy_env_application_task_uidx').on(
table.applicationId,
table.taskId,
),
uniqueIndex('ql3_cluster_legacy_env_application_task_revision_uidx').on(
table.applicationId,
table.projectId,
table.taskId,
table.revision,
table.contentDigest,
),
],
);
export const clusterLegacyEnvMigrationApplicationTriggers = ql3Schema.table(
'cluster_legacy_env_migration_application_triggers',
{
applicationId: varchar('application_id', { length: 128 }).notNull(),
ordinal: integer('ordinal').notNull(),
projectId: varchar('project_id', { length: 128 }).notNull(),
triggerId: varchar('trigger_id', { length: 128 }).notNull(),
taskId: varchar('task_id', { length: 128 }).notNull(),
previousRevision: integer('previous_revision').notNull(),
previousContentDigest: char('previous_content_digest', {
length: 64,
}).notNull(),
previousTaskRevision: integer('previous_task_revision').notNull(),
previousTaskContentDigest: char('previous_task_content_digest', {
length: 64,
}).notNull(),
mutationId: uuid('mutation_id').notNull(),
revision: integer('revision').notNull(),
contentDigest: char('content_digest', { length: 64 }).notNull(),
taskRevision: integer('task_revision').notNull(),
taskContentDigest: char('task_content_digest', { length: 64 }).notNull(),
itemDigest: char('item_digest', { length: 64 }).notNull(),
},
(table) => [
primaryKey({
name: 'cluster_legacy_env_migration_application_triggers_pkey',
columns: [table.applicationId, table.ordinal],
}),
foreignKey({
name: 'ql3_cluster_legacy_env_application_trigger_receipt_fk',
columns: [table.applicationId, table.projectId],
foreignColumns: [
clusterLegacyEnvMigrationApplicationReceipts.applicationId,
clusterLegacyEnvMigrationApplicationReceipts.projectId,
],
}).onDelete('restrict'),
foreignKey({
name: 'ql3_cluster_legacy_env_application_trigger_task_fk',
columns: [
table.applicationId,
table.projectId,
table.taskId,
table.taskRevision,
table.taskContentDigest,
],
foreignColumns: [
clusterLegacyEnvMigrationApplicationTasks.applicationId,
clusterLegacyEnvMigrationApplicationTasks.projectId,
clusterLegacyEnvMigrationApplicationTasks.taskId,
clusterLegacyEnvMigrationApplicationTasks.revision,
clusterLegacyEnvMigrationApplicationTasks.contentDigest,
],
}).onDelete('restrict'),
check(
'ql3_cluster_legacy_env_application_trigger_identity_check',
sql`${table.projectId} ~ '^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$' and char_length(${table.triggerId}) between 1 and 128 and ${table.triggerId} !~ '[[:cntrl:]]' and char_length(${table.taskId}) between 1 and 128 and ${table.taskId} !~ '[[:cntrl:]]'`,
),
check(
'ql3_cluster_legacy_env_application_trigger_revision_check',
sql`${table.ordinal} between 0 and 499999 and ${table.previousRevision} between 1 and 2147483646 and ${table.revision} = ${table.previousRevision} + 1 and ${table.previousTaskRevision} between 1 and 2147483647 and ${table.taskRevision} between 2 and 2147483647`,
),
check(
'ql3_cluster_legacy_env_application_trigger_digest_check',
sql`${table.previousContentDigest} ~ '^[0-9a-f]{64}$' and ${table.previousTaskContentDigest} ~ '^[0-9a-f]{64}$' and ${table.contentDigest} ~ '^[0-9a-f]{64}$' and ${table.taskContentDigest} ~ '^[0-9a-f]{64}$' and ${table.itemDigest} ~ '^[0-9a-f]{64}$'`,
),
uniqueIndex('ql3_cluster_legacy_env_application_trigger_uidx').on(
table.applicationId,
table.triggerId,
),
],
);
export const pluginPackageInstalls = ql3Schema.table(
'plugin_package_installs',
{
@@ -6289,6 +6496,9 @@ export const ql3PostgresTables = [
schemaCapabilities,
projects,
clusterLegacyEnvMigrationPlans,
clusterLegacyEnvMigrationApplicationReceipts,
clusterLegacyEnvMigrationApplicationTasks,
clusterLegacyEnvMigrationApplicationTriggers,
pluginPackageInstalls,
pluginPackageInstallHeads,
pluginPackageInstallMutations,
@@ -21,8 +21,8 @@ export interface PostgresSchemaContractTrigger {
export interface PostgresSchemaContract {
readonly schema: 'ql3';
readonly contractName: 'control-core';
readonly contractVersion: 69;
readonly migrationId: 'pg-0070-cluster-legacy-env-migration-plans';
readonly contractVersion: 70;
readonly migrationId: 'pg-0071-cluster-legacy-env-migration-applications';
readonly minimumServerMajor: 16;
readonly maximumServerMajor: 18;
readonly capabilities: Readonly<{
@@ -50,6 +50,7 @@ export interface PostgresSchemaContract {
cluster_scheduler_admission: 1;
database_role_grants: 1;
cluster_execution_revision: 1;
cluster_legacy_env_migration_application: 1;
cluster_legacy_env_migration_plan: 1;
identity_admin: 1;
plugin_package_admission: 1;
@@ -123,8 +124,8 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
Object.freeze({
schema: 'ql3',
contractName: 'control-core',
contractVersion: 69,
migrationId: 'pg-0070-cluster-legacy-env-migration-plans',
contractVersion: 70,
migrationId: 'pg-0071-cluster-legacy-env-migration-applications',
minimumServerMajor: 16,
maximumServerMajor: 18,
capabilities: Object.freeze({
@@ -138,6 +139,7 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
automation_management_boundary: 1,
automation_management_identity_keyset_ledger: 1,
cluster_execution_revision: 1,
cluster_legacy_env_migration_application: 1,
cluster_legacy_env_migration_plan: 1,
cluster_recovery: 1,
cluster_recovery_claim: 1,
@@ -251,6 +253,53 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
'planned_at_ms',
'plan_json',
]),
table('cluster_legacy_env_migration_application_receipts', [
'application_id',
'mutation_id',
'project_id',
'plan_id',
'plan_digest',
'environment_bundle_ref',
'task_revision_set_digest',
'trigger_revision_set_digest',
'task_mutation_set_digest',
'trigger_mutation_set_digest',
'task_count',
'trigger_count',
'committed_at_ms',
'receipt_digest',
'receipt_json',
]),
table('cluster_legacy_env_migration_application_tasks', [
'application_id',
'ordinal',
'project_id',
'task_id',
'previous_revision',
'previous_content_digest',
'mutation_id',
'revision',
'content_digest',
'execution_content_digest',
'item_digest',
]),
table('cluster_legacy_env_migration_application_triggers', [
'application_id',
'ordinal',
'project_id',
'trigger_id',
'task_id',
'previous_revision',
'previous_content_digest',
'previous_task_revision',
'previous_task_content_digest',
'mutation_id',
'revision',
'content_digest',
'task_revision',
'task_content_digest',
'item_digest',
]),
table('plugin_package_installs', [
'installation_id',
'project_id',
@@ -1566,6 +1615,17 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
'ql3_cluster_legacy_env_plan_mutation_uidx',
'ql3_cluster_legacy_env_plan_digest_uidx',
'ql3_cluster_legacy_env_plan_project_idx',
'cluster_legacy_env_migration_application_receipts_pkey',
'ql3_cluster_legacy_env_application_mutation_uidx',
'ql3_cluster_legacy_env_application_project_uidx',
'ql3_cluster_legacy_env_application_plan_uidx',
'ql3_cluster_legacy_env_application_digest_uidx',
'ql3_cluster_legacy_env_application_project_idx',
'cluster_legacy_env_migration_application_tasks_pkey',
'ql3_cluster_legacy_env_application_task_uidx',
'ql3_cluster_legacy_env_application_task_revision_uidx',
'cluster_legacy_env_migration_application_triggers_pkey',
'ql3_cluster_legacy_env_application_trigger_uidx',
'plugin_package_installs_pkey',
'ql3_plugin_package_installs_quarantine_target_key',
'ql3_plugin_package_installs_recovery_idx',
@@ -1896,6 +1956,16 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
'ql3_cluster_legacy_env_plan_target_check',
'ql3_cluster_legacy_env_plan_time_check',
'ql3_cluster_legacy_env_plan_json_check',
'ql3_cluster_legacy_env_application_identity_check',
'ql3_cluster_legacy_env_application_digest_check',
'ql3_cluster_legacy_env_application_target_check',
'ql3_cluster_legacy_env_application_json_check',
'ql3_cluster_legacy_env_application_task_identity_check',
'ql3_cluster_legacy_env_application_task_revision_check',
'ql3_cluster_legacy_env_application_task_digest_check',
'ql3_cluster_legacy_env_application_trigger_identity_check',
'ql3_cluster_legacy_env_application_trigger_revision_check',
'ql3_cluster_legacy_env_application_trigger_digest_check',
'ql3_plugin_package_installs_identity_check',
'ql3_plugin_package_installs_operation_check',
'ql3_plugin_package_installs_state_check',
@@ -2376,6 +2446,11 @@ export const postgresqlControlSchemaContract: PostgresSchemaContract =
foreignKeys: Object.freeze([
'ql3_schema_capabilities_migration_fk',
'ql3_cluster_legacy_env_plan_project_fk',
'ql3_cluster_legacy_env_application_project_fk',
'ql3_cluster_legacy_env_application_plan_fk',
'ql3_cluster_legacy_env_application_task_receipt_fk',
'ql3_cluster_legacy_env_application_trigger_receipt_fk',
'ql3_cluster_legacy_env_application_trigger_task_fk',
'ql3_plugin_package_installs_project_fk',
'ql3_plugin_package_install_heads_project_fk',
'ql3_plugin_package_install_heads_install_fk',
@@ -156,6 +156,24 @@ const REQUIRED_RUNTIME_PRIVILEGES = Object.freeze({
update: false,
delete: false,
}),
cluster_legacy_env_migration_application_receipts: Object.freeze({
select: false,
insert: false,
update: false,
delete: false,
}),
cluster_legacy_env_migration_application_tasks: Object.freeze({
select: false,
insert: false,
update: false,
delete: false,
}),
cluster_legacy_env_migration_application_triggers: Object.freeze({
select: false,
insert: false,
update: false,
delete: false,
}),
plugin_package_installs: Object.freeze({
select: false,
insert: false,
@@ -711,6 +729,24 @@ const REQUIRED_ADMIN_PRIVILEGES = Object.freeze({
update: false,
delete: false,
}),
cluster_legacy_env_migration_application_receipts: Object.freeze({
select: false,
insert: false,
update: false,
delete: false,
}),
cluster_legacy_env_migration_application_tasks: Object.freeze({
select: false,
insert: false,
update: false,
delete: false,
}),
cluster_legacy_env_migration_application_triggers: Object.freeze({
select: false,
insert: false,
update: false,
delete: false,
}),
plugin_package_installs: Object.freeze({
select: false,
insert: false,
@@ -1430,6 +1466,9 @@ const REQUIRED_AUTOMATION_MANAGER_PRIVILEGES: RequiredPrivileges =
}
: name === 'security_audit_events' ||
name === 'cluster_legacy_env_migration_plans' ||
name === 'cluster_legacy_env_migration_application_receipts' ||
name === 'cluster_legacy_env_migration_application_tasks' ||
name === 'cluster_legacy_env_migration_application_triggers' ||
name === 'task_definition_revisions' ||
name === 'task_execution_revisions' ||
name === 'trigger_revisions'