fix(self-recreate): capture built image SHA via docker images tag, normalize SHA comparison
The prior expected_image_sha was captured via docker compose images, which returns the image of the existing (pre-recreate) container — not the freshly-built one. Switch to docker images ${project}-${service}:latest --quiet --no-trunc which returns the post-build image SHA. Also normalize sha256: prefix in completeSelfRecreate comparison so docker compose images output (sha256-prefixed) and docker inspect output (also sha256-prefixed) match cleanly.
This commit is contained in:
parent
06852c227c
commit
db647bcd0a
10
server.js
10
server.js
|
|
@ -708,7 +708,11 @@ ${detail}`);
|
||||||
const selfRecreate = appName === SELF_APP_NAME && isLocal(server) && stateless.includes(SELF_APP_NAME);
|
const selfRecreate = appName === SELF_APP_NAME && isLocal(server) && stateless.includes(SELF_APP_NAME);
|
||||||
if (selfRecreate) {
|
if (selfRecreate) {
|
||||||
// Capture the freshly-built image SHA for post-restart verification.
|
// Capture the freshly-built image SHA for post-restart verification.
|
||||||
const builtSha = (await run(`docker compose -p ${composeProject} -f ${deployDir}/docker-compose.yml images --quiet ${SELF_APP_NAME} 2>/dev/null | head -1`)).stdout.trim() || null;
|
// `docker compose images` returns the image used by the EXISTING container
|
||||||
|
// (still the OLD one before recreate). For the just-built image, query the
|
||||||
|
// image tag that compose builds into: ${project}-${service}:latest.
|
||||||
|
const builtImageTag = `${composeProject}-${SELF_APP_NAME}:latest`;
|
||||||
|
const builtSha = (await run(`docker images ${builtImageTag} --quiet --no-trunc | head -1`)).stdout.trim() || null;
|
||||||
steps[steps.length - 1] = {
|
steps[steps.length - 1] = {
|
||||||
step: 'deploy',
|
step: 'deploy',
|
||||||
status: 'running',
|
status: 'running',
|
||||||
|
|
@ -1443,7 +1447,9 @@ async function completeSelfRecreate() {
|
||||||
}
|
}
|
||||||
} catch { /* docker unreachable — leave progress in pending; next startup retries */ }
|
} catch { /* docker unreachable — leave progress in pending; next startup retries */ }
|
||||||
|
|
||||||
const imageMatches = expectedSha && runningSha && expectedSha.endsWith(runningSha.replace(/^sha256:/, ''));
|
// Normalize: strip sha256: prefix from both sides for tolerant comparison.
|
||||||
|
const normSha = s => (s || '').replace(/^sha256:/, '').trim();
|
||||||
|
const imageMatches = expectedSha && runningSha && normSha(expectedSha) === normSha(runningSha);
|
||||||
const freshlyStarted = startedAtStr && recreateStartedAt && new Date(startedAtStr) >= recreateStartedAt;
|
const freshlyStarted = startedAtStr && recreateStartedAt && new Date(startedAtStr) >= recreateStartedAt;
|
||||||
const ok = !!(imageMatches && freshlyStarted && state === 'running');
|
const ok = !!(imageMatches && freshlyStarted && state === 'running');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue