mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-20 16:07:11 +08:00
fix(ci): ignore terminating CloudNativePG rollout remnants
This commit is contained in:
@@ -485,14 +485,24 @@ function verifyImageIds(pods, expectedDigests, description) {
|
|||||||
return [...new Set(imageIds)];
|
return [...new Set(imageIds)];
|
||||||
}
|
}
|
||||||
|
|
||||||
function operatorPods() {
|
function activeOperatorPods(pods) {
|
||||||
return kubectlJson(['-n', 'cnpg-system', 'get', 'pods']).items.filter((pod) =>
|
// A successful Deployment rollout can leave the old Pod terminating with
|
||||||
|
// an empty imageID. It is not evidence for the new serving generation.
|
||||||
|
return pods.filter(
|
||||||
|
(pod) =>
|
||||||
|
!pod.metadata?.deletionTimestamp &&
|
||||||
(pod.spec?.containers || []).some((container) =>
|
(pod.spec?.containers || []).some((container) =>
|
||||||
container.image.includes('cloudnative-pg'),
|
container.image.includes('cloudnative-pg'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function operatorPods() {
|
||||||
|
return activeOperatorPods(
|
||||||
|
kubectlJson(['-n', 'cnpg-system', 'get', 'pods']).items,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function nodeReady(name) {
|
function nodeReady(name) {
|
||||||
const node = kubectlJson(['get', 'node', name]);
|
const node = kubectlJson(['get', 'node', name]);
|
||||||
return node.status?.conditions?.some(
|
return node.status?.conditions?.some(
|
||||||
@@ -1034,6 +1044,7 @@ if (require.main === module) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
activeOperatorPods,
|
||||||
imageDigest,
|
imageDigest,
|
||||||
imageTag,
|
imageTag,
|
||||||
localApplicationManifest,
|
localApplicationManifest,
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const path = require('node:path');
|
|||||||
const { test } = require('node:test');
|
const { test } = require('node:test');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
activeOperatorPods,
|
||||||
imageDigest,
|
imageDigest,
|
||||||
imageTag,
|
imageTag,
|
||||||
localApplicationManifest,
|
localApplicationManifest,
|
||||||
@@ -20,6 +21,49 @@ const INDEX = `sha256:${'a'.repeat(64)}`;
|
|||||||
const PLATFORM = `sha256:${'b'.repeat(64)}`;
|
const PLATFORM = `sha256:${'b'.repeat(64)}`;
|
||||||
const VERSION = readReleaseIdentity(path.resolve(__dirname, '../..')).version;
|
const VERSION = readReleaseIdentity(path.resolve(__dirname, '../..')).version;
|
||||||
|
|
||||||
|
test('operator image evidence excludes terminating rollout remnants but never missing or unreviewed live pods', () => {
|
||||||
|
const operator = (imageID, deleting = false) => ({
|
||||||
|
metadata: deleting ? { deletionTimestamp: '2026-09-03T20:00:17Z' } : {},
|
||||||
|
spec: {
|
||||||
|
containers: [
|
||||||
|
{ image: `ghcr.io/cloudnative-pg/cloudnative-pg:1.30.0@${INDEX}` },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
status: { containerStatuses: [{ imageID }] },
|
||||||
|
});
|
||||||
|
const live = operator(`ghcr.io/cloudnative-pg/cloudnative-pg@${PLATFORM}`);
|
||||||
|
const old = operator('', true);
|
||||||
|
assert.throws(() =>
|
||||||
|
verifyImageIds([live, old], [INDEX, PLATFORM], 'operator'),
|
||||||
|
);
|
||||||
|
assert.deepEqual(activeOperatorPods([live, old]), [live]);
|
||||||
|
assert.deepEqual(
|
||||||
|
verifyImageIds(
|
||||||
|
activeOperatorPods([live, old]),
|
||||||
|
[INDEX, PLATFORM],
|
||||||
|
'operator',
|
||||||
|
),
|
||||||
|
[`ghcr.io/cloudnative-pg/cloudnative-pg@${PLATFORM}`],
|
||||||
|
);
|
||||||
|
assert.throws(() =>
|
||||||
|
verifyImageIds(activeOperatorPods([old]), [INDEX], 'operator'),
|
||||||
|
);
|
||||||
|
assert.throws(() =>
|
||||||
|
verifyImageIds(
|
||||||
|
activeOperatorPods([live, operator('')]),
|
||||||
|
[INDEX, PLATFORM],
|
||||||
|
'operator',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
assert.throws(() =>
|
||||||
|
verifyImageIds(
|
||||||
|
activeOperatorPods([live, operator(`sha256:${'c'.repeat(64)}`)]),
|
||||||
|
[INDEX, PLATFORM],
|
||||||
|
'operator',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
function pods(...imageIds) {
|
function pods(...imageIds) {
|
||||||
return imageIds.map((imageID) => ({
|
return imageIds.map((imageID) => ({
|
||||||
status: { containerStatuses: [{ imageID }] },
|
status: { containerStatuses: [{ imageID }] },
|
||||||
|
|||||||
Reference in New Issue
Block a user