mirror of
https://github.com/Febbweiss/ProjectDeployer.git
synced 2026-03-04 22:25:38 +00:00
Feature: add deployment + deployment logs
This commit is contained in:
@@ -22,3 +22,5 @@ fortawesome:fontawesome
|
|||||||
iron:router
|
iron:router
|
||||||
zenorocha:clipboard
|
zenorocha:clipboard
|
||||||
simple:reactive-method
|
simple:reactive-method
|
||||||
|
vsivsi:job-collection
|
||||||
|
ogamedia:timer
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
METEOR@1.2.0.4-logging.0
|
METEOR@1.2.1
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
autoupdate@1.2.4-logging
|
autoupdate@1.2.4
|
||||||
babel-compiler@5.8.24_1
|
babel-compiler@5.8.24_1
|
||||||
babel-runtime@0.1.4
|
babel-runtime@0.1.4
|
||||||
base64@1.0.4
|
base64@1.0.4
|
||||||
@@ -10,19 +10,20 @@ boilerplate-generator@1.0.4
|
|||||||
caching-compiler@1.0.0
|
caching-compiler@1.0.0
|
||||||
caching-html-compiler@1.0.2
|
caching-html-compiler@1.0.2
|
||||||
callback-hook@1.0.4
|
callback-hook@1.0.4
|
||||||
check@1.0.6
|
check@1.1.0
|
||||||
|
coffeescript@1.0.11
|
||||||
ddp@1.2.2
|
ddp@1.2.2
|
||||||
ddp-client@1.2.1
|
ddp-client@1.2.1
|
||||||
ddp-common@1.2.1
|
ddp-common@1.2.2
|
||||||
ddp-server@1.2.1
|
ddp-server@1.2.2
|
||||||
deps@1.0.9
|
deps@1.0.9
|
||||||
diff-sequence@1.0.1
|
diff-sequence@1.0.1
|
||||||
ecmascript@0.1.5
|
ecmascript@0.1.6
|
||||||
ecmascript-collections@0.1.6
|
ecmascript-runtime@0.2.6
|
||||||
ejson@1.0.7
|
ejson@1.0.7
|
||||||
es5-shim@4.1.13
|
es5-shim@4.1.14
|
||||||
fastclick@1.0.7
|
fastclick@1.0.7
|
||||||
fortawesome:fontawesome@4.4.0
|
fortawesome:fontawesome@4.4.0_1
|
||||||
geojson-utils@1.0.4
|
geojson-utils@1.0.4
|
||||||
hot-code-push@1.0.0
|
hot-code-push@1.0.0
|
||||||
html-tools@1.0.5
|
html-tools@1.0.5
|
||||||
@@ -42,20 +43,23 @@ jquery@1.11.4
|
|||||||
launch-screen@1.0.4
|
launch-screen@1.0.4
|
||||||
livedata@1.0.15
|
livedata@1.0.15
|
||||||
logging@1.0.8
|
logging@1.0.8
|
||||||
meteor@1.1.9
|
meteor@1.1.10
|
||||||
meteor-base@1.0.1
|
meteor-base@1.0.1
|
||||||
minifiers@1.1.7
|
minifiers@1.1.7
|
||||||
minimongo@1.0.10
|
minimongo@1.0.10
|
||||||
mobile-experience@1.0.1
|
mobile-experience@1.0.1
|
||||||
mobile-status-bar@1.0.6
|
mobile-status-bar@1.0.6
|
||||||
mongo@1.1.2
|
mongo@1.1.3
|
||||||
mongo-id@1.0.1
|
mongo-id@1.0.1
|
||||||
|
mrt:later@1.6.1
|
||||||
|
mrt:moment@2.8.1
|
||||||
npm-mongo@1.4.39_1
|
npm-mongo@1.4.39_1
|
||||||
observe-sequence@1.0.7
|
observe-sequence@1.0.7
|
||||||
|
ogamedia:timer@0.0.9
|
||||||
ordered-dict@1.0.4
|
ordered-dict@1.0.4
|
||||||
promise@0.5.0
|
promise@0.5.1
|
||||||
random@1.0.4
|
random@1.0.5
|
||||||
reactive-dict@1.1.2
|
reactive-dict@1.1.3
|
||||||
reactive-var@1.0.6
|
reactive-var@1.0.6
|
||||||
reload@1.1.4
|
reload@1.1.4
|
||||||
retry@1.0.4
|
retry@1.0.4
|
||||||
@@ -64,14 +68,15 @@ session@1.1.1
|
|||||||
simple:reactive-method@1.0.2
|
simple:reactive-method@1.0.2
|
||||||
spacebars@1.0.7
|
spacebars@1.0.7
|
||||||
spacebars-compiler@1.0.7
|
spacebars-compiler@1.0.7
|
||||||
standard-minifiers@1.0.1
|
standard-minifiers@1.0.2
|
||||||
templating@1.1.4
|
templating@1.1.5
|
||||||
templating-tools@1.0.0
|
templating-tools@1.0.0
|
||||||
tracker@1.0.9
|
tracker@1.0.9
|
||||||
twbs:bootstrap-noglyph@3.3.5
|
twbs:bootstrap-noglyph@3.3.5
|
||||||
ui@1.0.8
|
ui@1.0.8
|
||||||
underscore@1.0.4
|
underscore@1.0.4
|
||||||
url@1.0.5
|
url@1.0.5
|
||||||
webapp@1.2.2
|
vsivsi:job-collection@1.2.3
|
||||||
|
webapp@1.2.3
|
||||||
webapp-hashing@1.0.5
|
webapp-hashing@1.0.5
|
||||||
zenorocha:clipboard@1.4.2
|
zenorocha:clipboard@1.4.2
|
||||||
|
|||||||
11
client/deployment.service.js
Normal file
11
client/deployment.service.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Deployments = new Mongo.Collection('deployments');
|
||||||
|
|
||||||
|
DeploymentService = {
|
||||||
|
list: function(id) {
|
||||||
|
var deployments = Deployments.find(),
|
||||||
|
altered = deployments.map(function(doc, index, cursor) {
|
||||||
|
return _.extend(doc, {index: deployments.count() - index});
|
||||||
|
});
|
||||||
|
return altered;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a href="/management">Projects <span class="sr-only">(current)</span></a>
|
<a href="/projects">Projects <span class="sr-only">(current)</span></a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
21
client/project_details.controller.js
Normal file
21
client/project_details.controller.js
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
Template.deploymentsList.helpers({
|
||||||
|
deployments: function () {
|
||||||
|
return DeploymentService.list();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.deploymentDetails.helpers({
|
||||||
|
format: function() {
|
||||||
|
return this.data.replace(/\n/g, '<br />');
|
||||||
|
},
|
||||||
|
running: function() {
|
||||||
|
var string = this.status;
|
||||||
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.deploymentBtn.helpers({
|
||||||
|
running: function() {
|
||||||
|
return this.status === 'pending' ? 'visible' : 'hidden';
|
||||||
|
}
|
||||||
|
})
|
||||||
55
client/project_details.view.html
Normal file
55
client/project_details.view.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<template name="projectDetails">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li><a href="/projects">Projects</a></li>
|
||||||
|
<li class="active">{{label}}</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h1>
|
||||||
|
{{label}}
|
||||||
|
<a href="{{git_url}}" target="_blank">
|
||||||
|
<i class="fa fa-fw fa-github" title="Go to GIT repository"></i>
|
||||||
|
</a>
|
||||||
|
</h1>
|
||||||
|
{{> deploymentsList}}
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="deploymentsList">
|
||||||
|
<div>
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
{{#each deployments}}
|
||||||
|
{{> deploymentBtn}}
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content">
|
||||||
|
{{#each deployments}}
|
||||||
|
{{> deploymentDetails}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="deploymentBtn">
|
||||||
|
<li role="presentation">
|
||||||
|
<a id="heading{{index}}" role="tab" data-toggle="tab" href="#collapseDeployment{{index}}" aria-controls="collapseDeployment{{index}}">
|
||||||
|
# {{index}}
|
||||||
|
<i class="fa fa-cog fa-spin {{running}}"></i>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template name="deploymentDetails">
|
||||||
|
<div role="tabpanel" class="tab-pane" id="collapseDeployment{{index}}">
|
||||||
|
<div class="well">
|
||||||
|
<h4>Deployment # {{index}} - {{tm_cal timestamp}}</h4>
|
||||||
|
{{#each output}}
|
||||||
|
<p>
|
||||||
|
<samp>{{{format}}}</samp>
|
||||||
|
</p>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<div class="pull-right">
|
||||||
|
<h5>Status : <small>{{running}}</small></h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Template.management.helpers({
|
Template.projects.helpers({
|
||||||
projects: function () {
|
projects: function () {
|
||||||
return ProjectService.list();
|
return ProjectService.list();
|
||||||
}
|
}
|
||||||
@@ -13,10 +13,7 @@ Template.projectForm.events({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var form = event.target;
|
var form = event.target;
|
||||||
if( form.id.value ) {
|
if( form.id.value ) {
|
||||||
Meteor.call('editProject',form.id.value, form.label.value, form.git_url.value, form.public_url.value, form.commands.value, function(errors, result) {
|
Meteor.call('editProject',form.id.value, form.label.value, form.git_url.value, form.public_url.value, form.commands.value);
|
||||||
console.log(errors);
|
|
||||||
console.log(result);
|
|
||||||
});
|
|
||||||
form.id.value = '';
|
form.id.value = '';
|
||||||
} else {
|
} else {
|
||||||
Meteor.call('addProject', form.label.value, form.git_url.value, form.public_url.value, form.commands.value);
|
Meteor.call('addProject', form.label.value, form.git_url.value, form.public_url.value, form.commands.value);
|
||||||
|
|||||||
@@ -3,5 +3,9 @@ Projects = new Mongo.Collection('projects');
|
|||||||
ProjectService = {
|
ProjectService = {
|
||||||
list: function() {
|
list: function() {
|
||||||
return Projects.find({}, {sort: {label: 1}});
|
return Projects.find({}, {sort: {label: 1}});
|
||||||
|
},
|
||||||
|
|
||||||
|
get: function(id) {
|
||||||
|
return Projects.findOne({_id: id});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
<template name="management">
|
<template name="projects">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li class="active">Projects</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<h2>Register or edit a project</h2>
|
<h2>Register or edit a project</h2>
|
||||||
@@ -97,6 +101,9 @@
|
|||||||
<a href="#" class="edit" title="Edit the project">
|
<a href="#" class="edit" title="Edit the project">
|
||||||
<i class="fa fa-fw fa-pencil"></i>
|
<i class="fa fa-fw fa-pencil"></i>
|
||||||
</a>
|
</a>
|
||||||
|
<a href="/project/{{_id}}" title="View project">
|
||||||
|
<i class="fa fa-fw fa-eye"></i>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,32 @@ Router.map(function () {
|
|||||||
this.route('home', {
|
this.route('home', {
|
||||||
path: '/',
|
path: '/',
|
||||||
});
|
});
|
||||||
this.route('management', function() {
|
this.route('projects', {
|
||||||
this.subscribe('projects').wait();
|
waitOn: function() {
|
||||||
|
return Meteor.subscribe('projects');
|
||||||
|
},
|
||||||
|
action: function() {
|
||||||
if (this.ready()) {
|
if (this.ready()) {
|
||||||
this.render();
|
this.render();
|
||||||
} else {
|
} else {
|
||||||
this.render('Loading');
|
this.render('Loading');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.route('project_details', {
|
||||||
|
path: '/project/:_id',
|
||||||
|
waitOn: function() {
|
||||||
|
return [Meteor.subscribe('projects', this.params._id), Meteor.subscribe('deployments', this.params._id)];
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return ProjectService.get(this.params._id);
|
||||||
|
},
|
||||||
|
action: function() {
|
||||||
|
if (this.ready()) {
|
||||||
|
this.render();
|
||||||
|
} else {
|
||||||
|
this.render('Loading');
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
var DEPLOYMENT_FOLDER = 'deployment',
|
DEPLOYMENT_FOLDER = '/home/ubuntu/deployment';
|
||||||
|
|
||||||
SCRIPTS = {
|
SCRIPTS = {
|
||||||
CREATE : [
|
CREATE : [
|
||||||
{
|
{
|
||||||
cmd: 'mkdir %CWD%',
|
cmd: 'mkdir %CWD%',
|
||||||
@@ -8,17 +8,27 @@ var DEPLOYMENT_FOLDER = 'deployment',
|
|||||||
cwd: '%ROOT_CWD%'
|
cwd: '%ROOT_CWD%'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
cmd: 'cd %CWD%',
|
|
||||||
options : {
|
|
||||||
cwd: '%ROOT_CWD%'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
cmd: 'git clone %GIT% .',
|
cmd: 'git clone %GIT% .',
|
||||||
options : {
|
options : {
|
||||||
cwd: '%ROOT_CWD%/%CWD%'
|
cwd: '%ROOT_CWD%/%CWD%'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
UPDATE : [
|
||||||
|
{
|
||||||
|
cmd: 'git pull',
|
||||||
|
options : {
|
||||||
|
cwd: '%ROOT_CWD%/%CWD%'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
DELETE : [
|
||||||
|
{
|
||||||
|
cmd: 'rm -rf %CWD%',
|
||||||
|
options : {
|
||||||
|
cwd: '%ROOT_CWD%'
|
||||||
|
}
|
||||||
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
72
server/jobs/deploy.job.js
Normal file
72
server/jobs/deploy.job.js
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
Job.processJobs('projectDeployerJobQueue', 'create_repository',
|
||||||
|
function(job, callback) {
|
||||||
|
var deployment = DeploymentService.get(job.data.deploymentId),
|
||||||
|
project = ProjectService.get(deployment.project_id);
|
||||||
|
|
||||||
|
DeploymentService.update_status( deployment._id, 'pending', function() {
|
||||||
|
CommandRunner.run(
|
||||||
|
{
|
||||||
|
script: SCRIPTS.CREATE,
|
||||||
|
deployment: deployment,
|
||||||
|
project: project,
|
||||||
|
stdout: function(data) {
|
||||||
|
DeploymentService.appendLog(job.data.deploymentId, data, false);
|
||||||
|
},
|
||||||
|
stderr: function(data) {
|
||||||
|
DeploymentService.appendLog(job.data.deploymentId, data, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
if( callback ) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Job.processJobs('projectDeployerJobQueue', 'delete_repository',
|
||||||
|
function(job, callback) {
|
||||||
|
CommandRunner.run(
|
||||||
|
{
|
||||||
|
script: SCRIPTS.DELETE,
|
||||||
|
project: job.data.project
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
if( callback ) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Job.processJobs('projectDeployerJobQueue', 'update_repository',
|
||||||
|
function(job, callback) {
|
||||||
|
var deployment = DeploymentService.get(job.data.deploymentId),
|
||||||
|
project = ProjectService.get(deployment.project_id);
|
||||||
|
|
||||||
|
DeploymentService.update_status( deployment._id, 'pending', function() {
|
||||||
|
CommandRunner.run(
|
||||||
|
{
|
||||||
|
script: SCRIPTS.UPDATE,
|
||||||
|
deployment: deployment,
|
||||||
|
project: project,
|
||||||
|
stdout: function(data) {
|
||||||
|
DeploymentService.appendLog(job.data.deploymentId, data, false);
|
||||||
|
},
|
||||||
|
stderr: function(data) {
|
||||||
|
DeploymentService.appendLog(job.data.deploymentId, data, true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
if( callback ) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
@@ -1,35 +1,83 @@
|
|||||||
|
|
||||||
var exec = Npm.require('child_process').exec,
|
var exec = Npm.require('child_process').exec,
|
||||||
execSync = function(cmd, options, stdoutHandler, stderrHandler) {
|
execSync = function(cmd, options, stdoutHandler, stderrHandler, callback) {
|
||||||
|
stdoutHandler('$ ' + cmd);
|
||||||
exec(cmd,
|
exec(cmd,
|
||||||
options,
|
options,
|
||||||
Meteor.bindEnvironment(
|
Meteor.bindEnvironment(
|
||||||
function(error, stdout, stderr) {
|
function(error, stdout, stderr) {
|
||||||
if( stdout != '' ) {
|
if( stdout !== '' ) {
|
||||||
stdoutHandler(stdout);
|
stdoutHandler(stdout);
|
||||||
}
|
}
|
||||||
if( stderr != '' ) {
|
if( stderr != '' ) {
|
||||||
stderrHandler(stderr);
|
stderrHandler(stderr);
|
||||||
}
|
}
|
||||||
|
callback();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
},
|
||||||
|
replace = function(string, customs = {}) {
|
||||||
|
var globals = {'%ROOT_CWD%': DEPLOYMENT_FOLDER};
|
||||||
|
for(var key in globals) {
|
||||||
|
string = string.replace(key, globals[key]);
|
||||||
|
}
|
||||||
|
for(var key in customs) {
|
||||||
|
string = string.replace(key, customs[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
};
|
};
|
||||||
|
|
||||||
var CommandRunner = {
|
CommandRunner = {
|
||||||
run: function( script, deployment, stdout, stderr, counter, callback ) {
|
run: function( data, callback = undefined) {
|
||||||
var command = script[command].cmd.replace('%ROOT_CWD%', DEPLOYMENT_FOLDER).replace('%CWD%', deployment._id),
|
var bundle = _.extend({deployment: {}, project:{}, stdout: console.log, stderr: console.error, counter: 0, deploy_script: true}, data),
|
||||||
options = script[command].options;
|
customs = {'%CWD%': bundle.project._id, '%GIT%': bundle.project.git_url};
|
||||||
options.cwd.replace('%ROOT_CWD%', DEPLOYMENT_FOLDER).replace('%CWD%', deployment._id);
|
|
||||||
|
var line = bundle.script[bundle.counter],
|
||||||
|
command = replace(line.cmd, customs ),
|
||||||
|
options = line.options;
|
||||||
|
|
||||||
|
options.cwd = replace(options.cwd, customs);
|
||||||
|
|
||||||
execSync(command, options, stdout, stderr, function() {
|
execSync(command, options, bundle.stdout, bundle.stderr, function() {
|
||||||
counter++;
|
bundle.counter++;
|
||||||
if( counter > script.length ) {
|
if( bundle.counter >= bundle.script.length ) {
|
||||||
if( callback ) {
|
if( bundle.deploy_script && bundle.project.commands ) {
|
||||||
|
bundle.deploy_script = false;
|
||||||
|
bundle.script = bundle.project.commands.split('\n');
|
||||||
|
bundle.counter = 0;
|
||||||
|
CommandRunner.commands(bundle, callback);
|
||||||
|
} else if( callback ) {
|
||||||
|
if( bundle.deployment ) {
|
||||||
|
DeploymentService.update_status(bundle.deployment._id, 'closed', callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CommandRunner.run(bundle, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
commands: function(bundle, callback = undefined) {
|
||||||
|
var command = bundle.script[bundle.counter],
|
||||||
|
customs = {'%CWD%': bundle.project._id},
|
||||||
|
options = {
|
||||||
|
cwd: replace('%ROOT_CWD%/%CWD%', customs)
|
||||||
|
};
|
||||||
|
|
||||||
|
execSync(command, options, bundle.stdout, bundle.stderr, function() {
|
||||||
|
bundle.counter++;
|
||||||
|
if( bundle.counter >= bundle.script.length ) {
|
||||||
|
if( bundle.deployment ) {
|
||||||
|
DeploymentService.update_status(bundle.deployment._id, 'closed', callback);
|
||||||
|
} else {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CommandRunner.run(script, deployment, stdout, stderr, counter, callback);
|
CommandRunner.commands(bundle, callback);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,30 +2,65 @@ Deployments = new Mongo.Collection('deployments');
|
|||||||
|
|
||||||
DeploymentService = {
|
DeploymentService = {
|
||||||
get: function(id) {
|
get: function(id) {
|
||||||
return Deployments.find({_id: id}, {date: 1});
|
return Deployments.findOne({_id: id});
|
||||||
},
|
},
|
||||||
|
|
||||||
appendLog: function(id, data, error) {
|
appendLog: function(id, data, error) {
|
||||||
|
var deployment = DeploymentService.get(id),
|
||||||
|
project = ProjectService.get(deployment.project_id);
|
||||||
|
|
||||||
Deployments.update({ _id: id },{ $push: {
|
Deployments.update({ _id: id },{ $push: {
|
||||||
output: {
|
output: {
|
||||||
timestamp : new Date().getTime(),
|
timestamp : new Date().getTime(),
|
||||||
data : data
|
data : data.replace(new RegExp(project._id, 'g'), project.label),
|
||||||
|
error: error
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
},
|
},
|
||||||
create: function(project, callback) {
|
|
||||||
return Deployment.insert({
|
create: function(project) {
|
||||||
project_id: projet._id,
|
return Deployments.insert({
|
||||||
|
project_id: project._id,
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
output: [],
|
||||||
|
status: 'opened'
|
||||||
|
}, function(errors, deploymentId) {
|
||||||
|
JobService.create_repository(deploymentId);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
delete: function(projectId) {
|
||||||
|
Deployments.remove({project_id: projectId}, function(errors) {
|
||||||
|
if( !errors ) {
|
||||||
|
JobService.delete_repository({_id: projectId});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function(projectId) {
|
||||||
|
Deployments.insert({
|
||||||
|
project_id: projectId,
|
||||||
timestamp: new Date().getTime(),
|
timestamp: new Date().getTime(),
|
||||||
output: []
|
output: []
|
||||||
}, function(errors, deploymentId) {
|
}, function(errors, deploymentId) {
|
||||||
_execSync(cmd, function(data) {
|
JobService.update_repository(deploymentId);
|
||||||
DeploymentService.appendLog(deploymentId, data, false);
|
|
||||||
}, function(data) {
|
|
||||||
DeploymentService.appendLog(deploymentId, data, true);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
update_status: function(id, status, callback) {
|
||||||
|
Deployments.update(
|
||||||
|
id,
|
||||||
|
{ $set: {
|
||||||
|
status: status
|
||||||
|
}
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
list: function(projectId) {
|
||||||
|
return Deployments.find({project_id: projectId}, {sort: {timestamp: -1}});
|
||||||
|
},
|
||||||
|
|
||||||
deploy: function(project) {
|
deploy: function(project) {
|
||||||
|
|
||||||
|
|||||||
51
server/lib/jobs.service.js
Normal file
51
server/lib/jobs.service.js
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
var jobs = JobCollection('projectDeployerJobQueue');
|
||||||
|
jobs.allow({
|
||||||
|
// Grant full permission to any authenticated user
|
||||||
|
admin: function (userId, method, params) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
jobs.startJobServer();
|
||||||
|
|
||||||
|
JobService = {
|
||||||
|
create_repository : function(deploymentId) {
|
||||||
|
Job(jobs, 'create_repository',
|
||||||
|
{
|
||||||
|
deploymentId: deploymentId
|
||||||
|
})
|
||||||
|
.priority('normal')
|
||||||
|
.retry({
|
||||||
|
retries: 5,
|
||||||
|
wait: 10 * 1000
|
||||||
|
})
|
||||||
|
.save();
|
||||||
|
},
|
||||||
|
|
||||||
|
update_repository : function(deploymentId) {
|
||||||
|
Job(jobs, 'update_repository',
|
||||||
|
{
|
||||||
|
deploymentId: deploymentId
|
||||||
|
})
|
||||||
|
.priority('normal')
|
||||||
|
.retry({
|
||||||
|
retries: 5,
|
||||||
|
wait: 10 * 1000
|
||||||
|
})
|
||||||
|
.save();
|
||||||
|
},
|
||||||
|
|
||||||
|
delete_repository: function(project) {
|
||||||
|
Job(jobs, 'delete_repository',
|
||||||
|
{
|
||||||
|
project: project
|
||||||
|
})
|
||||||
|
.priority('normal')
|
||||||
|
.retry({
|
||||||
|
retries: 5,
|
||||||
|
wait: 10 * 1000
|
||||||
|
})
|
||||||
|
.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -10,18 +10,24 @@ Meteor.methods({
|
|||||||
addProject: function(label, git_url, public_url ,commands) {
|
addProject: function(label, git_url, public_url ,commands) {
|
||||||
return ProjectService.insert(label, git_url, public_url ,commands, function(errors, id) {
|
return ProjectService.insert(label, git_url, public_url ,commands, function(errors, id) {
|
||||||
if( id ) {
|
if( id ) {
|
||||||
/*DeploymentService.deploy(ProjectService.get(id), function(errors, deploymentId) {
|
DeploymentService.create(ProjectService.get(id));
|
||||||
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
editProject: function(id, label, git_url, public_url ,commands) {
|
editProject: function(id, label, git_url, public_url ,commands) {
|
||||||
ProjectService.update(id, label, git_url, public_url ,commands);
|
ProjectService.update(id, label, git_url, public_url ,commands, function(errors, updated_count) {
|
||||||
|
if( updated_count ) {
|
||||||
|
DeploymentService.update(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteProject: function(id) {
|
deleteProject: function(id) {
|
||||||
ProjectService.delete(id);
|
ProjectService.delete(id, function(errors) {
|
||||||
|
if( ! errors ) {
|
||||||
|
DeploymentService.delete(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ ProjectService = {
|
|||||||
}, callback);
|
}, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function(id, label, git_url, public_url ,commands) {
|
update: function(id, label, git_url, public_url ,commands, callback) {
|
||||||
Projects.update(
|
Projects.update(
|
||||||
id,
|
id,
|
||||||
{ $set: {
|
{ $set: {
|
||||||
@@ -19,12 +19,13 @@ ProjectService = {
|
|||||||
public_url: public_url,
|
public_url: public_url,
|
||||||
commands: commands
|
commands: commands
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
callback
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
delete: function(id) {
|
delete: function(id, callback) {
|
||||||
Projects.remove(id);
|
Projects.remove(id, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
get: function(id) {
|
get: function(id) {
|
||||||
|
|||||||
@@ -3,5 +3,9 @@ Meteor.publish('projects', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Meteor.publish('deployment', function(id) {
|
Meteor.publish('deployment', function(id) {
|
||||||
return DeploymentService.get(id);
|
return DeploymentService.get(id);
|
||||||
|
});
|
||||||
|
|
||||||
|
Meteor.publish('deployments', function(project_id) {
|
||||||
|
return DeploymentService.list(project_id);
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user