33 |
33 |
|
34 |
34 |
from kamaki.cli import command
|
35 |
35 |
from kamaki.cli.command_tree import CommandTree
|
36 |
|
from kamaki.cli.utils import print_dict, print_items
|
|
36 |
from kamaki.cli.utils import print_dict, print_items, print_json
|
37 |
37 |
from kamaki.clients.image import ImageClient
|
38 |
38 |
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument
|
39 |
39 |
from kamaki.cli.argument import IntArgument
|
40 |
40 |
from kamaki.cli.commands.cyclades import _init_cyclades
|
41 |
|
from kamaki.cli.commands import _command_init, errors
|
|
41 |
from kamaki.cli.commands import _command_init, errors, _optional_output_cmd
|
42 |
42 |
|
43 |
43 |
|
44 |
44 |
image_cmds = CommandTree(
|
... | ... | |
104 |
104 |
more=FlagArgument(
|
105 |
105 |
'output results in pages (-n to set items per page, default 10)',
|
106 |
106 |
'--more'),
|
107 |
|
enum=FlagArgument('Enumerate results', '--enumerate')
|
|
107 |
enum=FlagArgument('Enumerate results', '--enumerate'),
|
|
108 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
108 |
109 |
)
|
109 |
110 |
|
110 |
111 |
def _filtered_by_owner(self, detail, *list_params):
|
... | ... | |
146 |
147 |
images = self._filtered_by_owner(detail, filters, order)
|
147 |
148 |
else:
|
148 |
149 |
images = self.client.list_public(detail, filters, order)
|
149 |
|
images = self._filtered_by_name(images)
|
150 |
150 |
|
|
151 |
if self['json_output']:
|
|
152 |
print_json(images)
|
|
153 |
return
|
|
154 |
images = self._filtered_by_name(images)
|
151 |
155 |
if self['more']:
|
152 |
156 |
print_items(
|
153 |
157 |
images,
|
... | ... | |
171 |
175 |
- image os properties (os, fs, etc.)
|
172 |
176 |
"""
|
173 |
177 |
|
|
178 |
arguments = dict(
|
|
179 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
180 |
)
|
|
181 |
|
174 |
182 |
@errors.generic.all
|
175 |
183 |
@errors.plankton.connection
|
176 |
184 |
@errors.plankton.id
|
177 |
185 |
def _run(self, image_id):
|
178 |
|
image = self.client.get_meta(image_id)
|
179 |
|
print_dict(image)
|
|
186 |
printer = print_json if self['json_output'] else print_dict
|
|
187 |
printer(self.client.get_meta(image_id))
|
180 |
188 |
|
181 |
189 |
def main(self, image_id):
|
182 |
190 |
super(self.__class__, self)._run()
|
... | ... | |
200 |
208 |
('-p', '--property')),
|
201 |
209 |
is_public=FlagArgument('mark image as public', '--public'),
|
202 |
210 |
size=IntArgument('set image size', '--size'),
|
203 |
|
update=FlagArgument(
|
204 |
|
'update existing image properties',
|
205 |
|
('-u', '--update'))
|
|
211 |
#update=FlagArgument(
|
|
212 |
# 'update existing image properties',
|
|
213 |
# ('-u', '--update')),
|
|
214 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
206 |
215 |
)
|
207 |
216 |
|
208 |
217 |
@errors.generic.all
|
... | ... | |
232 |
241 |
params[key] = self[key]
|
233 |
242 |
|
234 |
243 |
properties = self['properties']
|
235 |
|
if self['update']:
|
236 |
|
self.client.reregister(location, name, params, properties)
|
237 |
|
else:
|
238 |
|
r = self.client.register(name, location, params, properties)
|
239 |
|
print_dict(r)
|
|
244 |
|
|
245 |
printer = print_json if self['json_output'] else print_dict
|
|
246 |
printer(self.client.register(name, location, params, properties))
|
240 |
247 |
|
241 |
248 |
def main(self, name, location):
|
242 |
249 |
super(self.__class__, self)._run()
|
... | ... | |
244 |
251 |
|
245 |
252 |
|
246 |
253 |
@command(image_cmds)
|
247 |
|
class image_unregister(_init_image):
|
|
254 |
class image_unregister(_init_image, _optional_output_cmd):
|
248 |
255 |
"""Unregister an image (does not delete the image file)"""
|
249 |
256 |
|
250 |
257 |
@errors.generic.all
|
251 |
258 |
@errors.plankton.connection
|
252 |
259 |
@errors.plankton.id
|
253 |
260 |
def _run(self, image_id):
|
254 |
|
self.client.unregister(image_id)
|
|
261 |
self._optional_output(self.client.unregister(image_id))
|
255 |
262 |
|
256 |
263 |
def main(self, image_id):
|
257 |
264 |
super(self.__class__, self)._run()
|
... | ... | |
259 |
266 |
|
260 |
267 |
|
261 |
268 |
@command(image_cmds)
|
262 |
|
class image_members(_init_image):
|
263 |
|
"""Get image members"""
|
|
269 |
class image_shared(_init_image):
|
|
270 |
"""List images shared by a member"""
|
|
271 |
|
|
272 |
arguments = dict(
|
|
273 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
274 |
)
|
264 |
275 |
|
265 |
276 |
@errors.generic.all
|
266 |
277 |
@errors.plankton.connection
|
267 |
|
@errors.plankton.id
|
268 |
|
def _run(self, image_id):
|
269 |
|
members = self.client.list_members(image_id)
|
270 |
|
print_items(members)
|
|
278 |
def _run(self, member):
|
|
279 |
r = self.client.list_shared(member)
|
|
280 |
if self['json_output']:
|
|
281 |
print_json(r)
|
|
282 |
else:
|
|
283 |
print_items(r, title=('image_id',))
|
271 |
284 |
|
272 |
|
def main(self, image_id):
|
|
285 |
def main(self, member):
|
273 |
286 |
super(self.__class__, self)._run()
|
274 |
|
self._run(image_id=image_id)
|
|
287 |
self._run(member)
|
275 |
288 |
|
276 |
289 |
|
277 |
290 |
@command(image_cmds)
|
278 |
|
class image_shared(_init_image):
|
279 |
|
"""List images shared by a member"""
|
|
291 |
class image_members(_init_image):
|
|
292 |
"""Manage members. Members of an image are users who can modify it"""
|
|
293 |
|
|
294 |
|
|
295 |
@command(image_cmds)
|
|
296 |
class image_members_list(_init_image):
|
|
297 |
"""List members of an image"""
|
|
298 |
|
|
299 |
arguments = dict(
|
|
300 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
301 |
)
|
280 |
302 |
|
281 |
303 |
@errors.generic.all
|
282 |
304 |
@errors.plankton.connection
|
283 |
|
def _run(self, member):
|
284 |
|
images = self.client.list_shared(member)
|
285 |
|
print_items(images)
|
|
305 |
@errors.plankton.id
|
|
306 |
def _run(self, image_id):
|
|
307 |
members = self.client.list_members(image_id)
|
|
308 |
if self['json_output']:
|
|
309 |
print_json(members)
|
|
310 |
else:
|
|
311 |
print_items(members, title=('member_id',), with_redundancy=True)
|
286 |
312 |
|
287 |
|
def main(self, member):
|
|
313 |
def main(self, image_id):
|
288 |
314 |
super(self.__class__, self)._run()
|
289 |
|
self._run(member)
|
|
315 |
self._run(image_id=image_id)
|
290 |
316 |
|
291 |
317 |
|
292 |
318 |
@command(image_cmds)
|
293 |
|
class image_addmember(_init_image):
|
|
319 |
class image_members_add(_init_image, _optional_output_cmd):
|
294 |
320 |
"""Add a member to an image"""
|
295 |
321 |
|
296 |
322 |
@errors.generic.all
|
297 |
323 |
@errors.plankton.connection
|
298 |
324 |
@errors.plankton.id
|
299 |
325 |
def _run(self, image_id=None, member=None):
|
300 |
|
self.client.add_member(image_id, member)
|
|
326 |
self._optional_output(self.client.add_member(image_id, member))
|
301 |
327 |
|
302 |
328 |
def main(self, image_id, member):
|
303 |
329 |
super(self.__class__, self)._run()
|
... | ... | |
305 |
331 |
|
306 |
332 |
|
307 |
333 |
@command(image_cmds)
|
308 |
|
class image_delmember(_init_image):
|
|
334 |
class image_members_delete(_init_image, _optional_output_cmd):
|
309 |
335 |
"""Remove a member from an image"""
|
310 |
336 |
|
311 |
337 |
@errors.generic.all
|
312 |
338 |
@errors.plankton.connection
|
313 |
339 |
@errors.plankton.id
|
314 |
340 |
def _run(self, image_id=None, member=None):
|
315 |
|
self.client.remove_member(image_id, member)
|
|
341 |
self._optional_output(self.client.remove_member(image_id, member))
|
316 |
342 |
|
317 |
343 |
def main(self, image_id, member):
|
318 |
344 |
super(self.__class__, self)._run()
|
... | ... | |
320 |
346 |
|
321 |
347 |
|
322 |
348 |
@command(image_cmds)
|
323 |
|
class image_setmembers(_init_image):
|
|
349 |
class image_members_set(_init_image, _optional_output_cmd):
|
324 |
350 |
"""Set the members of an image"""
|
325 |
351 |
|
326 |
352 |
@errors.generic.all
|
327 |
353 |
@errors.plankton.connection
|
328 |
354 |
@errors.plankton.id
|
329 |
355 |
def _run(self, image_id, members):
|
330 |
|
self.client.set_members(image_id, members)
|
|
356 |
self._optional_output(self.client.set_members(image_id, members))
|
331 |
357 |
|
332 |
358 |
def main(self, image_id, *members):
|
333 |
359 |
super(self.__class__, self)._run()
|
... | ... | |
352 |
378 |
more=FlagArgument(
|
353 |
379 |
'output results in pages (-n to set items per page, default 10)',
|
354 |
380 |
'--more'),
|
355 |
|
enum=FlagArgument('Enumerate results', '--enumerate')
|
|
381 |
enum=FlagArgument('Enumerate results', '--enumerate'),
|
|
382 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
356 |
383 |
)
|
357 |
384 |
|
358 |
385 |
def _make_results_pretty(self, images):
|
... | ... | |
364 |
391 |
@errors.cyclades.connection
|
365 |
392 |
def _run(self):
|
366 |
393 |
images = self.client.list_images(self['detail'])
|
|
394 |
if self['json_output']:
|
|
395 |
print_json(images)
|
|
396 |
return
|
367 |
397 |
if self['detail']:
|
368 |
398 |
self._make_results_pretty(images)
|
369 |
399 |
if self['more']:
|
... | ... | |
382 |
412 |
class image_compute_info(_init_cyclades):
|
383 |
413 |
"""Get detailed information on an image"""
|
384 |
414 |
|
|
415 |
arguments = dict(
|
|
416 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
417 |
)
|
|
418 |
|
385 |
419 |
@errors.generic.all
|
386 |
420 |
@errors.cyclades.connection
|
387 |
421 |
@errors.plankton.id
|
388 |
422 |
def _run(self, image_id):
|
389 |
423 |
image = self.client.get_image_details(image_id)
|
|
424 |
if self['json_output']:
|
|
425 |
print_json(image)
|
|
426 |
return
|
390 |
427 |
if 'metadata' in image:
|
391 |
428 |
image['metadata'] = image['metadata']['values']
|
392 |
429 |
print_dict(image)
|
... | ... | |
397 |
434 |
|
398 |
435 |
|
399 |
436 |
@command(image_cmds)
|
400 |
|
class image_compute_delete(_init_cyclades):
|
|
437 |
class image_compute_delete(_init_cyclades, _optional_output_cmd):
|
401 |
438 |
"""Delete an image (WARNING: image file is also removed)"""
|
402 |
439 |
|
403 |
440 |
@errors.generic.all
|
404 |
441 |
@errors.cyclades.connection
|
405 |
442 |
@errors.plankton.id
|
406 |
443 |
def _run(self, image_id):
|
407 |
|
self.client.delete_image(image_id)
|
|
444 |
self._optional_output(self.client.delete_image(image_id))
|
408 |
445 |
|
409 |
446 |
def main(self, image_id):
|
410 |
447 |
super(self.__class__, self)._run()
|
... | ... | |
413 |
450 |
|
414 |
451 |
@command(image_cmds)
|
415 |
452 |
class image_compute_properties(_init_cyclades):
|
416 |
|
"""Get properties related to OS installation in an image"""
|
|
453 |
"""Manage proeprties related to OS installation in an image"""
|
|
454 |
|
|
455 |
|
|
456 |
@command(image_cmds)
|
|
457 |
class image_compute_properties_list(_init_cyclades):
|
|
458 |
"""List all image properties"""
|
|
459 |
|
|
460 |
arguments = dict(
|
|
461 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
462 |
)
|
|
463 |
|
|
464 |
@errors.generic.all
|
|
465 |
@errors.cyclades.connection
|
|
466 |
@errors.plankton.id
|
|
467 |
def _run(self, image_id):
|
|
468 |
printer = print_json if self['json_output'] else print_dict
|
|
469 |
printer(self.client.get_image_metadata(image_id))
|
|
470 |
|
|
471 |
def main(self, image_id):
|
|
472 |
super(self.__class__, self)._run()
|
|
473 |
self._run(image_id=image_id)
|
|
474 |
|
|
475 |
|
|
476 |
@command(image_cmds)
|
|
477 |
class image_compute_properties_get(_init_cyclades):
|
|
478 |
"""Get an image property"""
|
|
479 |
|
|
480 |
arguments = dict(
|
|
481 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
482 |
)
|
417 |
483 |
|
418 |
484 |
@errors.generic.all
|
419 |
485 |
@errors.cyclades.connection
|
420 |
486 |
@errors.plankton.id
|
421 |
487 |
@errors.plankton.metadata
|
422 |
488 |
def _run(self, image_id, key):
|
423 |
|
r = self.client.get_image_metadata(image_id, key)
|
424 |
|
print_dict(r)
|
|
489 |
printer = print_json if self['json_output'] else print_dict
|
|
490 |
printer(self.client.get_image_metadata(image_id, key))
|
425 |
491 |
|
426 |
|
def main(self, image_id, key=''):
|
|
492 |
def main(self, image_id, key):
|
427 |
493 |
super(self.__class__, self)._run()
|
428 |
494 |
self._run(image_id=image_id, key=key)
|
429 |
495 |
|
430 |
496 |
|
431 |
497 |
@command(image_cmds)
|
432 |
|
class image_compute_addproperty(_init_cyclades):
|
433 |
|
"""Add an OS-related property to an image"""
|
|
498 |
class image_compute_properties_add(_init_cyclades):
|
|
499 |
"""Add a property to an image"""
|
|
500 |
|
|
501 |
arguments = dict(
|
|
502 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
503 |
)
|
434 |
504 |
|
435 |
505 |
@errors.generic.all
|
436 |
506 |
@errors.cyclades.connection
|
437 |
507 |
@errors.plankton.id
|
438 |
508 |
@errors.plankton.metadata
|
439 |
509 |
def _run(self, image_id, key, val):
|
440 |
|
r = self.client.create_image_metadata(image_id, key, val)
|
441 |
|
print_dict(r)
|
|
510 |
printer = print_json if self['json_output'] else print_dict
|
|
511 |
printer(self.client.create_image_metadata(image_id, key, val))
|
442 |
512 |
|
443 |
513 |
def main(self, image_id, key, val):
|
444 |
514 |
super(self.__class__, self)._run()
|
... | ... | |
446 |
516 |
|
447 |
517 |
|
448 |
518 |
@command(image_cmds)
|
449 |
|
class image_compute_setproperty(_init_cyclades):
|
450 |
|
"""Update an existing property in an image"""
|
|
519 |
class image_compute_properties_set(_init_cyclades):
|
|
520 |
"""Add / update a set of properties for an image
|
|
521 |
proeprties must be given in the form key=value, e.v.
|
|
522 |
/image compute properties set <image-id> key1=val1 key2=val2
|
|
523 |
"""
|
|
524 |
arguments = dict(
|
|
525 |
json_output=FlagArgument('Show results in json', ('-j', '--json'))
|
|
526 |
)
|
451 |
527 |
|
452 |
528 |
@errors.generic.all
|
453 |
529 |
@errors.cyclades.connection
|
454 |
530 |
@errors.plankton.id
|
455 |
|
@errors.plankton.metadata
|
456 |
|
def _run(self, image_id, key, val):
|
457 |
|
metadata = {key: val}
|
458 |
|
r = self.client.update_image_metadata(image_id, **metadata)
|
459 |
|
print_dict(r)
|
460 |
|
|
461 |
|
def main(self, image_id, key, val):
|
|
531 |
def _run(self, image_id, keyvals):
|
|
532 |
metadata = dict()
|
|
533 |
for keyval in keyvals:
|
|
534 |
key, val = keyval.split('=')
|
|
535 |
metadata[key] = val
|
|
536 |
printer = print_json if self['json_output'] else print_dict
|
|
537 |
printer(self.client.update_image_metadata(image_id, **metadata))
|
|
538 |
|
|
539 |
def main(self, image_id, *key_equals_value):
|
462 |
540 |
super(self.__class__, self)._run()
|
463 |
|
self._run(image_id=image_id, key=key, val=val)
|
|
541 |
self._run(image_id=image_id, keyvals=key_equals_value)
|
464 |
542 |
|
465 |
543 |
|
466 |
544 |
@command(image_cmds)
|
467 |
|
class image_compute_delproperty(_init_cyclades):
|
468 |
|
"""Delete a property of an image"""
|
|
545 |
class image_compute_properties_delete(_init_cyclades, _optional_output_cmd):
|
|
546 |
"""Delete a property from an image"""
|
469 |
547 |
|
470 |
548 |
@errors.generic.all
|
471 |
549 |
@errors.cyclades.connection
|
472 |
550 |
@errors.plankton.id
|
473 |
551 |
@errors.plankton.metadata
|
474 |
552 |
def _run(self, image_id, key):
|
475 |
|
self.client.delete_image_metadata(image_id, key)
|
|
553 |
self._optional_output(self.client.delete_image_metadata(image_id, key))
|
476 |
554 |
|
477 |
555 |
def main(self, image_id, key):
|
478 |
556 |
super(self.__class__, self)._run()
|