style: triton img ...
This commit is contained in:
		
							parent
							
								
									559162896f
								
							
						
					
					
						commit
						632d5a6568
					
				| @ -206,7 +206,6 @@ function CLI() { | ||||
|             'wait-instance', | ||||
|             'ssh', | ||||
|             { group: 'Images, Packages, Networks' }, | ||||
|             'images', | ||||
|             'image', | ||||
|             'package', | ||||
|             'networks', | ||||
|  | ||||
| @ -7,15 +7,15 @@ | ||||
| /* | ||||
|  * Copyright 2015 Joyent, Inc. | ||||
|  * | ||||
|  * `triton image ...` | ||||
|  * `triton image get ...` | ||||
|  */ | ||||
| 
 | ||||
| var format = require('util').format; | ||||
| 
 | ||||
| var errors = require('./errors'); | ||||
| var errors = require('../errors'); | ||||
| 
 | ||||
| 
 | ||||
| function do_image(subcmd, opts, args, callback) { | ||||
| function do_get(subcmd, opts, args, callback) { | ||||
|     if (opts.help) { | ||||
|         this.do_help('help', {}, [subcmd], callback); | ||||
|         return; | ||||
| @ -24,7 +24,7 @@ function do_image(subcmd, opts, args, callback) { | ||||
|             'incorrect number of args (%d)', args.length))); | ||||
|     } | ||||
| 
 | ||||
|     this.tritonapi.getImage(args[0], function onRes(err, img) { | ||||
|     this.top.tritonapi.getImage(args[0], function onRes(err, img) { | ||||
|         if (err) { | ||||
|             return callback(err); | ||||
|         } | ||||
| @ -38,7 +38,7 @@ function do_image(subcmd, opts, args, callback) { | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| do_image.options = [ | ||||
| do_get.options = [ | ||||
|     { | ||||
|         names: ['help', 'h'], | ||||
|         type: 'bool', | ||||
| @ -50,16 +50,16 @@ do_image.options = [ | ||||
|         help: 'JSON stream output.' | ||||
|     } | ||||
| ]; | ||||
| do_image.help = ( | ||||
| do_get.help = ( | ||||
|     /* BEGIN JSSTYLED */ | ||||
|     'Get an image.\n' + | ||||
|     '\n' + | ||||
|     'Usage:\n' + | ||||
|     '    {{name}} image [<options>] ID|NAME\n' + | ||||
|     '    {{name}} image get [<options>] ID|NAME\n' + | ||||
|     '\n' + | ||||
|     '{{options}}' + | ||||
|     '\n' + | ||||
|     'If there are more than one image with the given "NAME", the latest\n' + | ||||
|     'If there is more than one image with the given "NAME", the latest\n' + | ||||
|     'image (by "published_at") is returned.\n' + | ||||
|     '\n' + | ||||
|     'Note: Currently this dumps prettified JSON by default. That might change\n' + | ||||
| @ -67,6 +67,4 @@ do_image.help = ( | ||||
|     /* END JSSTYLED */ | ||||
| ); | ||||
| 
 | ||||
| do_image.aliases = ['img']; | ||||
| 
 | ||||
| module.exports = do_image; | ||||
| module.exports = do_get; | ||||
							
								
								
									
										158
									
								
								lib/do_image/do_list.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								lib/do_image/do_list.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,158 @@ | ||||
| /* | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
|  * Copyright 2015 Joyent, Inc. | ||||
|  * | ||||
|  * `triton image list ...` | ||||
|  */ | ||||
| 
 | ||||
| var format = require('util').format; | ||||
| var tabula = require('tabula'); | ||||
| 
 | ||||
| var common = require('../common'); | ||||
| var errors = require('../errors'); | ||||
| 
 | ||||
| // filters to pass triton.listImages
 | ||||
| var validFilters = [ | ||||
|     'name', | ||||
|     'os', | ||||
|     'version', | ||||
|     'public', | ||||
|     'state', | ||||
|     'owner', | ||||
|     'type' | ||||
| ]; | ||||
| 
 | ||||
| // columns default without -o
 | ||||
| var columnsDefault = 'shortid,name,version,state,flags,os,pubdate'; | ||||
| 
 | ||||
| // columns default with -l
 | ||||
| var columnsDefaultLong = 'id,name,version,state,flags,os,pubdate'; | ||||
| 
 | ||||
| // sort default with -s
 | ||||
| var sortDefault = 'published_at'; | ||||
| 
 | ||||
| function do_list(subcmd, opts, args, callback) { | ||||
|     if (opts.help) { | ||||
|         this.do_help('help', {}, [subcmd], callback); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     var columns = columnsDefault; | ||||
|     if (opts.o) { | ||||
|         columns = opts.o; | ||||
|     } else if (opts.long) { | ||||
|         columns = columnsDefaultLong; | ||||
|     } | ||||
|     columns = columns.split(','); | ||||
| 
 | ||||
|     var sort = opts.s.split(','); | ||||
| 
 | ||||
|     var listOpts; | ||||
|     try { | ||||
|         listOpts = common.kvToObj(args, validFilters); | ||||
|     } catch (e) { | ||||
|         callback(e); | ||||
|         return; | ||||
|     } | ||||
|     if (opts.all) { | ||||
|         listOpts.state = 'all'; | ||||
|     } | ||||
| 
 | ||||
|     this.top.tritonapi.listImages(listOpts, function onRes(err, imgs, res) { | ||||
|         if (err) { | ||||
|             return callback(err); | ||||
|         } | ||||
| 
 | ||||
|         if (opts.json) { | ||||
|             // XXX we should have a common method for all these:
 | ||||
|             //      XXX sorting
 | ||||
|             //      XXX if opts.o is given, then filter to just those fields?
 | ||||
|             common.jsonStream(imgs); | ||||
|         } else { | ||||
|             // Add some convenience fields
 | ||||
|             // Added fields taken from imgapi-cli.git.
 | ||||
|             for (var i = 0; i < imgs.length; i++) { | ||||
|                 var img = imgs[i]; | ||||
|                 img.shortid = img.id.split('-', 1)[0]; | ||||
|                 if (img.published_at) { | ||||
|                     // Just the date.
 | ||||
|                     img.pubdate = img.published_at.slice(0, 10); | ||||
|                     // Normalize on no milliseconds.
 | ||||
|                     img.pub = img.published_at.replace(/\.\d+Z$/, 'Z'); | ||||
|                 } | ||||
|                 if (img.files && img.files[0]) { | ||||
|                     img.size = img.files[0].size; | ||||
|                 } | ||||
|                 var flags = []; | ||||
|                 if (img.origin) flags.push('I'); | ||||
|                 if (img['public']) flags.push('P'); | ||||
|                 if (img.state !== 'active') flags.push('X'); | ||||
|                 img.flags = flags.length ? flags.join('') : undefined; | ||||
|             } | ||||
| 
 | ||||
|             tabula(imgs, { | ||||
|                 skipHeader: opts.H, | ||||
|                 columns: columns, | ||||
|                 sort: sort | ||||
|             }); | ||||
|         } | ||||
|         callback(); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| do_list.options = [ | ||||
|     { | ||||
|         names: ['help', 'h'], | ||||
|         type: 'bool', | ||||
|         help: 'Show this help.' | ||||
|     }, | ||||
|     { | ||||
|         group: 'Filtering options' | ||||
|     }, | ||||
|     { | ||||
|         names: ['all', 'a'], | ||||
|         type: 'bool', | ||||
|         help: 'List all images, not just "active" ones. This ' + | ||||
|             'is a shortcut for the "state=all" filter.' | ||||
|     } | ||||
| ].concat(common.getCliTableOptions({ | ||||
|     includeLong: true, | ||||
|     sortDefault: sortDefault | ||||
| })); | ||||
| 
 | ||||
| do_list.help = ( | ||||
|     /* BEGIN JSSTYLED */ | ||||
|     'List images.\n' + | ||||
|     '\n' + | ||||
|     'Usage:\n' + | ||||
|     '    {{name}} image list [<options>] [<filters>]\n' + | ||||
|     '\n' + | ||||
|     '{{options}}' + | ||||
|     '\n' + | ||||
|     'Filters:\n' + | ||||
|     '    FIELD=VALUE        Field equality filter. Supported fields: \n' + | ||||
|     '                       account, owner, state, name, os, and type.\n' + | ||||
|     '    FIELD=true|false   Field boolean filter. Supported fields: public.\n' + | ||||
|     '    FIELD=~SUBSTRING   Field substring filter. Supported fields: name\n' + | ||||
|     '\n' + | ||||
|     'Fields (most are self explanatory, the client adds some for convenience):\n' + | ||||
|     '    shortid            A short ID prefix.\n' + | ||||
|     '    flags              This is a set of single letter flags\n' + | ||||
|     '                       summarizing some fields. "P" indicates the\n' + | ||||
|     '                       image is public. "I" indicates an incremental\n' + | ||||
|     '                       image (i.e. has an origin). "X" indicates an\n' + | ||||
|     '                       image with a state *other* than "active".\n' + | ||||
|     '    pubdate            Short form of "published_at" with just the date\n' + | ||||
|     '    pub                Short form of "published_at" elliding milliseconds.\n' + | ||||
|     '    size               The number of bytes of the image file (files.0.size)\n' | ||||
|     /* END JSSTYLED */ | ||||
| ); | ||||
| 
 | ||||
| do_list.aliases = ['ls']; | ||||
| 
 | ||||
| module.exports = do_list; | ||||
							
								
								
									
										52
									
								
								lib/do_image/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								lib/do_image/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| /* | ||||
|  * This Source Code Form is subject to the terms of the Mozilla Public | ||||
|  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | ||||
|  */ | ||||
| 
 | ||||
| /* | ||||
|  * Copyright 2015 Joyent, Inc. | ||||
|  * | ||||
|  * `triton image ...` | ||||
|  */ | ||||
| 
 | ||||
| var Cmdln = require('cmdln').Cmdln; | ||||
| var util = require('util'); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // ---- CLI class
 | ||||
| 
 | ||||
| function ImageCLI(top) { | ||||
|     this.top = top; | ||||
|     Cmdln.call(this, { | ||||
|         name: top.name + ' image', | ||||
|         /* BEGIN JSSTYLED */ | ||||
|         desc: [ | ||||
|             'List, get, create and update Triton images.' | ||||
|         ].join('\n'), | ||||
|         /* END JSSTYLED */ | ||||
|         helpOpts: { | ||||
|             minHelpCol: 24 /* line up with option help */ | ||||
|         }, | ||||
|         helpSubcmds: [ | ||||
|             'help', | ||||
|             'list', | ||||
|             'get' | ||||
|         ] | ||||
|     }); | ||||
| } | ||||
| util.inherits(ImageCLI, Cmdln); | ||||
| 
 | ||||
| ImageCLI.prototype.init = function init(opts, args, cb) { | ||||
|     this.log = this.top.log; | ||||
|     Cmdln.prototype.init.apply(this, arguments); | ||||
| }; | ||||
| 
 | ||||
| ImageCLI.prototype.do_list = require('./do_list'); | ||||
| ImageCLI.prototype.do_get = require('./do_get'); | ||||
| 
 | ||||
| 
 | ||||
| ImageCLI.aliases = ['img']; | ||||
| 
 | ||||
| module.exports = ImageCLI; | ||||
							
								
								
									
										151
									
								
								lib/do_images.js
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								lib/do_images.js
									
									
									
									
									
								
							| @ -7,152 +7,23 @@ | ||||
| /* | ||||
|  * Copyright 2015 Joyent, Inc. | ||||
|  * | ||||
|  * `triton images ...` | ||||
|  * `triton images ...` bwcompat shortcut for `triton images list ...`. | ||||
|  */ | ||||
| 
 | ||||
| var format = require('util').format; | ||||
| var tabula = require('tabula'); | ||||
| 
 | ||||
| var common = require('./common'); | ||||
| var errors = require('./errors'); | ||||
| 
 | ||||
| // filters to pass triton.listImages
 | ||||
| var validFilters = [ | ||||
|     'name', | ||||
|     'os', | ||||
|     'version', | ||||
|     'public', | ||||
|     'state', | ||||
|     'owner', | ||||
|     'type' | ||||
| ]; | ||||
| 
 | ||||
| // columns default without -o
 | ||||
| var columnsDefault = 'shortid,name,version,state,flags,os,pubdate'; | ||||
| 
 | ||||
| // columns default with -l
 | ||||
| var columnsDefaultLong = 'id,name,version,state,flags,os,pubdate'; | ||||
| 
 | ||||
| // sort default with -s
 | ||||
| var sortDefault = 'published_at'; | ||||
| 
 | ||||
| function do_images(subcmd, opts, args, callback) { | ||||
|     if (opts.help) { | ||||
|         this.do_help('help', {}, [subcmd], callback); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     var columns = columnsDefault; | ||||
|     if (opts.o) { | ||||
|         columns = opts.o; | ||||
|     } else if (opts.long) { | ||||
|         columns = columnsDefaultLong; | ||||
|     } | ||||
|     columns = columns.split(','); | ||||
| 
 | ||||
|     var sort = opts.s.split(','); | ||||
| 
 | ||||
|     var listOpts; | ||||
|     try { | ||||
|         listOpts = common.kvToObj(args, validFilters); | ||||
|     } catch (e) { | ||||
|         callback(e); | ||||
|         return; | ||||
|     } | ||||
|     if (opts.all) { | ||||
|         listOpts.state = 'all'; | ||||
|     } | ||||
| 
 | ||||
|     this.tritonapi.listImages(listOpts, function onRes(err, imgs, res) { | ||||
|         if (err) { | ||||
|             return callback(err); | ||||
|         } | ||||
| 
 | ||||
|         if (opts.json) { | ||||
|             // XXX we should have a common method for all these:
 | ||||
|             //      XXX sorting
 | ||||
|             //      XXX if opts.o is given, then filter to just those fields?
 | ||||
|             common.jsonStream(imgs); | ||||
|         } else { | ||||
|             // Add some convenience fields
 | ||||
|             // Added fields taken from imgapi-cli.git.
 | ||||
|             for (var i = 0; i < imgs.length; i++) { | ||||
|                 var img = imgs[i]; | ||||
|                 img.shortid = img.id.split('-', 1)[0]; | ||||
|                 if (img.published_at) { | ||||
|                     // Just the date.
 | ||||
|                     img.pubdate = img.published_at.slice(0, 10); | ||||
|                     // Normalize on no milliseconds.
 | ||||
|                     img.pub = img.published_at.replace(/\.\d+Z$/, 'Z'); | ||||
|                 } | ||||
|                 if (img.files && img.files[0]) { | ||||
|                     img.size = img.files[0].size; | ||||
|                 } | ||||
|                 var flags = []; | ||||
|                 if (img.origin) flags.push('I'); | ||||
|                 if (img['public']) flags.push('P'); | ||||
|                 if (img.state !== 'active') flags.push('X'); | ||||
|                 img.flags = flags.length ? flags.join('') : undefined; | ||||
|             } | ||||
| 
 | ||||
|             tabula(imgs, { | ||||
|                 skipHeader: opts.H, | ||||
|                 columns: columns, | ||||
|                 sort: sort | ||||
|             }); | ||||
|         } | ||||
|         callback(); | ||||
|     }); | ||||
|     var subcmdArgv = ['node', 'triton', 'image', 'list'].concat(args); | ||||
|     this.dispatch('image', subcmdArgv, callback); | ||||
| } | ||||
| 
 | ||||
| do_images.options = [ | ||||
|     { | ||||
|         names: ['help', 'h'], | ||||
|         type: 'bool', | ||||
|         help: 'Show this help.' | ||||
|     }, | ||||
|     { | ||||
|         group: 'Filtering options' | ||||
|     }, | ||||
|     { | ||||
|         names: ['all', 'a'], | ||||
|         type: 'bool', | ||||
|         help: 'List all images, not just "active" ones. This ' + | ||||
|             'is a shortcut for the "state=all" filter.' | ||||
|     } | ||||
| ].concat(common.getCliTableOptions({ | ||||
|     includeLong: true, | ||||
|     sortDefault: sortDefault | ||||
| })); | ||||
| 
 | ||||
| do_images.help = ( | ||||
|     /* BEGIN JSSTYLED */ | ||||
|     'List images.\n' + | ||||
|     '\n' + | ||||
|     'Usage:\n' + | ||||
|     '    {{name}} images [<options>] [<filters>]\n' + | ||||
|     '\n' + | ||||
|     '{{options}}' + | ||||
|     '\n' + | ||||
|     'Filters:\n' + | ||||
|     '    FIELD=VALUE        Field equality filter. Supported fields: \n' + | ||||
|     '                       account, owner, state, name, os, and type.\n' + | ||||
|     '    FIELD=true|false   Field boolean filter. Supported fields: public.\n' + | ||||
|     '    FIELD=~SUBSTRING   Field substring filter. Supported fields: name\n' + | ||||
|     '\n' + | ||||
|     'Fields (most are self explanatory, the client adds some for convenience):\n' + | ||||
|     '    shortid            A short ID prefix.\n' + | ||||
|     '    flags              This is a set of single letter flags\n' + | ||||
|     '                       summarizing some fields. "P" indicates the\n' + | ||||
|     '                       image is public. "I" indicates an incremental\n' + | ||||
|     '                       image (i.e. has an origin). "X" indicates an\n' + | ||||
|     '                       image with a state *other* than "active".\n' + | ||||
|     '    pubdate            Short form of "published_at" with just the date\n' + | ||||
|     '    pub                Short form of "published_at" elliding milliseconds.\n' + | ||||
|     '    size               The number of bytes of the image file (files.0.size)\n' | ||||
|     /* END JSSTYLED */ | ||||
| ); | ||||
| do_images.help = [ | ||||
|     'A shortcut for "triton image list".', | ||||
|     '', | ||||
|     'Usage:', | ||||
|     '    {{name}} images ...' | ||||
| ].join('\n'); | ||||
| 
 | ||||
| do_images.aliases = ['imgs']; | ||||
| 
 | ||||
| do_images.hidden = true; | ||||
| 
 | ||||
| module.exports = do_images; | ||||
|  | ||||
| @ -55,7 +55,7 @@ do_get.help = ( | ||||
|     'Get a package.\n' + | ||||
|     '\n' + | ||||
|     'Usage:\n' + | ||||
|     '    {{name}} package [<options>] ID|NAME\n' + | ||||
|     '    {{name}} package get [<options>] ID|NAME\n' + | ||||
|     '\n' + | ||||
|     '{{options}}' + | ||||
|     '\n' + | ||||
|  | ||||
| @ -159,7 +159,7 @@ do_list.help = [ | ||||
|     'List packgaes.', | ||||
|     '', | ||||
|     'Usage:', | ||||
|     '    {{name}} packages [<filters>]', | ||||
|     '    {{name}} package list [<filters>]', | ||||
|     '', | ||||
|     '{{options}}', | ||||
|     'Filters:', | ||||
|  | ||||
| @ -100,7 +100,7 @@ test('triton manage workflow', opts, function (tt) { | ||||
|             'minimal-32': true, | ||||
|             'base': true | ||||
|         }; | ||||
|         h.safeTriton(t, ['imgs', '-j'], function (stdout) { | ||||
|         h.safeTriton(t, ['img', 'ls', '-j'], function (stdout) { | ||||
|             var imgs = _jsonStreamParse(stdout); | ||||
|             // Newest images first.
 | ||||
|             tabula.sortArrayOfObjects(imgs, ['-published_at']); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user