diff --git a/lib/do_instance/do_create.js b/lib/do_instance/do_create.js index 0562dc1..6b4386e 100644 --- a/lib/do_instance/do_create.js +++ b/lib/do_instance/do_create.js @@ -217,6 +217,19 @@ function do_create(subcmd, opts, args, cb) { next(); }); }, + function loadAddl(ctx, next) { + mat.addlFromCreateOpts(opts, log, function (err, addl) { + if (err) { + next(err); + return; + } + if (addl) { + log.trace({addl: addl}, 'additional parameters loaded from opts'); + ctx.addl = addl; + } + next(); + }); + }, function getImg(ctx, next) { var _opts = { name: args[0], @@ -294,6 +307,11 @@ function do_create(subcmd, opts, args, cb) { createOpts['tag.'+key] = ctx.tags[key]; }); } + if (ctx.addl) { + Object.keys(ctx.addl).forEach(function (key) { + createOpts[key] = ctx.addl[key]; + }); + } for (var i = 0; i < opts._order.length; i++) { var opt = opts._order[i]; @@ -427,7 +445,17 @@ do_create.options = [ '`INST`. Use this option more than once for multiple rules.', completionType: 'tritonaffinityrule' }, - + { + names: ['addl'], + type: 'arrayOfString', + helpArg: 'ADDL', + help: 'Add specific properties when creating the instance. These are ' + + 'key/value pairs available on the instance API object at the ' + + 'top level. ADDL is one of: a "key=value" string (bool and ' + + 'numeric "value" are converted to that type), a JSON object ' + + '(if first char is "{"), or a "@FILE" to have properties be ' + + 'loaded from FILE. This option can be used multiple times.' + }, { group: '' }, diff --git a/lib/metadataandtags.js b/lib/metadataandtags.js index e9438a6..07172a2 100644 --- a/lib/metadataandtags.js +++ b/lib/metadataandtags.js @@ -123,6 +123,52 @@ function tagsFromCreateOpts(opts, log, cb) { } +/* + * Load and validate additional parameters from these options: + * --addl-opts DATA + * + * + * says values may be string, num or bool. + */ +function addlFromCreateOpts(opts, log, cb) { + assert.arrayOfObject(opts._order, 'opts._order'); + assert.object(log, 'log'); + assert.func(cb, 'cb'); + + var addl = {}; + + vasync.forEachPipeline({ + inputs: opts._order, + func: function addlFromOpt(o, next) { + log.trace({opt: o}, 'addlFromOpt'); + if (o.key === 'addl') { + if (!o.value) { + next(new errors.UsageError( + 'empty additional parameters option value')); + return; + } else if (o.value[0] === '{') { + _addMetadataFromJsonStr('addl', addl, o.value, null, next); + } else if (o.value[0] === '@') { + _addMetadataFromFile('addl', addl, o.value.slice(1), next); + } else { + _addMetadataFromKvStr('addl', addl, o.value, null, next); + } + } else { + next(); + } + } + }, function (err) { + if (err) { + cb(err); + } else if (Object.keys(addl).length) { + cb(null, addl); + } else { + cb(); + } + }); +} + + /* * Load and validate tags from (a) these options: * -f,--file FILE @@ -342,6 +388,7 @@ function _addMetadatumFromFile(ilk, metadata, key, file, from, cb) { module.exports = { + addlFromCreateOpts: addlFromCreateOpts, metadataFromOpts: metadataFromOpts, tagsFromCreateOpts: tagsFromCreateOpts, tagsFromSetArgs: tagsFromSetArgs