From 299ca1a2633473ed201666069a25546074059e2b Mon Sep 17 00:00:00 2001 From: Salah Al Saleh Date: Wed, 27 Jul 2022 12:34:47 -0700 Subject: [PATCH] move reaping to a separate function (#99) --- hooks/src/commands/reap.ts | 119 ++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/hooks/src/commands/reap.ts b/hooks/src/commands/reap.ts index 73c399e..67d77d7 100644 --- a/hooks/src/commands/reap.ts +++ b/hooks/src/commands/reap.ts @@ -36,67 +36,17 @@ async function main(argv): Promise { cronTime: "* * * * *", onTick: async () => { if (jobRunning) { - console.log("-----> previous reap job is still running, skipping."); + console.log("-----> previous reap job is still running, skipping"); return; } + console.log("-----> beginning to reap expired images"); jobRunning = true; - const now = new Date().getTime(); - const images = await smembersAsync("current.images"); - console.log(` there are ${images.length} total images to evaluate`); - for (const image of images) { - try { - const expireAt = await hgetAsync(image, "expires"); - - if (+expireAt > now) { - const minutesLeft = (+expireAt - now) / 1000 / 60; - console.log(`not expiring ${image} for another ~${Math.round(minutesLeft)} minute(s)`); - continue; - } - - const imageAndTag = image.split(":"); - const headers = { - "Accept": "application/vnd.docker.distribution.manifest.v2+json", - }; - - // Get the manifest from the tag - const getOptions = { - method: "HEAD", - uri: `https://ttl.sh/v2/${imageAndTag[0]}/manifests/${imageAndTag[1]}`, - headers, - resolveWithFullResponse: true, - simple: false, - } - const getResponse = await rp(getOptions); - - if (getResponse.statusCode == 404) { - await sremAsync("current.images", image); - await delAsync(image); - continue; - } - - console.log("++++ status code", getResponse.statusCode); - console.log("++++ headers", JSON.stringify(getResponse.headers)); - const deleteURI = `https://ttl.sh/v2/${imageAndTag[0]}/manifests/${getResponse.headers.etag.replace(/"/g,"")}`; - - // Remove from the registry - const options = { - method: "DELETE", - uri: deleteURI, - headers, - resolveWithFullResponse: true, - simple: false, - } - - await rp(options); - - console.log(`expiring ${image}`); - await sremAsync("current.images", image); - await delAsync(image); - } catch(err) { - console.log(`failed to evaluate image ${image}:`, err); - } + try { + await reapExpiredImages(); + } catch(err) { + console.log("failed to reap expired images:", err); } jobRunning = false; @@ -106,3 +56,60 @@ async function main(argv): Promise { job.start(); } + +async function reapExpiredImages() { + const now = new Date().getTime(); + const images = await smembersAsync("current.images"); + console.log(` there are ${images.length} total images to evaluate`); + for (const image of images) { + try { + const expireAt = await hgetAsync(image, "expires"); + + if (+expireAt > now) { + const minutesLeft = (+expireAt - now) / 1000 / 60; + console.log(`not expiring ${image} for another ~${Math.round(minutesLeft)} minute(s)`); + continue; + } + + const imageAndTag = image.split(":"); + const headers = { + "Accept": "application/vnd.docker.distribution.manifest.v2+json", + }; + + // Get the manifest from the tag + const getOptions = { + method: "HEAD", + uri: `https://ttl.sh/v2/${imageAndTag[0]}/manifests/${imageAndTag[1]}`, + headers, + resolveWithFullResponse: true, + simple: false, + } + const getResponse = await rp(getOptions); + + if (getResponse.statusCode == 404) { + await sremAsync("current.images", image); + await delAsync(image); + continue; + } + + const deleteURI = `https://ttl.sh/v2/${imageAndTag[0]}/manifests/${getResponse.headers.etag.replace(/"/g,"")}`; + + // Remove from the registry + const options = { + method: "DELETE", + uri: deleteURI, + headers, + resolveWithFullResponse: true, + simple: false, + } + + await rp(options); + + console.log(`expiring ${image}`); + await sremAsync("current.images", image); + await delAsync(image); + } catch(err) { + console.log(`failed to evaluate image ${image}:`, err); + } + } +}