fix(images): minimize ql3 runtime base

This commit is contained in:
whyour
2026-08-22 12:44:49 +08:00
parent ca8ddf34b8
commit f1cca9a3ed
13 changed files with 119 additions and 40 deletions
+20 -3
View File
@@ -409,13 +409,15 @@ test('keeps Prompt output active-key rotation caller-driven and least privilege'
});
test('rejects mutable or overridable Cluster image bases', () => {
const digest =
const buildDigest =
'@sha256:6f7b03f7c2c8e2e784dcf9295400527b9b1270fd37b7e9a7285cf83b6951452d';
const runtimeDigest =
'@sha256:595398b0081eacda8e1c4c5b97b76cd1020e4d58a8ebcb4843b9bca1e79e7436';
const control = auditClusterDeployment({
root: ROOT,
readFile: intercept(
'deploy/containers/ql3-cluster-control/Dockerfile',
(source) => source.replace(digest, ''),
(source) => source.replace(buildDigest, ''),
),
});
assert.equal(control.compatible, false);
@@ -432,7 +434,7 @@ test('rejects mutable or overridable Cluster image bases', () => {
'deploy/containers/ql3-cluster-admin/Dockerfile',
(source) =>
`ARG NODE_IMAGE=node:24.18.0-bookworm-slim\n${source.replaceAll(
`node:24.18.0-bookworm-slim${digest}`,
`node:24.18.0-bookworm-slim${buildDigest}`,
'${NODE_IMAGE}',
)}`,
),
@@ -445,6 +447,21 @@ test('rejects mutable or overridable Cluster image bases', () => {
),
true,
);
const runtimeControl = auditClusterDeployment({
root: ROOT,
readFile: intercept(
'deploy/containers/ql3-cluster-control/Dockerfile',
(source) => source.replace(runtimeDigest, ''),
),
});
assert.equal(runtimeControl.compatible, false);
assert.equal(
runtimeControl.findings.some(
({ code }) => code === 'QL3_CLUSTER_DOCKERFILE_BASE_IMAGE_NOT_PINNED',
),
true,
);
});
test('keeps authenticated Plugin Package management optional and bounded', () => {
+32
View File
@@ -43,6 +43,14 @@ test('accepts the exact AI-excluded local application image contract', () => {
const report = auditLocalImageContract(root);
assert.equal(report.compatible, true);
assert.deepEqual(report.findings, []);
assert.equal(
report.nodeImage,
'node:24.18.0-alpine3.23@sha256:595398b0081eacda8e1c4c5b97b76cd1020e4d58a8ebcb4843b9bca1e79e7436',
);
assert.equal(
report.buildNodeImage,
'node:24.18.0-bookworm-slim@sha256:6f7b03f7c2c8e2e784dcf9295400527b9b1270fd37b7e9a7285cf83b6951452d',
);
assert.deepEqual(report.runtimePackages, [
'@qinglong/local-admin',
'@qinglong/local-application',
@@ -57,6 +65,30 @@ test('accepts the exact AI-excluded local application image contract', () => {
]);
});
test('rejects a mutable runtime base image', () => {
const current = fixture();
try {
const dockerfilePath = path.join(current.target, 'Dockerfile');
const dockerfile = fs.readFileSync(dockerfilePath, 'utf8');
fs.writeFileSync(
dockerfilePath,
dockerfile.replace(
'@sha256:595398b0081eacda8e1c4c5b97b76cd1020e4d58a8ebcb4843b9bca1e79e7436',
'',
),
);
const report = auditLocalImageContract(current.root);
assert.equal(report.compatible, false);
assert.ok(
report.findings.some(
({ code }) => code === 'BASE_IMAGE_NOT_EXACTLY_PINNED',
),
);
} finally {
current.close();
}
});
test('rejects a mutable or build-argument-controlled base image', () => {
const current = fixture();
try {