This commit is contained in:
Chuck Lantz 2021-02-05 07:03:30 -08:00 коммит произвёл GitHub
Родитель 899121ae27
Коммит 77bfb7c1e7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 246 добавлений и 67 удалений

Просмотреть файл

@ -0,0 +1,32 @@
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
ARG ORIGINAL_IMAGE=mcr.microsoft.com/vscode/devcontainers/javascript-node@sha256:58ecafbc0455c024b3bcdde60036f262edc3d139b8308c8f5e6e17c55252253a
FROM ${ORIGINAL_IMAGE}
ARG PACKAGE_LIST="\
sudo \
linux-libc-dev \
libp11-kit0 \
"
# Script to iterate through the above list and update packages
ARG PATCH_SCRIPT="\
export DEBIAN_FRONTEND=noninteractive \
&& if type yarn > /dev/null 2>&1; then curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | (OUT=$(apt-key add - 2>&1) || echo $OUT); fi \
&& apt-get update \
&& echo \"${PACKAGE_LIST}\" | tr ' ' '\n' | while read PKG; do \
echo \"Checking \$PKG...\" \
&& if [ \"\$PKG\" != '' ] && dpkg -s \$PKG >/dev/null 2>&1; then apt-get install -yq --only-upgrade --no-install-recommends \$PKG; fi; \
done \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/* \
"
RUN echo "${PATCH_SCRIPT}" \
&& if [ "$(id -u)" -ne 0 ]; then \
sudo bash -c "${PATCH_SCRIPT}"; \
else \
bash -c "${PATCH_SCRIPT}"; \
fi

Просмотреть файл

@ -0,0 +1,7 @@
Updates older image versions to resolve the following:
- sudo CVE-2021-3156 https://nvd.nist.gov/vuln/detail/CVE-2021-3156
- DLA 2534-1 https://lists.debian.org/debian-lts-announce/2021/01/msg00022.html
- DSA 4839-1 https://lists.debian.org/debian-security-announce/2021/msg00020.html
- linux-libc-dev USN-4679-1 https://lists.ubuntu.com/archives/ubuntu-security-announce/2021-January/005821.html
- libp11-kit0 USN-4677-1 https://lists.ubuntu.com/archives/ubuntu-security-announce/2021-January/005819.html

Просмотреть файл

@ -0,0 +1,89 @@
{
"dockerFile": "Dockerfile",
"bumpVersion": false,
"deleteUntaggedImages": true,
"imageIds": [
"sha256:a8af1da60b101b796a03180b2c7c493e99072e5bbc82a3be888efa17702dd443",
"sha256:1aa71b81f47df7267aa011521cdb2cf157af19d9f41613ee322bfb3ce6ca2256",
"sha256:c85f692b1e10a7f6721df8cfed510970d7dbb05bc2238b411745e5a267702321",
"sha256:58ecafbc0455c024b3bcdde60036f262edc3d139b8308c8f5e6e17c55252253a",
"sha256:846ef00e742cdb5f7f1f1dfbbee26aefcaf580313e7b1fda84c5d4b29fb5eb26",
"sha256:fe16aacc07a0d757cbf43184daf79486db8ff11eb79b7d2c1dd24f6a48959cbd",
"sha256:220bb3d3271d212ab6040b357ee3f26dd0b77b9fae6ac9a25857f82235b9d484",
"sha256:abd89f78ee61b6820b212d8c28aceff483cef8a269c550fdd7f8a877935b339a",
"sha256:3728eb9fb9382c8ebf6109bb514c34108b03d0480ec399ac7213e01810bd487f",
"sha256:094cce53876529d47aed4b808dca00e8ce6995392b9f2ec707035e431e759cde",
"sha256:c00b045739a1ee10e6841bab14dd8a88b4dafa65ff806c039e6d3beb05a5c1f3",
"sha256:c46e9895bf79b2c67cdaf08cd9f7ea45f94d38c6e0a7470c68111117d42e7f98",
"sha256:4e419bba619b323c622ed1f4bdb92d937121e52a467370a8707a40d3364d5d33",
"sha256:aa9827df6f29367d5fb7c5d423b89a1c5edabba5533472f22858c60eafcd5c71",
"sha256:9be22307104d4fdeb9a7443bf2860e517f9a549b41cb6f5909d48215b0efa138",
"sha256:bd5e106fc3251e20b62923f0b09123e254134dced5eb7c816902cb20c81d8e0b",
"sha256:704949a2073c39a51d8b73d81afccceab15a7e99390dc070581b15f43e65366e",
"sha256:76a6605d6671a6fdbfbedaa6772de9aef56605a787dbb3440e1bc20ddbfb186d",
"sha256:f499eed429600fb2586940eff10fe7deda5208ddaad3334f06613e651daef7a5",
"sha256:fd30f003f6946b3efb3dcd2aadf94addfdfa3399440593557b0001a8be8288ab",
"sha256:cd0152b458c1104e35f1b5a2a0c83164009b4004decf17a89d5f524876d65f96",
"sha256:9189178f892933772d345b166508ae8e89206e38ed7e2a47699acef2ae1cd08c",
"sha256:09b49131f112d84d2e2005902199dbbc4a13c312fce558c45165f3ac0408d225",
"sha256:57912dc8d5486e94e2263c47c4fbf60e55863d7b20e735ad6356d7b38f806662",
"sha256:7105c6f97fe9fc19e7dc3242733ea216bb3f9ba3f649b15c090d8a123f695943",
"sha256:19a697ce72942f7a0d1ccaea256e9d1fc924cb62360a3d8dfa4c9542e0687b43",
"sha256:71386ec768c04ee034eee0c3deb9284ad22f088e8f1c767175a43528fba8def2",
"sha256:329aff27952af3c5b5de84b63a9c25b0e09e0ba095798623442b746079433415",
"sha256:987ba6fc0bb700a70308f92c5179d6bb569a28c9eebf76bebc2fea56a3be45ff",
"sha256:205fb6ab5bd3fbcffaf7bcaac92b56b22d4c9d3025ae705bc2f351e61f7e0217",
"sha256:c22d4f9a9230d8439846e255a2095bd8e6a0e867f06fb0570c9ed4f94d475fbd",
"sha256:291f4dbe1cbf121727ada9d408be622268321fcae5b9d6877d3a61808c203eca",
"sha256:95dfa49338ae7cf6f5c78921bf379fad1ab75a0a777bfeca20eca953f166aac7",
"sha256:f57ac35a45c7e1e36597aaa6ab38b27885c01f41ed5ec05a519fd87a645358ff",
"sha256:2b64771de4263263a16cf56a6bd9318e3ce9ae9dc1186eb91a947c5033db8711",
"sha256:c60647384fa178e6a7827e0b95f974243260877bcf947099d4605cca78c814f0",
"sha256:8d56f479cbb8f80d8e1f87051cade28ef9d97516ce4f9efe5d83601e3d626d5a",
"sha256:29455e08b45bafa18db92aa1bc4ee70cbe7f0a3447b192106b26a22b36c74b04",
"sha256:a9e8abd46e7b4be3889a03daddfa5a9bf98c448d6d1ede30f20966f50d5edd2f",
"sha256:1840c0083355ea755292623c8ba7e28e7aa1650db59c6ce9c82539920658e685",
"sha256:3723215b151e405ddc391236675235932c5ab4200882b30ef7f2a7c154a25a1b",
"sha256:f0b487271278db3b6d421c2d18a8befe5f2f32b005e936b451a41a8e2cfd14fa",
"sha256:f13f11e0d2d58fe6fbc7d4a226dfb5d48f8d14458b4fc1f17f0a8d8b9c5e29f9",
"sha256:84af29fd2a8cedff36b584f544d7295b5dc03c3efc47f79a031743dc33c175d1",
"sha256:f454429ccfc77a3f6d66d792804850c7843bc5f953a87f6bbcffeec8f78436fd",
"sha256:99cb56e8b6d662c3344b438301ee6ed9747dfd5ddc0b755ee7169b589c899a7e",
"sha256:ca2876046864529c73765309822942e95e1c2709719fed9410b768b38afb648f",
"sha256:8d05a8cdd9337da08ded4593fa9865e16147da762471ba06a9ff0803e5b21fb9",
"sha256:315dbfa0c70f165b7f22dfb09c7982abfd20f7feaeefe4c1208d5160f4801a74",
"sha256:c7abfb8f059514d49cef0e14feee6f19db212b044634a80da87c82d333edae2f",
"sha256:6bfc0114353764257989e8fd8830df107e02c93f26b9f7e01fef09e873b4c04a",
"sha256:484c90c05dc7c4792a1f72de95fbaec3d73da7438aac0851c79d64478ea76617",
"sha256:fbcc9403bc8fb35ae591a6f2a862b62a09f683c69fd7f4fd39938993561f39ba",
"sha256:c9d24da5ac1339f8341676c057ad58d41842125f8ced2e78bb5a1cb494a0e7e6",
"sha256:ffb4ebc7804ed52924d62da9b2711202eacf8b6c352812014d9fa2ae1668826e",
"sha256:4ca4e26c022f8ad95182dc28ff9a6a45b42e419fe765d969653020d626fc86ae",
"sha256:c696ec70ff7410b47acbf8fb3776b1865d260061bfa5c00933ccc1ed85f68a05",
"sha256:8449ccb0580d9c3a1779e19b030bf2220ea79f8f126475e84152ac006ab22e45",
"sha256:64338b2eb6863f4b4cc46c8174137a5d5858c874cd9fc61fd274fe257f67b470",
"sha256:05a76d1393d8b3e02f956c7f2adcc9348cf1bfb8d59162363e31149fcafb11f5",
"sha256:c7822c2989fb5e8f6d905334539c97e19e41439e50df2b5764f02870e22476ea",
"sha256:e45350b7868b7e82b05977803505407e955db6b401ca2a15ed3b1bf2a162450f",
"sha256:60800829368bb9b35bc825a2240a290121c908f2bb93dfd1917cfe6b32aeb747",
"sha256:5d464ca75577cbff78c380b713d0f236f4ec4292a4b36e36801820bd02af4115",
"sha256:0440d8e47a045353a58600e94199309a83d464e78221a4520c570f05eeae02dd",
"sha256:cc483fda87dbe26c833a3f857e07b57c92587ab866764721b3f53d654d20e8be",
"sha256:18b3a18b81b6fbbb590dbd998b2eaaaca5a98d192b08c2e0dec717db3e98cf56",
"sha256:3c55f58d30ca8c580650057c92b4303a218eb629521bd5e8fb60e541008a4096",
"sha256:035a3d9e0021dcfe296445c88f0ccdc9c98b12169f64e0f7e13b2fb11bb23d57",
"sha256:78433e82bc36c78d799087efb62d251a4b18d0b95c30e6d2556c77164737ab38",
"sha256:5b51fcd014e37de1795034ec74f33cea65ba21b4c6d0940ee72047471219cdf4",
"sha256:f5ab061c6df520602bfbadf6a764d501346a551b25cd3fda7ca4e1121036b1b3",
"sha256:55ef0c5e4ed5de9aae13f42b4d8e71ab95b3c1e7bf2ea7c42cd1b91cedc5da8b",
"sha256:0dd988931313673ac1f24900de5184b560c9bcc144ce57bdfdaf01110e9f5286",
"sha256:a30ac278d31f0336ebf2a6c7638071bf1230105492daba2a4ba6bd5ebfe8519d",
"sha256:d14987bb9d4736717e7f5167870ec5fbab4d67a7bb46e95c1330ac68fd2bb9d3",
"sha256:a440f947c858ca29f4b02eafae5853c77c24bd078cbf734817aa16a2f40fff62",
"sha256:2a642eb222fb1cbef78ffa97f73c80d9418a150a4e3582ecf21c8d20a66eadaf",
"sha256:d422d36b76bf653bbcabb43b9a81bfac7cc2d453e4879d8f191b2839951accf4",
"sha256:0d5337570b3478f2f2b1da793bd38c23e39e023aaab9f2a112e1b765bb5bc093",
"sha256:7f62de18c4c9b366fc8451f9096eec2768104e3e36faaded744fa5a2ce92fbdf",
"sha256:011357a8697b1087db48d5315b6cc8ad52875c8904a5399944d1d0c50dad7be7"
]
}

Просмотреть файл

@ -10,81 +10,101 @@ const jsonc = require('jsonc').jsonc;
async function patch(patchPath, registry, registryPath) {
patchPath = path.resolve(patchPath);
const patchConfig = await getPatchConfig(patchPath);
// ACR registry name is the registry minus .azurecr.io
const registryName = registry.replace(/\..*/, '');
console.log(`(*) Applying patch located at "${patchPath}"...`);
let tagList = patchConfig.tagList || [];
// If imageIds specified, get the complete list of tags to update
if (patchConfig.imageIds) {
const manifests = await getImageManifests(registryName, patchConfig.imageIds);
tagList = tagList.concat(manifests.reduce((prev, manifest) => {
return prev.concat(manifest.tags.map((tag) => {
return `${manifest.repository}:${tag}`;
}));
}, []));
const dockerFilePath = `${patchPath}/${patchConfig.dockerFile || 'Dockerfile'}`;
if (patchConfig.tagList) {
throw new Error('tagList property has been deprecated.')
}
console.log(`(*) Tags to patch: ${JSON.stringify(tagList, undefined, 4)}`);
const spawnOpts = { stdio: 'inherit', cwd: patchPath, shell: true };
await asyncUtils.forEach(tagList, async (tag) => {
const newTag = patchConfig.bumpVersion ? updateVersionTag(tag, registryPath) : tag;
console.log(`\n(*) Patching ${tag}...`);
// Pull and build patched image for tag
let retry = false;
do {
try {
await asyncUtils.spawn('docker', [
'build',
'--pull',
'--build-arg', `ORIGINAL_IMAGE=${registry}/${tag}`,
'--tag', `${registry}/${newTag}`,
'-f', `${patchPath}/${patchConfig.dockerFile || 'Dockerfile'}`,
patchPath
], spawnOpts);
done = true;
} catch (ex) {
// Try to clean out unused images and retry once if get an out of storage response
if (ex.result.indexOf('no space left on device') >= 0 && retry === false) {
console.log(`(*) Out of space - pruning images..`);
asyncUtils.spawn('docker', ['image', 'prune', '--all', '--force'], spawnOpts);
console.log(`(*) Retrying..`);
retry = true;
} else {
throw ex;
}
}
} while (retry);
// Push update
await asyncUtils.spawn('docker', ['push', `${registry}/${newTag}`], spawnOpts);
// Update each listed imageId
await asyncUtils.forEach(patchConfig.imageIds, async (imageId) => {
await patchImage(imageId, patchPath, dockerFilePath, patchConfig.bumpVersion, registry, registryPath);
});
// If config says to delete any untagged images mentioned in the patch, do so.
if (patchConfig.deleteUntaggedImages && patchConfig.imageIds) {
await deleteUntaggedImages(patchConfig.imageIds, registry);
}
console.log('\n(*) Done!')
}
function updateVersionTag(fullTag, registryPath) {
const tag = fullTag.replace(registryPath + '/', '');
// Get the version number section of the tag if it exists
const colon = tag.indexOf(':');
const firstDash = tag.indexOf('-', colon);
if (firstDash > 0) {
const versionSection = tag.substring(colon + 1, firstDash - 1);
// See if there are three digits in the version number
const versionParts = versionSection.split('.');
if (versionParts.length === 3) {
// If there are, update the break fix version
return `${tag.substring(0, colon + 1)}${versionParts[0]}.${versionParts[1]}.${versionParts[2] + 1}${tag.substring(firstDash)}`;
}
return `${registryPath}:${tag}`;
async function patchImage(imageId, patchPath, dockerFilePath, bumpVersion, registry) {
console.log(`\n*** Updating Image: ${imageId} ***`);
const spawnOpts = { stdio: 'inherit', cwd: patchPath, shell: true };
// Get repository and tag list for imageId
let repoAndTagList = await getImageRepositoryAndTags(imageId, registry);
if(repoAndTagList.length === 0) {
console.log('(*) No tags to patch. Skipping.');
return;
}
return tag;
console.log(`(*) Tags to update: ${
JSON.stringify(repoAndTagList.reduce((prev, repoAndTag) => { return prev + repoAndTag.repository + ':' + repoAndTag.tag + ' ' }, ''), undefined, 4)
}`);
// Bump breakfix number of it applies
if(bumpVersion) {
repoAndTagList = updateVersionTags(repoAndTagList);
}
//Generate tag arguments
const tagArgs = repoAndTagList.reduce((prev, repoAndTag) => {
return prev.concat(['--tag', `${registry}/${repoAndTag.repository}:${repoAndTag.tag}`])
}, []);
// Pull and build patched image for tag
let retry = false;
do {
try {
await asyncUtils.spawn('docker', [
'build',
'--pull',
'--build-arg',
`ORIGINAL_IMAGE=${registry}/${repoAndTagList[0].repository}@${imageId}`]
.concat(tagArgs)
.concat('-f', dockerFilePath, patchPath), spawnOpts);
done = true;
} catch (ex) {
// Try to clean out unused images and retry once if get an out of storage response
if (ex.result && ex.result.indexOf('no space left on device') >= 0 && retry === false) {
console.log(`(*) Out of space - pruning images...`);
await asyncUtils.spawn('docker', ['image', 'prune', '--all', '--force'], spawnOpts);
console.log(`(*) Retrying...`);
retry = true;
} else {
throw ex;
}
}
} while (retry);
// Push updates
await asyncUtils.forEach(repoAndTagList, async (repoAndTag) => {
await asyncUtils.spawn('docker', ['push', `${registry}/${repoAndTag.repository}:${repoAndTag.tag}`], spawnOpts);
});
}
function updateVersionTags(repoAndTagList) {
return repoAndTagList.reduce((prev, repoAndTag) => {
let tag = repoAndTag.tag;
// Get the version number section of the tag if it exists
const firstDash = tag.indexOf('-');
if (firstDash > 0) {
const versionSection = tag.substring(0, firstDash - 1);
// See if there are three digits in the version number
const versionParts = versionSection.split('.');
if (versionParts.length === 3) {
// If there are, update the break fix version
tag = `${versionParts[0]}.${versionParts[1]}.${versionParts[2] + 1}${tag.substring(firstDash)}`;
}
}
return prev.push({
name: repoAndTag.repository,
tag: tag
});
}, []);
}
async function deleteUnpatchedImages(patchPath, registry) {
@ -99,11 +119,11 @@ async function deleteUnpatchedImages(patchPath, registry) {
async function deleteUntaggedImages(imageIds, registry) {
console.log(`(*) Deleting untagged images...`);
console.log('\n*** Deleting untagged images ***');
// ACR registry name is the registry minus .azurecr.io
const registryName = registry.replace(/\..*/, '');
const manifests = await getImageManifests(registryName, imageIds);
const manifests = await getImageManifests(imageIds, registry);
console.log(`(*) Manifests to delete: ${JSON.stringify(manifests, undefined, 4)}`);
@ -126,10 +146,42 @@ async function deleteUntaggedImages(imageIds, registry) {
], spawnOpts);
});
console.log('\n(*) Done deleting manifests!')
console.log('(*) Done deleting manifests!')
}
async function getImageManifests(registryName, imageIds) {
// Find tags for image
async function getImageRepositoryAndTags(imageId, registry) {
// ACR registry name is the registry minus .azurecr.io
const registryName = registry.replace(/\..*/, '');
// Get list of repositories
console.log(`(*) Getting repository list for ACR "${registryName}"...`)
const repositoryListOutput = await asyncUtils.spawn('az',
['acr', 'repository', 'list', '--name', registryName],
{ shell: true, stdio: 'pipe' });
const repositoryList = JSON.parse(repositoryListOutput);
let repoAndTagList = [];
await asyncUtils.forEach(repositoryList, async (repository) => {
console.log(`(*) Checking in for "${imageId}" in "${repository}"...`);
const tagListOutput = await asyncUtils.spawn('az',
['acr', 'repository', 'show-tags', '--detail', '--name', registryName, '--repository', repository, "--query", `"[?digest=='${imageId}'].name"`],
{ shell: true, stdio: 'pipe' });
const additionalTags = JSON.parse(tagListOutput);
repoAndTagList = repoAndTagList.concat(additionalTags.map((tag) => {
return {
repository:repository,
tag:tag
};
}));
});
return repoAndTagList;
}
async function getImageManifests(imageIds, registry) {
// ACR registry name is the registry minus .azurecr.io
const registryName = registry.replace(/\..*/, '');
let manifests = [];
// Get list of repositories

Просмотреть файл

@ -4,8 +4,7 @@
"latest": true,
"rootDistro": "debian",
"tags": [
"rust:${VERSION}-1",
"rust:${VERSION}"
"rust:${VERSION}-1"
]
},
"dependencies": {