feat(ql3): govern release version transitions

This commit is contained in:
whyour
2026-08-16 09:32:27 +08:00
parent 7130d77a76
commit bad8399cc3
24 changed files with 1462 additions and 128 deletions
+41 -28
View File
@@ -12,9 +12,13 @@ const {
reviewedOperatorManifest,
verifyImageIds,
} = require('../../scripts/ql3-cloudnativepg-live-contract.cjs');
const {
readReleaseIdentity,
} = require('../../scripts/lib/ql3-release-identity.cjs');
const INDEX = `sha256:${'a'.repeat(64)}`;
const PLATFORM = `sha256:${'b'.repeat(64)}`;
const VERSION = readReleaseIdentity(path.resolve(__dirname, '../..')).version;
function pods(...imageIds) {
return imageIds.map((imageID) => ({
@@ -23,10 +27,7 @@ function pods(...imageIds) {
}
test('extracts only one exact digest-pinned image reference', () => {
assert.equal(
imageDigest(`registry.example/operand:18.4@${INDEX}`),
INDEX,
);
assert.equal(imageDigest(`registry.example/operand:18.4@${INDEX}`), INDEX);
assert.throws(() => imageDigest('registry.example/operand:18.4'));
assert.throws(() => imageDigest(`registry.example/operand@${INDEX}:tag`));
});
@@ -41,16 +42,16 @@ test('derives a normal tagged preload reference from a reviewed image', () => {
});
test('replaces exactly one fail-closed application image only in live rendering', () => {
const placeholder = `registry.example.com/qinglong/qinglong3-cluster-control@sha256:${'0'.repeat(64)}`;
const placeholder = `registry.example.com/qinglong/qinglong3-cluster-control@sha256:${'0'.repeat(
64,
)}`;
const rendered = `kind: Deployment\nspec:\n image: ${placeholder}\n`;
assert.equal(
localApplicationManifest(rendered),
'kind: Deployment\nspec:\n image: registry.example.com/qinglong/qinglong3-cluster-control:3.0.0-alpha.0\n',
`kind: Deployment\nspec:\n image: registry.example.com/qinglong/qinglong3-cluster-control:${VERSION}\n`,
);
assert.throws(() => localApplicationManifest('kind: Deployment\n'));
assert.throws(() =>
localApplicationManifest(`${rendered}---\n${rendered}`),
);
assert.throws(() => localApplicationManifest(`${rendered}---\n${rendered}`));
});
test('accepts uniform runtime reporting of the reviewed index or platform digest', () => {
@@ -74,7 +75,8 @@ test('accepts uniform runtime reporting of the reviewed index or platform digest
test('rejects tags, unknown digests, missing status and widened reviewed sets', () => {
for (const invoke of [
() => verifyImageIds(pods('registry.example/operand:18.4'), [INDEX], 'operand'),
() =>
verifyImageIds(pods('registry.example/operand:18.4'), [INDEX], 'operand'),
() =>
verifyImageIds(
pods(`registry.example/operand@sha256:${'c'.repeat(64)}`),
@@ -82,7 +84,12 @@ test('rejects tags, unknown digests, missing status and widened reviewed sets',
'operand',
),
() => verifyImageIds([{ status: {} }], [INDEX], 'operand'),
() => verifyImageIds(pods(`registry.example/operand@${INDEX}`), ['*'], 'operand'),
() =>
verifyImageIds(
pods(`registry.example/operand@${INDEX}`),
['*'],
'operand',
),
]) {
assert.throws(invoke);
}
@@ -90,7 +97,10 @@ test('rejects tags, unknown digests, missing status and widened reviewed sets',
test('creates the namespaced control identity before the migration Job', () => {
const source = fs.readFileSync(
path.resolve(__dirname, '../../scripts/ql3-cloudnativepg-live-contract.cjs'),
path.resolve(
__dirname,
'../../scripts/ql3-cloudnativepg-live-contract.cjs',
),
'utf8',
);
const namespace = source.indexOf(
@@ -105,10 +115,7 @@ test('creates the namespaced control identity before the migration Job', () => {
assert.ok(namespace >= 0);
assert.ok(serviceAccount > namespace);
assert.ok(migration > serviceAccount);
assert.match(
source.slice(namespace, serviceAccount),
/kubectl\(\[/,
);
assert.match(source.slice(namespace, serviceAccount), /kubectl\(\[/);
assert.match(
source.slice(namespace, migration),
/'-n',\s*NAMESPACE,\s*'apply',\s*'-f',\s*'deploy\/kubernetes\/ql3-cluster\/base\/service-account\.yaml'/,
@@ -117,7 +124,10 @@ test('creates the namespaced control identity before the migration Job', () => {
test('provisions the fail-closed worker ingress identity and derives all role evidence from one set', () => {
const source = fs.readFileSync(
path.resolve(__dirname, '../../scripts/ql3-cloudnativepg-live-contract.cjs'),
path.resolve(
__dirname,
'../../scripts/ql3-cloudnativepg-live-contract.cjs',
),
'utf8',
);
assert.match(source, /const roleList = ROLE_NAMES\.map/);
@@ -144,7 +154,10 @@ test('provisions the fail-closed worker ingress identity and derives all role ev
test('preloads both lock-owned images before applying the operator manifest', () => {
const source = fs.readFileSync(
path.resolve(__dirname, '../../scripts/ql3-cloudnativepg-live-contract.cjs'),
path.resolve(
__dirname,
'../../scripts/ql3-cloudnativepg-live-contract.cjs',
),
'utf8',
);
const preload = source.indexOf(
@@ -158,14 +171,8 @@ test('preloads both lock-owned images before applying the operator manifest', ()
const contract = source.slice(preload, manifest);
assert.match(contract, /docker\(\['pull', reviewedImage\]\)/);
assert.match(contract, /imageDigest\(reviewedImage\)/);
assert.match(
contract,
/const preloadTag = imageTag\(reviewedImage\)/,
);
assert.match(
contract,
/docker\(\['tag', reviewedImage, preloadTag\]\)/,
);
assert.match(contract, /const preloadTag = imageTag\(reviewedImage\)/);
assert.match(contract, /docker\(\['tag', reviewedImage, preloadTag\]\)/);
assert.match(
contract,
/kind\(\['load', 'docker-image', preloadTag, '--name', clusterName\]\)/,
@@ -195,12 +202,18 @@ test('rejects a canonical but checksum-unreviewed operator manifest', () => {
test('bounds remote manifest retries and removes disposable temporary state', () => {
const source = fs.readFileSync(
path.resolve(__dirname, '../../scripts/ql3-cloudnativepg-live-contract.cjs'),
path.resolve(
__dirname,
'../../scripts/ql3-cloudnativepg-live-contract.cjs',
),
'utf8',
);
assert.match(source, /'--http1\.1'/);
assert.match(source, /'--retry-max-time',\s*'300'/);
assert.match(source, /reviewedOperatorManifest\(downloadedOperatorManifest\)/);
assert.match(
source,
/reviewedOperatorManifest\(downloadedOperatorManifest\)/,
);
assert.match(
source,
/fs\.rmSync\(tempDirectory, \{ recursive: true, force: true \}\)/,