Example #1
0
    def copy_volume_to_image(self, context, volume, image_service, image_meta):
        LOG.error('begin time of copy_volume_to_image is %s' %
                  (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        container_format = image_meta.get('container_format')
        file_name = image_meta.get('id')
        if container_format in ['fs_vgw_url', 'vcloud_vgw_url', 'aws_vgw_url']:
            LOG.debug('get the vgw url')
            vgw_url = CONF.vgw.vgw_url.get(container_format)
            #vgw_url = 'http://162.3.125.52:9999/'
            volume_id = volume['id']

            #1.get the provider_volume at provider cloud
            provider_volume_id = self._get_provider_volumeid_from_volume(
                volume)
            if not provider_volume_id:
                LOG.error('get provider_volume_id of volume %s error' %
                          volume_id)
                raise exception_ex.ProviderVolumeNotFound(volume_id=volume_id)
            provider_volume = self._get_provider_volume(provider_volume_id)
            if not provider_volume:
                LOG.error(
                    'get provider_volume of volume %s at provider cloud error'
                    % volume_id)
                raise exception_ex.ProviderVolumeNotFound(volume_id=volume_id)

            origin_provider_volume_state = provider_volume.extra.get(
                'attachment_status')
            origin_attach_node_id = None
            origin_device_name = None
            #2.judge if the volume is available
            if origin_provider_volume_state is not None:
                origin_attach_node_id = provider_volume.extra['instance_id']
                origin_device_name = provider_volume.extra['device']
                self.adpter.detach_volume(provider_volume)
                time.sleep(1)
                retry_time = 50
                provider_volume = self._get_provider_volume(provider_volume_id)
                while retry_time > 0:
                    if provider_volume and provider_volume.extra.get(
                            'attachment_status') is None:
                        break
                    else:
                        time.sleep(1)
                        provider_volume = self._get_provider_volume(
                            provider_volume_id)
                        retry_time = retry_time - 1
            #3.attach the volume to vgw host
            try:
                #3.1 get the vgw host
                vgw_host = self._get_provider_node(
                    self.configuration.cgw_host_id)
                if not vgw_host:
                    raise exception_ex.VgwHostNotFound(
                        Vgw_id=self.configuration.cgw_host_id)
                device_name = self._get_next_device_name(vgw_host)
                LOG.error('**********************************************')
                LOG.error('the volume status %s' % provider_volume.state)
                self.adpter.attach_volume(vgw_host, provider_volume,
                                          device_name)
                #query volume status
                time.sleep(1)
                retry_time = 120
                provider_volume = self._get_provider_volume(provider_volume_id)
                while retry_time > 0:
                    if provider_volume and provider_volume.extra.get(
                            'attachment_status') == 'attached':
                        break
                    else:
                        time.sleep(1)
                        provider_volume = self._get_provider_volume(
                            provider_volume_id)
                        retry_time = retry_time - 1

            except Exception as e:
                raise e
            time.sleep(5)
            conn = rpyc.connect(self.configuration.cgw_host_ip,
                                int(CONF.vgw.rpc_service_port))
            LOG.error('begin time of copy_volume_to_file is %s' %
                      (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
            full_file_path = conn.root.copy_volume_to_file(
                device_name, file_name, CONF.vgw.store_file_dir)
            LOG.error('end time of copy_volume_to_image is %s' %
                      (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
            #todo exception occured clean env
            if not full_file_path:
                self.adpter.detach_volume(provider_volume)
                conn.close()
                raise exception_ex.ProviderExportVolumeError(
                    volume_id=volume_id)
            LOG.error('begin time of push_file_to_vgw is %s' %
                      (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
            push_file_result = conn.root.exposed_push_file_to_vgw(
                full_file_path, vgw_url)
            LOG.error('end time of push_file_to_vgw is %s' %
                      (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
            if not push_file_result:
                LOG.error('post file file %s  to %s failed' %
                          (push_file_result, vgw_url))
                self.adpter.detach_volume(provider_volume)
                conn.close()
                raise exception_ex.ProviderExportVolumeError(
                    volume_id=volume_id)
            conn.close()
            #create a empty file to glance
            with image_utils.temporary_file() as tmp:
                image_utils.upload_volume(context, image_service, image_meta,
                                          tmp)
            fileutils.delete_if_exists(tmp)
            #4.detach form vgw
            self.adpter.detach_volume(provider_volume)
            time.sleep(1)
            retry_time = 120
            provider_volume = self._get_provider_volume(provider_volume_id)
            while retry_time > 0:
                if provider_volume and provider_volume.extra.get(
                        'attachment_status') is None:
                    break
                else:
                    time.sleep(1)
                    provider_volume = self._get_provider_volume(
                        provider_volume_id)
                    retry_time = retry_time - 1
            LOG.error('**********************************************')
            LOG.error('the volume status %s' % provider_volume.state)
            #attach the volume back
            if origin_provider_volume_state is not None:
                origin_attach_node = self._get_provider_node(
                    origin_attach_node_id)

                self.adpter.attach_volume(origin_attach_node, provider_volume,
                                          origin_device_name)

        else:
            if not os.path.exists(
                    self.configuration.provider_image_conversion_dir):
                fileutils.ensure_tree(
                    self.configuration.provider_image_conversion_dir)
            provider_volume_id = self._get_provider_volumeid_from_volume(
                volume)
            task_ret = self.adpter.export_volume(
                provider_volume_id,
                self.configuration.provider_image_conversion_dir,
                str(image_meta['id']),
                cgw_host_id=self.configuration.cgw_host_id,
                cgw_host_ip=self.configuration.cgw_host_ip,
                cgw_username=self.configuration.cgw_username,
                cgw_certificate=self.configuration.cgw_certificate,
                transfer_station=self.configuration.storage_tmp_dir)
            if not task_ret:
                raise exception_ex.ProviderExportVolumeError
            temp_path = os.path.join(
                self.configuration.provider_image_conversion_dir,
                str(image_meta['id']))
            upload_image = temp_path

            try:
                image_utils.upload_volume(context, image_service, image_meta,
                                          upload_image)
            finally:
                fileutils.delete_if_exists(upload_image)
        LOG.error('end time of copy_volume_to_image is %s' %
                  (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
Example #2
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        LOG.error('begin time of copy_image_to_volume is %s' %
                  (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        image_meta = image_service.show(context, image_id)
        container_format = image_meta.get('container_format')
        if container_format in ['fs_vgw_url', 'vcloud_vgw_url', 'aws_vgw_url']:
            #1.get the provider_volume at provider cloud
            provider_volume_id = self._get_provider_volumeid_from_volume(
                volume)
            retry_time = 10
            provider_volume = self._get_provider_volume(provider_volume_id)
            while retry_time > 0:
                if provider_volume and \
                   provider_volume.state == StorageVolumeState.AVAILABLE and \
                   provider_volume.extra.get('attachment_status') is None:
                    break
                else:
                    time.sleep(1)
                    provider_volume = self._get_provider_volume(
                        provider_volume_id)
                    retry_time = retry_time - 1
            try:
                #3.1 get the vgw host
                vgw_host = self._get_provider_node(
                    self.configuration.cgw_host_id)
                if not vgw_host:
                    raise exception_ex.VgwHostNotFound(
                        Vgw_id=self.configuration.cgw_host_id)
                device_name = self._get_next_device_name(vgw_host)
                self.adpter.attach_volume(vgw_host, provider_volume,
                                          device_name)
                #query volume status
                time.sleep(1)
                retry_time = 10
                provider_volume = self._get_provider_volume(provider_volume_id)
                while retry_time > 0:
                    if provider_volume and provider_volume.extra.get(
                            'attachment_status') == 'attached':
                        break
                    else:
                        time.sleep(1)
                        provider_volume = self._get_provider_volume(
                            provider_volume_id)
                        retry_time = retry_time - 1
                LOG.error('**********************************************')
                LOG.error('the volume status %s' % provider_volume.state)
                conn = rpyc.connect(self.configuration.cgw_host_ip,
                                    int(CONF.vgw.rpc_service_port))

                copy_file_to_device_result = conn.root.copy_file_to_volume(
                    image_id, CONF.vgw.store_file_dir, device_name)
                if not copy_file_to_device_result:
                    LOG.error("qemu-img convert %s %s failed" %
                              (image_id, device_name))
                    self.adpter.detach_volume(provider_volume)
                    conn.close()
                    raise exception.ImageUnacceptable(
                        reason=("copy image %s file to volume %s failed " %
                                (image_id, volume['id'])))
                conn.close()
                self.adpter.detach_volume(provider_volume)
                while retry_time > 0:
                    if provider_volume and provider_volume.extra.get(
                            'attachment_status') is None:
                        break
                    else:
                        time.sleep(1)
                        provider_volume = self._get_provider_volume(
                            provider_volume_id)
                        retry_time = retry_time - 1

                LOG.error('**********************************************')
                LOG.error('the volume status %s' % provider_volume.state)

            except Exception as e:
                raise e
        else:
            pass

        LOG.error('end time of copy_image_to_volume is %s' %
                  (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
Example #3
0
    def copy_image_to_volume(self, context, volume, image_service, image_id):
        LOG.error('begin time of copy_image_to_volume is %s' %(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
        image_meta = image_service.show(context, image_id)
        container_format=image_meta.get('container_format')
        if container_format == 'vgw_url':
            #1.get the provider_volume at provider cloud  
            provider_volume_id = self._get_provider_volumeid_from_volume(volume)
            retry_time = 10
            provider_volume=self._get_provider_volume(provider_volume_id)
            while retry_time > 0:
                if provider_volume and \
                   provider_volume.state == StorageVolumeState.AVAILABLE and \
                   provider_volume.extra.get('attachment_status') is None:
                    break
                else:
                    time.sleep(1)
                    provider_volume=self._get_provider_volume(provider_volume_id)
                    retry_time = retry_time-1
            try:
                #3.1 get the vgw host
                vgw_host= self._get_provider_node(self.configuration.cgw_host_id)
                if not vgw_host:
                    raise exception_ex.VgwHostNotFound(Vgw_id=self.configuration.cgw_host_id)
                device_name=self._get_next_device_name(vgw_host)
                self.adpter.attach_volume(vgw_host, provider_volume,
                                       device_name)
                #query volume status
                time.sleep(1)
                retry_time = 10
                provider_volume=self._get_provider_volume(provider_volume_id)
                while retry_time > 0:
                    if provider_volume and provider_volume.extra.get('attachment_status') =='attached':
                        break
                    else:
                        time.sleep(1)
                        provider_volume=self._get_provider_volume(provider_volume_id)
                        retry_time = retry_time-1
                LOG.error('**********************************************')
                LOG.error('the volume status %s' %provider_volume.state)
                conn=rpyc.connect(self.configuration.cgw_host_ip,int(CONF.vgw.rpc_service_port))
                
                copy_file_to_device_result = conn.root.copy_file_to_volume(image_id,CONF.vgw.store_file_dir,device_name)
                if not copy_file_to_device_result:
                    LOG.error("qemu-img convert %s %s failed" %(image_id,device_name)) 
                    self.adpter.detach_volume(provider_volume)
                    conn.close()
                    raise exception.ImageUnacceptable(
                        reason= ("copy image %s file to volume %s failed " %(image_id,volume['id'])))
                conn.close()   
                self.adpter.detach_volume(provider_volume)
                retry_time = 10
                while retry_time > 0:
                    if provider_volume and provider_volume.extra.get('attachment_status') is None:
                        break
                    else:
                        time.sleep(1)
                        provider_volume=self._get_provider_volume(provider_volume_id)
                        retry_time = retry_time-1
                
                LOG.error('**********************************************')
                LOG.error('the volume status %s' %provider_volume.state)
                              
            except Exception as e:
                raise e
        elif container_format == 'hypervm':
            # 0.get provider_image,
            image_uuid = self._get_image_id_from_meta(image_meta)
            provider_image = self._get_provider_image(image_meta)
            if provider_image is None:
                LOG.error('Get image %s error at provider cloud' % image_uuid)
                return
            # create provider node with hypervm volume
            provider_bdm = None
            size = volume.get('size')
            name = volume.get('display_name')
            provider_size = self._get_provider_node_size('m1.tiny')
            provider_tmp_volume = self.adpter.create_volume(size, name)
            provider_snap = self.adpter.create_volume_snapshot(provider_tmp_volume)
            self._wait_for_snapshot_completed(list(provider_snap.id))
            hypervm_bdm = {'DeviceName': '/dev/sdz',
                           'Ebs': {'SnapshotId': provider_snap.id,
                                   'DeleteOnTermination': True}
                           }
            provider_bdm.append(hypervm_bdm)
            provider_node_name = image_uuid

            try:
                provider_node = self.adpter.create_node(name = provider_node_name,
                                                                 image = provider_image,
                                                                 size=  provider_size,
                                                                 location=CONF.provider_opts.availability_zone,
                                                                 # ex_subnet=provider_subnet_data,
                                                                 ex_security_group_ids =self.provider_security_group_id,
                                                                 ex_blockdevicemappings = provider_bdm)
                                                                 # ex_network_interfaces=self.provider_interfaces,
                                                                 # ex_userdata=user_data,
                                                                 # auth=self._get_auth(instance._key_data,
                                                                 # instance._key_name)
            except Exception as e:
                LOG.warning('Provider instance is booting error')
                LOG.error(e.message)
                provider_node = self.adpter.list_nodes(ex_filters={'tag:name': provider_node_name})
                if not provider_node:
                    raise e
            # wait for node avalaible
            while provider_node.state != NodeState.RUNNING :
                try:
                    provider_nodes = self.adpter.list_nodes(ex_node_ids=[provider_node.id])
                    if len(provider_nodes) == 0:
                        break
                    else:
                        provider_node = provider_nodes[0]
                except Exception as e:
                    LOG.warning('Provider instance is booting but adapter is failed to get status. Try it later')
                time.sleep(10)

            provider_bdm_list = provider_node.extra.get('block_device_mapping')
            provider_volume_id = provider_bdm_list[0].get('ebs').get('volume_id')
            provider_volume = self.adpter.list_volumes(ex_volume_ids=[provider_volume_id])
            self.adpter.destroy_volume(provider_tmp_volume)
            # 7.2 create docker app
            base_ip = provider_node.private_ips[0]
            self._client = Client('http://%s' % base_ip + ':%s' % HYPER_SERVICE_PORT)
            self._client.config_network_service(CONF.rabbit_userid, CONF.rabbit_password, CONF.rabbit_host)
            self._client.create_container(image_meta.get('name', ''))
            self._client.start(network_info=network_info, block_device_info=block_device_info)
            # wait for docker running
            self.adpter.ex_stop_node(provider_node)
            # wait for node stoped
            while provider_node.state != NodeState.STOPPED:
                try:
                    provider_nodes = self.adpter.list_nodes(ex_node_ids=[provider_node.id])
                    if len(provider_nodes) == 0:
                        break
                    else:
                        provider_node = provider_nodes[0]
                except Exception as e:
                    LOG.warning('Provider instance is stop but adapter is failed to get status. Try it later')
                time.sleep(10)
            self.adpter.detach_volume(provider_volume)
            retry_time = 10
            while retry_time > 0:
                if provider_volume and provider_volume.extra.get('attachment_status') is None:
                    break
                else:
                    time.sleep(10)
                    provider_volume = self._get_provider_volume(provider_volume_id)
                    retry_time -= 1
            if (not provider_volume) or (provider_volume.extra.get('attachment_status') is not None):
                LOG.error('detach volume failed')
                raise Exception('detach volume failed')
            self.adpter.destroy_node(provider_volume)
            # map volume to provider volume
            create_tags_func = getattr(self.adpter, 'ex_create_tags')
            if create_tags_func:
                create_tags_func(provider_volume, {'hybrid_cloud_volume_id': volume['id']})
            ctx = cinder.context.get_admin_context()
            if ctx:
                self.db.volume_metadata_update(ctx, volume['id'], {'provider_volume_id': provider_volume.id}, False)
            model_update = {'provider_location': provider_volume.id}
            return model_update