-
-
Save marcbachmann/02a46c43eaea853cba9d1fde31544f15 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
var async = require('async') | |
var ms = require('ms') | |
var _ = require('lodash') | |
var config = require('./config') | |
var Docker = require('dockerode') | |
var docker = new Docker(config.docker) | |
var api | |
api = | |
module.exports = { | |
pull: function (name, callback) { | |
docker.pull(name, function(err, stream) { | |
if (err) return callback(err) | |
docker.modem.followProgress(stream, onFinished) | |
function onFinished(err, output) { | |
if (err) return callback(err) | |
callback(null, output) | |
} | |
}) | |
}, | |
run: function (opts, callback) { | |
var ttl = opts.ttl || '7 days' | |
if (typeof ttl === 'string') ttl = ms(ttl) | |
var labels = { | |
createdByDeployer: 'true', | |
stack: opts.stack, | |
type: opts.type, | |
deleteAfter: new Date(Date.now() + ttl).toISOString(), | |
} | |
docker.createContainer({ | |
Image: opts.image, | |
Labels: labels | |
}, function (err, container) { | |
if (err) return callback(err) | |
container.start(function(err, data) { | |
if (err) return callback(err) | |
callback(null, arguments) | |
}) | |
}) | |
}, | |
build: { | |
// Let docker host fetch the remote url | |
fromRemote: function (opts, callback) { | |
docker.buildImage(null, {remote: opts.repository, t: opts.name}, callback) | |
}, | |
fromTar: function (opts, callback) { | |
} | |
}, | |
listContainers: function (opts, callback) { | |
if (arguments.length == 1) callback = opts | |
if (opts && opts.stack) { | |
docker.listContainers({all: true}, function (err, containers) { | |
if (err) return callback(err) | |
var isStack = function (container) { return container.Labels && container.Labels.stack == opts.stack } | |
containers = _.filter(containers, isStack) | |
callback(null, containers) | |
}) | |
} | |
else { | |
docker.listContainers({all: true}, callback) | |
} | |
}, | |
removeStack: function (stackId, callback) { | |
api.listContainers({stack: stackId}, function (err, containers) { | |
if (err) return callback(err) | |
async.each(containers, function (c, done) { | |
docker.getContainer(c.Id).remove({force: true}, done) | |
}, function (err) { | |
if (err) return callback(err) | |
callback(null, { | |
totalRemoved: containers.length, | |
removedContainers: containers | |
}) | |
}) | |
}) | |
}, | |
// Clean containers | |
// TODO MB: Also remove unused images | |
clean: function (opts, callback) { | |
if (arguments.length == 1) callback = opts | |
api.listContainers(function (err, containers) { | |
if (err) return callback(err) | |
var currentTime = Date.now() | |
var containersToRemove = opts.force? filterDeployerServices(containers) : filterExpiredContainers(containers) | |
var stacksToRemove = _.unique(_.pluck(containersToRemove, 'Labels.stack')) | |
async.map(stacksToRemove, function (stack, done) { | |
api.removeStack(stack, done) | |
}, function (err, res) { | |
if (err) return callback(err) | |
var containers = _.flatten(_.pluck(res, 'removedContainers')) | |
var total = _.reduce(_.pluck(res, 'totalRemoved'), function(t, n) { return t + n }) | |
callback(null, { | |
totalRemoved: total, | |
removedContainers: containers | |
}) | |
}) | |
}) | |
} | |
} | |
function filterExpiredContainers (containers) { | |
_.filter(containers, function (container) { | |
// Filter containers that aren't from this service | |
if (_.isEmpty(container.Labels)) return false | |
if (!container.Labels.createdByDeployer) return false | |
var destroyAfter = new Date(container.Labels.destroyAfter) | |
if (destroyAfter && destroyAfter.getTime() < currentTime) return true | |
if (_.contains(container.Status, 'Exited')) return true | |
// Containers with the status 'Created' currently don't get removed | |
return false | |
}) | |
} | |
function filterDeployerServices (containers) { | |
_.filter(containers, function (container) { | |
// Filter containers that aren't from this service | |
if (_.isEmpty(container.Labels)) return false | |
if (!container.Labels.createdByDeployer) return false | |
return true | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment