Last active
June 15, 2016 10:31
-
-
Save Morriz/2d782e4661f29196476dd48445e3b02c to your computer and use it in GitHub Desktop.
Removes old docker tags, while keeping the last imagesToKeep number.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require('https') | |
const url = require('url') | |
const repo = process.argv[2] | |
const imagesToKeep = 5 | |
const baseUrl = `https://USERNAME:[email protected]/v2/${repo}/` | |
console.info('removing old images for repo: ', repo) | |
http.get(`${baseUrl}tags/list`, res => { | |
let body = '' | |
res.on('data', (d) => { | |
body += d | |
}) | |
res.on('end', () => { | |
const tags = JSON.parse(body).tags | |
const promises = [] | |
//console.log(`tags: %j`, tags) | |
tags.forEach(tag => { | |
promises.push(new Promise((resolve, reject) => { | |
const options = url.parse(`${baseUrl}manifests/${tag}`) | |
//console.log('asking tag with options: ', options) | |
Promise.all([ | |
new Promise((resolve, reject) => { | |
// get the correct digest via v2 | |
// @see: https://github.com/docker/distribution/blob/master/docs/spec/api.md#deleting-an-image | |
http.get(Object.assign({Accept: 'application/vnd.docker.distribution.manifest.v2+json'}, options), res => { | |
const digest = res.headers['docker-content-digest'] | |
resolve(digest) | |
}).on('error', (e) => { | |
console.error(`error: ${e.message}`) | |
reject(e) | |
}) | |
}), | |
new Promise((resolve, reject) => { | |
// get the image created timestamp via v1 | |
http.get(options, res => { | |
let body = '' | |
res.on('data', (d) => { | |
body += d | |
}) | |
res.on('end', () => { | |
const json = JSON.parse(body) | |
console.log(`json for tag ${tag}: `, json) | |
lastOp = JSON.parse(json.history.shift().v1Compatibility).created | |
console.log(`lastOp for tag ${tag}: `, lastOp) | |
resolve(lastOp) | |
}) | |
}).on('error', (e) => { | |
console.error(`error: ${e.message}`) | |
reject(e) | |
}) | |
}) | |
]).then(([digest, lastOp]) => { | |
resolve({tag, digest, lastOp}) | |
}).catch(reject) | |
})) | |
}) | |
Promise.all(promises).then(tagList => { | |
// sort tagList by date, newest first, and select all but latest 5, including 'latest' | |
const deleteTagList = tagList.sort((a, b) => { | |
return new Date(b.lastOp).getTime() - new Date(a.lastOp).getTime() | |
}).slice(imagesToKeep + 1) | |
//console.log(`deleteTagList: `, deleteTagList) | |
deleteTagList.forEach(item => { | |
console.log('deleting tag: ', item.tag) | |
const options = url.parse(`${baseUrl}manifests/${item.digest}`) | |
options.method = 'DELETE' | |
//console.log('deleting with options: ', options) | |
//http.request(options, res => { | |
// console.log(`status code for deletion of tag ${item.tag}: `, res.statusCode) | |
//}).on('error', (e) => { | |
// console.error(`error: ${e.message}`) | |
//}).end() | |
}) | |
}) | |
}) | |
}).on('error', (e) => { | |
console.error(`error: ${e.message}`) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment