def _handle_dv_for_svm(self, context, vol_res, server_id, dev_name, gw_id, gw_ip, undo_mgr): volume_id = vol_res.id LOG.debug('detach the volume %s form server %s', volume_id, server_id) self.compute_api.detach_volume(context, server_id, volume_id) undo_mgr.undo_with(functools.partial(self._attach_volume, context, server_id, volume_id, dev_name)) self._wait_for_volume_status(context, volume_id, server_id, 'available') client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) self.compute_api.attach_volume(context, gw_id, volume_id, None) LOG.debug('attach volume %s to gw host %s', volume_id, gw_id) undo_mgr.undo_with(functools.partial(self._detach_volume, context, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks LOG.debug('begin get info for volume,the vgw ip %s' % gw_ip) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port)) # sys_dev_name = client.vservices.get_disk_name(volume_id).get( # 'dev_name') # sys_dev_name = device_name # sys_dev_name = attach_resp._info.get('device') sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("dev_name = %s", sys_dev_name) vol_res.extra_properties['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: vol_res.extra_properties['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) vol_res.extra_properties['mount_point'] = mount_point.get( 'mount_disk')
def _handle_sv_for_svm(self, context, vol_res, gw_id, gw_ip, undo_mgr): volume_id = vol_res.id LOG.debug('Set the volume %s shareable', volume_id) self.volume_api.set_volume_shareable(context, volume_id, True) undo_mgr.undo_with(functools.partial(self._set_volume_shareable, context, volume_id, False)) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) self.compute_api.attach_volume(context, gw_id, volume_id, None) LOG.debug('Attach the volume %s to gw host %s ', volume_id, gw_id) undo_mgr.undo_with(functools.partial(self._detach_volume, context, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks LOG.debug('Begin get info for volume,the vgw ip %s' % gw_ip) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port)) # sys_dev_name = client.vservices.get_disk_name(volume_id).get( # 'dev_name') # sys_dev_name = device_name # sys_dev_name = attach_resp._info.get('device') sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("dev_name = %s", sys_dev_name) vol_res.extra_properties['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: vol_res.extra_properties['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) vol_res.extra_properties['mount_point'] = mount_point.get( 'mount_disk')
def _handle_volume_for_vm_after_clone(self, context, server_resource, resources): bdms = server_resource['properties'].get('block_device_mapping_v2', []) vgw_id = server_resource.get('extra_properties', {}).get('gw_id') sys_clone = server_resource.get('extra_properties', {}) \ .get('sys_clone') for bdm in bdms: volume_key = bdm.get('volume_id', {}).get('get_resource') boot_index = bdm.get('boot_index') device_name = bdm.get('device_name') volume_res = resources.get(volume_key) volume_id = volume_res.get('extra_properties', {}) \ .get('id') vgw_url = volume_res.get('extra_properties', {}) \ .get('gw_url') vgw_ip = vgw_url.split(':')[0] if not sys_clone and boot_index in ['0', 0]: continue try: client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port)) client.vservices._force_umount_disk("/opt/" + volume_id) self.nova_api.detach_volume(context, vgw_id, volume_id) self._wait_for_volume_status(context, volume_id, vgw_id, 'available') server_id = server_resource.get('extra_properties', {}) \ .get('id') self.nova_api.attach_volume(context, server_id, volume_id, device_name) self._wait_for_volume_status(context, volume_id, server_id, 'in-use') except Exception as e: LOG.error( _LE('Error from handle volume of vm after clone. ' 'Error=%(e)s'), {'e': e})
def _add_extra_prop_for_dep_in_use_volume(self, context, resource, copy_data, undo_mgr): volume_id = resource.extra_properties.get('id') volume = self.volume_api.get(context, volume_id) v_shareable = volume['shareable'] gw_url = resource.extra_properties.get('gw_url') gw_id = None gw_ip = None if not gw_url: az = resource.properties.get('availability_zone') gw_id, gw_ip = utils.get_next_vgw(az) if not gw_id or not gw_ip: raise exception.V2vException(message='no vgw host found') gw_url = gw_ip + ':' + str(CONF.v2vgateway_api_listen_port) resource.extra_properties.update({ "gw_url": gw_url, "gw_id": gw_id }) if not v_shareable: v_attachments = volume.get('attachments', []) resource.extra_properties['attachments'] = v_attachments for attachment in v_attachments: server_id = attachment.get('server_id') server_info = self.compute_api.get_server(context, server_id) vm_state = server_info.get('OS-EXT-STS:vm_state', None) if vm_state != 'stopped': _msg = 'the server %s not stopped' % server_id raise exception.V2vException(message=_msg) device = attachment.get('device') self.compute_api.detach_volume(context, server_id, volume_id) self._wait_for_volume_status(context, volume_id, server_id, 'available') undo_mgr.undo_with( functools.partial(self._attach_volume, context, server_id, volume_id, device)) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port)) disks = set(client.vservices.get_disk_name().get('dev_name')) LOG.debug('Attach volume %s to gw host %s', volume_id, gw_id) attach_resp = self.compute_api.attach_volume(context, gw_id, volume_id, None) LOG.debug('The volume attachment info is %s ' % str(attach_resp)) undo_mgr.undo_with( functools.partial(self._detach_volume, context, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks LOG.debug('Begin get info for volume,the vgw ip %s' % gw_ip) sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("dev_name = %s", sys_dev_name) resource.extra_properties['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: resource.extra_properties['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) resource.extra_properties['mount_point'] = mount_point.get( 'mount_disk')
def _handle_volume_for_svm_after_clone(self, context, server_resource, resources): bdms = server_resource['properties'].get('block_device_mapping_v2', []) vgw_id = server_resource.get('extra_properties', {}).get('gw_id') for bdm in bdms: volume_key = bdm.get('volume_id', {}).get('get_resource') boot_index = bdm.get('boot_index') device_name = bdm.get('device_name') volume_res = resources.get(volume_key) try: if volume_res.get('extra_properties', {}).get('is_deacidized'): volume_id = volume_res.get('extra_properties', {}) \ .get('id') vgw_url = volume_res.get('extra_properties', {}) \ .get('gw_url') sys_clone = volume_res.get('extra_properties', {}) \ .get('sys_clone') copy_data = volume_res.get('extra_properties', {}). \ get('copy_data') if (boot_index in ['0', 0] and not sys_clone) or \ not copy_data: continue vgw_ip = vgw_url.split(':')[0] client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port)) if boot_index not in ['0', 0] or sys_clone: client.vservices._force_umount_disk( "/opt/" + volume_id) # if provider cloud can not detcah volume in active status if not CONF.is_active_detach_volume: resouce_common = common.ResourceCommon() self.compute_api.stop_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'SHUTOFF') self.compute_api.detach_volume(context, vgw_id, volume_id) self._wait_for_volume_status(context, volume_id, vgw_id, 'available') server_id = server_resource.get('extra_properties', {}) \ .get('id') self.compute_api.attach_volume(context, server_id, volume_id, device_name) self._wait_for_volume_status(context, volume_id, server_id, 'in-use') if not CONF.is_active_detach_volume: self.compute_api.start_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'ACTIVE') except Exception as e: LOG.error(_LE('Error from handle volume of vm after' ' clone.' 'Error=%(e)s'), {'e': e})
def _handle_dep_volume(self, context, resource, gw_id, gw_ip, undo_mgr): volume_id = resource.id LOG.debug('Attach volume %s to gw host %s', volume_id, gw_id) # query disk list before attaching (add wanggang) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) self.compute_api.attach_volume(context, gw_id, volume_id, None) undo_mgr.undo_with(functools.partial(self._detach_volume, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks resource.extra_properties['status'] = 'in-use' LOG.debug('Begin get info for volume,the vgw ip %s' % gw_ip) # client = birdiegatewayclient.get_birdiegateway_client( # gw_ip, # str(CONF.v2vgateway_api_listen_port) # ) # sys_dev_name = client.vservices.get_disk_name(volume_id).get( # 'dev_name') # sys_dev_name = device_name # sys_dev_name = attach_resp._info.get('device') sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("in _handle_dep_volume dev_name = %s", sys_dev_name) resource.extra_properties['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: resource.extra_properties['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) resource.extra_properties['mount_point'] = mount_point.get( 'mount_disk' )
def _handle_dep_volume_after_clone(self, context, resource): volume_id = resource.get('extra_properties', {}).get('id') extra_properties = resource.get('extra_properties', {}) vgw_id = extra_properties.get('gw_id') if not extra_properties.get('copy_data', True): return if vgw_id: try: mount_point = resource.get('extra_properties', {}) \ .get('mount_point') if mount_point: vgw_url = resource.get('extra_properties', {}) \ .get('gw_url') vgw_ip = vgw_url.split(':')[0] client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port)) client.vservices._force_umount_disk( "/opt/" + volume_id) # if provider cloud can not detach volume in active status resouce_common = common.ResourceCommon() if not CONF.is_active_detach_volume: # resouce_common = common.ResourceCommon() self.compute_api.stop_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'SHUTOFF') self.compute_api.detach_volume(context, vgw_id, volume_id) self._wait_for_volume_status(context, volume_id, vgw_id, 'available') if not CONF.is_active_detach_volume: self.compute_api.start_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'ACTIVE') except Exception as e: LOG.error(_LE('Error from handle volume of vm after clone.' 'Error=%(e)s'), {'e': e})
def _handle_dep_volume_after_clone(self, context, resource): volume_id = resource.get('extra_properties', {}).get('id') if not resource.get('extra_properties', {}).get('copy_data'): return if resource.get('extra_properties', {}).get('is_deacidized'): extra_properties = resource.get('extra_properties', {}) vgw_id = extra_properties.get('gw_id') if vgw_id: try: mount_point = resource.get('extra_properties', {}) \ .get('mount_point') if mount_point: vgw_url = resource.get('extra_properties', {}) \ .get('gw_url') vgw_ip = vgw_url.split(':')[0] client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port)) client.vservices._force_umount_disk("/opt/" + volume_id) # if provider cloud can not detach volume in active status if not CONF.is_active_detach_volume: resouce_common = common.ResourceCommon() self.compute_api.stop_server(context, vgw_id) resouce_common._await_instance_status( context, vgw_id, 'SHUTOFF') self.compute_api.detach_volume(context, vgw_id, volume_id) self._wait_for_volume_status(context, volume_id, vgw_id, 'available') if not CONF.is_active_detach_volume: self.compute_api.start_server(context, vgw_id) resouce_common._await_instance_status( context, vgw_id, 'ACTIVE') except Exception as e: LOG.error( _LE('Error from handle volume of ' 'vm after clone. Error=%(e)s'), {'e': e})
def _handle_dep_volume(self, context, resource, gw_id, gw_ip, undo_mgr): volume_id = resource.id LOG.debug('Attach volume %s to gw host %s', volume_id, gw_id) # query disk list before attaching (add wanggang) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port)) disks = set(client.vservices.get_disk_name().get('dev_name')) self.compute_api.attach_volume(context, gw_id, volume_id, None) undo_mgr.undo_with( functools.partial(self._detach_volume, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks resource.extra_properties['status'] = 'in-use' LOG.debug('Begin get info for volume,the vgw ip %s' % gw_ip) # client = birdiegatewayclient.get_birdiegateway_client( # gw_ip, # str(CONF.v2vgateway_api_listen_port) # ) # sys_dev_name = client.vservices.get_disk_name(volume_id).get( # 'dev_name') # sys_dev_name = device_name # sys_dev_name = attach_resp._info.get('device') sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("in _handle_dep_volume dev_name = %s", sys_dev_name) resource.extra_properties['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: resource.extra_properties['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) resource.extra_properties['mount_point'] = mount_point.get( 'mount_disk')
def _handle_volume_for_vm_after_clone(self, context, server_resource, resources): bdms = server_resource['properties'].get('block_device_mapping_v2', []) vgw_id = server_resource.get('extra_properties', {}).get('gw_id') sys_clone = server_resource.get('extra_properties', {}) \ .get('sys_clone') for bdm in bdms: volume_key = bdm.get('volume_id', {}).get('get_resource') boot_index = bdm.get('boot_index') device_name = bdm.get('device_name') volume_res = resources.get(volume_key) volume_id = volume_res.get('extra_properties', {}) \ .get('id') vgw_url = volume_res.get('extra_properties', {}) \ .get('gw_url') vgw_ip = vgw_url.split(':')[0] if not sys_clone and boot_index in ['0', 0]: continue try: client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port)) client.vservices._force_umount_disk("/opt/" + volume_id) self.nova_api.detach_volume(context, vgw_id, volume_id) self._wait_for_volume_status(context, volume_id, vgw_id, 'available') server_id = server_resource.get('extra_properties', {}) \ .get('id') self.nova_api.attach_volume(context, server_id, volume_id, device_name) self._wait_for_volume_status(context, volume_id, server_id, 'in-use') except Exception as e: LOG.error(_LE('Error from handle volume of vm after clone. ' 'Error=%(e)s'), {'e': e})
def _copy_volume_data(self, context, resource_name, des_gw_ip, vgw_id, template, dev_name): LOG.debug('Clone volume driver copy data start for %s', resource_name) resources = template.get('resources') volume_res = resources.get(resource_name) volume_id = volume_res.get('id') volume_ext_properties = volume_res.get('extra_properties') # 1. get gateway vm conveyor agent service ip and port des_gw_port = str(CONF.v2vgateway_api_listen_port) des_gw_url = des_gw_ip + ':' + des_gw_port # data transformer procotol(ftp/fillp) data_trans_protocol = CONF.data_transformer_procotol # data_trans_ports = CONF.trans_ports # trans_port = data_trans_ports[0] trans_port = utils.get_next_port_for_vgw(vgw_id) # 2. get source cloud gateway vm conveyor agent service ip and port src_gw_url = volume_ext_properties.get('gw_url') src_urls = src_gw_url.split(':') if len(src_urls) != 2: LOG.error("Input source gw url error: %s", src_gw_url) msg = "Input source gw url error: " + src_gw_url raise exception.InvalidInput(reason=msg) src_gw_ip = src_urls[0] src_gw_port = src_urls[1] # 3. get volme mount point and disk format info boot_index = 1 src_mount_point = "/opt/" + volume_id if volume_ext_properties: src_dev_format = volume_ext_properties.get('guest_format') # volume dev name in system src_vol_sys_dev = volume_ext_properties.get('sys_dev_name') boot_index = volume_ext_properties.get('boot_index', 1) if dev_name: des_dev_name = dev_name else: des_dev_name = src_vol_sys_dev if not src_dev_format: client = birdiegatewayclient.get_birdiegateway_client(src_gw_ip, src_gw_port) d_fromat = client.vservices.get_disk_format(src_vol_sys_dev) src_dev_format = d_fromat.get('disk_format') # if disk does not format, then no data to copy if not src_dev_format and data_trans_protocol == 'ftp': rsp = {'volume_id': volume_id, 'des_ip': None, 'des_port': None, 'copy_tasks': None} return rsp mount_point = [] task_ids = [] if boot_index not in[0, '0'] and data_trans_protocol == 'ftp': mount_point.append(src_mount_point) # 4. copy data client = birdiegatewayclient.get_birdiegateway_client(des_gw_ip, des_gw_port) clone_rsp = client.vservices.clone_volume( src_vol_sys_dev, des_dev_name, src_dev_format, mount_point, src_gw_url, des_gw_url, trans_protocol=data_trans_protocol, trans_port=trans_port) task_id = clone_rsp.get('body').get('task_id') task_ids.append(task_id) rsp = {'volume_id': volume_id, 'des_ip': des_gw_ip, 'des_port': des_gw_port, 'copy_tasks': task_ids} LOG.debug('Clone volume driver copy data end for %s', resource_name) return rsp
def _handle_volume_for_stack(self, context, vol_res, gw_id, gw_ip, undo_mgr): volume_id = vol_res.get('id') volume_info = self.volume_api.get(context, volume_id) volume_status = volume_info['status'] v_shareable = volume_info['shareable'] if not v_shareable and volume_status == 'in-use': volume_attachments = volume_info.get('attachments', []) vol_res.get('extra_properties')['attachments'] = volume_attachments for attachment in volume_attachments: server_id = attachment.get('server_id') server_info = self.compute_api.get_server(context, server_id) vm_state = server_info.get('OS-EXT-STS:vm_state', None) if vm_state != 'stopped': _msg = 'the server %s not stopped' % server_id raise exception.V2vException(message=_msg) device = attachment.get('device') self.compute_api.detach_volume(context, server_id, volume_id) self._wait_for_volume_status(context, volume_id, server_id, 'available') undo_mgr.undo_with(functools.partial(self._attach_volume, context, server_id, volume_id, device)) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) LOG.debug('Attach volume %s to gw host %s', volume_id, gw_id) attach_resp = self.compute_api.attach_volume(context, gw_id, volume_id, None) LOG.debug('The volume attachment info is %s ' % str(attach_resp)) undo_mgr.undo_with(functools.partial(self._detach_volume, context, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks vol_res.get('extra_properties')['status'] = 'in-use' LOG.debug('Begin get info for volume,the vgw ip %s' % gw_ip) sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("dev_name = %s", sys_dev_name) # device_name = attach_resp._info.get('device') # sys_dev_name = client.vservices.get_disk_name(volume_id).get( # 'dev_name') # sys_dev_name = device_name vol_res.get('extra_properties')['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: vol_res.get('extra_properties')['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) vol_res.get('extra_properties')['mount_point'] = mount_point.get( 'mount_disk')
def add_extra_properties_for_server(self, context, resource, resource_map, sys_clone, copy_data, undo_mgr): migrate_net_map = CONF.migrate_net_map server_properties = resource.properties server_id = resource.id server_extra_properties = resource.extra_properties server_az = server_properties.get('availability_zone') vm_state = server_extra_properties.get('vm_state') gw_url = server_extra_properties.get('gw_url') if not gw_url: if vm_state == 'stopped': gw_id, gw_ip = utils.get_next_vgw(server_az) if not gw_id or not gw_ip: raise exception.V2vException(message='no vgw host found') gw_url = gw_ip + ':' + str(CONF.v2vgateway_api_listen_port) resource.extra_properties.update({"gw_url": gw_url, "gw_id": gw_id}) resource.extra_properties['sys_clone'] = sys_clone resource.extra_properties['is_deacidized'] = True block_device_mapping = server_properties.get( 'block_device_mapping_v2') if block_device_mapping: for block_device in block_device_mapping: volume_name = block_device.get('volume_id').get( 'get_resource') volume_resource = resource_map.get(volume_name) volume_resource.extra_properties['gw_url'] = gw_url volume_resource.extra_properties['is_deacidized'] = \ True boot_index = block_device.get('boot_index') dev_name = block_device.get('device_name') if boot_index == 0 or boot_index == '0': volume_resource.extra_properties['sys_clone'] = \ sys_clone if sys_clone: self._handle_dv_for_svm(context, volume_resource, server_id, dev_name, gw_id, gw_ip, undo_mgr) else: d_copy = copy_data and volume_resource. \ extra_properties['copy_data'] volume_resource.extra_properties['copy_data'] = \ d_copy if not d_copy: continue self._handle_dv_for_svm(context, volume_resource, server_id, dev_name, gw_id, gw_ip, undo_mgr) else: if migrate_net_map: # get the availability_zone of server server_az = server_properties.get('availability_zone') if not server_az: LOG.error(_LE('Not get the availability_zone' 'of server %s') % resource.id) raise exception.AvailabilityZoneNotFound( server_uuid=resource.id) migrate_net_id = migrate_net_map.get(server_az) if not migrate_net_id: LOG.error(_LE('Not get the migrate net of server %s') % resource.id) raise exception.NoMigrateNetProvided( server_uuid=resource.id) # attach interface LOG.debug('Attach a port of net %s to server %s', migrate_net_id, server_id) obj = self.compute_api.interface_attach(context, server_id, migrate_net_id, None, None) interface_attachment = obj._info if interface_attachment: LOG.debug('The interface attachment info is %s ' % str(interface_attachment)) migrate_fix_ip = interface_attachment.get('fixed_ips')[0] \ .get('ip_address') migrate_port_id = interface_attachment.get('port_id') undo_mgr.undo_with(functools.partial (self.compute_api.interface_detach, context, server_id, migrate_port_id)) gw_url = migrate_fix_ip + ':' + str( CONF.v2vgateway_api_listen_port) extra_properties = {} extra_properties['gw_url'] = gw_url extra_properties['is_deacidized'] = True extra_properties['migrate_port_id'] = migrate_port_id extra_properties['sys_clone'] = sys_clone resource.extra_properties.update(extra_properties) # waiting port attach finished, and can ping this vm self._await_port_status(context, migrate_port_id, migrate_fix_ip) # else: # interfaces = self.neutron_api.port_list( # context, device_id=server_id) # host_ip = None # for infa in interfaces: # if host_ip: # break # binding_profile = infa.get("binding:profile", []) # if binding_profile: # host_ip = binding_profile.get('host_ip') # if not host_ip: # LOG.error(_LE('Not find the clone data # ip for server')) # raise exception.NoMigrateNetProvided( # server_uuid=resource.id # ) # gw_url = host_ip + ':' + str( # CONF.v2vgateway_api_listen_port) # extra_properties = {} # extra_properties['gw_url'] = gw_url # extra_properties['sys_clone'] = sys_clone # resource.extra_properties.update(extra_properties) block_device_mapping = server_properties.get( 'block_device_mapping_v2') if block_device_mapping: client = None if gw_url: gw_urls = gw_url.split(':') client = birdiegatewayclient.get_birdiegateway_client( gw_urls[0], gw_urls[1]) for block_device in block_device_mapping: device_name = block_device.get('device_name') volume_name = block_device.get('volume_id').get( 'get_resource') volume_resource = resource_map.get(volume_name) boot_index = block_device.get('boot_index') if boot_index == 0 or boot_index == '0': volume_resource.extra_properties['sys_clone'] = \ sys_clone if not sys_clone: continue else: d_copy = copy_data and volume_resource. \ extra_properties['copy_data'] volume_resource.extra_properties['copy_data'] = \ d_copy if not d_copy: continue # need to check the vm disk name if not client: continue src_dev_format = client.vservices. \ get_disk_format(device_name).get('disk_format') src_mount_point = client. \ vservices.get_disk_mount_point(device_name). \ get('mount_point') volume_resource.extra_properties['guest_format'] = \ src_dev_format volume_resource.extra_properties['mount_point'] = \ src_mount_point volume_resource.extra_properties['gw_url'] = gw_url volume_resource.extra_properties['is_deacidized'] = \ True sys_dev_name = client. \ vservices.get_disk_name(volume_resource.id). \ get('dev_name') if not sys_dev_name: sys_dev_name = device_name volume_resource.extra_properties['sys_dev_name'] = \ sys_dev_name
def _add_extra_prop_for_dep_in_use_volume(self, context, resource, copy_data, undo_mgr): volume_id = resource.extra_properties.get('id') volume = self.volume_api.get(context, volume_id) v_shareable = volume['shareable'] gw_url = resource.extra_properties.get('gw_url') gw_id = None gw_ip = None if not gw_url: az = resource.properties.get('availability_zone') gw_id, gw_ip = utils.get_next_vgw(az) if not gw_id or not gw_ip: raise exception.V2vException(message='no vgw host found') gw_url = gw_ip + ':' + str(CONF.v2vgateway_api_listen_port) resource.extra_properties.update({"gw_url": gw_url, "gw_id": gw_id}) if not v_shareable: v_attachments = volume.get('attachments', []) resource.extra_properties['attachments'] = v_attachments for attachment in v_attachments: server_id = attachment.get('server_id') server_info = self.compute_api.get_server(context, server_id) vm_state = server_info.get('OS-EXT-STS:vm_state', None) if vm_state != 'stopped': _msg = 'the server %s not stopped' % server_id raise exception.V2vException(message=_msg) device = attachment.get('device') self.compute_api.detach_volume(context, server_id, volume_id) self._wait_for_volume_status(context, volume_id, server_id, 'available') undo_mgr.undo_with(functools.partial(self._attach_volume, context, server_id, volume_id, device)) client = birdiegatewayclient.get_birdiegateway_client( gw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) LOG.debug('Attach volume %s to gw host %s', volume_id, gw_id) attach_resp = self.compute_api.attach_volume(context, gw_id, volume_id, None) LOG.debug('The volume attachment info is %s ' % str(attach_resp)) undo_mgr.undo_with(functools.partial(self._detach_volume, context, gw_id, volume_id)) self._wait_for_volume_status(context, volume_id, gw_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks LOG.debug('Begin get info for volume,the vgw ip %s' % gw_ip) sys_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("dev_name = %s", sys_dev_name) resource.extra_properties['sys_dev_name'] = sys_dev_name guest_format = client.vservices.get_disk_format(sys_dev_name) \ .get('disk_format') if guest_format: resource.extra_properties['guest_format'] = guest_format mount_point = client.vservices.force_mount_disk( sys_dev_name, "/opt/" + volume_id) resource.extra_properties['mount_point'] = mount_point.get( 'mount_disk')
def _await_data_trans_status(self, context, host, port, task_ids, state_map, plan_id=None): start = time.time() retries = CONF.data_transformer_state_retries if retries < 0: LOG.warn( _LW("Treating negative config value (%(retries)s) for " "'datat_transformer_retries' as 0."), {'retries': retries}) # (1) treat negative config value as 0 # (2) the configured value is 0, one attempt should be made # (3) the configured value is > 0, then the total number attempts # is (retries + 1) # if not volume data to copy if not host: plan_state = state_map.get('DATA_TRANS_FINISHED') values = {} values['plan_status'] = plan_state values['task_status'] = 'DATA_TRANS_FINISHED' self.plan_api.update_plan(context, plan_id, values) return 0 attempts = 1 if retries >= 1: attempts = retries + 1 for attempt in range(1, attempts + 1): # record all volume data transformer task state task_states = [] for task_id in task_ids: cls = conveyorclient.get_birdiegateway_client(host, port) status = cls.vservices.get_data_trans_status(task_id) task_status = status.get('body').get('task_state') # if one volume data transformer failed, this clone failed if 'DATA_TRANS_FAILED' == task_status: plan_state = state_map.get(task_status) values = {} values['plan_status'] = plan_state values['task_status'] = task_status self.plan_api.update_plan(context, plan_id, values) return attempt task_states.append(task_status) # as long as one volume data does not transformer finished, # clone plan state is cloning if 'DATA_TRANSFORMING' in task_states: plan_state = state_map.get('DATA_TRANSFORMING') values = {} values['plan_status'] = plan_state values['task_status'] = 'DATA_TRANSFORMING' self.plan_api.update_plan(context, plan_id, values) # otherwise, plan state is finished else: LOG.debug(_("Data transformer finished!")) plan_state = state_map.get('DATA_TRANS_FINISHED') values = {} values['plan_status'] = plan_state values['task_status'] = 'DATA_TRANS_FINISHED' self.plan_api.update_plan(context, plan_id, values) return attempt greenthread.sleep(CONF.data_transformer_state_retries_interval) # NOTE(harlowja): Should only happen if we ran out of attempts raise exception.InstanceNotCreated(instance_id=task_id, seconds=int(time.time() - start), attempts=attempts)
def _await_data_trans_status(self, context, host, port, task_ids, state_map, plan_id=None): start = time.time() retries = CONF.data_transformer_state_retries if retries < 0: LOG.warn(_LW("Treating negative config value (%(retries)s) for " "'datat_transformer_retries' as 0."), {'retries': retries}) # (1) treat negative config value as 0 # (2) the configured value is 0, one attempt should be made # (3) the configured value is > 0, then the total number attempts # is (retries + 1) # if not volume data to copy if not host: plan_state = state_map.get('DATA_TRANS_FINISHED') values = {} values['plan_status'] = plan_state values['task_status'] = 'DATA_TRANS_FINISHED' self.plan_api.update_plan(context, plan_id, values) return 0 attempts = 1 if retries >= 1: attempts = retries + 1 for attempt in range(1, attempts + 1): # record all volume data transformer task state task_states = [] for task_id in task_ids: cls = conveyorclient.get_birdiegateway_client(host, port) status = cls.vservices.get_data_trans_status(task_id) task_status = status.get('body').get('task_state') # if one volume data transformer failed, this clone failed if 'DATA_TRANS_FAILED' == task_status: plan_state = state_map.get(task_status) values = {} values['plan_status'] = plan_state values['task_status'] = task_status self.plan_api.update_plan(context, plan_id, values) return attempt task_states.append(task_status) # as long as one volume data does not transformer finished, # clone plan state is cloning if 'DATA_TRANSFORMING' in task_states: plan_state = state_map.get('DATA_TRANSFORMING') values = {} values['plan_status'] = plan_state values['task_status'] = 'DATA_TRANSFORMING' self.plan_api.update_plan(context, plan_id, values) # otherwise, plan state is finished else: LOG.debug(_("Data transformer finished!")) plan_state = state_map.get('DATA_TRANS_FINISHED') values = {} values['plan_status'] = plan_state values['task_status'] = 'DATA_TRANS_FINISHED' self.plan_api.update_plan(context, plan_id, values) return attempt greenthread.sleep(CONF.data_transformer_state_retries_interval) # NOTE(harlowja): Should only happen if we ran out of attempts raise exception.InstanceNotCreated(instance_id=task_id, seconds=int(time.time() - start), attempts=attempts)
def _copy_stack_volume(self, context, resource_name, template, plan_id, trans_data_wait_fun=None, volume_wait_fun=None, set_plan_state=None): resources = template.get('resources') volume_res = resources.get(resource_name) ext_properties = volume_res.get('extra_properties', None) if ext_properties: sys_clone = ext_properties.get('sys_clone', False) boot_index = ext_properties.get('boot_index', 1) else: sys_clone = False boot_index = 1 if not sys_clone and boot_index in ['0', 0]: plan_state = 'DATA_TRANS_FINISHED' set_plan_state(context, plan_id, plan_state, plan_status.STATE_MAP) return volume_id = volume_res.get('id') try: volume_info = self.cinder_api.get(context, volume_id) except Exception as e: LOG.error("Clone volume driver get volume %(id)s error: %(error)s", {'id': volume_id, 'error': e}) raise exception.VolumeNotFound() volume_status = volume_info['status'] v_shareable = volume_info.get('shareable', False) volume_az = volume_info.get('availability_zone') volume_attachments = volume_info.get('attachments', []) if volume_status == 'in-use' and not v_shareable: for attachment in volume_attachments: server_id = attachment.get('server_id') if not CONF.is_active_detach_volume: resouce_common = common.ResourceCommon() self.compute_api.stop_server(context, server_id) resouce_common._await_instance_status(context, server_id, 'SHUTOFF') self.compute_api.detach_volume(context, server_id, volume_id) if volume_wait_fun: volume_wait_fun(context, volume_id, 'available') vgw_id, vgw_ip = utils.get_next_vgw(volume_az) LOG.debug('Clone volume driver vgw info: id: %(id)s,ip: %(ip)s', {'id': vgw_id, 'ip': vgw_ip}) des_dev_name = None try: client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) self.compute_api.attach_volume(context, vgw_id, volume_id, None) if volume_wait_fun: volume_wait_fun(context, volume_id, 'in-use') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks des_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 else None LOG.debug("dev_name = %s", des_dev_name) except Exception as e: LOG.error('Volume clone error: attach volume failed:%(id)s,%(e)s', {'id': volume_id, 'e': e}) raise exception.VolumeNotAttach(volume_id=volume_id, seconds=120, attempts=5) # 5. copy data try: result = self._copy_volume_data(context, resource_name, vgw_ip, vgw_id, template, des_dev_name) des_gw_ip = result.get('des_ip') des_port = result.get('des_port') task_ids = result.get('copy_tasks') if trans_data_wait_fun: trans_data_wait_fun(context, des_gw_ip, des_port, task_ids, plan_status.STATE_MAP, plan_id) except Exception as e: LOG.error('Volume clone error: copy data failed:%(id)s,%(e)s', {'id': volume_id, 'e': e}) raise finally: try: # if protocol is ftp, we should unmount volume in gateway vm data_trans_protocol = CONF.data_transformer_procotol if 'ftp' == data_trans_protocol: client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port) ) client.vservices._force_umount_disk("/opt/" + volume_id) # if provider cloud can not detach volume in active status if not CONF.is_active_detach_volume: resouce_common = common.ResourceCommon() self.compute_api.stop_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'SHUTOFF') # 5. detach volume self.compute_api.detach_volume(context, vgw_id, volume_id) if volume_wait_fun: volume_wait_fun(context, volume_id, 'available') if not CONF.is_active_detach_volume: self.compute_api.start_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'ACTIVE') for attachment in volume_attachments: server_id = attachment.get('server_id') self.compute_api.attach_volume(context, server_id, volume_id, None) if volume_wait_fun: volume_wait_fun(context, volume_id, 'in-use') except Exception as e: LOG.error('Volume clone error: detach failed:%(id)s,%(e)s', {'id': volume_id, 'e': e})
def start_volume_clone(self, context, resource_name, template, trans_data_wait_fun=None, volume_wait_fun=None, set_plan_state=None): resources = template.get('resources') volume_res = resources.get(resource_name) volume_id = volume_res.get('id') plan_id = template.get('plan_id', None) ext_properties = volume_res.get('extra_properties', None) d_copy = ext_properties.get('copy_data', True) if ext_properties \ else True if not d_copy: plan_state = 'DATA_TRANS_FINISHED' set_plan_state(context, plan_id, plan_state, plan_status.STATE_MAP) return resource_names = resource_name.split('.') if len(resource_names) >= 1: if resource_names[0].startswith('stack'): self._copy_stack_volume(context, resource_name, template, plan_id, trans_data_wait_fun, volume_wait_fun, set_plan_state) return # 1. check instance which dependences this volume in template or not # if instance exists in template do not execute copy data step is_attached = self._check_volume_attach_instance(resource_name, template) if is_attached: LOG.debug('Volume clone driver: volume %(id)s, name %(name)s', {'id': volume_id, 'name': resource_name}) # update plan status plan_state = 'DATA_TRANS_FINISHED' set_plan_state(context, plan_id, plan_state, plan_status.STATE_MAP) return # 2. if volume is system volume and does not clone, skip copy data step if ext_properties: sys_clone = ext_properties.get('sys_clone', False) boot_index = ext_properties.get('boot_index', 1) else: sys_clone = False boot_index = 1 if not sys_clone and boot_index in ['0', 0]: plan_state = 'DATA_TRANS_FINISHED' set_plan_state(context, plan_id, plan_state, plan_status.STATE_MAP) return # 3. get volume info try: volume_info = self.cinder_api.get(context, volume_id) except Exception as e: LOG.error("Clone volume driver get volume %(id)s error: %(error)s", {'id': volume_id, 'error': e}) raise exception.VolumeNotFound() volume_status = volume_info['status'] v_shareable = volume_info.get('shareable', False) volume_az = volume_info.get('availability_zone') need_set_shareable = False if volume_status == 'in-use' and not v_shareable: need_set_shareable = True # 3. attach volume to gateway vm vgw_id, vgw_ip = utils.get_next_vgw(volume_az) LOG.debug('Clone volume driver vgw info: id: %(id)s,ip: %(ip)s', {'id': vgw_id, 'ip': vgw_ip}) des_dev_name = None try: client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port) ) disks = set(client.vservices.get_disk_name().get('dev_name')) if CONF.is_provide_device_name: if need_set_shareable: self.cinder_api.set_volume_shareable(context, volume_id, True) self.compute_api.attach_volume(context, vgw_id, volume_id, None) # des_dev_name = attach_resp._info.get('device') self._wait_for_shareable_volume_status(context, volume_id, vgw_id, 'in-use') else: self.compute_api.attach_volume(context, vgw_id, volume_id, None) if volume_wait_fun: volume_wait_fun(context, volume_id, 'in-use') # des_dev_name = attach_resp._info.get('device') n_disks = set(client.vservices.get_disk_name().get('dev_name')) diff_disk = n_disks - disks des_dev_name = list(diff_disk)[0] if len(diff_disk) >= 1 \ else None LOG.debug("dev_name = %s", des_dev_name) else: des_dev_name = self._attach_volume_for_device_name( context, need_set_shareable, vgw_id, volume_id, volume_wait_fun, client) LOG.debug("dev_name = %s", des_dev_name) except Exception as e: LOG.error('Volume clone error: attach volume failed:%(id)s,%(e)s', {'id': volume_id, 'e': e}) raise exception.VolumeNotAttach(volume_id=volume_id, seconds=120, attempts=5) # 5. copy data try: result = self._copy_volume_data(context, resource_name, vgw_ip, vgw_id, template, des_dev_name) des_gw_ip = result.get('des_ip') des_port = result.get('des_port') task_ids = result.get('copy_tasks') if trans_data_wait_fun: trans_data_wait_fun(context, des_gw_ip, des_port, task_ids, plan_status.STATE_MAP, plan_id) except Exception as e: LOG.error('Volume clone error: copy data failed:%(id)s,%(e)s', {'id': volume_id, 'e': e}) raise finally: try: # if protocol is ftp, we should unmount volume in gateway vm data_trans_protocol = CONF.data_transformer_procotol if 'ftp' == data_trans_protocol: client = birdiegatewayclient.get_birdiegateway_client( vgw_ip, str(CONF.v2vgateway_api_listen_port) ) client.vservices._force_umount_disk("/opt/" + volume_id) # if provider cloud can not detach volume in active status if not CONF.is_active_detach_volume: resouce_common = common.ResourceCommon() self.compute_api.stop_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'SHUTOFF') # 5. detach volume self.compute_api.detach_volume(context, vgw_id, volume_id) if need_set_shareable: self._wait_for_shareable_volume_status(context, volume_id, vgw_id, 'available') self.cinder_api.set_volume_shareable(context, volume_id, False) else: if volume_wait_fun: volume_wait_fun(context, volume_id, 'available') if not CONF.is_active_detach_volume: self.compute_api.start_server(context, vgw_id) resouce_common._await_instance_status(context, vgw_id, 'ACTIVE') except Exception as e: LOG.error('Volume clone error: detach failed:%(id)s,%(e)s', {'id': volume_id, 'e': e})
def _copy_volume_data(self, context, resource_name, template, trans_data_wait_fun=None, port_wait_fun=None): '''copy volumes in template data''' resources = template.get('resources') instance = resources.get(resource_name) # 2. get server info server_id = instance.get('id') stack_id = template.get('stack_id') try: server = self.nova_api.get_server(context, server_id) except Exception as e: LOG.error("Query server %(server_id)s error: %(error)s", {'server_id': server_id, 'error': e}) raise exception.ServerNotFound(server_id=server_id) # 3. get volumes attached to this server properties = instance.get('properties') ext_properties = instance.get('extra_properties') volumes = properties.get('block_device_mapping_v2') if not volumes: LOG.warn("Clone instance warning: instance does not have volume.") rsp = {'server_id': server_id, 'port_id': None, 'des_ip': None, 'des_port': None, 'copy_tasks': []} return rsp bdms = [] for v_volume in volumes: # if volume id is string, this volume is using exist volume, # so does not copy data vol_res_id = v_volume.get('volume_id') if isinstance(vol_res_id, str) or vol_res_id.get('get_param'): _msg = "Instance clone warning: volume does not copy data: %s" \ % vol_res_id LOG.debug(_msg) continue vol_res_name = v_volume.get('volume_id').get('get_resource') sys_clone = ext_properties.get('sys_clone') boot_index = v_volume.get('boot_index') # 3.1 if do not clone system volume, # don't add system volume to bdms if not sys_clone and boot_index in [0, '0']: continue volume_ext_properties = \ resources.get(vol_res_name).get('extra_properties') if not volume_ext_properties.get('copy_data'): continue # 3.2 get volume id volume_id = self._get_resource_id(context, vol_res_name, stack_id) v_volume['id'] = volume_id if volume_ext_properties: v_volume['guest_format'] = \ volume_ext_properties.get('guest_format') v_volume['mount_point'] = \ volume_ext_properties.get('mount_point') # volume dev name in system vol_sys_dev = volume_ext_properties.get('sys_dev_name') # if not None, use it,otherwise use default name if vol_sys_dev: v_volume['device_name'] = vol_sys_dev bdms.append(v_volume) if not bdms: return {} # 4. create transform data port to new instances server_az = server.get('OS-EXT-AZ:availability_zone', None) id = server.get('id', None) if not server_az: LOG.error('Can not get the availability_zone of server %s', id) raise exception.AvailabilityZoneNotFound(server_uuid=id) migrate_net_map = CONF.migrate_net_map migrate_net_id = migrate_net_map.get(server_az, None) if migrate_net_id: # 4.1 call neutron api create port LOG.debug("Instance template driver attach port to instance start") net_info = self.nova_api.interface_attach(context, id, migrate_net_id, port_id=None, fixed_ip=None) interface_attachment = net_info._info if interface_attachment: LOG.debug('The interface attachment info is %s ' % str(interface_attachment)) des_gw_ip = \ interface_attachment.get('fixed_ips')[0].get('ip_address') port_id = interface_attachment.get('port_id') else: LOG.error("Instance template driver attach port failed") raise exception.NoMigrateNetProvided(server_uuid=id) else: retrying = 1 while retrying < 300: des_gw_ip = self._get_server_ip(context, server_id) if des_gw_ip: break retrying += 1 time.sleep(2) port_id = None LOG.debug("Instance template driver attach port end: %s", des_gw_ip) if not des_gw_ip: _msg = "New clone or migrate VM data transformer IP is None" raise exception.V2vException(message=_msg) des_port = str(CONF.v2vgateway_api_listen_port) des_gw_url = des_gw_ip + ":" + des_port # data transformer procotol(ftp/fillp) data_trans_protocol = CONF.data_transformer_procotol data_trans_ports = CONF.trans_ports trans_port = data_trans_ports[0] src_gw_url = ext_properties.get('gw_url') src_urls = src_gw_url.split(':') if len(src_urls) != 2: LOG.error("Input source gw url error: %s", src_gw_url) msg = "Input source gw url error: " + src_gw_url raise exception.InvalidInput(reason=msg) # 5. request birdiegateway service to clone each volume data # record all volume data copy task id task_ids = [] for bdm in bdms: # 6.1 query cloned new VM volume name # src_dev_name = "/dev/sdc" src_dev_name = bdm.get('device_name') client = birdiegatewayclient.get_birdiegateway_client(des_gw_ip, des_port) des_dev_name = \ client.vservices.get_disk_name(bdm.get('id')).get('dev_name') if not des_dev_name: des_dev_name = src_dev_name src_dev_format = bdm.get('guest_format') # if template does not hava disk format and mount point info # query them from conveyor-agent if not src_dev_format: client = \ birdiegatewayclient.get_birdiegateway_client(src_urls[0], src_urls[1]) d_format = client.vservices.get_disk_format(src_dev_name) src_dev_format = d_format.get('disk_format') # if volume does not format, this volume not data to transformer if not src_dev_format and CONF.data_transformer_procotol == 'ftp': continue src_mount_point = bdm.get('mount_point') if not src_mount_point: client = \ birdiegatewayclient.get_birdiegateway_client(src_urls[0], src_urls[1]) m_info = client.vservices.get_disk_mount_point(src_dev_name) src_mount_point = m_info.get('mount_point') if not src_mount_point and CONF.data_transformer_procotol == 'ftp': continue mount_point = [] mount_point.append(src_mount_point) LOG.debug('Volume %(dev_name)s disk format is %(disk_format)s' ' and mount point is %(point)s', {'dev_name': src_dev_name, 'disk_format': src_dev_format, 'point': src_mount_point}) # get conveyor gateway client to call birdiegateway api LOG.debug("Instance template driver transform data start") client = birdiegatewayclient.get_birdiegateway_client(des_gw_ip, des_port) clone_rsp = client.vservices.clone_volume( src_dev_name, des_dev_name, src_dev_format, mount_point, src_gw_url, des_gw_url, trans_protocol=data_trans_protocol, trans_port=trans_port) task_id = clone_rsp.get('body').get('task_id') if not task_id: LOG.warn("Clone volume %(dev_name)s response is %(rsp)s", {'dev_name': des_dev_name, 'rsp': clone_rsp}) continue task_ids.append(task_id) rsp = {'server_id': server_id, 'port_id': port_id, 'des_ip': des_gw_ip, 'des_port': des_port, 'copy_tasks': task_ids} LOG.debug("Instance template driver transform data end") return rsp