OpenStack 源码阅读-创建虚拟机(一)

openstack-neutron源码解析 openstack——neutron源码解析 阅读详情
本文为扶艾原创文章,版权所有,禁止转载!

请大家静下心来看源码分析的文章,看完后相信你会有收获的!

本文来自于微信公众号“扶艾”,欢迎大家关注获取更多精彩内容!

我们分析就分析全套的,创建虚拟机的源码分析总共分为三篇文章,我们将会用通俗易懂的语言来描述整个流程。第一篇文章将分析客户端部分的源码,也就是从点击创建虚拟机按钮后到发送http请求这部分的源码;第二篇文章将分析nova api如何接收到http请求的源码;第三篇文章将分析从筛选计算节点到创建虚拟机成功部分的源码。

本篇文章将分析虚拟机从点击创建按钮到发送http请求到nova api的源码分析。

从点击界面的创建虚拟机按钮后,在输入虚拟机的名称选择镜像和网络后那实际上做了什么工作呢?跟着我的思路来走一走!

客户端

这部分主要分析下客户端的源码,这部分源码分在两个地方:

  • 界面部分源码:/usr/share/openstack-dashboard/openstack_dashboard/
  • nova客户端源码:/usr/lib/python2.7/site-packages/novaclient/

点击创建按钮之后,实际执行了路径1这个文件中class LaunchInstance的handle方法。至于为什么界面点击创建按钮后执行这个,大家可以去看下我们的关于界面二次开发的文章,看完你会对前端界面的源码架构有个清晰的理解。

路径1. /usr/share/openstack-dashboard/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py 

部分源码:
from openstack_dashboard import api
...

class LaunchInstance(workflows.Workflow):
    ...

    def handle(self, request, context):
        ...
        api.nova.server_create(request,
                               context['name'],
                               image_id,
                               context['flavor'],
                               context['keypair_id'],
                               normalize_newlines(custom_script),
                               context['security_group_ids'],
                               block_device_mapping=dev_mapping_1,
                               block_device_mapping_v2=dev_mapping_2,
                               nics=nics,
                               availability_zone=avail_zone,
                               instance_count=int(context['count']),
                               admin_pass=context['admin_pass'],
                               disk_config=context.get('disk_config'),
                               config_drive=context.get('config_drive'),
                               scheduler_hints=scheduler_hints)

这里可以看到handle方法在收集了界面输入的相关参数后调用了api.nova.server_create()函数。那么我们继续看下api.nova.server_create()函数。

路径2. /usr/share/openstack-dashboard/openstack_dashboard/api/nova.py

部分源码
from novaclient import client as nova_client
...

def server_create(request, name, image, flavor, key_name, user_data,
                  security_groups, block_device_mapping=None,
                  block_device_mapping_v2=None, nics=None,
                  availability_zone=None, instance_count=1, admin_pass=None,
                  disk_config=None, config_drive=None, meta=None,
                  scheduler_hints=None, description=None):
    ...
    return Server(get_novaclient_with_instance_desc(request).servers.create(
        name.strip(), image, flavor, userdata=user_data,
        security_groups=security_groups,
        key_name=key_name, block_device_mapping=block_device_mapping,
        block_device_mapping_v2=block_device_mapping_v2,
        nics=nics, availability_zone=availability_zone,
        min_count=instance_count, admin_pass=admin_pass,
        disk_config=disk_config, config_drive=config_drive,
        meta=meta, scheduler_hints=scheduler_hints, **kwargs), request)


def get_novaclient_with_instance_desc(request):
    microversion = get_microversion(request, "instance_description")
    return novaclient(request, version=microversion)

def novaclient(request_auth_params, version=None):
    (
        username,
        token_id,
        project_id,
        project_domain_id,
        nova_url,
        auth_url
    ) = request_auth_params
    if version is None:
        version = VERSIONS.get_active_version()['version']
    c = nova_client.Client(version,
                           username,
                           token_id,
                           project_id=project_id,
                           project_domain_id=project_domain_id,
                           auth_url=auth_url,
                           insecure=INSECURE,
                           cacert=CACERT,
                           http_log_debug=settings.DEBUG,
                           auth_token=token_id,
                           endpoint_override=nova_url)
    return c

路径2这个server_create函数实际没有做什么工作,它在最后返回了这样一个东西Server(get_novaclient_with_instance_desc(request).servers.create(…)),看着挺复杂的一个东西,但不要被它给吓到了。只从这个地方看,可以知道这是Server()这个类,也就是说这里实际返回的是Server的对象,它的参数是get_novaclient_with_instance_desc(request).servers.create()。

至于为什么这样做,这里我可以先告诉大家,这么做是因为Server是一个专门用于封装虚拟机信息的封装类,它将创建虚拟机返回的值封装成一个对象。这里创建虚拟机返回的就是这台虚拟机创建成功之后这台虚拟机的详细信息。其实,用到这个Server类的不止创建虚拟机,包括获取指定虚拟机的详细信息(server_get)以及获取所有虚拟机信息(server_list)都用到了这个类,像server_list返回的是多台虚拟机的信息,而每台虚拟机的信息实际就是Server的一个对象。大家如果对封装这部分源码感兴趣的可以自行深入,这里我们就不将Server展开了。

这里继续看Server的参数get_novaclient_with_instance_desc(request).servers.create()。通过以上源码可以看到这个方法return novaclient,而novaclient方法返回的是nova_client下的一个Client类。也就是说Server这个参数就是这个Client类下的servers这个属性的create方法。也就是说Server类的这个复杂的参数就是create方法的返回值。如果大家对这个地方不理解,没关系,继续向下看!

查看上面代码块的第一行可以看到nova_client是从novaclient模块导入的。所以,这里就已经引入了nova客户端部分的源码了。我们继续看引入的是什么

路径3. /usr/lib/python2.7/site-packages/novaclient/client.py

部分源码
def Client():
    ...
    api_version, client_class = _get_client_class_and_version()
    ...
    return client_class(api_version=api_version,
                        auth_url=auth_url,
                        direct_use=False,
                        username=username,
                        **kwargs)


def _get_client_class_and_version(version):
    if not isinstance(version, api_versions.APIVersion):
        version = api_versions.get_api_version(version)
    else:
        api_versions.check_major_version(version)
    if version.is_latest():
        raise exceptions.UnsupportedVersion(
            _("The version should be explicit, not latest."))
    return version, importutils.import_class(
        "novaclient.v%s.client.Client" % version.ver_major)

看路径3的代码,发现Client是一个方法,不过它的返回值是一个类,而这个类是通过另一个方法_get_client_class_and_version获取的,而这个方法它实际导入的是novaclient.v2.client.Client类,也就是下面路径4中的Client类。

路径4. /usr/lib/python2.7/site-packages/novaclient/v2/client.py

部分源码
from novaclient import client
from novaclient.v2 import servers

class Client(object):

    def __init__():
        ...

        self.servers = servers.ServerManager(self)
        ...
        self.client = client._construct_http_client()

看了路径4的代码,这里面已经出现了servers这个属性了,它的值是servers.ServerManager。我们继续看下面路径5的源码,看到ServerManager有一个方法是create方法。至此,路径2中Server(get_novaclient_with_instance_desc(request).servers.create(…))这个已经明了,实际这个参数就是获取了nova客户端,并调用了其中ServerManager的create方法。

路径5. /usr/lib/python2.7/site-packages/novaclient/v2/servers.py

部分源码
class ServerManager(base.BootingManagerWithFind):

    def _boot()
        ...
        reurn self._create(resource_url, body, response_key,
                           return_raw=return_raw, **kwargs)
    ...
    def create(self, name, image, flavor, meta=None, files=None,
               reservation_id=None, min_count=None,
               max_count=None, security_groups=None, userdata=None,
               key_name=None, availability_zone=None,
               block_device_mapping=None, block_device_mapping_v2=None,
               nics=None, scheduler_hints=None,
               config_drive=None, disk_config=None, admin_pass=None,
               access_ip_v4=None, access_ip_v6=None, **kwargs)
        ...
        boot_kwargs = dict(
            meta=meta, files=files, userdata=userdata,
            reservation_id=reservation_id, min_count=min_count,
            max_count=max_count, security_groups=security_groups,
            key_name=key_name, availability_zone=availability_zone,
            scheduler_hints=scheduler_hints, config_drive=config_drive,
            disk_config=disk_config, admin_pass=admin_pass,
            access_ip_v4=access_ip_v4, access_ip_v6=access_ip_v6, **kwargs)

        if block_device_mapping:
            resource_url = "/os-volumes_boot"
            boot_kwargs['block_device_mapping'] = block_device_mapping
        elif block_device_mapping_v2:
            resource_url = "/os-volumes_boot"
            boot_kwargs['block_device_mapping_v2'] = block_device_mapping_v2
        else:
            resource_url = "/servers"
        if nics:
            boot_kwargs['nics'] = nics

        response_key = "server"
        return self._boot(resource_url, response_key, **boot_args, **boot_kwargs)

路径5这里create方法整合参数,并准备了创建虚拟机要用到的url,而后调用了ServerManager的_boot方法,_boot方法中也是在整合参数,将整合的参数放到了body这个字典中,然后调用了self._create()方法。而这个_create的方法在ServerManager的父类里,继承关系是这样的Manager <= ManagerWithFind(Manager) <= BootingManagerWithFind(ManagerWithFind) <= ServerManager(base.BootingManagerWithFind),_create方法就在Manager这个父类里。

这里为什么这么继承呢?根据源码来看Manager这个类是nova客户端这边管理虚拟机(server)、镜像(image)、模版(flavor)相关操作(创建、删除、查询、更新)的一个类,而ManagerWithFind继承Manager,ManagerWithFind不止有Manager的功能,它还有find的功能,BootingManagerWithFind就是说还有启动虚拟机的功能,ServerManager就具有以上所有功能。大家如果有兴趣可以深入研究下客户端这边这个源码结构,还是比较有趣的,对代码框架设计还是有一定帮助,其中还有hookmixin的使用。我们言归正传,继续看这个_create方法吧。

路径6. /usr/lib/python2.7/site-packages/novaclient/base.py

部分源码:
class Manager():

    def __init__(self, api):
        self.api = api

    def _create(self, url, body, response_key, return_raw=False, **kwargs):
        self.run_hooks('modify_body_for_create', body, **kwargs)
        resp, body = self.api.client.post(url, body=body)
        if return_raw:
            return self.convert_into_with_meta(body[response_key], resp)

        with self.completion_cache('human_id', self.resource_class, mode="a"):
            with self.completion_cache('uuid', self.resource_class, mode="a"):
                return self.resource_class(self, body[response_key], resp=resp))

看路径6这里是已经在准备发送请求了,调用了api.client.post方法。这个self.api是在init方法中赋值的,是在哪传过来的呢,注意看上面路径4中ServerManager有个参数是self,也就是说这个self.api就是路径4中Client类的对象,self.api.client则是路径4中self.client,它等于client._construct_http_client(),在路径7下看到_construct_http_client返回的是SessionClient,从这里看这个类没有post方法,那么我们再去它的父类看看,最终在路径8中的Adapter类中找到了post方法,真是山高路远。根据Adapter类的描述,这个Adapter是大部分组件客户端都会用到的,也就是说其它组件的客户端发送请求也会继承这个类,原来看到过kilo版本的这部分源码,post这些方法仍然是在novaclient这个模块的,现在来看应该是将这部分从各个客户端模块给拿出来统一到这里来了。

路径7. /usr/lib/python2.7/site-packages/novaclient/client.py

部分源码:
from keystoneauth1 import adapter
from keystoneauth1 import session as ksession

class SessionClient(adapter.LegacyJsonAdapter):
    ...
    def request(self, url, method, **kwargs):
        ...
        resp, body = super(SessionClient, self)request(url,
                                                       method,
                                                       raise_exc=False,
                                                       **kwargs)
        ...
        return resp, body

def _construct_http_client():
    ...
    if not session:
        if not auth and auth_token:
            auth = identity.Token(auth_url=auth_url,
                                  token=auth_token,
                                  project_id=project_id,
                                  project_name=project_name,
                                  project_domain_id=project_domain_id,
                                  project_domain_name=project_domain_name)
        elif not auth:
            auth = identity.Password(username=username,
                                     user_id=user_id,
                                     password=password,
                                     project_id=project_id,
                                     project_name=project_name,
                                     auth_url=auth_url,
                                     project_domain_id=project_domain_id,
                                     project_domain_name=project_domain_name,
                                     user_domain_id=user_domain_id,
                                     user_domain_name=user_domain_name)
        session = ksession.Session(auth=auth,
                                   verify=(cacert or not insecure),
                                   timeout=timeout,
                                   cert=cert,
                                   user_agent=user_agent)
    return SessionClient(api_version=api_version,
                         auth=auth,
                         endpoint_override=endpoint_override,
                         interface=endpoint_type,
                         logger=logger,
                         region_name=region_name,
                         service_name=service_name,
                         service_type=service_type,
                         session=session,
                         timings=timings,
                         user_agent=user_agent,
                         **kwargs)


路径8. /usr/lib/python2.7/site-packages/keystoneauth1/adapter.py

部分源码:
class Adapter()
    ...
    def __init__(self, session,...):
        ...
        self.session = session
        ...

    def request(self, url, method, **kwargs):
        ...
        return self.session.request(url, method, **kwargs)

    def post(self, url, **kwargs):
        return self.request(url, 'POST', **kwargs)


class LegacyJsonAdapter(Adapter):
    ...
    def request(self, *args, **kwargs):
        ...
        resp = super(LegacyJsonAdapter, self).request(*args, **kwargs)

        try:
            body = resp.json()
        except ValueError:
            body = None

        return resp, body

继续看看这个post方法,post方法调用的是request发送请求,而看看路径7中的request实际上是调用了父类中的request方法,然后看路径8中它的父类LegacyJsonAdapter也调用了父类的request方法。而Adapter的request又是调用的self.session.request,而则个session是哪来的呢?看路径7中的session,它实际也是keystoneauth1这个模块中来的,所以请求最后通过keystoneauth1/session.py中Session的request方法发出去了。这里不细说了。

至此,请求已经发出去了,下面将看看nova api是如何接收这个请求的,更多详情请看《OpenStack源码阅读-创建虚拟机(二)》

更多精彩内容,OpenStack干货请扫描下方二维码,关注我们微信公众号“扶艾”!
这里写图片描述

OpenStack中nova组件创建虚拟机的源码流程 OpenStack中创建虚拟机的源码流程分析 阅读详情

相关推荐

OpenStack源码阅读-创建虚拟机(三)

本文为扶艾原创文章,版权所有,禁止转载! 请大家静下心来看源码分析的文章,看完后相信你会有收获的! 本文来自于微信公众号“扶艾”,欢迎大家关注获取更多精彩内容! 上一篇文章我们分析了nova api是如何接收请求的,这篇文章我们将分析接收到请求之后创建虚拟机的流程。 nova api请求接收到请求之后,是执行的路径1的create方法。这个整合了创建虚拟机的用到的参数,并作了简单的合法性检...

塔尖草的博客 1525

openstack zun源码分析

openstack-zun源码分析,创建容器过程分析,挂载卷,网络流程,部署,测试,镜像,配额等

HYESC的博客 1222

openstack单机ubuntu虚拟机环境安装部署经验及源码结构简单介绍(适合入门者)

参考:OneStack脚本 本文主要关于近一个月对Openstack学习的一个总结,包括单机环境安装部署中出现的问题记录和源码学习的过程,适合入门者阅读。 一、openstack安装部署 目前看到的一个是官方的安装部署文档,一个是中文的OneStack脚本。 根据两个文档都能在虚拟机Ubuntu环境搭建好环境,中间也许或出现某些问题,搜一下应该可以得到解决。 因为OneStack的是中文

周绍禹-whuiss 6521

Openstack源代码分析之开篇

希望能把自己的学习与分析历程记录下来,与更多的程序员交流,沟通。 本人qq:260164797,欢迎交流~ 本人已经学习Openstack和python一段时间了,现在把Openstack学习历程记录下来,以Devstack部署为基础分析Openstack的源码。 Devstack安装部署网址:Devstack官网     Devstack是安装部署Openstack的最简单方法,通过脚本

戏笔 2975

OpenStack源码探秘(一)——Nova-Scheduler

OpenStack源码探秘(一)——Nova-Scheduler OpenStack源码探秘(二)——Oslo.Config 许久没有更新OpenStack源码探秘系列了。最近换工作颇不顺利,许多笔者心仪的公司都因为这样或那样的原因而失之交臂,这样下去可能会考虑到互联网公司做些服务器端的工作。晚上回到家心情都不太好,懒得动笔,不过经过了几天起伏,心态也慢慢调整过来了,今天就给大家分享一篇N

熠耀之森 8867

openstack其中四大组件源码

cinder、swift、glance、keystone等openstack四大模块的源码

OpenStack之Horizon源码架构浅析(二)之启动流程分析(简约版)

horizon启动过程 主要的文件是: openstack_dashborad.urls.py(OpenStack Dashboard的URL patterns)、 openstack_dashborad.settings.py(配置文件)、 horizon.base.py(Horizon的基础库) base.py实现了一套dashboard/panel注册、动态加载机制,使得Horiz

探索世界,改变世界 1128

避坑指南:ANSYS流固耦合计算中System Coupling数据传递设置与常见报错解决

本文深入解析ANSYS Workbench中System Coupling模块在双向流固耦合(FSI)计算中的应用,详细讲解数据传递机制、典型报错解决方案及高阶调试技巧。通过实际案例展示如何优化耦合步长、处理大变形问题,并提升并行计算效率,帮助工程师有效规避常见技术陷阱。

weixin_29213525的博客 730

如何阅读OpenStack源码(Python)

转载:如何阅读OpenStack源码 1 关于该项目 本项目使用在线绘图工具web sequencediagrams完成,目标是图形化OpenStack的所有操作流程,通过操作序列图能快速学习Openstack的工作原理,理清各个组件的关系,运维人员也能根据操作序列图进行更精确的故障定位和排查. 注意,该操作序列图基于L版OpenStack源码,未来版本的操作可能会有变化,请以最新版的源码为...

Yannick Jiang 的专栏 1392

Ubuntu22.04通过DKMS包安装Intel WiFi系列适配器(网卡驱动)

Ubuntu安装Intel WiFi系列适配器(网卡驱动)

lu_linux的博客 2602

FreeRTOS-Plus-CLI使用笔记

FreeRTOS-Plus-CLI使用笔记 一、简介 详细介绍可参考FreeRTOS-Plus-CLI官网地址入口 FreeRTOS+CLI(Command Line Interface, 命令行接口)提供了一种简单、小型、可扩展且RAM高效的方法,使FreeRTOS应用程序能够处理命令行输入。添加一条指令的步骤如下: 提供一个实现命令功能的函数 将命令映射到该功能函数 注册命令 运行命令解释器 命令行调试接口对于排查分析出现的问题提供了很好的接口,可以通过查看传感器信息判断传感器是否正常,可以查看内置

ApexYuan 6964

openstack源码架构_openstack创建虚拟机源码阅读

标签: openstack nova 源码阅读在openstack中,虚拟机的创建无疑是非常重要的,了解虚拟机创建流程并阅读nova模块关于创建虚拟机的源码对opensatck开发有很很大帮助,本篇文章将以openstack queens版本为基础.讲解创建虚拟机的源码.由于nova模块代码复杂,而且阅读源码所需知识较多,所以侧重于流程逻辑,源码阅读可能不够详尽指出.nova模块结构DB: 用于存...

weixin_39959298的博客 258

【知识分享】IBIS 建模指南 03

本文介绍了差分缓冲器的数据提取方法,重点分析了差分系统与单端系统的核心差异。文章详细阐述了差分接收机和驱动器的结构特点、工作原理及建模方法,指出全差分结构具有优异的电源噪声抑制能力。针对IBIS建模规范,作者提出了三维I-V曲面数据提取技术,并介绍了共模/差模电流分离、片上端接处理以及V-T表生成的解决方案。文章还探讨了差分电容(C_diff)的测量方法和数据简化策略,为复杂差分缓冲器的精确建模提供了系统化的技术路径。

一只豌豆象的博客 1282

OpenStack源码阅读-创建虚拟机(二)

本文为扶艾原创文章,版权所有,禁止转载! 请大家静下心来看源码分析的文章,看完后相信你会有收获的! 本文来自于微信公众号“扶艾”,欢迎大家关注获取更多精彩内容! 上篇内容主要分析了下创建虚拟机从点击按钮到发送http请求部分源码。这篇文章是本系列的第二篇文章,按照内容来说,这篇内容更多的在说nova api,和创建虚拟机的关系实在不大。不过这边文章能帮助大家更清晰的理解restful架构、w...

塔尖草的博客 1011

42页Claude 3技术报告解读(Opus, Sonnet, Haiku)

在Claude 3模型中,增加了一个额外的原则到Claude的宪法中,以鼓励尊重残疾人权利,这一原则源自对集体宪法AI的研究。Claude 3模型的训练基于专有的混合数据集,包括截至2023年8月互联网上公开可用的信息,以及第三方提供的非公开数据、数据标注服务和付费承包商提供的数据,还有内部生成的数据。这些初始响应通常包含有害和有毒的内容。Claude 3模型家族在推理、编码和问答任务上展现出卓越的性能,特别是在行业标准基准测试中取得了显著的提升,证明了其在处理复杂问题和提供准确答案方面的能力。

具身机器人和通用AI 2439

1、Ka频段双极化低剖面卫通相控阵天线

设计了双馈口叠层十字缝隙耦合天线,采用“双线极化天线 +旋转馈电 + 移相控制”架构,采用双馈口的叠层十字缝隙耦合天线,并以 2 x2 阵列为主体,旋转排布实现二次圆极化,同时极化可切换,通过多层 PCB 工艺实现天线层、控制/电源层功分网终层、芯片层一体化集成,研制出 64 阵元的圆极化可切换发射天线,测试结果表明:天线工作 频段为 27.5 ~31 GHz,可实现60°扫描,法向轴比

qq_43416206的博客 4370

如何阅读OpenStack源码

1 关于该项目 本项目使用在线绘图工具web sequencediagrams完成,目标是图形化OpenStack的所有操作流程,通过操作序列图能快速学习Openstack的工作原理,理清各个组件的关系,运维人员也能根据操作序列图进行更精确的故障定位和排查. 注意,该操作序列图基于L版OpenStack源码,未来版本的操作可能会有变化,请以最新版的源码为准,该项目提供的序列图仅供参考。 2 ...

成字第0431879 468

LeRobot 入门教程(七)数据集

LeRobot Dataset v3.0 是机器人学习数据的标准化格式,支持多模态时间序列数据和视频的统一访问。该版本通过基于文件的存储(Parquet/MP4)、关联元数据和Hub原生流式处理等新特性,显著提升了性能并降低了存储开销。文档详细介绍了格式设计、安装使用、数据记录与加载方法,以及从v2.1迁移到v3.0的步骤,特别针对大型数据集(如DROID 1.0.1)的处理提供了SLURM集群移植方案。v3.0通过优化文件组织和元数据管理,实现了更快的加载速度、更高的内存效率和更好的可扩展性。

2506_90492529的博客 2055

openstack源码阅读

1 OpenStack基础 1.1 OpenStack组件介绍 OpenStack是一个IaaS云计算平台开源实现,其对标产品为AWS。最开始OpenStack只有两个组件,分别为提供计算服务的Nova以及提供对象存储服务的Swift,其中Nova不仅提供计算服务,还包含了网络服务、块存储服务、镜像服务以及裸机管理服务。之后随着项目的不断发展,从Nova中根据功能拆分为多个独立的项目,如nova-volume拆分为Cinder项目提供块存储服务,nova-image拆分为Glance项目,提供镜像存储服

qq_42533216的博客 657

电化学-NanoStat-开源系统的使用说明

本文主要介绍了NanoStat开源系统的使用方法,从硬件打板、设备组装、软件安装3个层次进行了详细说明。整个流程根据作者提供的视频能够很好的完成,不需要太多的技术,对刚入门的新手是一个不错的练手项目。其次软件还有很大的优化空间,能够进一步提高系统的精度,对之后类似恒电位仪系统的开发也有很大的借鉴意义。

分享技术笔记,希望对大家能够有一定的帮助,同时也通过归纳总结提升自己的个人能力。 2003

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

openstack创建虚拟机源码阅读

标签: openstack nova 源码阅读 在openstack中,虚拟机的创建无疑是非常重要的,了解虚拟机创建流程并阅读nova模块关于创建虚拟机的源码对opensatck开发有很很大帮助,本篇文章将以openstack queens版本为基础.讲解创建虚拟机的源码.由于nova模块代码复杂,而且阅读源码所需知识较多,所以侧重于流...

weixin_33937913的博客 344

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Openstack中虚拟机的Resize功能详解

本文由guwenwu写于2012年08月11日,转载请注明出处,谢谢!    摘要:在Openstack中生成VM后,由于业务的变更或业务量的增加,需要对VM进行扩展。目前Openstack中提供了Resize功能,本文对Openstack中的源码进行了测试和分析,并进行了一定的修改。 环境:2台Centos6.2机器           HOSTA:10.28.170.

te_amo蘑菇 6280

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

openstack-nova源码之阅读流程

以创建虚拟机为例 1.项目入口setup.cfg文件 2.根据nova-compute = nova.cmd.compute:main找到功能入口 3.nova/api/openstack/compute/servers.py中create(self, req, body)中进行rpc调用 4.进去nova/compute/api.py中cre...

weixin_30417487的博客 643

openstack 源码阅读技巧2021(持续更新中……)

不要问楼主为什么同样的一篇博客不选更新选重发,问就是优快云不支持老博客从富文本编辑转到markdown,害! 写在开始之前 共性问题: 怎么读openstack代码这件事,是个持续性问题,毕竟官方半年就出一个新版本。有一些共性的小技巧放在前面说一说() 1.从一个特性入手是比较合适的看代码的方式 日志可以 针对人群 本文是为新手准备的,大佬请直接跳过,很多大佬觉得默认知道的事情,实际上对于新手来说比较致命,因为就卡在那些大佬认为简单不愿意写但是很容易混淆或者跟丢的地方 1.日志路径 /var/log/

TinaSprunt的开发笔记 1025
上一篇: restful、wsgi、paste
下一篇: OpenStack(Queens)详细安装部署(六)-界面(horizon)安装
林大大.
博客等级 码龄11年 111粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值