做个一个没怎么学过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代码部分凝视一的更多相关文章

  1. eclipse调试openstack的nova代码

    前段时间一直在研究openstack的nova部分的代码.特别想知道,怎样用eclipse来调试代码.也在论坛上问了别人.无果.最后还是自己摸索出了出路. 以下写出自己探索之路.我是用devstack ...

  2. OpenStack Nova 高性能虚拟机之 CPU 绑定

    目录 文章目录 目录 前文列表 KVM KVM 的功能列表 KVM 工具集 KVM 虚拟机的本质是什么 vCPU 的调度与性能问题 Nova 支持的 vCPU 绑定 vcpu\_pin\_set 配置 ...

  3. Openstack Nova 源码分析 — 使用 VCDriver 创建 VMware Instance

    目录 目录 前言 流程图 nova-compute vCenter 前言 在上一篇Openstack Nova 源码分析 - Create instances (nova-conductor阶段)中, ...

  4. Openstack Nova 源码分析 — Create instances (nova-conductor阶段)

    目录 目录 前言 Instance Flavor Instance Status Virt Driver Resource Tracker nova-conductor Create Instance ...

  5. OpenStack Nova启动实例流程

    1.概述 启动一个新的实例,会涉及到OpenStack Nova中的多个组件: API服务器,接收用户端的请求,并且将其传递给云控制器. 云控制器,处理计算节点.网络控制器.API服务器和调度器之前的 ...

  6. OpenStack nova VM migration (live and cold) call flow

    OpenStack nova compute supports two flavors of Virtual Machine (VM) migration: Cold migration -- mig ...

  7. 如何删除 OpenStack Nova 僵尸实例

    转自:http://www.vpsee.com/2011/11/how-to-delete-a-openstack-nova-zombie-instance/ 前天强制重启一台 OpenStack N ...

  8. OpenStack Nova 制作 Windows 镜像

    OpenStack Nova 制作 Windows 镜像   windows虚拟机ubuntuimage防火墙云计算 本贴转自http://www.vpsee.com 上次 VPSee 给 OpenS ...

  9. OpenStack提交代码的review流程

    本文整理向openstack社区提交代码的基本流程,以及社区一些介绍资料.如有转载,请注明出处! 先放张图说明一下OpenStack的code review的大体流程: 对OpenStack提交代码更 ...

随机推荐

  1. Summary—【base】(CSS)

    CSS知识点 1. CSS又被称为层叠样式表 2. CSS在html中的语法 a) <style> 选择器{键:值;} </style> b) css中最后一个键值可以不写分号 ...

  2. selenium webdriver——鼠标事件

    Web产品中提供了丰富的鼠标交互方式,例如鼠标右击.双击.悬停.甚至是鼠标拖动等功能,在WebDriver中,将这些关于鼠标操作的方法 封装在ActionChains类中: ActionChains类 ...

  3. Vue2.0 - 构造器的延伸 Vue.extend

    Vue.extend 返回的是一个“扩展实例构造器”,也就是预设了部分选项的Vue实例构造器.经常服务于Vue.component用来生成组件,可以简单理解为当在模板中遇到该组件名称作为标签的自定义元 ...

  4. 深入比较选择 Angular 还是 React

    我应该选择 Angular 还是 React?现在JS框架两强的格局让许多开发者选择起来很纠结.无论你是一个正在思考如何入门的新手,还是一个为下个项目挑选框架的设计者,或是一个架构师为公司做长远的规划 ...

  5. 东野圭吾--嫌疑人X的献身读后感

    经推荐,打算看日本大作家东野圭吾的<嫌疑人X的献身>.书很薄,八开大小的书两百多页,一下午的时间差不多就能读完.读了前面几章,代入感很强,压抑浓郁的气氛着实让人难受,所以打算先看一下电影, ...

  6. 洋媳妇Susan教育孩子的方法

    洋媳妇Susan教育孩子的方法 一个中国婆婆跟我说:「我的儿子去美国留学,毕业后定居美国. 还给我找了个洋媳妇Susan. 如今,小孙子Toby已经3岁了. 今年夏天,儿子為我申请了探亲签证. 在美国 ...

  7. CentOS下VNC使用

    1. 介绍 本文主要介绍了VNC Server的配置和使用 2. 安装 CentOS中默认就有安装VNC,可以通过命令rpm查看 [Jerry@localhost ~]$ rpm -qa | grep ...

  8. 什麼是 usb upstream port

    主機USB埠是定義為USB纜線的上行端(Upstream)或「A」接頭,即PC端.而裝置USB埠是定義為USB纜線的下行端(Downstream)或「B」接頭,即行動產品端. Reference ht ...

  9. SQL存储过程基础

    什么是存储过程呢?存储过程就是作为可执行对象存放在数据库中的一个或多个SQL命令. 通俗来讲:存储过程其实就是能完成一定操作的一组SQL语句. 那为什么要用存储过程呢?1.存储过程只在创造时进行编译, ...

  10. dracut 基本介绍

    dracut 维基   https://dracut.wiki.kernel.org/index.php/Main_Page  http://www.360doc.com/content/13/042 ...