diff --git a/lib/cli.js b/lib/cli.js
index b659650..21a8891 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -48,13 +48,24 @@ function CLI() {
{name: 'version', type: 'bool', help: 'Print version and exit.'},
{names: ['verbose', 'v'], type: 'bool',
help: 'Verbose/debug output.'},
- {names: ['profile', 'p'], type: 'string', env: 'SMRT_PROFILE',
- helpArg: 'NAME', help: 'SMRT Profile to use.'}
+ // XXX disable profile selection for now
+ //{names: ['profile', 'p'], type: 'string', env: 'TRITON_PROFILE',
+ // helpArg: 'NAME', help: 'Triton client profile to use.'}
],
helpOpts: {
includeEnv: true,
minHelpCol: 23 /* line up with option help */
- }
+ },
+ helpSubcmds: [
+ 'help',
+ { group: 'VMs/Machines/Containers' },
+ 'create',
+ 'vms',
+ 'vm-audit',
+ { group: 'Images' },
+ 'images',
+ { group: 'Other', unmatched: true }
+ ]
});
}
util.inherits(CLI, Cmdln);
@@ -84,240 +95,21 @@ CLI.prototype.init = function (opts, args, callback) {
Cmdln.prototype.init.apply(this, arguments);
};
-CLI.prototype.do_foo = function do_foo(subcmd, opts, args, callback) {
- console.log('XXX', subcmd, opts, args);
-
- this.triton.cloudapi.getAccount(function (err, body, res) {
- console.log('XXX getAccount', err);
- console.log('XXX getAccount', body);
- callback();
- });
-};
+//CLI.prototype.do_profile = require('./do_profile');
-CLI.prototype.do_profile = require('./do_profile');
+// Images
CLI.prototype.do_images = require('./do_images');
-
-
-CLI.prototype.do_provision = function (subcmd, opts, args, callback) {
- if (opts.help) {
- this.do_help('help', {}, [subcmd], callback);
- return;
- } else if (args.length > 1) {
- return callback(new Error('too many args: ' + args));
- }
- var sdc = this.sdc;
-
- assert.string(opts.image, '--image ');
- assert.string(opts['package'], '--package ');
- assert.number(opts.count)
-
- // XXX
- /*
- * Should all this move into sdc.createMachine? yes
- *
- * - lookup image, package, networks from args
- * - assign names
- * - start provisions (slight stagger, max N at a time)
- * - return immediately, or '-w|--wait'
- */
- async.series([
- function lookups(next) {
- async.parallel([
- //XXX
- //sdc.lookup(image)
- ])
- },
- function provisions(next) {
-
- },
- function wait(next) {
- next();
- }
- ], function (err) {
- callback(err);
- });
-};
-CLI.prototype.do_provision.options = [
- {
- names: ['help', 'h'],
- type: 'bool',
- help: 'Show this help.'
- },
- {
- names: ['dc', 'd'],
- type: 'string',
- helpArg: '',
- help: 'The datacenter in which to provision. Required if the current'
- + ' profile includes more than one datacenter. Use `sdc profile`'
- + ' to list profiles and `sdc dcs` to list available datacenters.'
- },
- {
- names: ['image', 'i'],
- type: 'string',
- helpArg: '',
- help: 'The machine image with which to provision. Required.'
- },
- {
- names: ['package', 'p'],
- type: 'string',
- helpArg: '',
- help: 'The package or instance type for the new machine(s). Required.'
- },
- {
- names: ['name', 'n'],
- type: 'string',
- helpArg: '',
- help: 'A name for the machine. If not specified, a short random name'
- + ' will be generated.',
- // TODO: for count>1 support '%d' code in name: foo0, foo1, ...
- },
- {
- names: ['count', 'c'],
- type: 'positiveInteger',
- 'default': 1,
- helpArg: '',
- help: 'The number of machines to provision. Default is 1.'
- },
-];
-CLI.prototype.do_provision.help = (
- 'Provision a new virtual machine instance.\n'
- + 'Alias: create-machine.\n'
- + '\n'
- + 'Usage:\n'
- + ' {{name}} provision \n'
- + '\n'
- + '{{options}}'
-);
-
-
-CLI.prototype.do_machines = function (subcmd, opts, args, callback) {
- var self = this;
- if (opts.help) {
- this.do_help('help', {}, [subcmd], callback);
- return;
- } else if (args.length > 1) {
- return callback(new Error('too many args: ' + args));
- }
-
- var machines = [];
- var errs = [];
- var res = this.sdc.listMachines();
- res.on('data', function (dc, dcMachines) {
- for (var i = 0; i < dcMachines.length; i++) {
- dcMachines[i].dc = dc;
- machines.push(dcMachines[i]);
- }
- });
- res.on('dcError', function (dc, dcErr) {
- dcErr.dc = dc;
- errs.push(dcErr);
- });
- res.on('end', function () {
- if (opts.json) {
- p(JSON.stringify(machines, null, 4));
- } else {
- /* BEGIN JSSTYLED */
- // TODO: get short output down to something like
- // 'us-west-1 e91897cf testforyunong2 linux running 2013-11-08'
- // 'us-west-1 e91897cf testforyunong2 ubuntu/13.3.0 running 2013-11-08'
- /* END JSSTYLED */
- common.tabulate(machines, {
- columns: 'dc,id,name,image,state,created',
- sort: 'created',
- validFields: 'dc,id,name,type,state,image,package,memory,'
- + 'disk,created,updated,compute_node,primaryIp'
- });
- }
- var err;
- if (errs.length === 1) {
- err = errs[0];
- } else if (errs.length > 1) {
- err = new errors.MultiError(errs);
- }
- callback(err);
- });
-};
-CLI.prototype.do_machines.options = [
- {
- names: ['help', 'h'],
- type: 'bool',
- help: 'Show this help.'
- },
- {
- names: ['json', 'j'],
- type: 'bool',
- help: 'JSON output.'
- }
-];
-CLI.prototype.do_machines.help = (
- 'List machines.\n'
- + '\n'
- + 'Usage:\n'
- + ' {{name}} machines [...]\n'
- + '\n'
- + '{{options}}'
-);
+// VMs/Containers/Machines
+CLI.prototype.do_create = require('./do_create');
+CLI.prototype.do_vms = require('./do_vms');
+CLI.prototype.do_vm_audit = require('./do_vm_audit');
-CLI.prototype.do_machine_audit = function (subcmd, opts, args, callback) {
- var self = this;
- if (opts.help) {
- this.do_help('help', {}, [subcmd], callback);
- return;
- } else if (args.length > 1) {
- //XXX Support multiple machines.
- return callback(new Error('too many args: ' + args));
- }
- var id = args[0];
- this.sdc.machineAudit({machine: id}, function (err, audit, dc) {
- if (err) {
- return callback(err);
- }
- for (var i = 0; i < audit.length; i++) {
- audit[i].dc = dc;
- }
- if (opts.json) {
- p(JSON.stringify(audit, null, 4));
- } else {
- return callback(new error.InternalError("tabular output for audit NYI")); // XXX
- //common.tabulate(audit, {
- // columns: 'dc,id,name,state,created',
- // sort: 'created',
- // validFields: 'dc,id,name,type,state,image,package,memory,'
- // + 'disk,created,updated,compute_node,primaryIp'
- //});
- }
- callback();
- });
-};
-CLI.prototype.do_machine_audit.options = [
- {
- names: ['help', 'h'],
- type: 'bool',
- help: 'Show this help.'
- },
- {
- names: ['json', 'j'],
- type: 'bool',
- help: 'JSON output.'
- }
-];
-CLI.prototype.do_machine_audit.help = (
- 'List machine actions.\n'
- + '\n'
- + 'Note: On the *client*-side, this adds the "dc" attribute to each\n'
- + 'audit record.\n'
- + '\n'
- + 'Usage:\n'
- + ' {{name}} machine-audit \n'
- + '\n'
- + '{{options}}'
-);
//---- mainline
diff --git a/lib/do_create.js b/lib/do_create.js
new file mode 100644
index 0000000..e8b842d
--- /dev/null
+++ b/lib/do_create.js
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015 Joyent Inc. All rights reserved.
+ *
+ * `triton images ...`
+ */
+
+var format = require('util').format;
+var tabula = require('tabula');
+
+var errors = require('./errors');
+
+
+function do_create(subcmd, opts, args, callback) {
+ if (opts.help) {
+ this.do_help('help', {}, [subcmd], callback);
+ return;
+ } else if (args.length > 1) {
+ return callback(new Error('too many args: ' + args));
+ }
+ var triton = this.triton;
+
+ // XXX The smarts here should move to Triton class.
+
+ assert.string(opts.image, '--image ');
+ assert.string(opts['package'], '--package ');
+ assert.number(opts.count)
+
+ // XXX
+ /*
+ * Should all this move into sdc.createMachine? yes
+ *
+ * - lookup image, package, networks from args
+ * - assign names
+ * - start provisions (slight stagger, max N at a time)
+ * - return immediately, or '-w|--wait'
+ */
+ async.series([
+ function lookups(next) {
+ async.parallel([
+ //XXX
+ //sdc.lookup(image)
+ ])
+ },
+ function provisions(next) {
+
+ },
+ function wait(next) {
+ next();
+ }
+ ], function (err) {
+ callback(err);
+ });
+};
+do_create.options = [
+ {
+ names: ['help', 'h'],
+ type: 'bool',
+ help: 'Show this help.'
+ },
+ {
+ names: ['dc', 'd'],
+ type: 'string',
+ helpArg: '',
+ help: 'The datacenter in which to provision. Required if the current'
+ + ' profile includes more than one datacenter. Use `sdc profile`'
+ + ' to list profiles and `sdc dcs` to list available datacenters.'
+ },
+ {
+ names: ['image', 'i'],
+ type: 'string',
+ helpArg: '',
+ help: 'The machine image with which to provision. Required.'
+ },
+ {
+ names: ['package', 'p'],
+ type: 'string',
+ helpArg: '',
+ help: 'The package or instance type for the new machine(s). Required.'
+ },
+ {
+ names: ['name', 'n'],
+ type: 'string',
+ helpArg: '',
+ help: 'A name for the machine. If not specified, a short random name'
+ + ' will be generated.',
+ // TODO: for count>1 support '%d' code in name: foo0, foo1, ...
+ },
+ {
+ names: ['count', 'c'],
+ type: 'positiveInteger',
+ 'default': 1,
+ helpArg: '',
+ help: 'The number of machines to provision. Default is 1.'
+ },
+];
+do_create.help = (
+ 'Create a new VM/container/machine.\n'
+ + '\n'
+ + 'Usage:\n'
+ + ' {{name}} provision \n'
+ + '\n'
+ + '{{options}}'
+);
+do_create.aliases = ['create-vm'];
+
+module.exports = do_create;
\ No newline at end of file
diff --git a/lib/do_vm_audit.js b/lib/do_vm_audit.js
new file mode 100644
index 0000000..ec5d62b
--- /dev/null
+++ b/lib/do_vm_audit.js
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2015 Joyent Inc. All rights reserved.
+ *
+ * `triton vms ...`
+ */
+
+var format = require('util').format;
+var tabula = require('tabula');
+
+var errors = require('./errors');
+
+
+do_vm_audit = function do_vm_audit(subcmd, opts, args, callback) {
+ var self = this;
+ if (opts.help) {
+ this.do_help('help', {}, [subcmd], callback);
+ return;
+ } else if (args.length > 1) {
+ //XXX Support multiple machines.
+ return callback(new Error('too many args: ' + args));
+ }
+
+ var id = args[0];
+ this.sdc.machineAudit({machine: id}, function (err, audit, dc) {
+ if (err) {
+ return callback(err);
+ }
+ for (var i = 0; i < audit.length; i++) {
+ audit[i].dc = dc;
+ }
+ if (opts.json) {
+ p(JSON.stringify(audit, null, 4));
+ } else {
+ return callback(new error.InternalError("tabular output for audit NYI")); // XXX
+ //common.tabulate(audit, {
+ // columns: 'dc,id,name,state,created',
+ // sort: 'created',
+ // validFields: 'dc,id,name,type,state,image,package,memory,'
+ // + 'disk,created,updated,compute_node,primaryIp'
+ //});
+ }
+ callback();
+ });
+};
+do_vm_audit.options = [
+ {
+ names: ['help', 'h'],
+ type: 'bool',
+ help: 'Show this help.'
+ },
+ {
+ names: ['json', 'j'],
+ type: 'bool',
+ help: 'JSON output.'
+ }
+];
+do_vm_audit.help = (
+ 'List instance actions.\n'
+ + '\n'
+ + 'Usage:\n'
+ + ' {{name}} vm-audit \n'
+ + '\n'
+ + '{{options}}'
+);
+
+
+
+module.exports = do_vm_audit;
\ No newline at end of file
diff --git a/lib/do_vms.js b/lib/do_vms.js
new file mode 100644
index 0000000..e6ab786
--- /dev/null
+++ b/lib/do_vms.js
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015 Joyent Inc. All rights reserved.
+ *
+ * `triton vms ...`
+ */
+
+var format = require('util').format;
+var tabula = require('tabula');
+
+var errors = require('./errors');
+
+
+do_vms = function do_vms(subcmd, opts, args, callback) {
+ var self = this;
+ if (opts.help) {
+ this.do_help('help', {}, [subcmd], callback);
+ return;
+ } else if (args.length > 1) {
+ return callback(new Error('too many args: ' + args));
+ }
+
+ var machines = [];
+ var errs = [];
+ var res = this.sdc.listMachines();
+ res.on('data', function (dc, dcMachines) {
+ for (var i = 0; i < dcMachines.length; i++) {
+ dcMachines[i].dc = dc;
+ machines.push(dcMachines[i]);
+ }
+ });
+ res.on('dcError', function (dc, dcErr) {
+ dcErr.dc = dc;
+ errs.push(dcErr);
+ });
+ res.on('end', function () {
+ if (opts.json) {
+ p(JSON.stringify(machines, null, 4));
+ } else {
+ /* BEGIN JSSTYLED */
+ // TODO: get short output down to something like
+ // 'us-west-1 e91897cf testforyunong2 linux running 2013-11-08'
+ // 'us-west-1 e91897cf testforyunong2 ubuntu/13.3.0 running 2013-11-08'
+ /* END JSSTYLED */
+ common.tabulate(machines, {
+ columns: 'dc,id,name,image,state,created',
+ sort: 'created',
+ validFields: 'dc,id,name,type,state,image,package,memory,'
+ + 'disk,created,updated,compute_node,primaryIp'
+ });
+ }
+ var err;
+ if (errs.length === 1) {
+ err = errs[0];
+ } else if (errs.length > 1) {
+ err = new errors.MultiError(errs);
+ }
+ callback(err);
+ });
+};
+do_vms.options = [
+ {
+ names: ['help', 'h'],
+ type: 'bool',
+ help: 'Show this help.'
+ },
+ {
+ names: ['json', 'j'],
+ type: 'bool',
+ help: 'JSON output.'
+ }
+];
+do_vms.help = (
+ 'List VMs/machines/containers.\n'
+ + '\n'
+ + 'Usage:\n'
+ + ' {{name}} vms [...]\n'
+ + '\n'
+ + '{{options}}'
+);
+
+
+module.exports = do_vms;
\ No newline at end of file