Container status sync'ed across app and docker host.

This commit is contained in:
Sean Li 2014-09-30 13:12:16 -07:00
parent 8f0dc52325
commit f69ddb1251
7 changed files with 143 additions and 49 deletions

View File

@ -1,12 +1,17 @@
var exec = require('exec');
var path = require('path');
var fs = require('fs');
var Convert = require('ansi-to-html');
var convert = new Convert();
AppUtil = {};
AppUtil.create = function () {
};
AppUtil.run = function (app) {
var image = Images.findOne({_id: app.imageId});
var image = Images.findOne({'docker.Id': app.docker.Image});
// Delete old container if one already exists
Docker.removeContainer(app.name, function (err) {
if (err) { console.error(err); }
@ -166,3 +171,83 @@ AppUtil.recover = function () {
});
});
};
AppUtil.sync = function () {
Docker.listContainers(function (err, containers) {
if (err) {
console.error(err);
} else {
var apps = Apps.find({}).fetch();
_.each(apps, function (app) {
if (app.docker && app.docker.Id) {
Docker.getContainerData(app.docker.Id, function (err, data) {
console.log(data);
var status = 'STARTING';
if (data.State.Running) {
status = 'READY';
} else {
status = 'ERROR';
}
Apps.update(app._id, {
$set: {
docker: data,
status: status
}
})
});
}
});
var dockerIds = _.map(apps, function (app) {
return app.docker.Id;
});
var containerIds = _.map(containers, function (container) {
return container.Id;
});
var diffApps = _.difference(dockerIds, containerIds);
_.each(diffApps, function (appContainerId) {
var app = Apps.findOne({'docker.Id': appContainerId});
if (app) {
AppUtil.remove(app._id);
}
});
var diffContainers = _.reject(containers, function (container) {
return _.contains(dockerIds, container.Id);
});
_.each(diffContainers, function (container) {
var appName = container.Name.substring(1);
var appPath = path.join(Util.KITE_PATH, appName);
if (!fs.existsSync(appPath)) {
console.log('Created Kite ' + appName + ' directory.');
fs.mkdirSync(appPath, function (err) {
if (err) { throw err; }
});
}
var envVars = container.Config.Env;
var config = {};
_.each(envVars, function (envVar) {
var eqPos = envVar.indexOf('=');
var envKey = envVar.substring(0, eqPos);
var envVal = envVar.substring(eqPos + 1);
config[envKey] = envVal;
});
var status = 'STARTING';
if (container.State.Running) {
status = 'READY';
} else {
status = 'ERROR';
}
var appObj = {
name: appName,
docker: container,
status: status,
config: config,
path: appPath,
logs: [],
createdAt: new Date()
};
console.log(appObj);
Apps.insert(appObj);
});
}
});
};

View File

@ -61,9 +61,15 @@ Docker.getContainerData = function (containerId, callback) {
callback(err, null);
return;
} else {
data.Config.Volumes = convertVolumeObjToArray(data.Config.Volumes);
data.Volumes = convertVolumeObjToArray(data.Volumes);
data.VolumesRW = convertVolumeObjToArray(data.VolumesRW);
if (data.Config && data.Config.Volumes) {
data.Config.Volumes = convertVolumeObjToArray(data.Config.Volumes);
}
if (data.Volumes) {
data.Volumes = convertVolumeObjToArray(data.Volumes);
}
if (data.VolumesRW) {
data.VolumesRW = convertVolumeObjToArray(data.VolumesRW);
}
callback(null, data);
return;
}

View File

@ -150,7 +150,7 @@ Meteor.setInterval(function () {
if (!Session.get('boot2dockerOff')) {
fixBoot2DockerVM(function (err) {
if (err) { console.log(err); return; }
AppUtil.recover();
//AppUtil.recover();
fixDefaultImages(function (err) {
if (err) { console.log(err); return; }
fixDefaultContainers(function (err) {
@ -161,3 +161,9 @@ Meteor.setInterval(function () {
}
}
}, 5000);
Meteor.setInterval(function () {
if (!Session.get('installing')) {
AppUtil.sync();
}
}, 5000);

View File

@ -9,24 +9,26 @@
{{/if}}
</div>
</div>
<div class="padded">
{{#if hasItem apps}}
<div class="apps line-item-collection">
{{#each apps}}
{{> dashboard_single_app}}
{{/each}}
</div>
{{else}}
<div class="empty-placeholder">
<div class="big-icon"><i class="fa fa-cube"></i></div>
<h4>There are no apps yet.</h4>
{{#if $.Session.equals 'boot2dockerState' 'poweroff'}}
<a href="#" data-toggle="modal" data-target="#modal-create-app" class="btn btn-action" disabled="disabled"><span class="typcn typcn-plus-outline"></span> Create App</a>
{{else}}
<a href="#" onclick="trackLink('create app')" data-toggle="modal" data-target="#modal-create-app" class="btn btn-action"><span class="typcn typcn-plus-outline"></span> Create App</a>
{{/if}}
</div>
{{/if}}
<div class="content">
<div class="padded">
{{#if hasItem apps}}
<div class="apps line-item-collection">
{{#each apps}}
{{> dashboard_single_app}}
{{/each}}
</div>
{{else}}
<div class="empty-placeholder">
<div class="big-icon"><i class="fa fa-cube"></i></div>
<h4>There are no apps yet.</h4>
{{#if $.Session.equals 'boot2dockerState' 'poweroff'}}
<a href="#" data-toggle="modal" data-target="#modal-create-app" class="btn btn-action" disabled="disabled"><span class="typcn typcn-plus-outline"></span> Create App</a>
{{else}}
<a href="#" onclick="trackLink('create app')" data-toggle="modal" data-target="#modal-create-app" class="btn btn-action"><span class="typcn typcn-plus-outline"></span> Create App</a>
{{/if}}
</div>
{{/if}}
</div>
</div>
{{> modal_create_app}}
{{> modal_create_image}}

View File

@ -36,11 +36,6 @@ Template.modal_create_app.events({
createdAt: new Date()
};
var appId = Apps.insert(appObj);
Apps.update(appId, {
$set: {
'config.APP_ID': appId
}
});
var app = Apps.findOne(appId);
var image = Images.findOne(app.imageId);
Util.copyVolumes(image.path, app.name, function (err) {

View File

@ -9,24 +9,26 @@
{{/if}}
</div>
</div>
<div class="padded">
{{#if hasItem images}}
<div class="images line-item-collection">
{{#each images}}
{{> dashboard_single_image}}
{{/each}}
</div>
{{else}}
<div class="empty-placeholder">
<div class="big-icon"><i class="fa fa-camera"></i></div>
<h4>There are no images yet.</h4>
{{#if $.Session.equals 'boot2dockerState' 'poweroff'}}
<a href="#" data-toggle="modal" data-target="#modal-create-image" class="btn btn-action" disabled="disabled"><span class="typcn typcn-plus-outline"></span> Create Image</a>
{{else}}
<a href="#" onclick="trackLink('create image')" data-toggle="modal" data-target="#modal-create-image" class="btn btn-action"><span class="typcn typcn-plus-outline"></span>Create Image</a>
{{/if}}
</div>
{{/if}}
<div class="content">
<div class="padded">
{{#if hasItem images}}
<div class="images line-item-collection">
{{#each images}}
{{> dashboard_single_image}}
{{/each}}
</div>
{{else}}
<div class="empty-placeholder">
<div class="big-icon"><i class="fa fa-camera"></i></div>
<h4>There are no images yet.</h4>
{{#if $.Session.equals 'boot2dockerState' 'poweroff'}}
<a href="#" data-toggle="modal" data-target="#modal-create-image" class="btn btn-action" disabled="disabled"><span class="typcn typcn-plus-outline"></span> Create Image</a>
{{else}}
<a href="#" onclick="trackLink('create image')" data-toggle="modal" data-target="#modal-create-image" class="btn btn-action"><span class="typcn typcn-plus-outline"></span>Create Image</a>
{{/if}}
</div>
{{/if}}
</div>
</div>
{{> modal_create_app}}
{{> modal_create_image}}

View File

@ -6,9 +6,7 @@
{{> dashboard_menu}}
<div class="dashboard-body">
<div class="mac-window-header"><a href="#">Kitematic</a></div>
<div class="content longer">
{{> yield}}
</div>
{{> yield}}
</div>
</div>
</div>