From c780d107eb97fde1dda93edac04d627c0f352d64 Mon Sep 17 00:00:00 2001 From: Amir Moualem Date: Mon, 10 Feb 2020 12:34:55 +0200 Subject: [PATCH 1/2] chore: stop returning skopeo's copy result we're not using the return value of `skopeo.pull`, let's stop returning it and fix the function's signature. --- src/scanner/images/skopeo.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/scanner/images/skopeo.ts b/src/scanner/images/skopeo.ts index 78215aaa8..8dfa99c1b 100644 --- a/src/scanner/images/skopeo.ts +++ b/src/scanner/images/skopeo.ts @@ -1,5 +1,3 @@ -import { SpawnPromiseResult } from 'child-process-promise'; - import * as processWrapper from '../../common/process'; import * as config from '../../common/config'; import * as credentials from './credentials'; @@ -33,7 +31,7 @@ function prefixRespository(target: string, type: SkopeoRepositoryType): string { export async function pull( image: string, destination: string, -): Promise { +): Promise { const creds = await credentials.getSourceCredentials(image); const credentialsParameters = getCredentialParameters(creds); @@ -43,7 +41,7 @@ export async function pull( args.push({body: prefixRespository(image, SkopeoRepositoryType.ImageRegistry), sanitise: false}); args.push({body: prefixRespository(destination, SkopeoRepositoryType.DockerArchive), sanitise: false}); - return processWrapper.exec('skopeo', ...args); + processWrapper.exec('skopeo', ...args); } export function getCredentialParameters(credentials: string | undefined): Array { From b752a6f871f5f8f90c283c8d56644296d3ac631d Mon Sep 17 00:00:00 2001 From: Amir Moualem Date: Tue, 11 Feb 2020 10:03:51 +0200 Subject: [PATCH 2/2] fix: retry skopeo copy command DockerHub being instable recently introduced new flakiness to our tests, which points towards our "skopeo copy" command being a bit too fragile. this commit introduces a retry mechnanism on that command, always retrying to pull the image. a more efficient solution would be inspecting the error causing the instability and retrying only on that, but this should be good enough as we'll waste only 2 seconds at worst. --- src/scanner/images/skopeo.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/scanner/images/skopeo.ts b/src/scanner/images/skopeo.ts index 8dfa99c1b..da5a18f8d 100644 --- a/src/scanner/images/skopeo.ts +++ b/src/scanner/images/skopeo.ts @@ -1,3 +1,5 @@ +import * as sleep from 'sleep-promise'; + import * as processWrapper from '../../common/process'; import * as config from '../../common/config'; import * as credentials from './credentials'; @@ -41,7 +43,24 @@ export async function pull( args.push({body: prefixRespository(image, SkopeoRepositoryType.ImageRegistry), sanitise: false}); args.push({body: prefixRespository(destination, SkopeoRepositoryType.DockerArchive), sanitise: false}); - processWrapper.exec('skopeo', ...args); + await pullWithRetry(args); +} + +async function pullWithRetry(args: Array): Promise { + const MAX_ATTEMPTS = 10; + const RETRY_INTERVAL_SEC = 0.2; + + for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { + try { + await processWrapper.exec('skopeo', ...args); + return; + } catch (err) { + if (attempt + 1 > MAX_ATTEMPTS) { + throw err; + } + await sleep(RETRY_INTERVAL_SEC * 1000); + } + } } export function getCredentialParameters(credentials: string | undefined): Array {