}        #                where N is no negative integer
        # device name = the device name seen by guest kernel.
        # They are converted into
        # block_device_mapping/mapping/{virtual, device}
        #
        # Do NOT confuse this with ec2-register's block device mapping
        # argument.
        mappings = []
        try:
            block_device_mapping = manifest.findall('machine_configuration/'
                                                    'block_device_mapping/'
                                                    'mapping')
            for bdm in block_device_mapping:
                mappings.append({'virtual': bdm.find('virtual').text,
                                 'device': bdm.find('device').text})
        except Exception:
            mappings = []
        properties = metadata['properties']
        properties['architecture'] = arch
        def _translate_dependent_image_id(image_key, image_id):
            image_uuid = ec2utils.ec2_id_to_glance_id(context, image_id)
            properties[image_key] = image_uuid
        if kernel_id:
            _translate_dependent_image_id('kernel_id', kernel_id)
        if ramdisk_id:
            _translate_dependent_image_id('ramdisk_id', ramdisk_id)
        if mappings:
            properties['mappings'] = mappings
        metadata.update({'disk_format': image_format,
                         'container_format': image_format,
                         'status': 'queued',
                         'is_public': False,
                         'properties': properties})
        metadata['properties']['image_state'] = 'pending'
        #TODO(bcwaldon): right now, this removes user-defined ids.
        # We need to re-enable this.
        metadata.pop('id', None)
        image = self.service.create(context, metadata)
        # extract the new uuid and generate an int id to present back to user
        image_uuid = image['id']
        image['id'] = ec2utils.glance_id_to_id(context, image_uuid)
        # return image_uuid so the caller can still make use of image_service
        return manifest, image, image_uuid
**** CubicPower OpenStack Study ****
        def _translate_dependent_image_id(image_key, image_id):
            image_uuid = ec2utils.ec2_id_to_glance_id(context, image_id)
            properties[image_key] = image_uuid
        if kernel_id:
            _translate_dependent_image_id('kernel_id', kernel_id)
        if ramdisk_id:
            _translate_dependent_image_id('ramdisk_id', ramdisk_id)
        if mappings:
            properties['mappings'] = mappings
        metadata.update({'disk_format': image_format,
                         'container_format': image_format,
                         'status': 'queued',
                         'is_public': False,
                         'properties': properties})
        metadata['properties']['image_state'] = 'pending'
        #TODO(bcwaldon): right now, this removes user-defined ids.
        # We need to re-enable this.
        metadata.pop('id', None)
        image = self.service.create(context, metadata)
        # extract the new uuid and generate an int id to present back to user
        image_uuid = image['id']
        image['id'] = ec2utils.glance_id_to_id(context, image_uuid)
        # return image_uuid so the caller can still make use of image_service
        return manifest, image, image_uuid
**** CubicPower OpenStack Study ****
    def _s3_create(self, context, metadata):
        """Gets a manifest from s3 and makes an image."""
        image_path = tempfile.mkdtemp(dir=CONF.image_decryption_dir)
        image_location = metadata['properties']['image_location'].lstrip('/')
        bucket_name = image_location.split('/')[0]
        manifest_path = image_location[len(bucket_name) + 1:]
        bucket = self._conn(context).get_bucket(bucket_name)
        key = bucket.get_key(manifest_path)
        manifest = key.get_contents_as_string()
        manifest, image, image_uuid = self._s3_parse_manifest(context,
                                                              metadata,
                                                              manifest)
        def delayed_create():
            """This handles the fetching and decrypting of the part files."""
            context.update_store()
            log_vars = {'image_location': image_location,
                        'image_path': image_path}
            def _update_image_state(context, image_uuid, image_state):
                metadata = {'properties': {'image_state': image_state}}
                self.service.update(context, image_uuid, metadata,
                                    purge_props=False)
            def _update_image_data(context, image_uuid, image_data):
                metadata = {}
                self.service.update(context, image_uuid, metadata, image_data,
                                    purge_props=False)
            try:
                _update_image_state(context, image_uuid, 'downloading')
                try:
                    parts = []
                    elements = manifest.find('image').getiterator('filename')
                    for fn_element in elements:
                        part = self._download_file(bucket,
                                                   fn_element.text,
                                                   image_path)
                        parts.append(part)
                    # NOTE(vish): this may be suboptimal, should we use cat?
                    enc_filename = os.path.join(image_path, 'image.encrypted')
                    with open(enc_filename, 'w') as combined:
                        for filename in parts:
                            with open(filename) as part:
                                shutil.copyfileobj(part, combined)
                except Exception:
                    LOG.exception(_("Failed to download %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_download')
                    return
                _update_image_state(context, image_uuid, 'decrypting')
                try:
                    hex_key = manifest.find('image/ec2_encrypted_key').text
                    encrypted_key = binascii.a2b_hex(hex_key)
                    hex_iv = manifest.find('image/ec2_encrypted_iv').text
                    encrypted_iv = binascii.a2b_hex(hex_iv)
                    dec_filename = os.path.join(image_path, 'image.tar.gz')
                    self._decrypt_image(context, enc_filename, encrypted_key,
                                        encrypted_iv, dec_filename)
                except Exception:
                    LOG.exception(_("Failed to decrypt %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_decrypt')
                    return
                _update_image_state(context, image_uuid, 'untarring')
                try:
                    unz_filename = self._untarzip_image(image_path,
                                                        dec_filename)
                except Exception:
                    LOG.exception(_("Failed to untar %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_untar')
                    return
                _update_image_state(context, image_uuid, 'uploading')
                try:
                    with open(unz_filename) as image_file:
                        _update_image_data(context, image_uuid, image_file)
                except Exception:
                    LOG.exception(_("Failed to upload %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_upload')
                    return
                metadata = {'status': 'active',
                            'properties': {'image_state': 'available'}}
                self.service.update(context, image_uuid, metadata,
                        purge_props=False)
                shutil.rmtree(image_path)
            except exception.ImageNotFound:
                LOG.info(_("Image %s was deleted underneath us"), image_uuid)
                return
        eventlet.spawn_n(delayed_create)
        return image
**** CubicPower OpenStack Study ****
        def delayed_create():
            """This handles the fetching and decrypting of the part files."""
            context.update_store()
            log_vars = {'image_location': image_location,
                        'image_path': image_path}
            def _update_image_state(context, image_uuid, image_state):
                metadata = {'properties': {'image_state': image_state}}
                self.service.update(context, image_uuid, metadata,
                                    purge_props=False)
            def _update_image_data(context, image_uuid, image_data):
                metadata = {}
                self.service.update(context, image_uuid, metadata, image_data,
                                    purge_props=False)
            try:
                _update_image_state(context, image_uuid, 'downloading')
                try:
                    parts = []
                    elements = manifest.find('image').getiterator('filename')
                    for fn_element in elements:
                        part = self._download_file(bucket,
                                                   fn_element.text,
                                                   image_path)
                        parts.append(part)
                    # NOTE(vish): this may be suboptimal, should we use cat?
                    enc_filename = os.path.join(image_path, 'image.encrypted')
                    with open(enc_filename, 'w') as combined:
                        for filename in parts:
                            with open(filename) as part:
                                shutil.copyfileobj(part, combined)
                except Exception:
                    LOG.exception(_("Failed to download %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_download')
                    return
                _update_image_state(context, image_uuid, 'decrypting')
                try:
                    hex_key = manifest.find('image/ec2_encrypted_key').text
                    encrypted_key = binascii.a2b_hex(hex_key)
                    hex_iv = manifest.find('image/ec2_encrypted_iv').text
                    encrypted_iv = binascii.a2b_hex(hex_iv)
                    dec_filename = os.path.join(image_path, 'image.tar.gz')
                    self._decrypt_image(context, enc_filename, encrypted_key,
                                        encrypted_iv, dec_filename)
                except Exception:
                    LOG.exception(_("Failed to decrypt %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_decrypt')
                    return
                _update_image_state(context, image_uuid, 'untarring')
                try:
                    unz_filename = self._untarzip_image(image_path,
                                                        dec_filename)
                except Exception:
                    LOG.exception(_("Failed to untar %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_untar')
                    return
                _update_image_state(context, image_uuid, 'uploading')
                try:
                    with open(unz_filename) as image_file:
                        _update_image_data(context, image_uuid, image_file)
                except Exception:
                    LOG.exception(_("Failed to upload %(image_location)s "
                                    "to %(image_path)s"), log_vars)
                    _update_image_state(context, image_uuid, 'failed_upload')
                    return
                metadata = {'status': 'active',
                            'properties': {'image_state': 'available'}}
                self.service.update(context, image_uuid, metadata,
                        purge_props=False)
                shutil.rmtree(image_path)
            except exception.ImageNotFound:
                LOG.info(_("Image %s was deleted underneath us"), image_uuid)
                return
        eventlet.spawn_n(delayed_create)
        return image
**** CubicPower OpenStack Study ****
    def _decrypt_image(self, context, encrypted_filename, encrypted_key,
                       encrypted_iv, decrypted_filename):
        elevated = context.elevated()
        try:
            key = self.cert_rpcapi.decrypt_text(elevated,
                    project_id=context.project_id,
                    text=base64.b64encode(encrypted_key))
        except Exception as exc:
            msg = _('Failed to decrypt private key: %s') % exc
            raise exception.NovaException(msg)
        try:
            iv = self.cert_rpcapi.decrypt_text(elevated,
                    project_id=context.project_id,
                    text=base64.b64encode(encrypted_iv))
        except Exception as exc:
            raise exception.NovaException(_('Failed to decrypt initialization '
                                    'vector: %s') % exc)
        try:
            utils.execute('openssl', 'enc',
                          '-d', '-aes-128-cbc',
                          '-in', '%s' % (encrypted_filename,),
                          '-K', '%s' % (key,),
                          '-iv', '%s' % (iv,),
                          '-out', '%s' % (decrypted_filename,))
        except processutils.ProcessExecutionError as exc:
            raise exception.NovaException(_('Failed to decrypt image file '
                                    '%(image_file)s: %(err)s') %
                                    {'image_file': encrypted_filename,
                                     'err': exc.stdout})
    @staticmethod
**** CubicPower OpenStack Study ****
    def _test_for_malicious_tarball(path, filename):
        """Raises exception if extracting tarball would escape extract path."""
        tar_file = tarfile.open(filename, 'r|gz')
        for n in tar_file.getnames():
            if not os.path.abspath(os.path.join(path, n)).startswith(path):
                tar_file.close()
                raise exception.NovaException(_('Unsafe filenames in image'))
        tar_file.close()
    @staticmethod
**** CubicPower OpenStack Study ****
    def _untarzip_image(path, filename):
        S3ImageService._test_for_malicious_tarball(path, filename)
        tar_file = tarfile.open(filename, 'r|gz')
        tar_file.extractall(path)
        image_file = tar_file.getnames()[0]
        tar_file.close()
        return os.path.join(path, image_file)