Skip to content

Add a new parameter --projectName to set the project name for docker-compose #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules/*
.idea/*
80 changes: 35 additions & 45 deletions docker-chaos.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,14 @@ var knownOpts = {
"composeFile" : [String],
"plan": [String],
"logPath": [String],
"duration": [Number]
"duration": [Number],
"projectName": [String]
};
var shortHands = {};

var options = nopt(knownOpts, shortHands, process.argv);

var dockerComposeFile, planFile, command, duration;
var dockerComposeFile, planFile, command, duration, project_name;

if (!options.duration) {
options.duration = 30000;
Expand All @@ -61,16 +62,21 @@ try {
}

if (!options.plan) {
console.log("A plan file is needed so we know where to create chaos");
console.log("A plan file is needed so we know how to create chaos");
process.exit(1);
}
if (!options.projectName) {
console.log("A project name is needed so we know where to create chaos");
process.exit(1);
}

planFile = fs.realpathSync(options.plan);
project_name = options.projectName;

//
// Command
//
var command = options.argv.remain[0];
command = options.argv.remain[0];
if (!command) {
console.log("you need to pass the command to be executed");
process.exit(1);
Expand Down Expand Up @@ -102,54 +108,38 @@ console.log();
var planData = fs.readFileSync(planFile);

var chaosPlanFactory = new ChaosPlanFactory();
var chaosPlan = chaosPlanFactory.getChaosPlan(planData);

var exitCode = 0;
var executor = new Executor();

var spinner = new Spinner('Running ... ');

executor.on('start', function() {
spinner.start();
});
executor.on('pass', function() {
console.log(clc.green("Passed"));
spinner.stop();
});
executor.on('fail', function(stdout, stderr) {
exitCode = 1;
console.log(clc.red("Failed"));
if (stdout.length) {
console.log(stdout);
}
if (stderr.length) {
console.log(stderr);
}
spinner.stop();
});
executor.exec(command);
var chaosPlan = chaosPlanFactory.getChaosPlan(planData, project_name);

process.on('beforeExit', function() {
process.exit(exitCode);
});
var chaosPlanExecutor = new ChaosPlanExecutor(dockerComposeFile, chaosPlan);
var testExecutor = new Executor(command);

var dockerLogger = new DockerLogger(logPath);
dockerLogger.start(function() {});

var chaosPlanExecutor = new ChaosPlanExecutor();
chaosPlanExecutor.exec(dockerComposeFile, chaosPlan);
chaosPlanExecutor.on('dockerContainersChanged', function() {
dockerLogger.update(function() {});
});
chaosPlanExecutor.on('error', function(err) {
console.log(err);
process.exit(1);
});
function mainloop(lastStartTime, retryCount) {
if(retryCount === void 0) {
retryCount = 0;
}
console.log("Running tests... Attempt %s", retryCount + 1);
testExecutor.runTests(function(err, result) {
if(err) {
console.log("Tests errored out!", result);
return mainloop(lastStartTime, retryCount + 1);
}
console.log("Test run succeeded! Number of retries: %s. Time until recovery: %s seconds", retryCount, (new Date() - lastStartTime)/1000);
return chaosPlanExecutor.runNextScenario(function(err) {
if (err) {
console.log("Error setting up scenario");
}
mainloop(new Date());
});
})
}

mainloop(new Date());

setTimeout(function() {
console.log("Stopping execution");
executor.stop();
chaosPlanExecutor.stop();
dockerLogger.stop();
process.exit(exitCode);
//process.exit();
}, duration);
49 changes: 15 additions & 34 deletions lib/ChaosPlanExecutor.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,46 +22,27 @@
* THE SOFTWARE.
**/

var util = require('util');
var EventEmitter = require('events').EventEmitter;
var ScenarioExecuter = require('./ScenarioExecutor');
var ScenarioExecutor = require('./ScenarioExecutor');

function ChaosPlanExecutors (scenarioExecuter) {
this.scenarioExecuter = scenarioExecuter || new ScenarioExecuter();
this.stopped = false;
function ChaosPlanExecutors (composeFile, chaosPlan, scenarioExecutor) {
this.composeFile = composeFile;
this.chaosPlan = chaosPlan;
this.scenarioId = 0;

this.scenarioExecutor = scenarioExecutor || new ScenarioExecutor();
}

util.inherits(ChaosPlanExecutors, EventEmitter);

ChaosPlanExecutors.prototype.exec = function(composeFile, chaosPlan) {
var scenarios = chaosPlan.getScenarios();
ChaosPlanExecutors.prototype.runNextScenario = function(callback) {
var scenarios = this.chaosPlan.getScenarios();

var self = this;
var scenario = 0;
function executeScenario(scenario) {
if (scenarios.length === scenario) {
scenario = 0;
}
self.scenarioExecuter.exec(composeFile, scenarios[scenario], function(err) {
if (err) {
self.emit('error', new Error("Failed to execute Scenario: " + err));
return;
}
if (!self.stopped) {
scenario++;
executeScenario(scenario);
}
});
self.scenarioExecuter.on('scaled', function() {
self.emit('dockerContainersChanged');
});
if (this.scenarioId >= scenarios.length) {
this.scenarioId = 0;
}

executeScenario(scenario);
};

ChaosPlanExecutors.prototype.stop = function() {
this.stopped = true;
var scenario = scenarios[this.scenarioId];
console.log("Starting scenario %s", scenario);
this.scenarioExecutor.exec(this.composeFile, scenario, callback);
this.scenarioId ++;
};

module.exports = ChaosPlanExecutors;
4 changes: 2 additions & 2 deletions lib/ChaosPlanFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ function ChaosPlanFactory (yamlInj, scenariosFactory) {
this.scenarios = scenariosFactory || new ScenariosFactory();
}

ChaosPlanFactory.prototype.getChaosPlan = function(chaosPlanData) {
ChaosPlanFactory.prototype.getChaosPlan = function(chaosPlanData, project_name) {
var yaml = this.yaml.safeLoad(chaosPlanData);

var chaosPlan = new ChaosPlan();
chaosPlan.setName(yaml.name);

var scenarios = this.scenarios.getScenarios(yaml.scenarios);
var scenarios = this.scenarios.getScenarios(yaml.scenarios, project_name);
chaosPlan.setScenarios(scenarios);

return chaosPlan;
Expand Down
4 changes: 2 additions & 2 deletions lib/Docker.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function Docker (exec) {
this.exec = exec || require("child_process").exec;
}

Docker.prototype.modify = function(composeFile, modifications, callback) {
Docker.prototype.modify = function(composeFile, modifications, project_name, callback) {
var containers = "";
var name, amount;
modifications.forEach(function (value) {
Expand All @@ -37,7 +37,7 @@ Docker.prototype.modify = function(composeFile, modifications, callback) {
containers += name + "=" + amount + " ";
});

var command = "docker-compose --file " + composeFile + " scale " + containers;
var command = "docker-compose --file " + composeFile + " --project-name " + project_name + " scale " + containers;
this.exec(command, function(code, stdout, stderr) {
if (code !== null) {
callback(code, stdout, stderr);
Expand Down
31 changes: 5 additions & 26 deletions lib/Executor.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,37 +22,16 @@
* THE SOFTWARE.
**/

var util = require("util");
var events = require("events");

function Executor (exec) {
function Executor (script, exec) {
this.script = script;
this.execImpl = exec || require('child_process').exec;
this.stopped = false;
}

util.inherits(Executor, events.EventEmitter);

Executor.prototype.exec = function(script) {
if (this.stopped) {
return;
}

this.stopped = false;

var self = this;
self.emit('start');
this.execImpl(script, function(error, stdout, stderr) {
if (error !== null) {
self.emit('fail', stdout, stderr);
} else {
self.emit('pass');
}
self.exec(script);
Executor.prototype.runTests = function(callback) {
this.execImpl(this.script, function(err, stdout, stderr) {
callback(err, stdout + stderr);
});
};

Executor.prototype.stop = function() {
this.stopped = true;
};

module.exports = Executor;
19 changes: 10 additions & 9 deletions lib/Scaler.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,18 @@ function Scaler (implementation, random) {
this.random = random || function(){return Math.floor(Math.random() * (max - min + 1)) + min}
}

Scaler.prototype.restore = function(file, containers, callback) {
var name;
containers.forEach(function (value) {
name = Object.keys(value)[0];
value[name] = 1;
Scaler.prototype.restore = function(file, containers, project_name, callback) {
var restoreContainers = containers.map(function (value) {
var containerName = Object.keys(value)[0];
var obj ={};
obj[containerName] = 1;
return obj;
});

this.implementation.modify(file, containers, callback);
}
this.implementation.modify(file, restoreContainers, project_name, callback);
};

Scaler.prototype.scale = function(file, containers, callback) {
Scaler.prototype.scale = function(file, containers, project_name, callback) {
var self = this;
containers.forEach(function (value) {
name = Object.keys(value)[0];
Expand All @@ -51,7 +52,7 @@ Scaler.prototype.scale = function(file, containers, callback) {
}
});

this.implementation.modify(file, containers, callback);
this.implementation.modify(file, containers, project_name, callback);
};


Expand Down
12 changes: 12 additions & 0 deletions lib/Scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ Scenario.prototype.getContainers = function() {
return this.containers;
};

Scenario.prototype.setProjectName = function(project_name) {
this.project_name = project_name;
};

Scenario.prototype.getProjectName = function() {
return this.project_name;
};

Scenario.prototype.toString = function() {
return "[Scenario " + this.getName() + "]";
};

module.exports = Scenario;


Expand Down
14 changes: 7 additions & 7 deletions lib/ScenarioExecutor.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,21 @@ util.inherits(ScenarioExecutor, EventEmitter);

ScenarioExecutor.prototype.exec = function(composeFile, scenario, callback) {
var containers = scenario.getContainers();
var project_name = scenario.getProjectName();

var self = this;
this.scaler.scale(composeFile, containers, function (err){
this.scaler.scale(composeFile, containers, project_name, function (err){
if (err) {
callback(err);
return;
}
self.emit('scaled', scenario);

self.timeout(function() {
self.emit('beforeRestore', scenario);
self.scaler.restore(composeFile, containers, function() {
callback();
});
}, self.restoreTime);
self.emit('beforeRestore', scenario);
self.scaler.restore(composeFile, containers, project_name, function() {
console.log("Restored containers!");
callback();
});
});
};

Expand Down
4 changes: 2 additions & 2 deletions lib/ScenariosFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ var Scenario = require('./Scenario');
function ScenariosFactory () {
}

ScenariosFactory.prototype.getScenarios = function(scenariosData) {
ScenariosFactory.prototype.getScenarios = function(scenariosData, project_name) {
var scenarios = [];
var scenario, name;
scenariosData.forEach(function (value) {
Expand All @@ -37,7 +37,7 @@ ScenariosFactory.prototype.getScenarios = function(scenariosData) {

var scena = value[name];
scenario.setContainers(scena.containers);

scenario.setProjectName(project_name);
scenarios.push(scenario);
});

Expand Down