diff --git a/lib/cli.js b/lib/cli.js index c41f96a..f9e016d 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -70,6 +70,7 @@ function CLI() { 'start-instance', 'stop-instance', 'reboot-instance', + 'delete-instance', 'ssh', { group: 'Images' }, 'images', @@ -128,6 +129,7 @@ CLI.prototype.do_instance_audit = require('./do_instance_audit'); CLI.prototype.do_stop_instance = require('./do_startstop_instance')('stop'); CLI.prototype.do_start_instance = require('./do_startstop_instance')('start'); CLI.prototype.do_reboot_instance = require('./do_startstop_instance')('reboot'); +CLI.prototype.do_delete_instance = require('./do_delete_instance'); CLI.prototype.do_ssh = require('./do_ssh'); // Packages diff --git a/lib/cloudapi2.js b/lib/cloudapi2.js index 7a4e94e..2fc7b46 100644 --- a/lib/cloudapi2.js +++ b/lib/cloudapi2.js @@ -214,6 +214,9 @@ CloudAPI.prototype._request = function _request(options, callback) { var method = (options.method || 'GET').toLowerCase(); assert.ok(['get', 'post', 'delete', 'head'].indexOf(method) >= 0, 'invalid method given'); + switch (method) { + case 'delete': method = 'del'; break; + } self._getAuthHeaders(function (err, headers) { if (err) { callback(err); @@ -366,6 +369,26 @@ CloudAPI.prototype.getMachine = function getMachine(uuid, callback) { }); }; +/** + * delete a machine by id. + * + * @param {String} uuid (required) The machine id. + * @param {Function} callback of the form `function (err, machine, response)` + */ +CloudAPI.prototype.deleteMachine = function deleteMachine(uuid, callback) { + var self = this; + assert.string(uuid, 'uuid'); + assert.func(callback, 'callback'); + + var opts = { + path: sprintf('/%s/machines/%s', self.user, uuid), + method: 'DELETE' + }; + this._request(opts, function (err, req, res, body) { + callback(err, body, res); + }); +}; + /** * start a machine by id. * @@ -438,13 +461,13 @@ CloudAPI.prototype.waitForMachineStates = function waitForMachineStates(opts, ca poll(); function poll() { - self.getMachine(opts.id, function (err, machine) { + self.getMachine(opts.id, function (err, machine, res) { if (err) { - callback(err); + callback(err, null, res); return; } if (opts.states.indexOf(machine.state) !== -1) { - callback(null, machine); + callback(null, machine, res); return; } setTimeout(poll, interval); diff --git a/lib/do_delete_instance.js b/lib/do_delete_instance.js new file mode 100644 index 0000000..464d7e5 --- /dev/null +++ b/lib/do_delete_instance.js @@ -0,0 +1,92 @@ +/* + * Copyright 2015 Joyent Inc. + * + * `triton delete ...` + */ + +var common = require('./common'); + +function do_delete_instance(subcmd, opts, args, callback) { + var self = this; + + if (opts.help) { + this.do_help('help', {}, [subcmd], callback); + return; + } else if (args.length !== 1) { + callback(new Error('invalid args: ' + args)); + return; + } + + var arg = args[0]; + var uuid; + + if (common.isUUID(arg)) { + uuid = arg; + go1(); + } else { + self.triton.getMachineByAlias(arg, function (err, machine) { + if (err) { + callback(err); + return; + } + uuid = machine.id; + go1(); + }); + } + + function go1() { + // called when "uuid" is set + self.triton.cloudapi.deleteMachine(uuid, function (err, body, res) { + if (err) { + callback(err); + return; + } + + if (!opts.wait) { + callback(); + return; + } + + self.triton.cloudapi.waitForMachineStates({ + id: uuid, + states: ['deleted'] + }, function (err, machine, res) { + if (res && res.statusCode === 410) { + // gone... success! + callback(); + return; + } else if (err) { + callback(err); + return; + } + callback(); + }); + }); + } +} + +do_delete_instance.aliases = ['delete']; + +do_delete_instance.help = [ + 'delete a single instance.', + '', + 'Usage:', + ' {{name}} delete ', + '', + '{{options}}' +]; +do_delete_instance.options = [ + { + names: ['help', 'h'], + type: 'bool', + help: 'Show this help.' + }, + { + names: ['wait', 'w'], + type: 'bool', + help: 'Wait for machine to be deleted.' + } +]; + + +module.exports = do_delete_instance;