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提交代码更 ...
随机推荐
- Spring框架annotation实现IOC介绍
Spring学习笔记(三) 续Spring 学习笔记(二)之后,对Spring框架的annotation实现方法进行整理 本文目录 @Autowire 1 @Autowire+@Qualifier t ...
- Codeforces Round #418 (Div. 2) A+B+C!
终判才知道自己失了智.本场据说是chinese专场,可是请允许我吐槽一下题意! A. An abandoned sentiment from past shabi贪心手残for循环边界写错了竟然还过了 ...
- Redis实现缓存,你应该懂的哪些思路!
场景一:类似于微博,实现关注和被关注功能. 思路: 对每个用户使用两个集合类型键,用来存储关注别人的用户和被该用户关注的用户.当用户A关注用户B的时候,执行两步操作: sadd user:A B sa ...
- hdu6136[模拟+优先队列] 2017多校8
有点麻烦.. /*hdu6136[模拟+优先队列] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long ...
- java写文件的基本操作
import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOExce ...
- [AGC004F] Namori
Description 现在给你一张N个点M条边的连通图,我们保证N−1≤M≤N,且无重边和自环. 每一个点都有一种颜色,非黑即白.初始时,所有点都是白色的. "全"想通过执行若干 ...
- 【CF1015F】Bracket Substring(字符串DP)
题意:给定一个只由左右括号组成的字符串s,问长度为2*n的包含它的合法括号序列方案数,答案对1e9+7取模 1≤n≤100,1≤|s|≤200 思路:暴力预处理出s的每个前缀[0..i]后加左右括号分 ...
- DataSet导出到Excel文件
public static void ExportToExcel(DataSet source, string fileName) { System.IO.StreamWriter excelDoc ...
- 自定义及发布一个webservice服务
自定义及发布一个webservice服务 - 声明 某个业务服务为webservice服务 通过@webservice 注解来声明 - 发布webservice服务 ...
- 转 网络编程学习笔记一:Socket编程
题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...