示例#1
0
 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')
示例#2
0
 def _add_extra_prop(template, stack_id):
     temp_res = template.get('resources')
     for key, value in temp_res.items():
         res_type = value.get('type')
         if res_type == 'OS::Cinder::Volume':
             # v_prop = value.get('properties')
             v_exra_prop = value.get('extra_properties', {})
             d_copy = copy_data and v_exra_prop['copy_data']
             v_exra_prop['copy_data'] = d_copy
             if not d_copy:
                 continue
             if not v_exra_prop or not v_exra_prop.get('gw_url'):
                 phy_id = v_exra_prop.get('id')
                 res_info = self.volume_api.get(context, phy_id)
                 az = res_info.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)
                 v_exra_prop.update({"gw_url": gw_url, "gw_id": gw_id})
                 volume_status = res_info['status']
                 v_exra_prop['status'] = volume_status
                 value['extra_properties'] = v_exra_prop
                 value['id'] = phy_id
                 self._handle_volume_for_stack(context, value, gw_id,
                                               gw_ip, undo_mgr)
         elif res_type == 'OS::Nova::Server':
             v_exra_prop = value.get('extra_properties', {})
             phy_id = v_exra_prop.get('id')
             server_info = self.compute_api.get_server(context, phy_id)
             vm_state = server_info.get('OS-EXT-STS:vm_state', None)
             v_exra_prop['vm_state'] = vm_state
             value['extra_properties'] = v_exra_prop
示例#3
0
def convert_version_to_int(version):
    try:
        if isinstance(version, six.string_types):
            version = convert_version_to_tuple(version)
        if isinstance(version, tuple):
            return reduce(lambda x, y: (x * 1000) + y, version)
    except Exception:
        msg = _("Version %s is invalid.") % version
        raise exception.V2vException(msg)
示例#4
0
    def start_template_clone(self, context, resource_name, template):

        if not template:
            LOG.error("Resources in template is null")
            raise exception.V2vException(message='Template is null')

        try:
            trans_data_wait_fun = \
                self.resource_common._await_data_trans_status
            self.clone_driver.start_volume_clone(
                context,
                resource_name,
                template,
                volume_wait_fun=self.resource_common._await_volume_status,
                trans_data_wait_fun=trans_data_wait_fun,
                set_plan_state=self._set_plan_statu)
        except Exception as e:
            LOG.error(_LW("Clone volume error: %s"), e)
            _msg = 'Volume clone error: %s' % e
            raise exception.V2vException(message=_msg)
示例#5
0
 def _add_extra_properties_for_dep_volume(self, context, resource,
                                          copy_data, undo_mgr):
     gw_url = resource.extra_properties.get('gw_url')
     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
         })
         resource.extra_properties['is_deacidized'] = True
         self._handle_dep_volume(context, resource, gw_id, gw_ip, undo_mgr)
示例#6
0
    def __get_backend(self):
        if not self.__backend:
            if self.__config_group is None:
                backend_name = CONF[self.__pivot]
            else:
                backend_name = CONF[self.__config_group][self.__pivot]
            if backend_name not in self.__backends:
                msg = _('Invalid backend: %s') % backend_name
                raise exception.V2vException(msg)

            backend = self.__backends[backend_name]
            if isinstance(backend, tuple):
                name = backend[0]
                fromlist = backend[1]
            else:
                name = backend
                fromlist = backend

            self.__backend = __import__(name, None, None, fromlist)
        return self.__backend
示例#7
0
 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
示例#8
0
 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')
示例#9
0
    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