仇晗的专栏

虚拟机的镜像文件主要是指磁盘镜像文件,当然有的还包括ramdisk和kernel镜像来配合磁盘镜像文件使用,这篇文章我们来重点分析一下创建虚拟机磁盘镜像的整个过程。

虚拟机磁盘镜像是虚拟机正常运行不可缺少的镜像文件,它是虚拟机的主磁盘。先来概述一下创建虚拟机磁盘镜像的整个流程:

1. LibvirtDriver类中的_create_img方法,完成虚拟机镜像文件的创建工作的准备工作后,调用Qcow2类的cache方法。

2. Qcow2类的cache方法调用create_image方法,首先检查本地计算节点上是否缓存了虚拟机所需的磁盘镜像文件。如果不存在缓存文件,则调用libvirt_utils包的fetch_image方法从Glance服务器下载。然后,Qcow2类的create_image方法调用copy_qcow2_img方法创建qcow2格式的虚拟机磁盘镜像文件。

3. libvirt_utils包的fetch_image方法调用fetch_to_raw方法。fetch_to_raw方法首先调用fetch方法从Glance服务器上下载镜像文件,然后检查下载的镜像文件格式是否正确,如果下载的不是raw格式,则将其转化为raw格式。

4. Qcow2类的copy_qcow2_img方法通过执行qemu-img命令完成虚拟机磁盘镜像文件的创建,创建的虚拟机磁盘镜像文件会把换成的镜像文件作为baking file。

接着上一篇文章,来分析创建虚拟机镜像文件的代码

class LibvirtDriver(driver.ComputeDriver):def _create_image(self, context, instance,                      disk_mapping, suffix='',                      disk_images=None, network_info=None,                      block_device_info=None, files=None, admin_pass=None):#默认的磁盘镜像文件后缀为空if not suffix:            suffix = ''… #创建保存虚拟机磁盘镜像的目录fileutils.ensure_tree(basepath(suffix='')…if not booted_from_volume:#获取磁盘镜像在本地的文件名            root_fname = imagecache.get_cache_fname(disk_images, 'image_id')#获取磁盘镜像的大小            size = instance['root_gb'] * 1024 * 1024 * 1024            if size == 0 or suffix == '.rescue':                size = None#将磁盘镜像保存在本地image('disk').cache(fetch_func=libvirt_utils.fetch_image,                                context=context,                                filename=root_fname,                                size=size,                                image_id=disk_images['image_id'],                                user_id=instance['user_id'],                                project_id=instance['project_id'])…

为了便于理解,我们先看一下传入的“instance”变量中保存的是什么?

{'vm_state': 'building', 'availability_zone': None, 'terminated_at': None, 'ephemeral_gb': 0, 'instance_type_id': 4, 'user_data': 'IyEvYmluL2Jhc2gKdXNlcmFkZCAtbSByb290CnBhc3N3ZCByb290IDw8IEVPRgpyb29vdApyb29vdApFT0YKcGFzc3dkIHJvb3QgPDwgRU9GCnJvb290CnJvb290CkVPRgo=', 'vm_mode': None, 'deleted_at': None, 'reservation_id': 'r-ze5a808m', 'id': 70, 'security_groups': [{'project_id': 'e2c96ea3efe0418cb86fef29aabc2725', 'user_id': 'cc4f87ee9b0d43a4bfe6d1113473f796', 'name': 'default', 'deleted': False, 'created_at': '2014-11-10T02:43:37.000000', 'updated_at': None, 'rules': […], 'disable_terminate': False, 'root_device_name': None, 'user_id': 'cc4f87ee9b0d43a4bfe6d1113473f796', 'uuid': '19df2538-47c2-49f1-8735-afbc24e68743', 'server_name': None, 'default_swap_device': None, 'info_cache': {'instance_uuid': '19df2538-47c2-49f1-8735-afbc24e68743', 'deleted': False, 'created_at': '2015-02-12T06:05:27.000000', 'updated_at': None, 'network_info': '[]', 'deleted_at': None, 'id': 70}, 'hostname': 'test', 'launched_on': None, 'display_description': 'test', 'key_data': None, 'deleted': False, 'scheduled_at': '2015-02-12T06:05:28.000000', 'power_state': 0, 'default_ephemeral_device': None, 'progress': 0, 'project_id': 'e2c96ea3efe0418cb86fef29aabc2725', 'launched_at': None, 'config_drive': '', 'node': 'sts-zestack-02', 'ramdisk_id': '', 'access_ip_v6': None, 'access_ip_v4': None, 'kernel_id': '', 'key_name': None, 'updated_at': '2015-02-12T06:05:28.446678', 'host': 'sts-zestack-02', 'display_name': 'test', 'system_metadata': […], 'task_state': 'scheduling', 'shutdown_terminate': False, 'cdrom_active': False, 'root_gb': 0, 'locked': False, 'name': 'instance-00000046', 'hypervisor': 'libvirt', 'created_at': '2015-02-12T06:05:27.000000', 'launch_index': 0, 'memory_mb': 512, 'instance_type': {'memory_mb': 512, 'root_gb': 0, 'name': 'm1.tiny', 'deleted': False, 'created_at': None, 'ephemeral_gb': 0, 'updated_at': None, 'disabled': False, 'vcpus': 1, 'flavorid': '1', 'swap': 0, 'rxtx_factor': 1.0, 'is_public': True, 'deleted_at': None, 'vcpu_weight': None, 'id': 4}, 'vcpus': 1, 'image_ref': '11d25bff-1091-4f7a-9a3c-0e48be0cc21b', 'architecture': None, 'auto_disk_config': None, 'os_type': None, 'metadata': []}逐一分析一下_create_image方法:

1. ensure_tree方法

相信优美的生命,就是一曲无字的挽歌,

仇晗的专栏

相关文章:

你感兴趣的文章:

标签云: