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

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

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

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

上篇内容主要分析了下创建虚拟机从点击按钮到发送http请求部分源码。这篇文章是本系列的第二篇文章,按照内容来说,这篇内容更多的在说nova api,和创建虚拟机的关系实在不大。不过这边文章能帮助大家更清晰的理解restful架构、wsgi以及openstack 如何构建api接口的。文中涉及东西很多,但都是必要得铺垫,有说得不对的地方,欢迎大家指出,欢迎大家拍砖!

nova api

这部分源码主要在两个地方:
- nova源码 /usr/lib/python2.7/site-packages/nova
- openstack服务管理源码 /usr/lib/python2.7/site-packages/oslo_service

首先,在开始阅读源码之前,需要先有几个铺垫。

rest

restful在openstack中大家应该是听得比较多了。rest是Roy Thomas Fielding在2000年的博士论文中提出的。如果大家想深入理解rest是什么,相比于网上去搜索答案,不如看下那篇博士论文。这里我们为大家准备了一份他的中文版的博士论文,大家扫描下方微信公众号二维码,回复fuai_rest即可获取。

现在网上一搜restful是什么?会出来很多的解释,很多术语都很专业,很多人都是看得云里雾里的。之前在网上看到一篇形象的解释,现在放在这大家理解理解:

没有用rest

POST /users/getuser    获取用户信息
POST /users/createuser 创建用户
POST /users/updateuser 更新用户信息
POST /users/deleteUser 删除用户

使用rest风格

GET    /users/{user_id} 获取用户信息
POST   /users           创建用户
PUT    /users/{user_id} 更新用户信息
DELETE /users/{user_id} 删除用户信息

这里我也不过多解释rest了。openstack的api就是这种风格的api,所以叫它restful api。举个简单的例子:

POST v2/{project_id}/servers                创建虚拟机
GET  v2/{project_id}/servers                获取所有虚拟机信息

routes
openstack的api是restful api,而restful架构的核心是资源以及对这些资源的操作。openstack定义了很多资源以及这些资源的操作函数。当openstack api接收到http请求时,怎么知道请求调用的是哪个资源的操作函数?这时候路由模块就登场了,它可以将请求url转换成相应的资源,并路由到对应的操作函数上。

Example:
#创建一个映射对象
mapper = routes.Mapper()

#实现一个资源类,openstack中有很多类似的Controller类,每一个Controller都对应了一个restful资源,该类下有对该资源的各种操作函数,比如index、show、create等
sc = ServerController()

#定义url到资源的映射
mapper.connect(None, '/svrlist', controller=sc, action='list')
mapper.resource('server', 'servers', controller=sc)

wsgi

wsgi是python中定义的web服务器和web应用程序之间的通用接口标准。它分成三个部分web服务器、web中间件、web应用程序。如果不理解这句话,那我再白话一点,它就像web服务器与你的应用程序之间管道一样。还不理解?那你知道nova api是需要实现那三个部分的就行了。

oslo.service

openstack的api接口既然采用的是wsgi标准,那它们是怎么实现这个标准的,翻了下前面几个版本的源码,kilo版本及之前实现wsgi相关的东西都是在nova这个源码目录下的,到了liberty版本之后,就正式将这部分源码从各个组件模块中提出了,就是现在的oslo.service。

oslo_service实现中,核心是oslo_serivce.service中的Service类和Launcher类。Service类描述一个服务,Launcher类用来启动服务。

paste.deploy

paste是openstack中用于实现wsgi标准的具体工具模块,它可以根据配置文件/etc/nova/api-paste.ini来加载wsgi app

api-paste.ini部分内容如下:

[composite:osapi_compute]
use = call:nova.api.openstack.urlmap:urlmap_factory
/: oscomputeversions
...
/v2.1: openstack_compute_api_v21

[composite:openstack_compute_api_v21]
use = call:nova.api.auth:pipeline_factory_v21
...
keystone = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext osapi_compute_app_v21

...
[filter:sizelimit]
paste.filter_factory = oslo_middleware:RequestBodySizeLimiter.factory 

[app:osapi_compute_app_v21]
paste.app_factory = nova.api.openstack.compute:APIRouterV21.factory

上面配置文件出现了下面几个部分
- composite, 这个部分是将url请求分发到对应的app,use表明的是分发的方式,这里是urlmap进行分发的
- filter,这个其实对应的是wsgi 的middleware。上面的cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext这些都是middleware,osapi_compute_app_v21才是app。这些middleware是可以自行增加或删除的

接收到请求后,首先会交给middleware依次处理,最后交给app。

  • paste的deploy可根据传入的app名称来加载wsgi app:
deploy.loadapp("config:/etc/nova/api-paste.ini", name=name)

下面会具体用到paste,再细说。

nova api

现在进入主题。nova api是什么?nova api是nova提供各种服务的公共接口。nova api从客户端接收到请求之后,然后将请求给nova,nova处理完成请求之后将处理结果返回给nova客户端。那么nova api是如何接收请求的。前面已经简单说了下rest和wsgi,而nova api就是rest风格的api,它也是采用的wsgi标准,有web server、web middleware、web app。
如果要看nova api如何接收请求,我们先看它是如何启动起来的。看它的服务启动文件/usr/lib/systemd/system/openstack-nova-api.service,知道它启动脚本是/usr/bin/nova-api

...
[Service]
...
ExecStart=/usr/bin/nova-api
...

/usr/bin/nova-api文件内容如下

#!/usr/bin/python2
# PBR Generated from u'console_scripts'
import sys
from nova.cmd.api import main

if __name__ == "__main__":
    sys.exit(main())

我们看下/usr/lib/python2.7/site-packages/nova/cmd/api.py文件,看看启动nova api要做哪些工作。下面路径1即为api.py的主要内容。首先获得了一个服务启动的对象launcher,它是 service.process_launcher()返回的。这里的service是导入路径2的service.py,在路径2中我们看到了process_launcher方法。它返回的是service.ProcessLauncher类,而路径2的service导入了的oslo_service的service.py(路径3)中的class ProcessLauncher。

继续看路径1,server = service.WSGIService(api, use_ssl=should_use_ssl)这里返回了一个wsgi的服务对象。用于描述一个wsgi服务。这里WSGIService也是在路径2中,它继承的是oslo_service的Service类(路径3),这就是我们文章开头说的oslo_service的两个类。

继续看路径1,launcher.launch_service启动了wsgi服务,最后launcher.wait让api服务处于等待外部请求状态。关于launch_service的信息请看路径3。

...
路径1. /usr/lib/python2.7/site-packages/nova/cmd/api.py

部分源码:
from nova import service
def main():
    ...
    #创建一个ProcessLauncer对象,该对象可以启动一个或多个wsgi服务
    launcher = service.process_launcher()   
    started = 0
    for api in CONF.enabled_apis:
        should_use_ssl = api in CONF.enabled_ssl_apis
        try:
            #创建一个wsgi服务对象,该对象具有wsgi服务的生命周期管理功能
            server = service.WSGIService(api, use_ssl=should_use_ssl) 
            #启动wsgi server
            launcher.launch_service(server, workers=server.workers or 1)
            started += 1
        except exception.PasteAppNotFound as ex:
            log.warning("%s. ``enabled_apis`` includes bad values. "
                        "Fix to remove this warning.", ex)

    if started == 0:
        log.error('No APIs were started. '
                  'Check the enabled_apis config option.')
        sys.exit(1)

    launcher.wait()

路径2. /usr/lib/python2.7/site-packages/nova/service.py

部分源码:
from oslo_service import service
from nova import wsgi

def process_launcher():
    return service.ProcessLauncher(CONF, restart_method='mutate')

#继承oslo_service中的service.Service
class WSGIService(service.Service):  
    """Provides ability to launch API from a 'paste' configuration."""
    def __init__(self, name, loader=None, use_ssl=False, max_url_len=None):
        """Initialize, but do not start the WSGI server.

        :param name: The name of the WSGI server given to the loader.
        :param loader: Loads the WSGI application using the given name.
        :returns: None

        """
        #name是路径1中传递过来的api,这里是"osapi_compute"
        self.name = name
        ...
        self.loader = loader or wsgi.Loader()
        #加载的是osapi_compute这个app
        self.app = self.loader.load_app(name)
        ...
        self.host = getattr(CONF, '%s_listen' % name, "0.0.0.0")
        self.port = getattr(CONF, '%s_listen_port' % name, 0)
        self.workers = (getattr(CONF, '%s_workers' % wname, None) or
                        processutils.get_worker_count())
        ...
        #初始化一个wsgi.Server来发布app服务
        self.server = wsgi.Server()
        ...

路径3. /usr/lib/python2.7/site-packages/oslo_service/service.py

部分源码:
#服务封装类 
class ServiceWrapper(object):
    def __init__(self, service, workers):
        self.service = service
        self.workers = workers
        self.children = set()
        self.forktimes = []

class ProcessLauncher(object):
    """Launch a service with a given number of workers."""

    def __init__(self, conf, wait_interval=0.01, restart_method='reload'):
        ... 

    #这里wrap是服务封装类ServiceWrapper的对象
    def _start_child(self, wrap):
        ...
        pid = os.fork()  #开进程
        if pid == 0:
            self.launcher = self._child_process(wrap.service)
            while True:
                self._child_process_handle_signal()
                status, signo = self._child_wait_for_exit_or_signal(
                    self.launcher)
                if not _is_sighup_and_daemon(signo):
                    self.launcher.wait()
                    break
                self.launcher.restart()

            os._exit(status)

        LOG.debug('Started child %d', pid)

        wrap.children.add(pid)
        self.children[pid] = wrap

        return pid

    def launch_service(self, service, workers=1):
        """Launch a service with a given number of workers.
        ...
        #判断是否是ServerBase对象。WSGIService继承的Service,而Service继承的ServerBase
        _check_service_base(service)
        #服务封装类 
        wrap = ServiceWrapper(service, workers)
        ...
        while self.running and len(wrap.children) < wrap.workers:
            #启动服务
            self._start_child(wrap)

class Service(ServiceBase):
    def __init__(self, threads=1000):
        self.tg = threadgroup.ThreadGroup(threads)

    def reset(self):
        ...

    def start(self):
        ...

    def stop(self):
        ...

    def wait(self):
        self.tg.wait()

上面简单说了下启动nova api的过程,也就是启动wsgi服务的过程,创建launcher对象、创建wsgi服务对象、启动wsgi服务。那么我们具体看下是如何实现的。看上面路径2中的WSGIService(),它是描述wsgi服务的类。其中获取wsgi app通过self.loader.load_app来获取的,这里self.loader是等于wsgi.Loader(),wsgi是引入的路径4的这个wsgi.py。根据路径4中load_app可以发现它就是通过文章前面说的paste模块来加载的。继续看WSGIService类,获取主机ip及端口,然后wsgi.Server来发布app服务

路径4. /usr/lib/python2.7/site-packages/nova/wsgi.py

部分源码:
#用于从paste配置文件加载wsgi app的类
class Loader(object):
    #初始化加载类,并检测配置文件是否存在
    def __inti__(self, config_path=None):

        self.config_path = None
        #根据配置文件,可以发现CONF.wsgi.api_paste_config默认是"api-paste.ini"
        config_path = config_path or CONF.wsgi.api_paste_config
        if not os.path.isabs(config_path):
            self.config_path = CONF.find_file(config_path)
        elif os.path.exists(config_path):
            self.config_path = config_path

        if not self.config_path:
            raise exception.ConfigNotFound(path=config_path)

    #这里name是路径2的self.loader.load_app传过来的值,是"osapi_compute"
    def load_app(self, name):
        ...
        #这里加载的app是osapi_compute,配置文件路径是api-paste.ini
        return deploy.loadapp("config:%s" % self.config_path, name=name)

从上面内容来看,我们已经知道WSGIService使用self.loader.load_app(name)来加载wsgi app,加载app完成之后,使用nova.wsgi.Server来发布服务。wsgi.Server会将监听到的http请求交给app处理。

上面加载了osapi_compute,wsgi server接收到的http请求首先会交给nova.api.openstack.urlmap:urlmap_factory的可调用对象,处理之后将请求分发给openstack_compute_api_v21,openstack_compute_api_v21使用nova.api.auth:pipeline_factory_v21来返回wsgi app,pipeline_factory_v21会依次加载cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext这些filter(这些filter就是wsgi middleware),这些filter处理完成之后才会将请求交给osapi_compute_app_v21(相当于wsgi app)。
api-paste.ini

[composite:osapi_compute]
use = call:nova.api.openstack.urlmap:urlmap_factory
...
/v2.1: openstack_compute_api_v21

[composite:openstack_compute_api_v21]
use = call:nova.api.auth:pipeline_factory_v21
...
keystone = cors http_proxy_to_wsgi compute_req_id faultwrap request_log sizelimit osprofiler authtoken keystonecontext osapi_compute_app_v21

...
[filter:sizelimit]
paste.filter_factory = oslo_middleware:RequestBodySizeLimiter.factory 

[app:osapi_compute_app_v21]
paste.app_factory = nova.api.openstack.compute:APIRouterV21.factory

这里的这些filter我们就不一一分析了,我们直接看osapi_compute_app_v21这边如何处理请求的。根据上面配置文件信息,我们知道调用了nova.api.openstack.compute.APIRouterV21.factory的可调用对象。这个factory实际就在下面路径6所示,它应该返回一个可调用对象。这里可以看到它返回的是类对象,而APIRouterV21继承的是base_wsgi.Router,也就是说请求是调用了路径7中的call方法。而call方法返回的是self._router,_router是routes.middleware.RoutesMiddleware的实例化对象,使用self._dispatch和self.map来初始化的。self.map是哪传进来的呢?注意看路径6中的APIRouterV21的init方法,其中传入了一个nova.api.openstack.ProjectMapper()对象,而这个ProjectMapper最终继承的是routes.Mapper,routes.Mapper在文章铺垫部分已经说明,它是一个路由模块,所以路径7中的self.map已经明了是一个routes.Mapper()对象,并且通过路径6中的APIRouterV21的init方法建立了映射关系,nova api在启动的时候已经初始化并建立url与资源的映射关系。继续看路径7中的dispatch方法,它通过前面设置environ[‘wsgiorg.routing_args’]来找到url对应的controller,找不到返回404。根据路径6的ROUTE_LIST信息,可以看到/servers对应的controller是nova.api.openstack.compute.servers中的ServersController

路径5. /usr/lib/python2.7/site-packages/nova/api/openstack/compute/__init__.py

部分源码:
from nova.api.openstack.compute.routes import APIRouterV21 

路径6. /usr/lib/python2.7/site-packages/nova/api/openstack/compute/routes.py

部分源码:
from nova import wsgi as base_wsgi
from nova.api.openstack.compute import servers
...
server_controller = functools.partial(_create_controller,
    servers.ServersController
...

ROUTE_LIST= (... 
('/servers', {
        'GET': [server_controller, 'index'],
        'POST': [server_controller, 'create']
    }),...)

class APIRouterV21(base_wsgi.Router):
    ...
    def __init__(self, custom_routes=None):
        super(APIRouterV21, self).__init__(nova.api.openstack.ProjectMapper())
        ...
            for path, methods in ROUTE_LIST + custom_routes:

            if isinstance(methods, str):
                self.map.redirect(path, methods)
                continue

            for method, controller_info in methods.items():
                # TODO(alex_xu): In the end, I want to create single controller
                # instance instead of create controller instance for each
                # route.
                controller = controller_info[0]()
                action = controller_info[1]
                self.map.create_route(path, method, controller, action)

    def factory(cls, global, **local_config):
        return cls()

路径7. /usr/lib/python2.7/site-packages/nova/wsgi.py

部分源码:
import routes.middleware
class Router(object):
    def __init__(self, mapper):
        self.map = mapper
        self._router = routes.middleware.RoutesMiddleware(self._dispatch,
                                                          self.map)

    def __call__(self, req):
        """Route the incoming request to a controller based on self.map.

        If no match, return a 404.

        """
        return self._router

    def _dispatch(req):
        match = req.environ['wsgiorg.routing_args'][1]
        if not match:
            return webob.exc.HTTPNotFound()
        app = match['controller']
        return app

最后看看ServerController,找到了post对应的方法create。也就是说nova客户端发送的请求最后是调用到了操作函数create。

路径8. /usr/lib/python2.7/site-packages/nova/api/openstack/compute/servers.py

部分源码:
class ServersController(wsgi.Controller):
    ...
    def create(self, req, body):
        ...
        (instances, resv_id) = self.compute_api.create()
        ...
        return wsgi.ResponseObject(...) 

本篇文章涉及得东西很多,只是分析了下大体流程,很多地方展开说又是一篇文章。

至此,nova api已经接收到创建虚拟机的请,后面则是nova具体创建虚拟机的操作。我们将再《OpenStack源码阅读-创建虚拟机(三)》呈现给大家

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

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

相关推荐

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

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

塔尖草的博客 1525

OpenStack创建虚拟机代码分析过程

nova创建虚拟机源码分析前言nova-apinova_compute APIconductorlibvirt后记 前言 本文暂不分析novaclient的认证部分,从nova-api开始。 认证部分会单独拿出来。 这一模块先叙述整个流程,再分析每个小点 代码为Rocky版本 nova-api 传入数据举例 req : Accept: application/json Accept-Encodi...

mr1jie的博客 560

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

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

周绍禹-whuiss 6521

OpenStack平台搭建,超详细,附源码。

简单六大步,搭建OpenStack,iaas云计算基础架构平台。

无求道贾的博客 8275

OpenStack源码安装与组件配置指南

Nova是OpenStack项目中的核心组件之一,负责虚拟机的生命周期管理,包括创建、调度、暂停、停止和销毁虚拟机实例。Nova的工作原理涉及与多个OpenStack组件的交互,如Keystone进行身份验证、Glance提供镜像服务、Neutron处理网络配置以及Cinder进行块存储管理。Nova的架构包含多个服务和组件,每个组件都负责处理虚拟机生命周期的不同阶段。其中核心组件是nova-api、nova-compute、nova-scheduler和nova-conductor。

weixin_31591833的博客 1089

openstack其中四大组件源码

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

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

本文为扶艾原创文章,版权所有,禁止转载! 请大家静下心来看源码分析的文章,看完后相信你会有收获的! 本文来自于微信公众号“扶艾”,欢迎大家关注获取更多精彩内容! 我们分析就分析全套的,创建虚拟机的源码分析总共分为三篇文章,我们将会用通俗易懂的语言来描述整个流程。第一篇文章将分析客户端部分的源码,也就是从点击创建虚拟机按钮后到发送http请求这部分的源码;第二篇文章将分析nova api如何接...

塔尖草的博客 1710

使用python创建OpenStack虚拟机

手把手教您如何使用python语言,创建OpenStack虚拟机。

如何阅读OpenStack源码(Python)

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

Yannick Jiang 的专栏 1392

【hadoop编译报错】(yarn install) on project hadoop-yarn-applications-catalog-webapp Failed to run task

ambari+bigtop自定义组件集成

TTBIGDATA的博客 1804

Android HTTPS抓包证书配置全解:Proxyman实战避坑指南

HTTPS抓包本质是中间人(MITM)通信的可信建立过程,其核心在于客户端对代理根证书的信任链配置。在Android平台,自7.0起系统默认不信任用户安装的CA证书,必须通过Network Security Config显式声明trust-anchors,将Proxyman导出的PEM格式根证书纳入App级信任锚点。这一机制区别于iOS和桌面浏览器,导致大量开发者卡在‘证书已安装却无法解密’的误区。技术价值在于打通开发调试闭环:精准定位SSLHandshakeException、绕过证书固定、支持React

weixin_32175665的博客 651

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

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

weixin_39959298的博客 258

2025年抖音面试:商业生态与安全质量运营技能要求及面试

在商业生态与安全岗的质量运营工作中,规则运营职责占据着极为重要的地位,它是保障内容风控质量的关键环节。

王国平的博客 609

如何阅读OpenStack源码

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

成字第0431879 468

STM32 MCU解除读保护的方法及STM32CubeProgrammer的应用

下面是一个简单的源代码示例,演示如何在STM32CubeProgrammer中使用命令行界面(Command-Line Interface,CLI)来解除STM32 MCU的读保护。通过按照这些步骤操作,您可以成功解除STM32 MCU的读保护,并在需要的时候进行调试、烧录或修改固件。模块调用了STM32CubeProgrammer的命令行界面(CLI),并传递了相应的参数来解除STM32 MCU的读保护。请注意,在进行任何与读保护相关的操作之前,请确保您拥有合法的授权和权利,以避免潜在的安全风险。

ZwcCsharp的博客 3549

前拉后推计划逻辑适用于哪些行业和企业规模?

《前拉后推计划逻辑的行业适用性分析》摘要:前拉后推计划逻辑(需求端后推锚定交付、供应端前拉匹配资源)最适用于需求波动大且具规模效益的行业,包括家具制造(定制化需求+批量运输)、机械装备(非标设备+部件采购)、消费电子(短周期产品+核心部件备货)及汽车配套(交期绑定+批量生产)等领域。该模式要求企业具备:1)独立计划部门;2)ERP/MES等信息系统;3)资源冗余能力,故更适配中型(1-10亿营收)和大型企业(10亿+)。小型企业需简化应用,仅聚焦关键环节。不适配需求稳定(如快消品)、无规模效益或短周期生产的

追随内心 144

openstack源码阅读

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

qq_42533216的博客 657

【NLP】第10章 使用基于 BERT 的 Transformer 进行语义角色标记

Transformers 在过去几年里取得的进步比上一代 NLP 还要多。标准 NLU 方法首先学习句法和词汇特征来解释句子的结构。在运行语义角色标签( SRL )之前,将训练以前的 NLP 模型理解语言的基本语法。Shi和Lin(2019)在他们的论文开始时询问是否可以跳过初步的句法和词汇训练。基于 BERT 的模型可以在不经过那些经典训练阶段的情况下执行 SRL 吗?答案是肯定的!Shi和Lin (2019) 建议 SRL 可以被视为序列标记并提供标准化的输入格式。他们基于 BERT 的模型产生了令人惊

sikh_0529的博客 7375

openstack创建虚拟机源码阅读

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

weixin_33937913的博客 344

【嘉立创EDA】PCB金属包边设计快捷方法

本文使用嘉立创EDA,描述如何在PCB设计时,快速增加边框包边设计,特别是金属包边(伪)——这里标记(伪)是因为该这里的包边特指不含边缘壁。请参考本文时特别注意!本文将此过程记录,以供有需要的读者参考。

l64481000的博客 1744

Pinocchio 快速详细入门教程 —— 开源机器人运动学动力学库

本文介绍了机器人学中的数字机器人学、正逆运动学、动力学仿真与控制、最优控制等核心主题,以及Pinocchio库的应用。内容包括: 数字机器人学:通过UR5机器人模型演示了构型空间采样、碰撞检测、路径规划等基础操作,使用优化方法在约束条件下寻找有效构型。 运动学:详细讲解了二维和三维机器人的正运动学(构型到末端位置)和逆运动学(目标位置到构型),包括串联机械臂和并联机器人的处理。 动力学与控制:介绍了动力学仿真(如自由落体、摩擦效应)、PD控制、计算扭矩控制,以及接触仿真(碰撞检测与处理)。 最优控制:以独轮

机器人控制与仿真应用 2883

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

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Nova创建虚拟机实例过程简述

登录 | 注册 bingxx11的专栏 目录视图摘要视图订阅 2016攒课第二期之你听课我买单,快来攒你想听的课!     2016大数据应用调查     AngularJS知识库发布   Nova创建虚拟机实例过程简述 2014-

Edwin_ZH的专栏 938

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

上一篇: OpenStack(Queens)详细安装部署(六)-界面(horizon)安装
下一篇: OpenStack源码阅读-创建虚拟机(三)
林大大.
博客等级 码龄11年 111粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值