refactor(docker): break out manifest retrieval function (#2931)

This commit is contained in:
Mike Bryant 2018-12-11 12:04:09 +00:00 committed by Rhys Arkins
parent 8c2cad0647
commit 9ac84fa4e3
2 changed files with 98 additions and 51 deletions

View file

@ -102,6 +102,82 @@ function extractDigestFromResponse(manifestResponse) {
return manifestResponse.headers['docker-content-digest'];
}
async function getManifestResponse(registry, repository, tag) {
logger.debug(`getManifestResponse(${registry}, ${repository}, ${tag})`);
try {
const headers = await getAuthHeaders(registry, repository);
if (!headers) {
logger.info('No docker auth found - returning');
return null;
}
headers.accept = 'application/vnd.docker.distribution.manifest.v2+json';
const url = `${registry}/v2/${repository}/manifests/${tag}`;
const manifestResponse = await got(url, {
headers,
timeout: 10000,
});
return manifestResponse;
} catch (err) /* istanbul ignore next */ {
if (err.message === 'registry-failure') {
throw err;
}
if (err.statusCode === 401) {
logger.info(
{ registry, dockerRepository: repository },
'Unauthorized docker lookup'
);
logger.debug({ err });
return null;
}
if (err.statusCode === 404) {
logger.info(
{
err,
registry,
repository,
tag,
},
'Docker Manifest is unknown'
);
return null;
}
if (err.statusCode === 429 && registry.endsWith('docker.io')) {
logger.warn({ err }, 'docker registry failure: too many requests');
throw new Error('registry-failure');
}
if (err.statusCode >= 500 && err.statusCode < 600) {
logger.warn(
{
err,
registry,
repository,
tag,
},
'docker registry failure: internal error'
);
throw new Error('registry-failure');
}
if (err.code === 'ETIMEDOUT') {
logger.info(
{ registry },
'Timeout when attempting to connect to docker registry'
);
logger.debug({ err });
return null;
}
logger.info(
{
err,
registry,
repository,
tag,
},
'Unknown Error looking up docker manifest'
);
return null;
}
}
/*
* docker.getDigest
*
@ -125,17 +201,10 @@ async function getDigest(config, newValue) {
if (cachedResult) {
return cachedResult;
}
const headers = await getAuthHeaders(massagedRegistry, repository);
if (!headers) {
logger.info('No docker auth found - returning');
const manifestResponse = await getManifestResponse(massagedRegistry, repository, newTag);
if (!manifestResponse) {
return null;
}
headers.accept = 'application/vnd.docker.distribution.manifest.v2+json';
const url = `${massagedRegistry}/v2/${repository}/manifests/${newTag}`;
const manifestResponse = await got(url, {
headers,
timeout: 10000,
});
const digest = extractDigestFromResponse(manifestResponse);
logger.debug({ digest }, 'Got docker digest');
const cacheMinutes = 30;
@ -145,48 +214,6 @@ async function getDigest(config, newValue) {
if (err.message === 'registry-failure') {
throw err;
}
if (err.statusCode === 401) {
logger.info(
{ dockerRegistry, dockerRepository: repository },
'Unauthorized docker lookup'
);
logger.debug({ err });
return null;
}
if (err.statusCode === 404) {
logger.info(
{
err,
depName,
newTag,
},
'Docker Manifest is unknown'
);
return null;
}
if (err.statusCode === 429 && massagedRegistry.endsWith('docker.io')) {
logger.warn({ err }, 'docker registry failure: too many requests');
throw new Error('registry-failure');
}
if (err.statusCode >= 500 && err.statusCode < 600) {
logger.warn(
{
err,
depName,
newTag,
},
'docker registry failure: internal error'
);
throw new Error('registry-failure');
}
if (err.code === 'ETIMEDOUT') {
logger.info(
{ massagedRegistry },
'Timeout when attempting to connect to docker registry'
);
logger.debug({ err });
return null;
}
logger.info(
{
err,

View file

@ -141,6 +141,26 @@ describe('api/docker', () => {
);
expect(res).toBe('some-digest');
});
it('should throw error for 429', async () => {
got.mockRejectedValueOnce({statusCode: 429});
let e;
try {
await docker.getDigest({ depName: 'some-dep' }, 'latest');
} catch (err) {
e = err;
}
expect(e.message).toBe('registry-failure');
});
it('should throw error for 5xx', async () => {
got.mockRejectedValueOnce({statusCode: 503});
let e;
try {
await docker.getDigest({ depName: 'some-dep' }, 'latest');
} catch (err) {
e = err;
}
expect(e.message).toBe('registry-failure');
});
});
describe('getPkgReleases', () => {
beforeEach(() => {