Skip to content

Instantly share code, notes, and snippets.

@Morriz
Last active June 15, 2016 10:31
Show Gist options
  • Save Morriz/2d782e4661f29196476dd48445e3b02c to your computer and use it in GitHub Desktop.
Save Morriz/2d782e4661f29196476dd48445e3b02c to your computer and use it in GitHub Desktop.
Removes old docker tags, while keeping the last imagesToKeep number.
const http = require('https')
const url = require('url')
const repo = process.argv[2]
const imagesToKeep = 5
const baseUrl = `https://USERNAME:PASSWORD@reg.your.com/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