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提交代码更 ...
随机推荐
- X-UA-Compatible设置IE浏览器兼容模式
文件兼容性用来告诉IE,让它如何来编译你的网页. 指定 文件兼容性模式 以下是指定为Emulate IE7 mode 兼容性范例. <html> <head> <!-- ...
- Puppet单机实战之Nginx代理Tomcat
author:JevonWei 版权声明:原创作品 blog:http://119.23.52.191/ --- 构建实战之Nginx代理Tomcat [root@node1 modules]# mk ...
- 【HDU 1686 Oulipo】
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...
- 笔记:CS231n+assignment1(作业一)
CS231n的课后作业非常的好,这里记录一下自己对作业一些笔记. 一.第一个是KNN的代码,这里的trick是计算距离的三种方法,核心的话还是python和machine learning中非常实用的 ...
- leetcode 15 3sum & leetcode 18 4sum
3sum: 1 class Solution { public: vector<vector<int>> threeSum(vector<int>& num ...
- pat 甲级 1053. Path of Equal Weight (30)
1053. Path of Equal Weight (30) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...
- 东野圭吾--嫌疑人X的献身读后感
经推荐,打算看日本大作家东野圭吾的<嫌疑人X的献身>.书很薄,八开大小的书两百多页,一下午的时间差不多就能读完.读了前面几章,代入感很强,压抑浓郁的气氛着实让人难受,所以打算先看一下电影, ...
- javascript获取querystring值【个人觉得这种方法最好最棒最像.NET】
原文发布时间为:2009-05-22 -- 来源于本人的百度文章 [由搬家工具导入] JavaScript获取QueryString值, 当没有QueryString值时输出bool型 null 用j ...
- jquery text
scenario: need to display raw xml, what does text() method do: <> converted to <> i.e. 把 ...
- 模拟浏览器的GET和POST动作
Jakarta的httpclient3.1是最新版本,项目中需要用程序模拟浏览器的GET和POST动作.在使用过程中遇到不少问题.1. 带附件的POST提交 最开始都是使用MultipartPo ...