Openstack nova代码部分凝视一
做个一个没怎么学过python的菜鸟。看源代码是最好的学习方式了,如今就从nova入手,主要凝视一下 nova/compute/api.py 中的 create_instance函数
def _create_instance(self, context, instance_type,
image_href, kernel_id, ramdisk_id,
min_count, max_count,
display_name, display_description,
key_name, key_data, security_group,
availability_zone, user_data, metadata,
injected_files, admin_password,
access_ip_v4, access_ip_v6,
requested_networks, config_drive,
block_device_mapping, auto_disk_config,
reservation_id=None, create_instance_here=False,
scheduler_hints=None):
"""Verify all the input parameters regardless of the provisioning
strategy being performed and schedule the instance(s) for
creation.""" if not metadata:
metadata = {}
if not display_description:
display_description = ''
if not security_group:
security_group = 'default' if not instance_type:
instance_type = instance_types.get_default_instance_type()
if not min_count:
min_count = 1
if not max_count:
max_count = min_count
if not metadata:
metadata = {} block_device_mapping = block_device_mapping or [] #从quota得到详细的实例限制
num_instances = quota.allowed_instances(context, max_count,
instance_type)
if num_instances < min_count:
pid = context.project_id
if num_instances <= 0:
msg = _("Cannot run any more instances of this type.")
else:
msg = (_("Can only run %s more instances of this type.") %
num_instances)
LOG.warn(_("Quota exceeded for %(pid)s,"
" tried to run %(min_count)s instances. " + msg) % locals())
raise exception.QuotaError(code="InstanceLimitExceeded") #检查元数据、注入文件、网络
self._check_metadata_properties_quota(context, metadata)
self._check_injected_file_quota(context, injected_files)
self._check_requested_networks(context, requested_networks) (image_service, image_id) = nova.image.get_image_service(context,
image_href)
#通过镜像id。訪问镜像的详细服务。 得到一个image字典。
image = image_service.show(context, image_id) #iamge 是一个字典。返回key='min_ram'相应的值, get是字典的一个方法。
#memory_mb:是虚拟机所属内存。
if instance_type['memory_mb'] < int(image.get('min_ram') or 0):
raise exception.InstanceTypeMemoryTooSmall()
#root_gb :虚拟机根硬盘大小。instance_type代表了创建虚拟机的需求或者说配置。image则是实际上存在镜像的一个东西。
if instance_type['root_gb'] < int(image.get('min_disk') or 0):
raise exception.InstanceTypeDiskTooSmall() config_drive_id = None
if config_drive and config_drive is not True:
# config_drive is volume id
config_drive, config_drive_id = None, config_drive os_type = None
#properties是字典image的一个属性,image[properties]又是一个字典。
if 'properties' in image and 'os_type' in image['properties']:
os_type = image['properties']['os_type']
architecture = None
if 'properties' in image and 'arch' in image['properties']:
architecture = image['properties']['arch']
vm_mode = None
if 'properties' in image and 'vm_mode' in image['properties']:
vm_mode = image['properties']['vm_mode'] # If instance doesn't have auto_disk_config overridden by request, use
# whatever the image indicates
if auto_disk_config is None:
if ('properties' in image and
'auto_disk_config' in image['properties']):
#bool_from_str:将字符串转化为数组
auto_disk_config = utils.bool_from_str(
image['properties']['auto_disk_config']) if kernel_id is None:
kernel_id = image['properties'].get('kernel_id', None)
if ramdisk_id is None:
ramdisk_id = image['properties'].get('ramdisk_id', None)
# FIXME(sirp): is there a way we can remove null_kernel?
# No kernel and ramdisk for raw images
if kernel_id == str(FLAGS.null_kernel):
kernel_id = None
ramdisk_id = None
LOG.debug(_("Creating a raw instance"))
# Make sure we have access to kernel and ramdisk (if not raw)
#locals() 返回一个名字/值对的字典
LOG.debug(_("Using Kernel=%(kernel_id)s, Ramdisk=%(ramdisk_id)s")
% locals()) #show详细是干嘛的????
if kernel_id:
image_service.show(context, kernel_id)
if ramdisk_id:
image_service.show(context, ramdisk_id)
if config_drive_id:
image_service.show(context, config_drive_id) #检查是否具有安全防火墙。假设不具有就创建一个默认的安全组。
self.ensure_default_security_group(context) #ssh 密钥文件名称存在。可是数据不存在。 if key_data is None and key_name:
key_pair = self.db.key_pair_get(context, context.user_id, key_name)
key_data = key_pair['public_key'] if reservation_id is None:
reservation_id = utils.generate_uid('r') #根设备名
root_device_name = block_device.properties_root_device_name(
image['properties']) # NOTE(vish): We have a legacy hack to allow admins to specify hosts
# via az using az:host. It might be nice to expose an
# api to specify specific hosts to force onto, but for
# now it just supports this legacy hack.
host = None
#parition 函数进行切割字符串,假设切割成功。返回tuple,中间的为分隔符;假设找不到。返回1个实用字符串
#剩余两个元素为空。
#下边主要功能是设置调度集群。
if availability_zone:
availability_zone, _x, host = availability_zone.partition(':')
if not availability_zone:
availability_zone = FLAGS.default_schedule_zone
if context.is_admin and host:
filter_properties = {'force_hosts': [host]}
else:
filter_properties = {} filter_properties['scheduler_hints'] = scheduler_hints base_options = {
'reservation_id': reservation_id,
'image_ref': image_href,
'kernel_id': kernel_id or '',
'ramdisk_id': ramdisk_id or '',
'power_state': power_state.NOSTATE,
'vm_state': vm_states.BUILDING, #注意刚開始是创建中状态。
'config_drive_id': config_drive_id or '',
'config_drive': config_drive or '',
'user_id': context.user_id,
'project_id': context.project_id,
'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),#格式化一个时间字符串。
'instance_type_id': instance_type['id'],#虚拟机的套餐类型。 'memory_mb': instance_type['memory_mb'],#虚拟机的内存
'vcpus': instance_type['vcpus'],#虚拟机的cpu核数。
'root_gb': instance_type['root_gb'],#虚机根硬盘大小
'ephemeral_gb': instance_type['ephemeral_gb'],
'display_name': display_name,
'display_description': display_description,
'user_data': user_data or '',
'key_name': key_name,#密钥文件名称
'key_data': key_data,#密钥数据
'locked': False,
'metadata': metadata,
'access_ip_v4': access_ip_v4,
'access_ip_v6': access_ip_v6,
'availability_zone': availability_zone,
'os_type': os_type,#操作系统类型。
'architecture': architecture,
'vm_mode': vm_mode,#虚机状态。
'root_device_name': root_device_name,#根设备名称。
'progress': 0,
'auto_disk_config': auto_disk_config} LOG.debug(_("Going to run %s instances...") % num_instances) if create_instance_here:
instance = self.create_db_entry_for_new_instance(
context, instance_type, image, base_options,
security_group, block_device_mapping)
# Tells scheduler we created the instance already.
base_options['uuid'] = instance['uuid']
#cast是单向的不须要等待对方回复就可以返回。
rpc_method = rpc.cast
else:
# We need to wait for the scheduler to create the instance
# DB entries, because the instance *could* be # created in
# a child zone.
#我的理解:该实例不一定在这个集群创建。可能去子集群。由于可能有非常多个吧
#因此须要等待他的创建完毕。 rpc_method = rpc.call # TODO(comstud): We should use rpc.multicall when we can
# retrieve the full instance dictionary from the scheduler.
# Otherwise, we could exceed the AMQP max message size limit.
# This would require the schedulers' schedule_run_instances
# methods to return an iterator vs a list.
#这里应该是调度器发消息了,让调度器去通知详细节点的nova-compute进程去创建虚机。
instances = self._schedule_run_instance(
rpc_method,
context, base_options,
instance_type,
availability_zone, injected_files,
admin_password, image,
num_instances, requested_networks,
block_device_mapping, security_group,
filter_properties)
#这里创建完毕。返回instance实例。
if create_instance_here:
return ([instance], reservation_id)
return (instances, reservation_id)
下边这个是给调度器发送instance创建消息的函数:_schedule_run_instance
#create_instance 调用,发送消息给调度器
def _schedule_run_instance(self,
rpc_method,
context, base_options,
instance_type,
availability_zone, injected_files,
admin_password, image,
num_instances,
requested_networks,
block_device_mapping,
security_group,
filter_properties):
"""Send a run_instance request to the schedulers for processing.""" #pid不是进程id,是项目id.....
pid = context.project_id
uid = context.user_id LOG.debug(_("Sending create to scheduler for %(pid)s/%(uid)s's") %
locals()) request_spec = {
'image': utils.to_primitive(image),
'instance_properties': base_options,
'instance_type': instance_type,
'num_instances': num_instances,
'block_device_mapping': block_device_mapping,
'security_group': security_group,
} return rpc_method(context,
FLAGS.scheduler_topic,
{"method": "run_instance",
"args": {"topic": FLAGS.compute_topic,
"request_spec": request_spec,
"admin_password": admin_password,
"injected_files": injected_files,
"requested_networks": requested_networks,
"is_first_time": True,
"filter_properties": filter_properties}})
这个代码是我个人的理解。最进学习openstack感觉一头雾水。边看《云计算与openstack》边写一些东西出来,也是一种体验吧。
加油!!。!
Openstack nova代码部分凝视一的更多相关文章
- eclipse调试openstack的nova代码
前段时间一直在研究openstack的nova部分的代码.特别想知道,怎样用eclipse来调试代码.也在论坛上问了别人.无果.最后还是自己摸索出了出路. 以下写出自己探索之路.我是用devstack ...
- OpenStack Nova 高性能虚拟机之 CPU 绑定
目录 文章目录 目录 前文列表 KVM KVM 的功能列表 KVM 工具集 KVM 虚拟机的本质是什么 vCPU 的调度与性能问题 Nova 支持的 vCPU 绑定 vcpu\_pin\_set 配置 ...
- Openstack Nova 源码分析 — 使用 VCDriver 创建 VMware Instance
目录 目录 前言 流程图 nova-compute vCenter 前言 在上一篇Openstack Nova 源码分析 - Create instances (nova-conductor阶段)中, ...
- Openstack Nova 源码分析 — Create instances (nova-conductor阶段)
目录 目录 前言 Instance Flavor Instance Status Virt Driver Resource Tracker nova-conductor Create Instance ...
- OpenStack Nova启动实例流程
1.概述 启动一个新的实例,会涉及到OpenStack Nova中的多个组件: API服务器,接收用户端的请求,并且将其传递给云控制器. 云控制器,处理计算节点.网络控制器.API服务器和调度器之前的 ...
- OpenStack nova VM migration (live and cold) call flow
OpenStack nova compute supports two flavors of Virtual Machine (VM) migration: Cold migration -- mig ...
- 如何删除 OpenStack Nova 僵尸实例
转自:http://www.vpsee.com/2011/11/how-to-delete-a-openstack-nova-zombie-instance/ 前天强制重启一台 OpenStack N ...
- OpenStack Nova 制作 Windows 镜像
OpenStack Nova 制作 Windows 镜像 windows虚拟机ubuntuimage防火墙云计算 本贴转自http://www.vpsee.com 上次 VPSee 给 OpenS ...
- OpenStack提交代码的review流程
本文整理向openstack社区提交代码的基本流程,以及社区一些介绍资料.如有转载,请注明出处! 先放张图说明一下OpenStack的code review的大体流程: 对OpenStack提交代码更 ...
随机推荐
- 微信小程序--问题汇总及详解之form表单
附上微信小程序开发文档链接:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/MINA.html form表单: 当点击 <form/> ...
- php 不重新编译增加openssl扩展
安装openssl和开发包 yum install openssl openssl-devel 跳转到PHP源码下的openssl cd /usr/local/src/php-5.5.27/ext/o ...
- Event Loop详解
1.进程,单线程与多线 进程: 运行的程序就是一个进程,比如你正在运行的浏览器,它会有一个进程. 线程: 程序中独立运行的代码段. 一个进程由单个或多个线程组成,线程是负责执行代码的. 2.单线程与多 ...
- 谈谈Python中元类Metaclass(二):ORM实践
什么是ORM? ORM的英文全称是“Object Relational Mapping”,即对象-关系映射,从字面上直接理解,就是把“关系”给“对象”化. 对应到数据库,我们知道关系数据库(例如Mys ...
- 【bzoj2527】[Poi2011]Meteors 整体二分+树状数组
题目描述 有N个成员国.现在它发现了一颗新的星球,这颗星球的轨道被分为M份(第M份和第1份相邻),第i份上有第Ai个国家的太空站. 这个星球经常会下陨石雨.BIU已经预测了接下来K场陨石雨的情况.BI ...
- [POJ3352]Road Construction
[POJ3352]Road Construction 试题描述 It's almost summer time, and that means that it's almost summer cons ...
- imx6 PCIE使能加载ath9k无线网卡
imx6q配置pcie无线网卡遇到如下问题: imx6q-pcie 1ffc000.pcie: PCI host bridge to bus 0000:00 pci_bus 0000:00: root ...
- 【VBA】全局数组定义
[说明] 全局数组定义(写在Module的最上面) 'Array Public Arr_approver Public Arr_delegator Public Arr_Role
- c#的字典序
//Dictionary System.Collections.DictionaryEntry dic=new System.Collections.DictionaryEntry("key ...
- AssetDatabase.RenameAsset 重命名文件失败
今天想写一段Unity Editor 的代码将在 Project Panel 中选中的所有 Texture 改变 Format,然后重命名 成 xxx.Dither.png 然后自动进行上一篇文章提到 ...