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