joyent/node-triton#26 triton command crashes with self-signed cert
Refactor do_instances to not call `callback` twice. Also don't assume if a `res` on an error callback from CloudApi._request. Fixes #26.
This commit is contained in:
parent
7aa59f148f
commit
c93b08dd68
@ -342,6 +342,7 @@ CloudApi.prototype.listKeys = function listKeys(opts, cb) {
|
|||||||
* <http://apidocs.joyent.com/cloudapi/#ListImages>
|
* <http://apidocs.joyent.com/cloudapi/#ListImages>
|
||||||
*
|
*
|
||||||
* @param {Object} options (optional)
|
* @param {Object} options (optional)
|
||||||
|
* XXX be more strict about accepted options
|
||||||
* XXX document this, see the api doc above :)
|
* XXX document this, see the api doc above :)
|
||||||
* @param {Function} callback of the form `function (err, images, res)`
|
* @param {Function} callback of the form `function (err, images, res)`
|
||||||
*/
|
*/
|
||||||
@ -553,9 +554,12 @@ function createListMachinesStream(options) {
|
|||||||
var endpoint = self._path(format('/%s/machines', self.user), options);
|
var endpoint = self._path(format('/%s/machines', self.user), options);
|
||||||
|
|
||||||
self._request(endpoint, function (err, req, res, body) {
|
self._request(endpoint, function (err, req, res, body) {
|
||||||
|
if (err) {
|
||||||
|
return donecb(err);
|
||||||
|
}
|
||||||
var resourcecount = res.headers['x-resource-count'];
|
var resourcecount = res.headers['x-resource-count'];
|
||||||
var done = once || resourcecount < options.limit;
|
var done = once || resourcecount < options.limit;
|
||||||
donecb(err, {done: done, results: body});
|
donecb(null, {done: done, results: body});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -10,12 +10,14 @@
|
|||||||
* `triton instances ...`
|
* `triton instances ...`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var f = require('util').format;
|
var format = require('util').format;
|
||||||
|
|
||||||
var tabula = require('tabula');
|
var tabula = require('tabula');
|
||||||
|
var vasync = require('vasync');
|
||||||
|
|
||||||
var common = require('./common');
|
var common = require('./common');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// to be passed as query string args to /my/machines
|
// to be passed as query string args to /my/machines
|
||||||
var validFilters = [
|
var validFilters = [
|
||||||
'name',
|
'name',
|
||||||
@ -36,6 +38,7 @@ var columnsDefaultLong = 'id,name,img,package,state,primaryIp,created';
|
|||||||
var sortDefault = 'created';
|
var sortDefault = 'created';
|
||||||
|
|
||||||
function do_instances(subcmd, opts, args, callback) {
|
function do_instances(subcmd, opts, args, callback) {
|
||||||
|
var self = this;
|
||||||
if (opts.help) {
|
if (opts.help) {
|
||||||
this.do_help('help', {}, [subcmd], callback);
|
this.do_help('help', {}, [subcmd], callback);
|
||||||
return;
|
return;
|
||||||
@ -59,55 +62,64 @@ function do_instances(subcmd, opts, args, callback) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
i++;
|
var imgs;
|
||||||
var images;
|
var insts;
|
||||||
this.tritonapi.listImages({useCache: true}, function (err, _images) {
|
|
||||||
|
vasync.parallel({funcs: [
|
||||||
|
function getTheImages(next) {
|
||||||
|
self.tritonapi.listImages({useCache: true}, function (err, _imgs) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
next(err);
|
||||||
return;
|
} else {
|
||||||
|
imgs = _imgs;
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
images = _images;
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
},
|
||||||
i++;
|
function getTheMachines(next) {
|
||||||
var machines;
|
self.tritonapi.cloudapi.listMachines(listOpts,
|
||||||
this.tritonapi.cloudapi.listMachines(listOpts, function (err, _machines) {
|
function (err, _insts) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
next(err);
|
||||||
return;
|
} else {
|
||||||
|
insts = _insts;
|
||||||
|
next();
|
||||||
}
|
}
|
||||||
machines = _machines;
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
function done() {
|
]}, function (err, results) {
|
||||||
if (--i > 0)
|
/*
|
||||||
return;
|
* Error handling: vasync.parallel's `err` is always a MultiError. We
|
||||||
|
* want to prefer the `getTheMachines` err, e.g. if both get a
|
||||||
|
* self-signed cert error.
|
||||||
|
*/
|
||||||
|
if (err) {
|
||||||
|
err = results.operations[1].err || err;
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
|
||||||
// map "uuid" => "image_name"
|
// map "uuid" => "image_name"
|
||||||
var imgmap = {};
|
var imgmap = {};
|
||||||
images.forEach(function (image) {
|
imgs.forEach(function (img) {
|
||||||
imgmap[image.id] = f('%s@%s', image.name, image.version);
|
imgmap[img.id] = format('%s@%s', img.name, img.version);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add extra fields for nice output.
|
// Add extra fields for nice output.
|
||||||
// XXX FWIW, the "extra fields" for images and packages are not added
|
// XXX FWIW, the "extra fields" for images and packages are not added
|
||||||
// for `opts.json`. Thoughts? We should be consistent there. --TM
|
// for `opts.json`. Thoughts? We should be consistent there. --TM
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
machines.forEach(function (machine) {
|
insts.forEach(function (inst) {
|
||||||
var created = new Date(machine.created);
|
var created = new Date(inst.created);
|
||||||
machine.ago = common.longAgo(created, now);
|
inst.ago = common.longAgo(created, now);
|
||||||
machine.img = imgmap[machine.image] || machine.image;
|
inst.img = imgmap[inst.image] || inst.image;
|
||||||
machine.shortid = machine.id.split('-', 1)[0];
|
inst.shortid = inst.id.split('-', 1)[0];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (opts.json) {
|
if (opts.json) {
|
||||||
common.jsonStream(machines);
|
common.jsonStream(insts);
|
||||||
} else {
|
} else {
|
||||||
tabula(machines, {
|
tabula(insts, {
|
||||||
skipHeader: opts.H,
|
skipHeader: opts.H,
|
||||||
columns: columns,
|
columns: columns,
|
||||||
sort: sort,
|
sort: sort,
|
||||||
@ -115,7 +127,7 @@ function do_instances(subcmd, opts, args, callback) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
callback();
|
callback();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
do_instances.options = [
|
do_instances.options = [
|
||||||
|
Reference in New Issue
Block a user