Created
April 16, 2016 06:08
-
-
Save allbinmani/3510de25560b6ca522935c8727a26acd to your computer and use it in GitHub Desktop.
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
#!/usr/bin/env node | |
/** | |
* Crude script to find images that are lingering and/or missing in the docker registry 2.0 | |
* | |
* Finds all unreferences images in all repos, given the path to the registry-data | |
* directory (the one that contains 'storage'). Also lists all images that are referenced, | |
* but are missing on disk. | |
* | |
* License: GPL 2.0 | |
* Author: Mattias Nilsson <[email protected]> | |
* | |
* Changelog: | |
* - 2016-04-15: Initial revision | |
* | |
*/ | |
var fs = require('fs'); | |
var path = require('path'); | |
var regDataDir = process.argv[2]; | |
if(!regDataDir) { | |
console.error('Specify registry-data directory as argument'); | |
process.exit(1); | |
} | |
var storageDir = path.join(regDataDir, 'storage'); | |
var reposDir = path.join(storageDir, 'repositories'); | |
var imagesDir = path.join(storageDir, 'images'); | |
var numRepos = 0; | |
var _imageIndex = {}; | |
function formatImageList(imageList) { | |
return imageList.map(function(img_id) { | |
return img_id + (_imageIndex[img_id] ? ' ( ' + _imageIndex[img_id].join(',') + ' )' : ''); | |
}).join('\n'); | |
} | |
fs.readdir(reposDir, function(err, files) { | |
if(err) { | |
console.error('failed to scan repositories directory %s: %s', reposDir, err); | |
process.exit(1); | |
} | |
function imageExists(image_id) { | |
var image_dir = path.join(imagesDir, image_id); | |
var json_file = path.join(image_dir, 'json'); | |
try { | |
var stat = fs.statSync(image_dir); | |
if(!stat || !stat.isDirectory()) { | |
return false; | |
} | |
stat = fs.statSync(json_file); | |
return stat && stat.isFile(); | |
} catch(e) { | |
return false; | |
} | |
} | |
Promise.all( | |
files.filter(function(f) { | |
var stat = fs.statSync(path.join(reposDir, f)); | |
return stat && stat.isDirectory(); | |
}).map(function(subName) { | |
var subDir = path.join(reposDir, subName); | |
return new Promise(function(resolve, reject) { | |
fs.readdir(subDir, function(err, repoList) { | |
if(err) { | |
return reject(err); | |
} | |
numRepos++; | |
resolve({path: subDir, | |
name: subName, | |
repos: repoList.map(function(repoName) { | |
var imgsFile = path.join(subDir, repoName, '_index_images'); | |
var _index_images = JSON.parse(fs.readFileSync(imgsFile).toString()); | |
return {name: repoName, | |
path: path.join(subDir, repoName), | |
index_images: _index_images.map(function(img) { | |
if(!_imageIndex[img.id]) { _imageIndex[img.id] = [];} | |
_imageIndex[img.id].push(repoName); | |
return {id: img.id, exists: imageExists(img.id)}; | |
}) | |
}; | |
}) | |
}); | |
}); | |
}).then(function(x) { | |
return x; | |
}); | |
}) | |
).then(function(result) { | |
var _usedImages = {}; | |
var allUsedImages = result.map(function(sub) { | |
return sub.repos.map(function(repo) { | |
return repo.index_images.map(function(im) { | |
_usedImages[im.id] = true; | |
return im.id; | |
}); | |
}); | |
}).reduce(function(a, b) { | |
return a.concat(b); | |
}, []).reduce(function(a, b) { | |
return a.concat(b); | |
}, []); | |
fs.readdir(imagesDir, function(err, image_dir_list) { | |
var unusedImages = image_dir_list.filter(function(img_dir) { | |
return !_usedImages[img_dir]; | |
}); | |
var missingImages = Object.keys(_usedImages).filter(function(img_id) { | |
return image_dir_list.indexOf(img_id) === -1; | |
}); | |
console.log('Scanned %d repositories', numRepos); | |
console.log('- total # of images: %d', image_dir_list.length); | |
console.log('- referenced images: %d', Object.keys(_usedImages).length); | |
console.log('- unreferenced images: %d', unusedImages.length); | |
if(unusedImages.length > 0) { | |
console.log(formatImageList(unusedImages)); | |
} | |
console.log('- missing images: %d', missingImages.length); | |
if(missingImages.length > 0) { | |
console.log(formatImageList(missingImages)); | |
} | |
process.exit(0); | |
}); | |
}).catch(function(err) { | |
console.error('Error occurred: %s', err); | |
process.exit(1); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment