Refactored code and fixed bin dir path issue.

This commit is contained in:
Sean Li 2014-08-31 22:10:32 -07:00
parent 1cc0d3acd4
commit c299ef3a07
7 changed files with 234 additions and 228 deletions

View File

@ -143,6 +143,8 @@
"docker": true, "docker": true,
"async": true, "async": true,
"child_process": true, "child_process": true,
"convert": true,
"Convert": true,
// Collections // Collections
"SimpleSchema": false, "SimpleSchema": false,
@ -221,6 +223,7 @@
"saveImageFolderSync": true, "saveImageFolderSync": true,
"rebuildImageSync": true, "rebuildImageSync": true,
"saveImageFolder": true, "saveImageFolder": true,
"getFromImage": true,
// Forms // Forms
"showFormErrors": true, "showFormErrors": true,

View File

@ -75,7 +75,7 @@ addAppWatcher = function (app) {
exec(cmd, function () {}); exec(cmd, function () {});
} }
} catch (e) { } catch (e) {
// console.error(e); //console.error(e);
} }
syncing = false; syncing = false;
if (willSyncAgain) { if (willSyncAgain) {

View File

@ -7,9 +7,13 @@ Util.getHomePath = function () {
Util.getBinDir = function () { Util.getBinDir = function () {
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
return path.join(path.join(process.env.PWD, '..'), 'resources'); return path.join(path.join(process.env.PWD, '..'), 'resources');
} else {
if (Meteor.isClient) {
return path.join(process.cwd(), 'resources');
} else { } else {
return path.join(process.cwd(), '../../../resources'); return path.join(process.cwd(), '../../../resources');
} }
}
}; };
Util.deleteFolder = function (directory) { Util.deleteFolder = function (directory) {

View File

@ -1,3 +1,71 @@
deleteApp = function (app, callback) {
if (!app.docker) {
callback(null);
return;
}
try {
Docker.removeContainerSync(app.docker.Id);
} catch (e) {
console.error(e);
}
callback(null);
};
deleteAppSync = function (app) {
return Meteor._wrapAsync(deleteApp)(app);
};
restartApp = function (app, callback) {
if (app.docker && app.docker.Id) {
try {
Docker.restartContainerSync(app.docker.Id);
} catch (e) {
console.error(e);
}
var containerData = Docker.getContainerDataSync(app.docker.Id);
Fiber(function () {
Apps.update(app._id, {$set: {
status: 'READY',
docker: containerData
}});
}).run();
callback(null);
// Use dig to refresh the DNS
exec('/usr/bin/dig dig ' + app.name + '.dev @172.17.42.1 ', function() {});
} else {
callback(null);
}
};
getAppLogs = function (app) {
if (app.docker && app.docker.Id) {
var container = docker.getContainer(app.docker.Id);
container.logs({follow: false, stdout: true, stderr: true, timestamps: true, tail: 300}, function (err, response) {
if (err) { throw err; }
Fiber(function () {
Apps.update(app._id, {
$set: {
logs: []
}
});
}).run();
var logs = [];
response.setEncoding('utf8');
response.on('data', function (line) {
logs.push(convert.toHtml(line.slice(8)));
Fiber(function () {
Apps.update(app._id, {
$set: {
logs: logs
}
});
}).run();
});
response.on('end', function () {});
});
}
};
removeBindFolder = function (name, callback) { removeBindFolder = function (name, callback) {
exec(path.join(Util.getBinDir(), 'boot2docker') + ' ssh "sudo rm -rf /var/lib/docker/binds/' + name + '"', function(err, stdout) { exec(path.join(Util.getBinDir(), 'boot2docker') + ' ssh "sudo rm -rf /var/lib/docker/binds/' + name + '"', function(err, stdout) {
callback(err, stdout); callback(err, stdout);

View File

@ -1,8 +1,5 @@
Dockerode = Meteor.require('dockerode'); Dockerode = Meteor.require('dockerode');
var Convert = Meteor.require('ansi-to-html');
var convert = new Convert();
var DOCKER_HOST='192.168.59.103'; var DOCKER_HOST='192.168.59.103';
docker = new Dockerode({host: '192.168.59.103', port: '2375'}); docker = new Dockerode({host: '192.168.59.103', port: '2375'});
@ -28,23 +25,6 @@ Docker.removeContainerSync = function (containerId) {
return Meteor._wrapAsync(Docker.removeContainer)(containerId); return Meteor._wrapAsync(Docker.removeContainer)(containerId);
}; };
deleteApp = function (app, callback) {
if (!app.docker) {
callback(null);
return;
}
try {
Docker.removeContainerSync(app.docker.Id);
} catch (e) {
console.error(e);
}
callback(null);
};
deleteAppSync = function (app) {
return Meteor._wrapAsync(deleteApp)(app);
};
Docker.getContainerData = function (containerId, callback) { Docker.getContainerData = function (containerId, callback) {
var container = docker.getContainer(containerId); var container = docker.getContainer(containerId);
container.inspect(function (err, data) { container.inspect(function (err, data) {
@ -123,68 +103,6 @@ Docker.restartContainerSync = function (containerId) {
return Meteor._wrapAsync(Docker.restartContainer)(containerId); return Meteor._wrapAsync(Docker.restartContainer)(containerId);
}; };
var getFromImage = function (dockerfile) {
var patternString = "(FROM)(.*)";
var regex = new RegExp(patternString, "g");
var fromInstruction = dockerfile.match(regex);
if (fromInstruction && fromInstruction.length > 0) {
return fromInstruction[0].replace('FROM', '').trim();
} else {
return null;
}
};
restartApp = function (app, callback) {
if (app.docker && app.docker.Id) {
try {
Docker.restartContainerSync(app.docker.Id);
} catch (e) {
console.error(e);
}
var containerData = Docker.getContainerDataSync(app.docker.Id);
Fiber(function () {
Apps.update(app._id, {$set: {
status: 'READY',
docker: containerData
}});
}).run();
callback(null);
// Use dig to refresh the DNS
exec('/usr/bin/dig dig ' + app.name + '.dev @172.17.42.1 ', function() {});
} else {
callback(null);
}
};
getAppLogs = function (app) {
if (app.docker && app.docker.Id) {
var container = docker.getContainer(app.docker.Id);
container.logs({follow: false, stdout: true, stderr: true, timestamps: true, tail: 300}, function (err, response) {
if (err) { throw err; }
Fiber(function () {
Apps.update(app._id, {
$set: {
logs: []
}
});
}).run();
var logs = [];
response.setEncoding('utf8');
response.on('data', function (line) {
logs.push(convert.toHtml(line.slice(8)));
Fiber(function () {
Apps.update(app._id, {
$set: {
logs: logs
}
});
}).run();
});
response.on('end', function () {});
});
}
};
createTarFile = function (image, callback) { createTarFile = function (image, callback) {
var TAR_PATH = path.join(KITE_TAR_PATH, image._id + '.tar'); var TAR_PATH = path.join(KITE_TAR_PATH, image._id + '.tar');
exec('tar czf ' + TAR_PATH + ' -C ' + image.path + ' .', function (err) { exec('tar czf ' + TAR_PATH + ' -C ' + image.path + ' .', function (err) {
@ -243,23 +161,6 @@ Docker.removeImageSync = function (imageId) {
return Meteor._wrapAsync(Docker.removeImage)(imageId); return Meteor._wrapAsync(Docker.removeImage)(imageId);
}; };
deleteImage = function (image, callback) {
if (!image.docker) {
callback(null, {});
return;
}
try {
Docker.removeImageSync(image.docker.Id);
} catch (e) {
console.error(e);
}
callback(null);
};
deleteImageSync = function (image) {
return Meteor._wrapAsync(deleteImage)(image);
};
var defaultContainerOptions = function () { var defaultContainerOptions = function () {
return [ return [
{ {
@ -502,132 +403,6 @@ killAndRemoveContainers = function (names, callback) {
}); });
}; };
pullImageFromDockerfile = function (dockerfile, imageId, callback) {
var fromImage = getFromImage(dockerfile);
console.log('From image: ' + fromImage);
var installedImage = null;
try {
installedImage = Docker.getImageDataSync(fromImage);
} catch (e) {
console.error(e);
}
if (fromImage && !installedImage) {
Fiber(function () {
Images.update(imageId, {
$set: {
buildLogs: []
}
});
}).run();
var logs = [];
docker.pull(fromImage, function (err, response) {
if (err) { callback(err); return; }
response.setEncoding('utf8');
response.on('data', function (data) {
try {
var logData = JSON.parse(data);
var logDisplay = '';
if (logData.id) {
logDisplay += logData.id + ' | ';
}
logDisplay += logData.status;
if (logData.progressDetail && logData.progressDetail.current && logData.progressDetail.total) {
logDisplay += ' - ' + Math.round(logData.progressDetail.current / logData.progressDetail.total * 100) + '%';
}
logs.push(logDisplay);
Fiber(function () {
Images.update(imageId, {
$set: {
buildLogs: logs
}
});
}).run();
} catch (e) {
console.error(e);
}
});
response.on('end', function () {
console.log('Finished pulling image: ' + fromImage);
callback(null);
});
});
} else {
callback(null);
}
};
buildImage = function (image, callback) {
Fiber(function () {
var tarFilePath = createTarFileSync(image);
Images.update(image._id, {
$set: {
buildLogs: []
}
});
docker.buildImage(tarFilePath, {t: image._id.toLowerCase()}, function (err, response) {
if (err) { callback(err); }
console.log('Building Docker image...');
var logs = [];
response.setEncoding('utf8');
response.on('data', function (data) {
try {
var line = JSON.parse(data).stream;
logs.push(convert.toHtml(line));
Fiber(function () {
Images.update(image._id, {
$set: {
buildLogs: logs
}
});
}).run();
} catch (e) {
console.error(e);
}
});
response.on('end', function () {
console.log('Finished building Docker image.');
try {
fs.unlinkSync(tarFilePath);
console.log('Cleaned up tar file.');
} catch (e) {
console.error(e);
}
Fiber(function () {
var imageData = null;
try {
imageData = Docker.getImageDataSync(image._id);
Images.update(image._id, {
$set: {
docker: imageData,
status: 'READY'
}
});
} catch (e) {
console.log(e);
Images.update(image._id, {
$set: {
status: 'ERROR'
}
});
}
var oldImageId = null;
if (image.docker && image.docker.Id) {
oldImageId = image.docker.Id;
}
if (oldImageId && imageData && oldImageId !== imageData.Id) {
try {
Docker.removeImageSync(oldImageId);
} catch (e) {
console.error(e);
}
}
}).run();
callback(null);
});
});
}).run();
};
Meteor.methods({ Meteor.methods({
runApp: function (app) { runApp: function (app) {
this.unblock(); this.unblock();

View File

@ -1,3 +1,14 @@
getFromImage = function (dockerfile) {
var patternString = "(FROM)(.*)";
var regex = new RegExp(patternString, "g");
var fromInstruction = dockerfile.match(regex);
if (fromInstruction && fromInstruction.length > 0) {
return fromInstruction[0].replace('FROM', '').trim();
} else {
return null;
}
};
getImageJSON = function (directory) { getImageJSON = function (directory) {
var KITE_JSON_PATH = path.join(directory, 'image.json'); var KITE_JSON_PATH = path.join(directory, 'image.json');
if (fs.existsSync(KITE_JSON_PATH)) { if (fs.existsSync(KITE_JSON_PATH)) {
@ -38,6 +49,23 @@ getImageMetaData = function (directory) {
return kiteJSON; return kiteJSON;
}; };
deleteImage = function (image, callback) {
if (!image.docker) {
callback(null, {});
return;
}
try {
Docker.removeImageSync(image.docker.Id);
} catch (e) {
console.error(e);
}
callback(null);
};
deleteImageSync = function (image) {
return Meteor._wrapAsync(deleteImage)(image);
};
rebuildImage = function (image, callback) { rebuildImage = function (image, callback) {
Util.deleteFolder(image.path); Util.deleteFolder(image.path);
var imageMetaData = getImageMetaData(image.originPath); var imageMetaData = getImageMetaData(image.originPath);
@ -75,6 +103,132 @@ rebuildImageSync = function (image) {
return Meteor._wrapAsync(rebuildImage)(image); return Meteor._wrapAsync(rebuildImage)(image);
}; };
pullImageFromDockerfile = function (dockerfile, imageId, callback) {
var fromImage = getFromImage(dockerfile);
console.log('From image: ' + fromImage);
var installedImage = null;
try {
installedImage = Docker.getImageDataSync(fromImage);
} catch (e) {
console.error(e);
}
if (fromImage && !installedImage) {
Fiber(function () {
Images.update(imageId, {
$set: {
buildLogs: []
}
});
}).run();
var logs = [];
docker.pull(fromImage, function (err, response) {
if (err) { callback(err); return; }
response.setEncoding('utf8');
response.on('data', function (data) {
try {
var logData = JSON.parse(data);
var logDisplay = '';
if (logData.id) {
logDisplay += logData.id + ' | ';
}
logDisplay += logData.status;
if (logData.progressDetail && logData.progressDetail.current && logData.progressDetail.total) {
logDisplay += ' - ' + Math.round(logData.progressDetail.current / logData.progressDetail.total * 100) + '%';
}
logs.push(logDisplay);
Fiber(function () {
Images.update(imageId, {
$set: {
buildLogs: logs
}
});
}).run();
} catch (e) {
console.error(e);
}
});
response.on('end', function () {
console.log('Finished pulling image: ' + fromImage);
callback(null);
});
});
} else {
callback(null);
}
};
buildImage = function (image, callback) {
Fiber(function () {
var tarFilePath = createTarFileSync(image);
Images.update(image._id, {
$set: {
buildLogs: []
}
});
docker.buildImage(tarFilePath, {t: image._id.toLowerCase()}, function (err, response) {
if (err) { callback(err); }
console.log('Building Docker image...');
var logs = [];
response.setEncoding('utf8');
response.on('data', function (data) {
try {
var line = JSON.parse(data).stream;
logs.push(convert.toHtml(line));
Fiber(function () {
Images.update(image._id, {
$set: {
buildLogs: logs
}
});
}).run();
} catch (e) {
console.error(e);
}
});
response.on('end', function () {
console.log('Finished building Docker image.');
try {
fs.unlinkSync(tarFilePath);
console.log('Cleaned up tar file.');
} catch (e) {
console.error(e);
}
Fiber(function () {
var imageData = null;
try {
imageData = Docker.getImageDataSync(image._id);
Images.update(image._id, {
$set: {
docker: imageData,
status: 'READY'
}
});
} catch (e) {
console.log(e);
Images.update(image._id, {
$set: {
status: 'ERROR'
}
});
}
var oldImageId = null;
if (image.docker && image.docker.Id) {
oldImageId = image.docker.Id;
}
if (oldImageId && imageData && oldImageId !== imageData.Id) {
try {
Docker.removeImageSync(oldImageId);
} catch (e) {
console.error(e);
}
}
}).run();
callback(null);
});
});
}).run();
};
Meteor.methods({ Meteor.methods({
createImage: function (directory) { createImage: function (directory) {
this.unblock(); this.unblock();

View File

@ -7,3 +7,5 @@ exec = Meteor.require('child_process').exec;
async = Meteor.require('async'); async = Meteor.require('async');
Fiber = Meteor.require('fibers'); Fiber = Meteor.require('fibers');
child_process = Meteor.require('child_process'); child_process = Meteor.require('child_process');
Convert = Meteor.require('ansi-to-html');
convert = new Convert();