Revision 00336c85 kamaki/cli/commands/image.py
b/kamaki/cli/commands/image.py | ||
---|---|---|
39 | 39 |
from kamaki.cli.command_tree import CommandTree |
40 | 40 |
from kamaki.cli.utils import print_dict, print_items, print_json |
41 | 41 |
from kamaki.clients.image import ImageClient |
42 |
from kamaki.clients.pithos import PithosClient |
|
43 |
from kamaki.clients.astakos import AstakosClient |
|
44 |
from kamaki.clients import ClientError |
|
42 | 45 |
from kamaki.cli.argument import FlagArgument, ValueArgument, KeyValueArgument |
43 | 46 |
from kamaki.cli.argument import IntArgument |
44 | 47 |
from kamaki.cli.commands.cyclades import _init_cyclades |
45 | 48 |
from kamaki.cli.commands import _command_init, errors, _optional_output_cmd |
49 |
from kamaki.cli.errors import raiseCLIError |
|
46 | 50 |
|
47 | 51 |
|
48 | 52 |
image_cmds = CommandTree( |
... | ... | |
262 | 266 |
# ('-u', '--update')), |
263 | 267 |
json_output=FlagArgument('Show results in json', ('-j', '--json')), |
264 | 268 |
property_file=ValueArgument( |
265 |
'Load properties from a json-formated file. Contents:'
|
|
269 |
'Load properties from a json-formated file <img-file>.meta :'
|
|
266 | 270 |
'{"key1": "val1", "key2": "val2", ...}', |
267 |
('--property-file')) |
|
271 |
('--property-file')), |
|
272 |
prop_file_force=FlagArgument( |
|
273 |
'Store remote property object, even it already exists', |
|
274 |
('-f', '--force-upload-property-file')), |
|
275 |
no_prop_file_upload=FlagArgument( |
|
276 |
'Do not store properties in remote property file', |
|
277 |
('--no-property-file-upload')), |
|
278 |
container=ValueArgument( |
|
279 |
'Remote image container', ('-C', '--container')), |
|
280 |
fileowner=ValueArgument( |
|
281 |
'UUID of the user who owns the image file', ('--fileowner')) |
|
268 | 282 |
) |
269 | 283 |
|
284 |
def _get_uuid(self): |
|
285 |
uuid = self['fileowner'] or self.config.get('image', 'fileowner') |
|
286 |
if uuid: |
|
287 |
return uuid |
|
288 |
atoken = self.client.token |
|
289 |
user = AstakosClient(self.config.get('user', 'url'), atoken) |
|
290 |
return user.term('uuid') |
|
291 |
|
|
292 |
def _get_pithos_client(self, uuid, container): |
|
293 |
purl = self.config.get('file', 'url') |
|
294 |
ptoken = self.client.token |
|
295 |
return PithosClient(purl, ptoken, uuid, container) |
|
296 |
|
|
297 |
def _store_remote_property_file(self, pclient, remote_path, properties): |
|
298 |
return pclient.upload_from_string( |
|
299 |
remote_path, _validate_image_props(properties, return_str=True)) |
|
300 |
|
|
301 |
def _get_container_path(self, container_path): |
|
302 |
container = self['container'] or self.config.get('image', 'container') |
|
303 |
if container: |
|
304 |
return container, container_path |
|
305 |
|
|
306 |
container, sep, path = container_path.partition(':') |
|
307 |
if not sep or not container or not path: |
|
308 |
raiseCLIError( |
|
309 |
'%s is not a valid pithos remote location' % container_path, |
|
310 |
details=[ |
|
311 |
'To set "image" as container and "my_dir/img.diskdump" as', |
|
312 |
'the image path, try one of the following as ' |
|
313 |
'container:path', |
|
314 |
'- <image container>:<remote path>', |
|
315 |
' e.g. image:/my_dir/img.diskdump', |
|
316 |
'- <remote path> -C <image container>', |
|
317 |
' e.g. /my_dir/img.diskdump -C image']) |
|
318 |
return container, path |
|
319 |
|
|
270 | 320 |
@errors.generic.all |
271 | 321 |
@errors.plankton.connection |
272 |
def _run(self, name, location): |
|
273 |
if not location.startswith('pithos://'): |
|
274 |
account = self.config.get('file', 'account') \ |
|
275 |
or self.config.get('global', 'account') |
|
276 |
assert account, 'No user account provided' |
|
277 |
if account[-1] == '/': |
|
278 |
account = account[:-1] |
|
279 |
container = self.config.get('file', 'container') \ |
|
280 |
or self.config.get('global', 'container') |
|
281 |
if not container: |
|
282 |
location = 'pithos://%s/%s' % (account, location) |
|
283 |
else: |
|
284 |
location = 'pithos://%s/%s/%s' % (account, container, location) |
|
322 |
def _run(self, name, container_path): |
|
323 |
container, path = self._get_container_path(container_path) |
|
324 |
uuid = self._get_uuid() |
|
325 |
prop_path = '%s.meta' % path |
|
326 |
|
|
327 |
pclient = None if ( |
|
328 |
self['no_prop_file_upload']) else self._get_pithos_client( |
|
329 |
uuid, container) |
|
330 |
if pclient and not self['prop_file_force']: |
|
331 |
try: |
|
332 |
pclient.get_object_info(prop_path) |
|
333 |
raiseCLIError('Property file %s: %s already exists' % ( |
|
334 |
container, prop_path)) |
|
335 |
except ClientError as ce: |
|
336 |
if ce.status != 404: |
|
337 |
raise |
|
338 |
|
|
339 |
location = 'pithos://%s/%s/%s' % (uuid, container, path) |
|
285 | 340 |
|
286 | 341 |
params = {} |
287 | 342 |
for key in set([ |
... | ... | |
301 | 356 |
printer = print_json if self['json_output'] else print_dict |
302 | 357 |
printer(self.client.register(name, location, params, properties)) |
303 | 358 |
|
304 |
def main(self, name, location): |
|
359 |
if pclient: |
|
360 |
prop_headers = pclient.upload_from_string( |
|
361 |
prop_path, _validate_image_props(properties, return_str=True)) |
|
362 |
print('Property file location is %s: %s' % (container, prop_path)) |
|
363 |
print('\twith version %s' % prop_headers['x-object-version']) |
|
364 |
|
|
365 |
def main(self, name, container___path): |
|
305 | 366 |
super(self.__class__, self)._run() |
306 |
self._run(name, location)
|
|
367 |
self._run(name, container___path)
|
|
307 | 368 |
|
308 | 369 |
|
309 | 370 |
@command(image_cmds) |
Also available in: Unified diff