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())))
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())))
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