Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5600430
  • 博文数量: 669
  • 博客积分: 10821
  • 博客等级: 上将
  • 技术积分: 11746
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-02 10:41
个人简介

大数据、ML、AI、云计算openstack、Linux、SpringCloud。

文章分类

全部博文(669)

分类: 云计算

2020-05-21 11:39:49

/usr/lib/python2.7/site-packages/nova/virt/libvirt/driver.py 

孵化虚拟机

+3051-3095
def spawn(self, context, instance, image_meta, injected_files,
              admin_password, allocations, network_info=None,
              block_device_info=None):
        disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
                                            instance,
                                            image_meta,
                                            block_device_info)
        injection_info = InjectionInfo(network_info=network_info,
                                       files=injected_files,
                                       admin_pass=admin_password)
        gen_confdrive = functools.partial(self._create_configdrive,
                                          context, instance,
                                          injection_info)
        self._create_image(context, instance, disk_info['mapping'],
                           injection_info=injection_info,
                           block_device_info=block_device_info)

        # Required by Quobyte CI
        self._ensure_console_log_for_instance(instance)

        # Does the guest need to be assigned some vGPU mediated devices ?
        mdevs = self._allocate_mdevs(allocations)

        xml = self._get_guest_xml(context, instance, network_info,
                                  disk_info, image_meta,
                                  block_device_info=block_device_info,
                                  mdevs=mdevs)
        self._create_domain_and_network(
            context, xml, instance, network_info,
            block_device_info=block_device_info,
            post_xml_callback=gen_confdrive,
            destroy_disks_on_failure=True)
        LOG.debug("Guest created on hypervisor", instance=instance)

        def _wait_for_boot():
            """Called at an interval until the VM is running."""
            state = self.get_info(instance).state

            if state == power_state.RUNNING:
                LOG.info("Instance spawned successfully.", instance=instance)
                raise loopingcall.LoopingCallDone()

        timer = loopingcall.FixedIntervalLoopingCall(_wait_for_boot)
        timer.start(interval=0.5).wait()

创建虚拟机

_create_domain_and_network()最终调用
    # TODO(sahid): Consider renaming this to _create_guest.
    def _create_domain(self, xml=None, domain=None,
                       power_on=True, pause=False, post_xml_callback=None):
        """Create a domain.

        Either domain or xml must be passed in. If both are passed, then
        the domain definition is overwritten from the xml.

        :returns guest.Guest: Guest just created
        """
        if xml:
            guest = libvirt_guest.Guest.create(xml, self._host)
            if post_xml_callback is not None:
                post_xml_callback()
        else:
            guest = libvirt_guest.Guest(domain)

        if power_on or pause:
            guest.launch(pause=pause)

        if not utils.is_neutron():
            guest.enable_hairpin()

        return guest

  创建镜像:_create_image()

 # NOTE(sileht): many callers of this method assume that this
    # method doesn't fail if an image already exists but instead
    # think that it will be reused (ie: (live)-migration/resize)
    def _create_image(self, context, instance,
                      disk_mapping, injection_info=None, suffix='',
                      disk_images=None, block_device_info=None,
                      fallback_from_host=None,
                      ignore_bdi_for_swap=False):
        booted_from_volume = self._is_booted_from_volume(block_device_info)

        def image(fname, image_type=CONF.libvirt.images_type):
            return self.image_backend.by_name(instance,
                                              fname + suffix, image_type)

        def raw(fname):
            return image(fname, image_type='raw')

        # ensure directories exist and are writable
        fileutils.ensure_tree(libvirt_utils.get_instance_path(instance))

        LOG.info('Creating image', instance=instance)

        inst_type = instance.get_flavor()
        swap_mb = 0
        if 'disk.swap' in disk_mapping:
            mapping = disk_mapping['disk.swap']

            if ignore_bdi_for_swap:
                # This is a workaround to support legacy swap resizing,
                # which does not touch swap size specified in bdm,
                # but works with flavor specified size only.
                # In this case we follow the legacy logic and ignore block
                # device info completely.
                # NOTE(ft): This workaround must be removed when a correct
                # implementation of resize operation changing sizes in bdms is
                # developed. Also at that stage we probably may get rid of
                # the direct usage of flavor swap size here,
                # leaving the work with bdm only.
                swap_mb = inst_type['swap']
            else:
                swap = driver.block_device_info_get_swap(block_device_info)
                if driver.swap_is_usable(swap):
                    swap_mb = swap['swap_size']
                elif (inst_type['swap'] > 0 and
                      not block_device.volume_in_mapping(
                        mapping['dev'], block_device_info)):
                    swap_mb = inst_type['swap']

            if swap_mb > 0:
                if (CONF.libvirt.virt_type == "parallels" and
                        instance.vm_mode == fields.VMMode.EXE):
                    msg = _("Swap disk is not supported "
                            "for Virtuozzo container")
                    raise exception.Invalid(msg)

        if not disk_images:
            disk_images = {'image_id': instance.image_ref,
                           'kernel_id': instance.kernel_id,
                           'ramdisk_id': instance.ramdisk_id}
       if disk_images['kernel_id']:
            fname = imagecache.get_cache_fname(disk_images['kernel_id'])
            raw('kernel').cache(fetch_func=libvirt_utils.fetch_raw_image,
                                context=context,
                                filename=fname,
                                image_id=disk_images['kernel_id'])
            if disk_images['ramdisk_id']:
                fname = imagecache.get_cache_fname(disk_images['ramdisk_id'])
                raw('ramdisk').cache(fetch_func=libvirt_utils.fetch_raw_image,
                                     context=context,
                                     filename=fname,
                                     image_id=disk_images['ramdisk_id'])

        if CONF.libvirt.virt_type == 'uml':
            # PONDERING(mikal): can I assume that root is UID zero in every
            # OS? Probably not.
            uid = pwd.getpwnam('root').pw_uid
            nova.privsep.path.chown(image('disk').path, uid=uid)

        self._create_and_inject_local_root(context, instance,
                                           booted_from_volume, suffix,
                                           disk_images, injection_info,
                                           fallback_from_host)

        # Lookup the filesystem type if required
        os_type_with_default = nova.privsep.fs.get_fs_type_for_os_type(
            instance.os_type)
        # Generate a file extension based on the file system
        # type and the mkfs commands configured if any
        file_extension = nova.privsep.fs.get_file_extension_for_os_type(
            os_type_with_default, CONF.default_ephemeral_format)

        vm_mode = fields.VMMode.get_from_instance(instance)
        ephemeral_gb = instance.flavor.ephemeral_gb
        if 'disk.local' in disk_mapping:
            disk_image = image('disk.local')
            fn = functools.partial(self._create_ephemeral,
                                   fs_label='ephemeral0',
                                   os_type=instance.os_type,
                                   is_block_dev=disk_image.is_block_dev,
                                   vm_mode=vm_mode)
            fname = "ephemeral_%s_%s" % (ephemeral_gb, file_extension)
            size = ephemeral_gb * units.Gi
            disk_image.cache(fetch_func=fn,
                             context=context,
                             filename=fname,
                             size=size,
                             ephemeral_size=ephemeral_gb)

        for idx, eph in enumerate(driver.block_device_info_get_ephemerals(
                block_device_info)):
            disk_image = image(blockinfo.get_eph_disk(idx))

            specified_fs = eph.get('guest_format')
            if specified_fs and not self.is_supported_fs_format(specified_fs):
                msg = _("%s format is not supported") % specified_fs
                raise exception.InvalidBDMFormat(details=msg)

            fn = functools.partial(self._create_ephemeral,
                                   fs_label='ephemeral%d' % idx,
                                   os_type=instance.os_type,
                                   is_block_dev=disk_image.is_block_dev,
                                   vm_mode=vm_mode)
            size = eph['size'] * units.Gi
            fname = "ephemeral_%s_%s" % (eph['size'], file_extension)
            disk_image.cache(fetch_func=fn,
                             context=context,
                             filename=fname,
                             size=size,
                             ephemeral_size=eph['size'],
                             specified_fs=specified_fs)

        if swap_mb > 0:
            size = swap_mb * units.Mi
            image('disk.swap').cache(fetch_func=self._create_swap,
                                     context=context,
                                     filename="swap_%s" % swap_mb,
                                     size=size,
                                     swap_mb=swap_mb)







阅读(126) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~