Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Started lib rewriting.

  • Loading branch information...
commit 890eb4c1d8a413640f87d7047b29a75fac4daf24 1 parent 1676906
@cliffano authored
View
1  CHANGELOG.md
@@ -1,4 +1,5 @@
### 0.0.3
+* Rewrite lib
### 0.0.2
* Add Jenkins discovery feature
View
120 bin/nestor
@@ -1,120 +1,4 @@
#!/usr/bin/env node
-var DEFAULT_URL = 'http://localhost:8080',
- fs = require('fs'),
- nomnom = require('nomnom'),
- path = require('path'),
- Nestor = require('../lib/nestor').Nestor,
- Service = require('../lib/service').Service,
- service = new Service(process.env.JENKINS_URL || DEFAULT_URL),
- nestor = new Nestor(service, function (err) {
- console.error(err.message);
- }),
- args, scriptOpts;
-
-scriptOpts = {
- version: {
- string: '-v',
- flag: true,
- help: 'nestor version number',
- callback: function () {
- return JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json'))).version;
- }
- }
-}
-
-nomnom.scriptName('nestor').opts(scriptOpts);
-nomnom.command('dashboard').callback(function (args) {
- nestor.dashboard(function (err, result) {
- if (err) {
- console.error(err.message);
- } else if (result.length === 0) {
- console.log('Jobless Jenkins');
- } else {
- result.forEach(function (job) {
- console.log(job.status + '\t' + job.name);
- });
- }
- });
-});
-nomnom.command('job')
- .opts({
- jobnames: { position: 1, required: true, list: true }
- })
- .callback(function (args) {
- args.jobnames.forEach(function (jobname) {
- nestor.job(jobname, function (err, result) {
- if (err) {
- console.error(jobname + ' - ' + err.message);
- } else {
- console.log(jobname + ' - ' + 'Status: ' + result.status);
- result.reports.forEach(function (report) {
- console.log(jobname + ' - ' + report);
- });
- }
- });
- });
- });
-nomnom.command('build').callback(function (args) {
- nestor.build(args._[1], args._[2], function (err, result) {
- if (err) {
- console.error(err.message);
- } else {
- console.log('Job was started successfully');
- }
- });
-});
-nomnom.command('queue').callback(function (args) {
- nestor.queue(function (err, result) {
- if (err) {
- console.error(err.message);
- } else {
- if (result.length === 0) {
- console.log('Queue is empty');
- } else {
- result.forEach(function (build) {
- console.log(build);
- });
- }
- }
- });
-});
-nomnom.command('executor').callback(function (args) {
- nestor.executor(function (err, result) {
- if (err) {
- console.error(err.message);
- } else {
- for (computer in result) {
- if (result.hasOwnProperty(computer)) {
- console.log('* ' + computer);
- result[computer].forEach(function (executor) {
- if (executor.idle) {
- console.log('idle');
- } else {
- console.log(executor.progress + '%\t' + executor.name);
- }
- });
- }
- }
- }
- });
-});
-nomnom.command('discover').callback(function (args) {
- nestor.discover(args._[1], function (err, result) {
- if (err) {
- console.error(err.message);
- } else {
- console.log('Jenkins ' + result.version + ' running at ' + result.url);
- }
- });
-});
-nomnom.command('version').callback(function (args) {
- nestor.version(function (err, result) {
- if (err) {
- console.error(err.message);
- } else {
- console.log(result);
- }
- });
-});
-nomnom.parseArgs();
+var cli = require('../lib/cli');
+cli.exec();
View
194 lib/cli.js
@@ -0,0 +1,194 @@
+var Jenkins = require('./jenkins').Jenkins,
+ nomnom = require('nomnom'),
+ url = require('url')
+ jenkins = new Jenkins(url.parse(process.env.JENKINS_URL || 'http://localhost:8080'));
+
+function exec() {
+
+ var scriptOpts = {
+ version: {
+ string: '-v',
+ flag: true,
+ help: 'AE86 version number',
+ callback: function () {
+ return JSON.parse(fs.readFileSync(p.join(__dirname, '../package.json'))).version;
+ }
+ }
+ };
+
+ nomnom.scriptName('nestor').opts(scriptOpts);
+
+ nomnom.command('build').callback(function (args) {
+ jenkins.build(args._[1], args._[2], function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.command('dashboard').callback(function (args) {
+ jenkins.dashboard(function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.command('discover').callback(function (args) {
+ jenkins.discover(args._[1] || 'localhost', function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.command('executor').callback(function (args) {
+ jenkins.executor(function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.command('job').callback(function (args) {
+ jenkins.job(args._[1], function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.command('queue').callback(function (args) {
+ jenkins.queue(function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.command('version').callback(function (args) {
+ jenkins.version(function (err, result) {
+ console.error("ERR" + err)
+ console.log("RESULT" + require('util').inspect(result))
+ });
+ });
+
+ nomnom.parseArgs();
+}
+
+exports.exec = exec;
+
+/*
+var DEFAULT_URL = 'http://localhost:8080',
+ fs = require('fs'),
+ nomnom = require('nomnom'),
+ path = require('path'),
+ Nestor = require('../lib/nestor').Nestor,
+ Service = require('../lib/service').Service,
+ service = new Service(process.env.JENKINS_URL || DEFAULT_URL),
+ nestor = new Nestor(service, function (err) {
+ console.error(err.message);
+ }),
+ args, scriptOpts;
+
+scriptOpts = {
+ version: {
+ string: '-v',
+ flag: true,
+ help: 'nestor version number',
+ callback: function () {
+ return JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json'))).version;
+ }
+ }
+}
+
+nomnom.scriptName('nestor').opts(scriptOpts);
+nomnom.command('dashboard').callback(function (args) {
+ nestor.dashboard(function (err, result) {
+ if (err) {
+ console.error(err.message);
+ } else if (result.length === 0) {
+ console.log('Jobless Jenkins');
+ } else {
+ result.forEach(function (job) {
+ console.log(job.status + '\t' + job.name);
+ });
+ }
+ });
+});
+nomnom.command('job')
+ .opts({
+ jobnames: { position: 1, required: true, list: true }
+ })
+ .callback(function (args) {
+ args.jobnames.forEach(function (jobname) {
+ nestor.job(jobname, function (err, result) {
+ if (err) {
+ console.error(jobname + ' - ' + err.message);
+ } else {
+ console.log(jobname + ' - ' + 'Status: ' + result.status);
+ result.reports.forEach(function (report) {
+ console.log(jobname + ' - ' + report);
+ });
+ }
+ });
+ });
+ });
+nomnom.command('build').callback(function (args) {
+ nestor.build(args._[1], args._[2], function (err, result) {
+ if (err) {
+ console.error(err.message);
+ } else {
+ console.log('Job was started successfully');
+ }
+ });
+});
+nomnom.command('queue').callback(function (args) {
+ nestor.queue(function (err, result) {
+ if (err) {
+ console.error(err.message);
+ } else {
+ if (result.length === 0) {
+ console.log('Queue is empty');
+ } else {
+ result.forEach(function (build) {
+ console.log(build);
+ });
+ }
+ }
+ });
+});
+nomnom.command('executor').callback(function (args) {
+ nestor.executor(function (err, result) {
+ if (err) {
+ console.error(err.message);
+ } else {
+ for (computer in result) {
+ if (result.hasOwnProperty(computer)) {
+ console.log('* ' + computer);
+ result[computer].forEach(function (executor) {
+ if (executor.idle) {
+ console.log('idle');
+ } else {
+ console.log(executor.progress + '%\t' + executor.name);
+ }
+ });
+ }
+ }
+ }
+ });
+});
+nomnom.command('discover').callback(function (args) {
+ nestor.discover(args._[1], function (err, result) {
+ if (err) {
+ console.error(err.message);
+ } else {
+ console.log('Jenkins ' + result.version + ' running at ' + result.url);
+ }
+ });
+});
+nomnom.command('version').callback(function (args) {
+ nestor.version(function (err, result) {
+ if (err) {
+ console.error(err.message);
+ } else {
+ console.log(result);
+ }
+ });
+});
+nomnom.parseArgs();
+*/
View
64 lib/comm.js
@@ -0,0 +1,64 @@
+var dgram = require('dgram'),
+ _http = require('http'),
+ xml2js = require('xml2js');
+
+function http(path, method, url, cb) {
+ var req = _http.request({
+ path: path,
+ method: method,
+ host: url.hostname,
+ port: url.port,
+ headers: (url.auth)
+ ? { 'Authorization': 'Basic ' + new Buffer(url.auth).toString('base64') }
+ : null
+ }, function (res) {
+ var data = '';
+ res.setEncoding('utf8');
+ res.on('data', function (chunk) {
+ data += chunk;
+ });
+ res.on('end', function () {
+ console.log('statusCode: ' + res.statusCode);
+ //console.log('headers: ' + JSON.stringify(res.headers));
+ console.log('data: ' + data);
+ cb(null, {
+ statusCode: res.statusCode,
+ headers: res.headers,
+ data: data
+ });
+ });
+ });
+ req.on('error', function (err) {
+ cb(err);
+ });
+ req.end();
+}
+
+function udp(message, host, port, cb) {
+ var socket = dgram.createSocket('udp4'),
+ buffer = new Buffer(message),
+ parser = new xml2js.Parser();
+
+ socket.on('error', function (err) {
+ socket.close();
+ cb(err);
+ });
+
+ socket.on('message', function (data) {
+ socket.close();
+ parser.addListener('end', function (data) {
+ cb(null, data);
+ });
+ parser.parseString(data);
+ });
+
+ socket.send(buffer, 0, buffer.length, port, host, function (err, result) {
+ if (err) {
+ socket.close();
+ cb(err);
+ }
+ });
+}
+
+exports.http = http;
+exports.udp = udp;
View
150 lib/jenkins.js
@@ -0,0 +1,150 @@
+var _ = require('underscore'),
+ comm = require('./comm');
+
+function Jenkins(url) {
+
+ var status = {
+ 'blue': 'OK',
+ 'green': 'OK',
+ 'grey': 'ABORT',
+ 'red': 'FAIL',
+ 'yellow': 'WARN'
+ };
+
+ function _cb(opts, cb) {
+ return function (err, result) {
+ if (err) {
+ cb(err);
+ } else if (result.statusCode === 401 || result.statusCode === 403) {
+ cb(new Error('Username and password are required'))
+ } else {
+ var fn;
+ _.keys(opts).forEach(function (opt) {
+ if ((opt === 'ok' && !result.statusCode.toString().match(/^(4|5)/)) ||
+ (parseInt(opt, 10) === result.statusCode)) {
+ fn = opts[opt];
+ }
+ });
+ if (fn) {
+ try {
+ cb(null, fn(result));
+ } catch (e) {
+ cb(e);
+ }
+ } else {
+ cb(new Error('Unexpected status code ' + result.statusCode));
+ }
+ }
+ };
+ }
+
+ function build(job, params, cb) {
+ var json = { parameter: [] };
+ if (params) {
+ params.split('&').forEach(function (item) {
+ var pair = item.split('=');
+ json.parameter.push({ name: pair[0], value: pair[1] });
+ });
+ }
+ comm.http('/job/' + job + '/build?token=nestor&json=' + JSON.stringify(json), 'POST', url, _cb({
+ 404: function (result) {
+ throw new Error('Job does not exist');
+ },
+ 'ok': function (result) {
+ return { status: 'ok' };
+ }
+ }, cb));
+ }
+
+ function dashboard(cb) {
+ comm.http('/api/json', 'GET', url, _cb({
+ 'ok': function (result) {
+ var jobs = JSON.parse(result.data).jobs, data = [];
+ if (jobs && jobs.length > 0) {
+ jobs.forEach(function (job) {
+ data.push({ status: status[job.color], name: job.name });
+ });
+ }
+ return data;
+ }
+ }, cb));
+ }
+
+ // discover expects host because it's meant to find a jenkins
+ // instance on any host, not just localhost
+ function discover(host, cb) {
+ comm.udp('Long live Jenkins', host, 33848, cb);
+ }
+
+ function executor(cb) {
+ comm.http('/computer/api/json?depth=1', 'GET', url, _cb({
+ 'ok': function (result) {
+ var computers = JSON.parse(result.data).computer, data = {};
+ computers.forEach(function (computer) {
+ data[computer.displayName] = [];
+ computer.executors.forEach(function (executor) {
+ data[computer.displayName].push({
+ idle: executor.idle,
+ progress: executor.progress,
+ name: (!executor.idle) ? executor.currentExecutable.url.replace(/.*\/job\//, '').replace(/\/.*/, '') : ''
+ });
+ });
+ });
+ return data;
+ }
+ }, cb));
+ }
+
+ function job(job, cb) {
+ comm.http('/job/' + job + '/api/json', 'GET', url, _cb({
+ 404: function (result) {
+ throw new Error('Job does not exist');
+ },
+ 'ok': function (result) {
+ var json = JSON.parse(result.data), data = {};
+ data.status = status[json.color];
+ data.reports = [];
+ json.healthReport.forEach(function (report) {
+ data.reports.push(report.description);
+ });
+ return data;
+ }
+ }, cb));
+ }
+
+ function queue(cb) {
+ comm.http('/queue/api/json', 'GET', url, _cb({
+ 'ok': function (result) {
+ var items = JSON.parse(result.data).items, data = [];
+ if (items && items.length > 0) {
+ items.forEach(function (item) {
+ data.push(item.task.name);
+ });
+ }
+ return data;
+ }
+ }, cb));
+ }
+
+ function version(cb) {
+ comm.http('/', 'HEAD', url, _cb({
+ 'ok': function (result) {
+ return (result.headers['x-jenkins'])
+ ? result.headers['x-jenkins']
+ : new Error('Not a Jenkins server');
+ }
+ }, cb));
+ }
+
+ return {
+ build: build,
+ dashboard: dashboard,
+ discover: discover,
+ executor: executor,
+ job: job,
+ queue: queue,
+ version: version
+ };
+}
+
+exports.Jenkins = Jenkins;
View
1  package.json
@@ -29,6 +29,7 @@
},
"dependencies": {
"nomnom": "1.5.1",
+ "underscore": "1.2.3",
"xml2js": "0.1.9"
},
"devDependencies": {
View
2  test/nestor.js
@@ -437,4 +437,4 @@ vows.describe('Nestor').addBatch({
assert.isUndefined(_result);
}
}
-}).export(module);
+}).export(module);
Please sign in to comment.
Something went wrong with that request. Please try again.