From 0951cc73e426480205501203c36ecd0a47c0ec33 Mon Sep 17 00:00:00 2001 From: Vincent Van Ouytsel Date: Mon, 24 Nov 2025 16:14:02 +0100 Subject: [PATCH] Improve validation checks after copying (#285) * fix: calculate hash again after failure The hash from the source is calculated only once. The source hash is checked with the destination hash, but if the destination hash does not match, the destination match is calculated again. The problem is that if the source hash is incorrect, the check will keep failing because the source hash is never re-calculated. Now, in the event that the hashes do not match, the hash of the source and the destination are calculated again. * fix: use size instead of block size Previously the %b parameter was used with stat. This displays the block size of the file. We noticed that in some cases the block size of the source and the destination file could be slightly different. Since the source and target run in different containers, they can have different block sizes defined. If the block size did not match, the hash would also not match, even if the file content would be exactly the same. With this change, the block size is no longer used. Instead the actual size in bytes of the file is listed. --- packages/k8s/src/k8s/index.ts | 23 ++++++++++++----------- packages/k8s/src/k8s/utils.ts | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/k8s/src/k8s/index.ts b/packages/k8s/src/k8s/index.ts index 311a44a..86ac023 100644 --- a/packages/k8s/src/k8s/index.ts +++ b/packages/k8s/src/k8s/index.ts @@ -427,16 +427,16 @@ export async function execCpToPod( } } - const want = await localCalculateOutputHashSorted([ - 'sh', - '-c', - listDirAllCommand(runnerPath) - ]) - let attempts = 15 const delay = 1000 for (let i = 0; i < attempts; i++) { try { + const want = await localCalculateOutputHashSorted([ + 'sh', + '-c', + listDirAllCommand(runnerPath) + ]) + const got = await execCalculateOutputHashSorted( podName, JOB_CONTAINER_NAME, @@ -468,11 +468,6 @@ export async function execCpFromPod( core.debug( `Copying from pod ${podName} ${containerPath} to ${targetRunnerPath}` ) - const want = await execCalculateOutputHashSorted( - podName, - JOB_CONTAINER_NAME, - ['sh', '-c', listDirAllCommand(containerPath)] - ) let attempt = 0 while (true) { @@ -533,6 +528,12 @@ export async function execCpFromPod( const delay = 1000 for (let i = 0; i < attempts; i++) { try { + const want = await execCalculateOutputHashSorted( + podName, + JOB_CONTAINER_NAME, + ['sh', '-c', listDirAllCommand(containerPath)] + ) + const got = await localCalculateOutputHashSorted([ 'sh', '-c', diff --git a/packages/k8s/src/k8s/utils.ts b/packages/k8s/src/k8s/utils.ts index 25428ff..9116919 100644 --- a/packages/k8s/src/k8s/utils.ts +++ b/packages/k8s/src/k8s/utils.ts @@ -296,5 +296,5 @@ export async function sleep(ms: number): Promise { } export function listDirAllCommand(dir: string): string { - return `cd ${shlex.quote(dir)} && find . -not -path '*/_runner_hook_responses*' -exec stat -c '%b %n' {} \\;` + return `cd ${shlex.quote(dir)} && find . -not -path '*/_runner_hook_responses*' -exec stat -c '%s %n' {} \\;` }