├── .gitignore ├── LICENSE ├── Makefile ├── README.en.md ├── README.md ├── format_code.sh ├── generate.py ├── img └── vim.png ├── output ├── nova │ ├── backup.png │ ├── changePassword.png │ ├── create.png │ ├── delete.png │ ├── evacuate.png │ ├── interface-attach.png │ ├── interface-detach.png │ ├── list.png │ ├── list.svg │ ├── list_simple.png │ ├── live_migrate.png │ ├── lock.png │ ├── migrate.png │ ├── pause.png │ ├── reboot.png │ ├── rebuild.png │ ├── rebuild副本.png │ ├── refresh_network.png │ ├── rename.png │ ├── rescue.png │ ├── reset_network.png │ ├── reset_state.png │ ├── resize.png │ ├── shelve.png │ ├── shelve_offload.png │ ├── snapshot.png │ ├── start.png │ ├── stop.png │ ├── suspend.png │ ├── unlock.png │ ├── unpause.png │ ├── unrescue.png │ ├── unshelve.png │ ├── volume-detach.png │ ├── volume_attach.png │ └── volume_detach.png └── sahara │ └── create_cluster.png └── src ├── nova ├── backup.wsd ├── changePassword.wsd ├── create.wsd ├── delete.wsd ├── evacuate.wsd ├── interface-attach.wsd ├── interface-detach.wsd ├── list.wsd ├── list_simple.wsd ├── live_migrate.wsd ├── lock.wsd ├── migrate.wsd ├── pause.wsd ├── reboot.wsd ├── rebuild.wsd ├── refresh_network.wsd ├── rename.wsd ├── rescue.wsd ├── reset_network.wsd ├── reset_state.wsd ├── resize.wsd ├── shelve.wsd ├── shelve_offload.wsd ├── snapshot.wsd ├── start.wsd ├── stop.wsd ├── suspend.wsd ├── unlock.wsd ├── unpause.wsd ├── unrescue.wsd ├── unshelve.wsd ├── volume_attach.wsd └── volume_detach.wsd └── sahara ├── create_cluster.wsd └── create_cluster.wsd.backup /.gitignore: -------------------------------------------------------------------------------- 1 | target/* 2 | test/* 3 | *~ 4 | *.swp 5 | **/test.* 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 int32bit 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | ./generate.py 3 | clean: 4 | rm -rf output 5 | -------------------------------------------------------------------------------- /README.en.md: -------------------------------------------------------------------------------- 1 | [👉中文版本](./README.zh.md) 2 | 3 | # Openstack Sequence Diagrams 4 | 5 | Draw Openstack operation sequence diagrams using [Websequence Diagrams Tool](https://www.websequencediagrams.com/). An easiest way to track the source of Openstack and can be useful for user to learn Openstack or administer to problem troubleshooting. Noted that all these works are based on Openstack Liberty version, it may be changed in the future version, be careful to use if your Openstack version is not Liberty. 6 | 7 | ## Action List 8 | 9 | ### 1. Virtual Machine Manager 10 | 11 | - [x] [Boot](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/create.png) 12 | - [x] [Start](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/start.png) 13 | - [x] [Stop](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/stop.png) 14 | - [x] [Reboot](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reboot.png) 15 | - [x] [Rebuild](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/rebuild.png) 16 | - [x] [Resize](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/resize.png) 17 | - [x] [List](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/list.png) 18 | - [x] [Delete](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/delete.png) 19 | - [x] [Reset State](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reset_state.png) 20 | - [x] [Create Image(Snapshot)](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/snapshot.png) 21 | - [x] [Change Admin Password](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/changePassword.png) 22 | - [x] [Evacuate](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/evacuate.png) 23 | - [x] [Pause](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/pause.png) 24 | - [x] [Unpause](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unpause.png) 25 | - [x] [Suspend](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/suspend.png) 26 | - [x] [Resume](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/resume.png) 27 | - [x] [Reset Network](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reset_network.png) 28 | - [x] [Cold Migrate](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/migrate.png) 29 | - [x] [Live Migrate](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/live_migrate.png) 30 | - [x] [Shelve](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/shelve.png) 31 | - [x] [Shelve-offload](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/shelve_offload.png) 32 | - [x] [Unshelve](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unshelve.png) 33 | - [x] [Lock](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/lock.png) 34 | - [x] [Unlock](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unlock.png) 35 | - [x] [Backup](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/backup.png) 36 | - [x] [Refresh Network](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reset_network.png) 37 | - [x] [Rename](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/rename.png) 38 | - [x] [Rescue](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/rescue.png) 39 | - [x] [Unrescue](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unrescue.png) 40 | - [x] [volume Attach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/volume_attach.png) 41 | - [x] [Volume Detach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/volume-detach.png) 42 | - [x] [Interface Attach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/interface-attach.png) 43 | - [x] [Interface Detach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/interface-detach.png) 44 | 45 | 46 | ### 2. Todo 47 | 48 | - [ ] Cinder 49 | - [ ] Neutron 50 | - [ ] Sahara 51 | 52 | * - [x] [Create cluster](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/sahara/create_cluster.png) 53 | 54 | ![create cluster](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/sahara/create_cluster.png) 55 | 56 | - [ ] Magnum 57 | - [ ] ... 58 | 59 | ## Quick Start 60 | 61 | 62 | ### 1. Generate diagrams 63 | 64 | Before generate the diagrams on your localhost, ensure your machine can access the Internet and the `make` tools hava been correctly installed. 65 | 66 | ``` 67 | make 68 | ``` 69 | 70 | All diagrams generated will be placed in `./output` by default. 71 | 72 | ### 2. Remove diagrams 73 | 74 | To cleanup the diagrams, just run this as follows: 75 | 76 | ``` 77 | make clean 78 | ``` 79 | 80 | 81 | ## Some demo 82 | 83 | ### 1. Create Server Workflow 84 | 85 | ![create server workflow](output/nova/create.png) 86 | 87 | ### 2. Reboot Server 88 | 89 | 90 | ![reboot server](output/nova/reboot.png) 91 | 92 | ### 3. Stop Server 93 | 94 | ![stop server](output/nova/stop.png) 95 | 96 | ### 4. Rebuild Server 97 | 98 | ![rebuild server](output/nova/rebuild.png) 99 | 100 | 101 | ## Need more diagrams ? 102 | 103 | DYI, as you need! 104 | 105 | For example: 106 | 107 | ``` 108 | title pause a server 109 | 110 | participant client 111 | participant nova_api 112 | 113 | client->nova_api: pause 114 | activate client 115 | activate nova_api 116 | 117 | # nova/api/openstack/compute/pause_server.py _pause() 118 | note over nova_api: authrize context 119 | nova_api->database: get instance by uuid 120 | database->nova_api: done 121 | 122 | # nova/compute/api.py pause() 123 | note over nova_api: check policy 124 | note over nova_api: check instance lock 125 | note over nova_api: check instance cell 126 | note over nova_api: ensure instance state is ACTIVE 127 | nova_api->database: task_state = PAUSING 128 | database->nova_api: done 129 | 130 | note over nova_api: record pause action 131 | # nova/compute/rpcapi.py pause_instance() 132 | nova_api->nova_compute: pause_instance 133 | deactivate nova_api 134 | deactivate client 135 | activate nova_compute 136 | 137 | # nova/compute/manager.py pause_instance() 138 | note over nova_compute: notify: pause.start 139 | nova_compute->libvirt: pause 140 | activate libvirt 141 | 142 | # nova/virt/libvirt/driver.py pause() 143 | note over libvirt: get domain 144 | note over libvirt: domain.suspend() 145 | libvirt->nova_compute: done 146 | deactivate libvirt 147 | # nova/compute/manager.py pause_instance() 148 | nova_compute->database: vm_state = vm_states.PAUSED\ntask_state = None 149 | database->nova_compute: done 150 | note over nova_compute: notify: pause.end 151 | deactivate nova_compute 152 | ``` 153 | 154 | ## Contributors 155 | 156 | The following have contributed to this project: 157 | 158 | * AndiaQ 159 | * int32bit 160 | * ljjjustin 161 | 162 | Many thanks for this! (If I have forgotten you, please let me know and put you in the list of fame. :-)) 163 | 164 | ## License 165 | 166 | MIT 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [👉English](./README.en.md) 2 | 3 | ## 1 关于该项目 4 | 5 | 本项目使用在线绘图工具[web sequencediagrams](https://www.websequencediagrams.com/)完成,目标是图形化OpenStack的所有操作流程,通过操作序列图能快速学习Openstack的工作原理,理清各个组件的关系,运维人员也能根据操作序列图进行更精确的故障定位和排查. 6 | 7 | 注意,该操作序列图基于L版OpenStack源码,未来版本的操作可能会有变化,请以最新版的源码为准,该项目提供的序列图仅供参考。 8 | 9 | ## 2 OpenStack基础 10 | 11 | ### 2.1 OpenStack组件介绍 12 | 13 | OpenStack是一个IaaS层的云计算平台开源实现,其对标产品为AWS。最开始OpenStack只有两个组件,分别为提供计算服务的Nova以及提供对象存储服务的Swift,其中Nova不仅提供计算服务,还包含了网络服务、块存储服务、镜像服务以及裸机管理服务。之后随着项目的不断发展,从Nova中根据功能拆分为多个独立的项目,如nova-volume拆分为Cinder项目提供块存储服务,nova-image拆分为Glance项目,提供镜像存储服务,nova-network则是neutron的前身,裸机管理也从Nova中分离出来为Ironic项目。最开始容器服务也是由Nova提供支持的,作为Nova的driver之一来实现,而后迁移到Heat,到现在已经独立为一个单独的项目Magnum,后来Magnum的愿景调整为主要提供容器编排服务,单纯的容器服务则由Zun项目接管。最开始OpenStack并没有认证功能,从E版开始才加入认证服务Keystone。 14 | 15 | 目前OpenStack核心组件如下: 16 | 17 | * Keystone:认证服务。 18 | * Glance:镜像服务。 19 | * Nova:计算服务。 20 | * Cinder:块存储服务。 21 | * Neutorn:网络服务。 22 | * Swift:对象存储服务。 23 | 24 | E版之后,在这些核心服务之上,又不断涌现新的服务,如面板服务Horizon、编排服务Heat、数据库服务Trove、文件共享服务Manila、大数据服务Sahara以及前面提到的Magnum等,这些服务几乎都依赖于以上的核心服务。比如Sahara大数据服务会先调用Heat模板服务,Heat又会调用Nova创建虚拟机,调用Glance获取镜像,调用Cinder创建数据卷,调用Neutron创建网络等。 25 | 26 | 截至现在(2016年11月27日),OpenStack已经走过了6年半的岁月,最新发布的版本为第14个版本,代号为Newton,Ocata版已经处在快速开发中。 27 | 28 | OpenStack服务越来越多、越来越复杂,覆盖的技术生态越来越庞大,宛如一个庞然大物,刚接触如此庞大的分布式系统,都或多或少感觉有点如"盲人摸象"的感觉。不过不必先过于绝望,好在OpenStack项目具有非常良好的设计,虽然OpenStack项目众多,组件繁杂,但几乎所有的服务骨架脉络基本是一样的,熟悉了其中一个项目的架构,深入读了其中一个项目源码,再去看其它项目可谓轻车熟路。 29 | 30 | 本文档会以Nova项目为例,一步一步剖析源码结构,阅读完之后,你再去看Cinder项目,发现非常轻松。 31 | 32 | ### 2.2 工欲善其事必先利其器 33 | 34 | 要阅读源代码首先需要安装科学的代码阅读工具,图形界面使用pycharm没有问题,不过通常在虚拟机中是没有图形界面的,首选vim,需要简单的配置使其支持代码跳转和代码搜索,可以参考[GitHub - int32bit/dotfiles: A set of vim, zsh, git, and tmux configuration files.](https://github.com/int32bit/dotfiles)。如图: 35 | 36 | ![vim demo](./img/vim.png) 37 | 38 | OpenStack所有项目都是基于Python开发,都是标准的Python项目,通过setuptools工具管理项目,负责Python包的安装和分发。想知道一个项目有哪些服务组成,入口函数(main函数)在哪里,最直接的方式就是查看项目根目录下的`setup.cfg`文件,其中`console_scripts`就是所有服务组件的入口,比如nova的`setup.cfg`的`console_scripts`如下: 39 | 40 | ``` 41 | [entry_points] 42 | ... 43 | console_scripts = 44 | nova-all = nova.cmd.all:main 45 | nova-api = nova.cmd.api:main 46 | nova-api-metadata = nova.cmd.api_metadata:main 47 | nova-api-os-compute = nova.cmd.api_os_compute:main 48 | nova-cells = nova.cmd.cells:main 49 | nova-cert = nova.cmd.cert:main 50 | nova-compute = nova.cmd.compute:main 51 | nova-conductor = nova.cmd.conductor:main 52 | nova-console = nova.cmd.console:main 53 | nova-consoleauth = nova.cmd.consoleauth:main 54 | nova-dhcpbridge = nova.cmd.dhcpbridge:main 55 | nova-idmapshift = nova.cmd.idmapshift:main 56 | nova-manage = nova.cmd.manage:main 57 | nova-network = nova.cmd.network:main 58 | nova-novncproxy = nova.cmd.novncproxy:main 59 | nova-rootwrap = oslo_rootwrap.cmd:main 60 | nova-rootwrap-daemon = oslo_rootwrap.cmd:daemon 61 | nova-scheduler = nova.cmd.scheduler:main 62 | nova-serialproxy = nova.cmd.serialproxy:main 63 | nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main 64 | nova-xvpvncproxy = nova.cmd.xvpvncproxy:main 65 | ... 66 | ``` 67 | 68 | 由此可知nova项目安装后会包含21个可执行程序,其中nova-compute服务的入口函数为`nova/cmd/compute.py`(. -> /)模块的`main`函数: 69 | 70 | ```python 71 | def main(): 72 | config.parse_args(sys.argv) 73 | logging.setup(CONF, 'nova') 74 | utils.monkey_patch() 75 | objects.register_all() 76 | 77 | gmr.TextGuruMeditation.setup_autorun(version) 78 | 79 | if not CONF.conductor.use_local: 80 | block_db_access() 81 | objects_base.NovaObject.indirection_api = \ 82 | conductor_rpcapi.ConductorAPI() 83 | else: 84 | LOG.warning(_LW('Conductor local mode is deprecated and will ' 85 | 'be removed in a subsequent release')) 86 | 87 | server = service.Service.create(binary='nova-compute', 88 | 89 | 由于OpenStack使用python语言开发,而python是动态类型语言,参数类型不容易从代码中看出,因此必须部署一个allinone的OpenStack开发测试环境,建议使用RDO部署:[Packstack quickstart](https://www.rdoproject.org/install/quickstart/),当然乐于折腾使用Devstack也是没有问题的。 90 | 91 | 要想深入研究源码,最有效的方式就是一步一步跟踪代码执行,因此会使用debug工具是关键技能之一。python的debug工具有很多,为了简便起见,pdb工具就够了。使用方法也非常简单,只要在你想设置断点的地方,嵌入以下代码: 92 | 93 | ``` 94 | import pdb; pdb.set_trace() 95 | ``` 96 | 97 | 然后在命令行(不能通过systemd执行)直接运行服务即可。假如想跟踪nova创建虚拟机的过程,首先在`nova/api/openstack/compute/servers.py`模块的`create`方法打上断点,如下: 98 | 99 | ```python 100 | @wsgi.response(202) 101 | @extensions.expected_errors((400, 403, 409, 413)) 102 | @validation.schema(schema_server_create_v20, '2.0', '2.0') 103 | @validation.schema(schema_server_create, '2.1', '2.18') 104 | @validation.schema(schema_server_create_v219, '2.19') 105 | def create(self, req, body): 106 | """Creates a new server for a given user.""" 107 | 108 | import pdb; pdb.set_trace() # 设置断点 109 | context = req.environ['nova.context'] 110 | server_dict = body['server'] 111 | password = self._get_server_admin_password(server_dict) 112 | name = common.normalize_name(server_dict['name']) 113 | 114 | if api_version_request.is_supported(req, min_version='2.19'): 115 | if 'description' in server_dict: 116 | # This is allowed to be None 117 | description = server_dict['description'] 118 | else: 119 | # No default description 120 | description = None 121 | else: 122 | description = name 123 | ... 124 | ``` 125 | 126 | 然后注意需要通过命令行直接运行,而不是通过systemd启动: 127 | 128 | ``` 129 | su -c 'nova-api' nova 130 | ``` 131 | 132 | 此时调用创建虚拟机API,nova-api进程就会马上弹出pdb shell,此时你可以通过`s`或者`n`命令一步一步执行了。 133 | 134 | ### 2.3 OpenStack项目通用骨骼脉络 135 | 136 | 阅读源码的首要问题就是就要对代码的结构了然于胸,**需要强调的是,OpenStack项目的目录结构并不是根据组件严格划分,而是根据功能划分**,以Nova为例,compute目录并不是一定在nova-compute节点上运行,而主要是和compute相关(虚拟机操作相关)的功能实现,同样的,scheduler目录代码并不全在scheduler服务节点运行,但主要是和调度相关的代码。不过目录结构并不是完全没有规律,它遵循一定的套路。 137 | 138 | 通常一个服务的目录都会包含`api.py`、`rpcapi.py`、`manager.py`,这个三个是最重要的模块。 139 | 140 | * `api.py`: 通常是供其它组件调用的封装库。换句话说,该模块通常并不会由本模块调用。比如compute目录的api.py,通常由nova-api服务的controller调用。 141 | * rpcapi.py:这个是RPC请求的封装,或者说是RPC封装的client端,该模块封装了RPC请求调用。 142 | * manager.py: 这个才是真正服务的功能实现,也是RPC的服务端,即处理RPC请求的入口,实现的方法通常和rpcapi实现的方法一一对应。 143 | 144 | 比如对一个虚拟机执行关机操作: 145 | 146 | ``` 147 | API节点 148 | nova-api接收用户请求 -> nova-api调用compute/api.py -> compute/api调用compute/rpcapi.py -> rpcapi.py向目标计算节点发起stop_instance()RPC请求 149 | 150 | 计算节点 151 | 收到stop_instance()请求 -> 调用compute/manager.py的callback方法stop_instance() -> 调用libvirt关机虚拟机 152 | 153 | ``` 154 | 155 | 前面提到OpenStack项目的目录结构是按照功能划分的,而不是服务组件,因此并不是所有的目录都能有对应的组件。仍以Nova为例: 156 | 157 | * cmd:这是服务的启动脚本,即所有服务的main函数。看服务怎么初始化,就从这里开始。 158 | * db: 封装数据库访问,目前支持的driver为sqlalchemy。 159 | * conf:Nova的配置项声明都在这里。 160 | * locale: 本地化处理。 161 | * image: 封装Glance调用接口。 162 | * network: 封装网络服务接口,根据配置不同,可能调用nova-network或者neutron。 163 | * volume: 封装数据卷访问接口,通常是Cinder的client封装。 164 | * virt: 这是所有支持的hypervisor驱动,主流的如libvirt、xen等。 165 | * objects: 对象模型,封装了所有实体对象的CURD操作,相对以前直接调用db的model更安全,并且支持版本控制。 166 | * policies: policy校验实现。 167 | * tests: 单元测试和功能测试代码。 168 | 169 | 以上同样适用于其它服务,比如Cinder等。 170 | 171 | 另外需要了解的是,所有的API入口都是从xxx-api开始的,RESTFul API是OpenStack服务的唯一入口,也就是说,阅读源码就从api开始。而api组件也是根据实体划分的,不同的实体对应不同的controller,比如servers、flavors、keypairs等,controller的index方法对应list操作、show方法对应get操作、create创建、delete删除、update更新等。 172 | 173 | 根据进程阅读源码并不是什么好的实践,因为光理解服务如何初始化、如何通信、如何发送心跳等就不容易,各种高级封装太复杂了。我认为比较好的阅读源码方式是追踪一个任务的执行过程,比如看启动虚拟机的整个流程,因此接下来本文将以创建一台虚拟机为例,一步步分析其过程。 174 | 175 | ## 3 创建虚拟机过程分析 176 | 177 | 这里以创建虚拟机过程为例,根据前面的总体套路,一步步跟踪其执行过程。需要注意的是,Nova支持同时创建多台虚拟机,因此在调度时需要选择多个宿主机。 178 | 179 | ### S1 nova-api 180 | 181 | 入口为nova/api/openstack/compute/servers.py的create方法,该方法检查了一堆参数以及policy后,调用`compute_api`的create方法。 182 | 183 | ```python 184 | def create(self, req, body): 185 | """Creates a new server for a given user.""" 186 | 187 | context = req.environ['nova.context'] 188 | server_dict = body['server'] 189 | password = self._get_server_admin_password(server_dict) 190 | name = common.normalize_name(server_dict['name']) 191 | 192 | ... 193 | 194 | flavor_id = self._flavor_id_from_req_data(body) 195 | try: 196 | inst_type = flavors.get_flavor_by_flavor_id( 197 | flavor_id, ctxt=context, read_deleted="no") 198 | 199 | (instances, resv_id) = self.compute_api.create(context, 200 | inst_type, 201 | image_uuid, 202 | display_name=name, 203 | display_description=description, 204 | availability_zone=availability_zone, 205 | forced_host=host, forced_node=node, 206 | metadata=server_dict.get('metadata', {}), 207 | admin_password=password, 208 | requested_networks=requested_networks, 209 | check_server_group_quota=True, 210 | **create_kwargs) 211 | except (exception.QuotaError, 212 | exception.PortLimitExceeded) as error: 213 | raise exc.HTTPForbidden( 214 | explanation=error.format_message()) 215 | ``` 216 | 217 | 这里的`compute_api`即前面说的`nova/compute/api.py`模块,找到该模块的create方法,该方法会创建数据库记录、检查参数等,然后调用`compute_task_api`的`build_instances`方法: 218 | 219 | ```python 220 | self.compute_task_api.schedule_and_build_instances( 221 | context, 222 | build_requests=build_requests, 223 | request_spec=request_specs, 224 | image=boot_meta, 225 | admin_password=admin_password, 226 | injected_files=injected_files, 227 | requested_networks=requested_networks, 228 | block_device_mapping=block_device_mapping) 229 | ``` 230 | 231 | `compute_task_api`即conductor的api.py。conductor的api并没有执行什么操作,直接调用了`conductor_compute_rpcapi`的`build_instances`方法: 232 | 233 | ```python 234 | def schedule_and_build_instances(self, context, build_requests, 235 | request_spec, image, 236 | admin_password, injected_files, 237 | requested_networks, block_device_mapping): 238 | self.conductor_compute_rpcapi.schedule_and_build_instances( 239 | context, build_requests, request_spec, image, 240 | admin_password, injected_files, requested_networks, 241 | block_device_mapping) 242 | 243 | ``` 244 | 245 | 该方法即时conductor RPC调用api,即`nova/conductor/rpcapi.py`模块,该方法除了一堆的版本检查,剩下的就是对RPC调用的封装,代码只有两行: 246 | 247 | ``` 248 | cctxt = self.client.prepare(version=version) 249 | cctxt.cast(context, 'build_instances', **kw) 250 | ``` 251 | 252 | 其中cast表示异步调用,`build_instances`是远程调用的方法,`kw`是传递的参数。参数是字典类型,没有复杂对象结构,因此不需要特别的序列化操作。 253 | 254 | 截至到现在,虽然目录由`api->compute->conductor`,但仍在nova-api进程中运行,直到cast方法执行,该方法由于是异步调用,因此nova-api任务完成,此时会响应用户请求,虚拟机状态为`building`。 255 | 256 | ### S2 nova-conductor 257 | 258 | 由于是向nova-conductor发起的RPC调用,而前面说了接收端肯定是`manager.py`,因此进程跳到`nova-conductor`服务,入口为`nova/conductor/manager.py`的`build_instances`方法,该方法首先调用了`_schedule_instances`方法,该方法调用了`scheduler_client`的`select_destinations`方法: 259 | 260 | ```python 261 | def _schedule_instances(self, context, request_spec, filter_properties): 262 | scheduler_utils.setup_instance_group(context, request_spec, 263 | filter_properties) 264 | # TODO(sbauza): Hydrate here the object until we modify the 265 | # scheduler.utils methods to directly use the RequestSpec object 266 | spec_obj = objects.RequestSpec.from_primitives( 267 | context, request_spec, filter_properties) 268 | hosts = self.scheduler_client.select_destinations(context, spec_obj) 269 | return hosts 270 | ``` 271 | 272 | `scheduler_client`和`compute_api`以及`compute_task_api`都是一样对服务的client调用,不过scheduler没有`api.py`,而是有个单独的client目录,实现在client目录的`__init__.py`,这里仅仅是调用query.py下的SchedulerQueryClient的`select_destinations`实现,然后又很直接的调用了`scheduler_rpcapi`的`select_destinations`方法,终于又到了RPC调用环节。 273 | 274 | ```python 275 | def select_destinations(self, context, spec_obj): 276 | """Returns destinations(s) best suited for this request_spec and 277 | filter_properties. 278 | 279 | The result should be a list of dicts with 'host', 'nodename' and 280 | 'limits' as keys. 281 | """ 282 | return self.scheduler_rpcapi.select_destinations(context, spec_obj) 283 | ``` 284 | 285 | 毫无疑问,RPC封装同样是在scheduler的rpcapi中实现。该方法RPC调用代码如下: 286 | 287 | ``` 288 | return cctxt.call(ctxt, 'select_destinations', **msg_args) 289 | ``` 290 | 291 | 注意这里调用的call方法,即同步RPC调用,此时nova-conductor并不会退出,而是堵塞等待直到nova-scheduler返回。因此当前状态为nova-conductor为blocked状态,等待nova-scheduler返回,nova-scheduler接管任务。 292 | 293 | ### S3 nova-scheduler 294 | 295 | 同理找到scheduler的manager.py模块的`select_destinations`方法,该方法会调用driver方法,这里的driver其实就是调度算法实现,通常用的比较多的就是`filter_scheduler`的,对应`filter_scheduler.py`模块,该模块首先通过`host_manager`拿到所有的计算节点信息,然后通过filters过滤掉不满足条件的计算节点,剩下的节点通过weigh方法计算权值,最后选择权值高的作为候选计算节点返回。最后nova-scheduler返回调度结果的hosts集合,任务结束,返回到nova-conductor服务。 296 | 297 | ### S4 nova-condutor 298 | 299 | 回到`scheduler/manager.py`的`build_instances`方法,nova-conductor等待nova-scheduler返回后,拿到调度的计算节点列表。因为可能同时启动多个虚拟机,因此循环调用了`compute_rpcapi`的`build_and_run_instance`方法。 300 | 301 | ```python 302 | for (instance, host) in six.moves.zip(instances, hosts): 303 | instance.availability_zone = ( 304 | availability_zones.get_host_availability_zone(context, 305 | host['host'])) 306 | try: 307 | # NOTE(danms): This saves the az change above, refreshes our 308 | # instance, and tells us if it has been deleted underneath us 309 | instance.save() 310 | except (exception.InstanceNotFound, 311 | exception.InstanceInfoCacheNotFound): 312 | LOG.debug('Instance deleted during build', instance=instance) 313 | continue 314 | ... 315 | self.compute_rpcapi.build_and_run_instance(context, 316 | instance=instance, host=host['host'], image=image, 317 | request_spec=request_spec, 318 | filter_properties=local_filter_props, 319 | admin_password=admin_password, 320 | injected_files=injected_files, 321 | requested_networks=requested_networks, 322 | security_groups=security_groups, 323 | block_device_mapping=bdms, node=host['nodename'], 324 | limits=host['limits']) 325 | ``` 326 | 327 | 看到xxxrpc立即想到对应的代码位置,位于`compute/rpcapi`模块,该方法向nova-compute发起RPC请求: 328 | 329 | ``` 330 | cctxt.cast(ctxt, 'build_and_run_instance', ...) 331 | ``` 332 | 333 | 由于是cast调用,因此发起的是异步RPC,因此nova-conductor任务结束,紧接着终于轮到nova-compute登场了。 334 | 335 | ### S5 nova-compute 336 | 337 | 到了nova-compute服务,入口为compute/manager.py,找到`build_and_run_instance`方法,该方法调用了driver的spawn方法,这里的driver就是各种hypervisor的实现,所有实现的driver都在virt目录下,入口为`driver.py`,比如libvirt driver实现对应为`virt/libvirt/driver.py`,找到spawn方法,该方法拉取镜像创建根磁盘、生成xml文件、define domain,启动domain等。最后虚拟机完成创建。nova-compute服务结束。 338 | 339 | 以上是创建虚拟机的各个服务的交互过程以及调用关系,需要注意的是,所有的数据库操作,比如`instance.save()`以及`update`操作,如果配置`use_local`为false,则会向nova-conductor发起RPC调用,由nova-conductor代理完成数据库更新,而不是由nova-compute直接访问数据库,这里的RPC调用过程在以上的分析中省略了。 340 | 341 | ## 4 操作序列图 342 | 343 | ### 4.1 虚拟机操作列表 344 | 345 | - [x] [boot](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/create.png) 346 | - [x] [start](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/start.png) 347 | - [x] [stop](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/stop.png) 348 | - [x] [reboot](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reboot.png) 349 | - [x] [rebuild](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/rebuild.png) 350 | - [x] [resize](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/resize.png) 351 | - [x] [list](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/list.png) 352 | - [x] [delete](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/delete.png) 353 | - [x] [reset-state](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reset_state.png) 354 | - [x] [create-image(快照)](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/snapshot.png) 355 | - [x] [set-password](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/changePassword.png) 356 | - [x] [evacuate(疏散迁移)](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/evacuate.png) 357 | - [x] [pause](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/pause.png) 358 | - [x] [unpause](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unpause.png) 359 | - [x] [suspend](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/suspend.png) 360 | - [x] [resume](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/resume.png) 361 | - [x] [reset-network](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reset_network.png) 362 | - [x] [migrate(冷迁移)](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/migrate.png) 363 | - [x] [live-migrate(在线迁移)](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/live_migrate.png) 364 | - [x] [Shelve](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/shelve.png) 365 | - [x] [Shelve-offload](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/shelve_offload.png) 366 | - [x] [Unshelve](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unshelve.png) 367 | - [x] [lock](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/lock.png) 368 | - [x] [unlock](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unlock.png) 369 | - [x] [backup](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/backup.png) 370 | - [x] [Refresh Network](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/reset_network.png) 371 | - [x] [rename/update](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/rename.png) 372 | - [x] [rescue](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/rescue.png) 373 | - [x] [unrescue](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/unrescue.png) 374 | - [x] [volume-attach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/volume_attach.png) 375 | - [x] [volume-detach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/volume-detach.png) 376 | - [x] [interface-attach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/interface-attach.png) 377 | - [x] [interface-detach](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/nova/interface-detach.png) 378 | 379 | 380 | ### 4.2 Todo列表 381 | 382 | - [ ] Cinder 383 | - [ ] Neutron 384 | - [ ] Sahara 385 | 386 | * - [x] [create(创建集群)](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/sahara/create_cluster.png) 387 | 388 | ![create cluster](https://raw.githubusercontent.com/int32bit/openstack-workflow/master/output/sahara/create_cluster.png) 389 | 390 | - [ ] Magnum 391 | - [ ] ... 392 | 393 | ## 5 如何开始工作 394 | 395 | ### 5.1 编译图形 396 | 397 | 生成最新图片需要连接外网并且依赖于Make工具,请确保所依赖的包已经安装。 398 | 399 | 直接执行make即可扫描所有的源码并自动生成操作序列图. 400 | 401 | ``` 402 | make 403 | ``` 404 | 405 | 生成的图片默认会保存在`./output`路径下. 406 | 407 | ### 5.2 删除图片 408 | 409 | 执行以下命令可清理所有的图片: 410 | 411 | ``` 412 | make clean 413 | ``` 414 | 415 | ### 6.3 操作流程案例分析 416 | 417 | 注意: 418 | 419 | * 图中蓝色线表示当前进程是active的,因此可以很容易看出是RPC同步调用还是异步调用的。 420 | * Nova conductor配置use_local为false,访问数据库需要通过RPC调用conductor,但图中为了方便表示数据库操作,省略了RPC调用conductor访问数据库的过程。Nova已经使用objects模型封装了数据库操作,代码位于`nova/objects`目录。 421 | 422 | #### 1. 创建虚拟机 423 | 424 | ![create server workflow](output/nova/create.png) 425 | 426 | 从操作序列图看,虚拟机的创建主要分为三步:第一步是nova api对用户创建虚拟机的参数进行检查,如果参数没有问题,nova api会在数据库中创建相应的表项用来记录用户的请求,然后给nova-conductor发起一个异步RPC调用,conductor会对调度时的filters spect进行初始化,并向nova-scheduler发起RPC同步调用,nova-scheduler收到nova conductor发来的请求之后筛选能够满足虚拟机资源需求的hypervisor,并按照一定的策略选取其中的一台hypervisor,返回给nova-conductor,conductor然后给候选的计算节点nova compute发起一个run_instance的RPC调用。 Nova compute收到run_instance的请求之后,会为虚拟机的运行分配各种资源,如:ip地址、磁盘、网络等。分配完各种资源之后,nova会调用libvirt创建根磁盘、xml文件等,并启动虚拟机。到此,虚拟机的创建基本上就结束了,等虚拟机启动完成,用户就可以登录和控制虚拟机了。 427 | 428 | #### 2. 重启虚拟机 429 | 430 | Nova中reboot操作可以分成两种:soft reboot和hard reboot。Soft reboot通过发送acpid或者guest agent信号给虚拟机,虚拟机接收到信号号主动执行重启操作。虚拟机必须支持appid或者运行qemu guest agent才能执行soft reboot。若soft reboot失败或者超时(默认120秒),则会进入hard reboot。hard reboot将执行强制重启(相当于强制切电源),虚拟机重启的序列图如下: 431 | 432 | ![reboot server](output/nova/reboot.png) 433 | 434 | 从上图可以看出,soft reboot和hard reboot最主要的差别是libvirt所执行的操作不同,soft reboot关机时执行shutdown操作,而hard reboot执行destroy操作,可能导致正在运行的虚拟机异常关机导致数据丢失。 435 | 436 | #### 3. 修改管理员密码 437 | 438 | ![change password](output/nova/changePassword.png) 439 | 440 | 从上图中看出,修改管理员密码是通过libvirt调用qemu guest agent执行的,因此虚拟机必须安装了qemu-guest-agent服务并且处于运行状态。 441 | 442 | 注意L版修改管理员密码只支持使用kvm/qemu hypervisor。 443 | 444 | #### 4. 在线迁移 445 | 446 | Live migrate是在不停止虚拟机的情况下,将虚拟机从一台宿主机上迁移到另外一台宿主机。在线迁移操作序列图如下: 447 | 448 | ![live migrage](output/nova/live_migrate.png) 449 | 450 | 在线迁移相对复杂,不过从图中看还是比较清晰的。如果不使用共享存储,传输虚拟机磁盘会花很长一段时间,导致虚拟机迁移很慢,因此建议使用统一共享分布式存储做OpenStack存储后端。 451 | 在线迁移会不断的增量同步内存状态信息,直到收敛到很小的变化时,虚拟机会freeze一段时间,即处于downtime状态,完成最后的状态同步。迁移完成后,原来的虚拟机会自动删除。 452 | 453 | #### 更多的操作序列图 454 | 455 | 所有的图形均使用工具生成,并且是可编程的。你只需要阅读源代码并使用[Websequence Diagrams Tool](https://www.websequencediagrams.com/)语法编写代码,语法请参考官方文档。以pause操作为例,对应源码为: 456 | 457 | ``` 458 | title pause a server 459 | 460 | participant client 461 | participant nova_api 462 | 463 | client->nova_api: pause 464 | activate client 465 | activate nova_api 466 | 467 | # nova/api/openstack/compute/pause_server.py _pause() 468 | note over nova_api: authrize context 469 | nova_api->database: get instance by uuid 470 | database->nova_api: done 471 | 472 | # nova/compute/api.py pause() 473 | note over nova_api: check policy 474 | note over nova_api: check instance lock 475 | note over nova_api: check instance cell 476 | note over nova_api: ensure instance state is ACTIVE 477 | nova_api->database: task_state = PAUSING 478 | database->nova_api: done 479 | 480 | note over nova_api: record pause action 481 | # nova/compute/rpcapi.py pause_instance() 482 | nova_api->nova_compute: pause_instance 483 | deactivate nova_api 484 | deactivate client 485 | activate nova_compute 486 | 487 | # nova/compute/manager.py pause_instance() 488 | note over nova_compute: notify: pause.start 489 | nova_compute->libvirt: pause 490 | activate libvirt 491 | 492 | # nova/virt/libvirt/driver.py pause() 493 | note over libvirt: get domain 494 | note over libvirt: domain.suspend() 495 | libvirt->nova_compute: done 496 | deactivate libvirt 497 | # nova/compute/manager.py pause_instance() 498 | nova_compute->database: vm_state = vm_states.PAUSED\ntask_state = None 499 | database->nova_compute: done 500 | note over nova_compute: notify: pause.end 501 | deactivate nova_compute 502 | ``` 503 | 504 | 新增了源码后,只需要重新执行`make`命令即可生成新的图片。 505 | 506 | ## 6 贡献列表 507 | 508 | 以下这些开发者参与了该项目: 509 | 510 | * AndiaQ: 喜爱研究OpenStack的萌妹纸,她的博客: `https://andiaq.github.io`。 511 | * int32bit: 从2013年开始折腾OpenStack H版本,研究生期间曾在英特尔实习研究nova、ironic项目, 毕业后在UnitedStack负责cinder、nova开发和运维,现供职于云极星创,主要研究nova和容器相关技术。nova、cinder以及oslo的代码贡献者。 512 | * ljjjustin: OpenStack专家, 更多资料查看[他的博客](https://www.ljjjustin.xyz/about/) 513 | 514 | ## 7 虚拟机操作列表 515 | 516 | * boot: 创建虚拟机。 517 | * delete: 删除虚拟机。 518 | * force-delete: 无视虚拟机当前状态,强制删除虚拟机。即使开启了软删除功能,该操作也会立即清理虚拟机资源。 519 | * list: 显示虚拟机列表。 520 | * show: 查看指定虚拟机的详细信息。 521 | * stop: 关机虚拟机。 522 | * start: 开机虚拟机。 523 | * reboot: 重启虚拟机。默认先尝试软重启,当软重启尝试120后失败,将执行强制重启。 524 | * migrate: 冷迁移虚拟机,迁移过程中虚拟机将关机。 525 | * live-migrate: 在线迁移虚拟机,虚拟机不会关机。 526 | * resize: 修改虚拟机配置,即使用新的flavor重建虚拟机。 527 | * rebuild: 重建虚拟机,指定新的image,如果指定快照,则相当于虚拟机状态回滚。 528 | * evacuate: 疏散迁移,只有当compute服务down时执行,能够迁移虚拟机到其它正常计算节点中。 529 | * reset-state: 手动重置虚拟机状态为error或者active。 530 | * create-image: 创建虚拟机快照。 531 | * backup: 定期创建虚拟机快照。 532 | * volume-attach: 挂载volume卷。 533 | * volume-detach: 卸载volume卷。 534 | * lock/unlock: 锁定虚拟机,锁定后的虚拟机普通用户不能执行删除、关机等操作。 535 | * set-password: 修改管理员密码,虚拟机需要运行qemu guest agent服务。 536 | * pause/unpause: 暂停运行的虚拟机,如果底层的虚拟化使用的是libvirt,那么libvirt会在将虚拟机的信息保存到内存中,KVM/QEMU进程仍然在运行,只是暂停执行虚拟机的指令。 537 | * suspend/resume: 挂起虚拟机,将虚拟机内存中的信息保存到磁盘上,虚拟机对于的KVM/QEMU进程会终止掉,该操作对应于libvirt中的save操作。resume从挂起的虚拟机恢复。 538 | * reset-network: 重置虚拟机网络,在使用libvirt时,该操作不执行任何实际的动作,因此功能尚未实现。 539 | * shelve/unshelve: 虚拟机关机后仍占用资源,如果虚拟机长期不使用,可以执行shelve操作,该操作先创建虚拟机快照,然后删除虚拟机,恢复时从快照中重建虚拟机。 540 | * rename: 重命名虚拟机, 后期版本将被update操作替代。 541 | * update: 修改虚拟机名称、description信息等。 542 | * rescue/unrescue: 虚拟机进入拯救模式。原理是创建一台新的虚拟机,并把需要rescue的虚拟机的根磁盘作为第二块硬盘挂载到新创建的虚拟机。当原虚拟机根磁盘破坏不能启动时该操作非常有用。 543 | * interface-attach/interface-dettach: 绑定/解绑网卡。 544 | * trigger-crash-dump: 使虚拟机触发crash dump错误,测试使用。 545 | * resize-confirm: 确认resize操作,此时原来的虚拟机将被删除, 可以配置为自动确认。 546 | * resize-revert: 撤销resize操作,新创建的虚拟机删除,并使用原来的虚拟机。 547 | * console-log: 查看虚拟机日志。 548 | * get-vnc-console: 获取虚拟机vnc地址, 通常使用novnc协议。 549 | * restore: 恢复虚拟机。如果配置了软删除功能,当虚拟机被删除时,不会立即删除,而仅仅标识下,此时能够使用restore操作恢复删除的虚拟机。 550 | * instance-action-list: 查看虚拟机的操作日志。 551 | * instance-action:查看某个虚拟机操作的详细信息,如操作用户、操作时间等。 552 | 553 | ## 8 协议 554 | 555 | MIT 556 | 557 | ## 9 如何贡献 558 | 559 | 欢迎有兴趣的读者补充更多的操作序列图或者参与讨论。 560 | 561 | * 如果你有任何问题,请直接创建issure。 562 | * 如果你要贡献代码,请直接PR。 563 | 564 | ## 10 更多项目 565 | 566 | * [dotfiles](https://github.com/int32bit/dotfiles): vim、tmux、zsh、iterm配置,阅读OpenStack源码必备,vim支持标签列表、函数跳转、代码搜索、智能补全功能。 567 | * [openstack-cheat-sheet](https://github.com/int32bit/openstack-cheat-sheet): 汇集所有OpenStack相关的资料。 568 | * [int32bit's blog](http://int32bit.me/): int32bit的博客,主要专注于OpenStack、Docker、Ceph相关。 569 | 570 | **--by int32bit(OpenStack Contributor).** 571 | -------------------------------------------------------------------------------- /format_code.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! which yapf &>/dev/null; then 4 | echo "Install yapf..." 5 | pip install yapf 6 | fi 7 | 8 | yapf -i --style pep8 --recursive . 9 | -------------------------------------------------------------------------------- /generate.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding=utf-8 3 | # vim ts=4 4 | 5 | import urllib 6 | import re 7 | import os.path 8 | 9 | from os import walk 10 | 11 | 12 | def getSequenceDiagram(wsdfile, outputFile, style='default'): 13 | request = {} 14 | assert os.path.isfile(wsdfile) 15 | with open(wsdfile, "r") as f: 16 | message = f.read() 17 | request["message"] = message 18 | request["style"] = style 19 | request["apiVersion"] = "1" 20 | 21 | url = urllib.urlencode(request) 22 | 23 | line = None 24 | try: 25 | f = urllib.urlopen("http://www.websequencediagrams.com/", url) 26 | line = f.readline() 27 | f.close() 28 | except IOError as e: 29 | print(e) 30 | return False 31 | expr = re.compile("(\?(img|pdf|png|svg)=[a-zA-Z0-9]+)") 32 | m = expr.search(line) 33 | 34 | if m == None: 35 | print "Invalid response from server." 36 | return False 37 | 38 | urllib.urlretrieve("http://www.websequencediagrams.com/" + m.group(0), 39 | outputFile) 40 | return True 41 | 42 | 43 | def getSources(root="./src"): 44 | sources = [] 45 | for (root, _, files) in walk("src"): 46 | for f in files: 47 | if f.endswith(".wsd"): 48 | sources.append(os.path.join(root, f)) 49 | return sources 50 | 51 | 52 | def generate(src="src", target="output", format="png", style="modern-blue"): 53 | for f in getSources(src): 54 | src_path = os.path.dirname(f) 55 | src_file = os.path.basename(f) 56 | target_path = target + src_path[src_path.index('/'):] 57 | output_file = src_file[:src_file.rindex('.') + 1] + format 58 | 59 | if not os.path.isdir(target_path): 60 | os.makedirs(target_path) 61 | output = target_path + "/" + output_file 62 | print("generating %s ..." % output) 63 | if getSequenceDiagram(f, output, style): 64 | print("Succeed to generate %s!" % output) 65 | else: 66 | print("Failed to generate %s!" % output) 67 | 68 | 69 | def main(): 70 | generate("src", "output", "png", 71 | "modern-blue") # png only, svg & pdf must register and pay 15$. 72 | 73 | 74 | if __name__ == "__main__": 75 | main() 76 | -------------------------------------------------------------------------------- /img/vim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/img/vim.png -------------------------------------------------------------------------------- /output/nova/backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/backup.png -------------------------------------------------------------------------------- /output/nova/changePassword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/changePassword.png -------------------------------------------------------------------------------- /output/nova/create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/create.png -------------------------------------------------------------------------------- /output/nova/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/delete.png -------------------------------------------------------------------------------- /output/nova/evacuate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/evacuate.png -------------------------------------------------------------------------------- /output/nova/interface-attach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/interface-attach.png -------------------------------------------------------------------------------- /output/nova/interface-detach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/interface-detach.png -------------------------------------------------------------------------------- /output/nova/list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/list.png -------------------------------------------------------------------------------- /output/nova/list.svg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/list.svg -------------------------------------------------------------------------------- /output/nova/list_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/list_simple.png -------------------------------------------------------------------------------- /output/nova/live_migrate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/live_migrate.png -------------------------------------------------------------------------------- /output/nova/lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/lock.png -------------------------------------------------------------------------------- /output/nova/migrate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/migrate.png -------------------------------------------------------------------------------- /output/nova/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/pause.png -------------------------------------------------------------------------------- /output/nova/reboot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/reboot.png -------------------------------------------------------------------------------- /output/nova/rebuild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/rebuild.png -------------------------------------------------------------------------------- /output/nova/rebuild副本.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/rebuild副本.png -------------------------------------------------------------------------------- /output/nova/refresh_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/refresh_network.png -------------------------------------------------------------------------------- /output/nova/rename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/rename.png -------------------------------------------------------------------------------- /output/nova/rescue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/rescue.png -------------------------------------------------------------------------------- /output/nova/reset_network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/reset_network.png -------------------------------------------------------------------------------- /output/nova/reset_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/reset_state.png -------------------------------------------------------------------------------- /output/nova/resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/resize.png -------------------------------------------------------------------------------- /output/nova/shelve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/shelve.png -------------------------------------------------------------------------------- /output/nova/shelve_offload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/shelve_offload.png -------------------------------------------------------------------------------- /output/nova/snapshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/snapshot.png -------------------------------------------------------------------------------- /output/nova/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/start.png -------------------------------------------------------------------------------- /output/nova/stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/stop.png -------------------------------------------------------------------------------- /output/nova/suspend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/suspend.png -------------------------------------------------------------------------------- /output/nova/unlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/unlock.png -------------------------------------------------------------------------------- /output/nova/unpause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/unpause.png -------------------------------------------------------------------------------- /output/nova/unrescue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/unrescue.png -------------------------------------------------------------------------------- /output/nova/unshelve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/unshelve.png -------------------------------------------------------------------------------- /output/nova/volume-detach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/volume-detach.png -------------------------------------------------------------------------------- /output/nova/volume_attach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/volume_attach.png -------------------------------------------------------------------------------- /output/nova/volume_detach.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/nova/volume_detach.png -------------------------------------------------------------------------------- /output/sahara/create_cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/int32bit/openstack-workflow/7219ed80f4076a00845eeb2261b19a26f901275f/output/sahara/create_cluster.png -------------------------------------------------------------------------------- /src/nova/backup.wsd: -------------------------------------------------------------------------------- 1 | title backup an instance 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant nova_compute 7 | participant libvirt 8 | participant glance_api 9 | 10 | #nova/openstack/compute/create_backup.py _create_backup() 11 | client->nova_api:backup an instance 12 | activate client 13 | activate nova_api 14 | note over nova_api:validate "create_backup" schema 15 | note over nova_api:get context 16 | note over nova_api:authorize context 17 | note over nova_api:get attributes 18 | nova_api->database:get instance by id 19 | activate database 20 | database->nova_api:done 21 | deactivate database 22 | 23 | #nova/compute/api.py backup() 24 | note over nova_api:check policy 25 | note over nova_api:check instance cell 26 | note over nova_api:ensure instance state in[ACTIVE, \n STOPPED,PAUSED,SUSPENDED] 27 | 28 | alt if is volume_backed_instance 29 | note over nova_api:InvalidRequest() 30 | else if not volume_backed_instance 31 | #nova/compute/api.py _create_image() 32 | nova_api->nova_compute:get image meta 33 | activate nova_compute 34 | nova_compute->nova_api:done 35 | deactivate nova_compute 36 | note over nova_api:get session 37 | nova_api->glance_api:create image with meta 38 | activate glance_api 39 | note over glance_api:create image 40 | glance_api->nova_api:image meta 41 | deactivate glance_api 42 | nova_api->database:task_states=IMAGE_BACKUP 43 | activate database 44 | database->nova_api:done 45 | deactivate database 46 | 47 | nova_api->nova_compute:backup instance 48 | deactivate nova_api 49 | deactivate client 50 | activate nova_compute 51 | nova_compute->libvirt:get instance power state 52 | activate libvirt 53 | libvirt->nova_compute:done 54 | deactivate libvirt 55 | note over nova_compute:log a warning if power_state is not running 56 | note over nova_compute:notify snapshot.start 57 | nova_compute->database:update instance power state 58 | activate database 59 | database->nova_compute:done 60 | deactivate database 61 | nova_compute->libvirt:snapshot 62 | activate libvirt 63 | note over libvirt:get instance guest 64 | note over libvirt:get guest domain 65 | libvirt->glance_api:get snapshot by id 66 | activate glance_api 67 | glance_api->libvirt:snapshot object 68 | deactivate glance_api 69 | note over libvirt:get source type and source format 70 | note over libvirt:get snapshot metadata 71 | note over libvirt: check if we can perform live snapshot 72 | note over libvirt: get image snapshot backend according to image type 73 | note over libvirt: perform image snapshot operation 74 | libvirt->database: task_states=IMAGE_PENDING_UPLOAD 75 | activate database 76 | database->libvirt: done 77 | deactivate database 78 | libvirt->database: task_states=IMAGE_UPLOAD 79 | activate database 80 | database->libvirt: done 81 | deactivate database 82 | alt if not live snapshot 83 | note over libvirt: create snapshot domain 84 | note over libvirt: attach pci devices 85 | note over libvirt: attach sriov ports 86 | end 87 | libvirt->+glance_api: update image 88 | note over glance_api: update image metadata 89 | note over glance_api: upload image 90 | glance_api->libvirt: done 91 | deactivate glance_api 92 | note over libvirt: log snapshot image upload complete 93 | libvirt->nova_compute: done 94 | deactivate libvirt 95 | 96 | nova_compute->database:task_states=IMAGE_UPLOADING 97 | activate database 98 | database->nova_compute:done 99 | deactivate database 100 | 101 | note over nova_compute:notify:snapshot.end 102 | note over nova_compute:get filters 103 | nova_compute->glance_api:get all images according to filters 104 | activate glance_api 105 | glance_api->nova_compute:images 106 | deactivate glance_api 107 | alt if num_images > rotation 108 | nova_compute->glance_api:deletes all backups that exceed the rotation limit 109 | activate glance_api 110 | note over glance_api:delete images 111 | glance_api->nova_compute:done 112 | end 113 | deactivate glance_api 114 | nova_compute->nova_api:image meta 115 | end 116 | deactivate nova_compute 117 | activate nova_api 118 | nova_api->client:response 119 | deactivate nova_api 120 | 121 | -------------------------------------------------------------------------------- /src/nova/changePassword.wsd: -------------------------------------------------------------------------------- 1 | title change admin password for a server 2 | participant client 3 | participant nova_api 4 | 5 | 6 | # nova/api/compute/admin_password.py 7 | client->nova_api: changePassword 8 | activate client 9 | activate nova_api 10 | 11 | # nova/api/openstack/compute/servers.py _action_create_image() 12 | note over nova_api: validation schema 13 | note over nova_api: authorize context 14 | note over nova_api: get instance by uuid 15 | note over nova_api: check policy 16 | note over nova_api: check instance lock 17 | note over nova_api: check instance cell 18 | note over nova_api: ensure instance state is ACTIVE 19 | nova_api->database: task_state = UPDATING_PASSWORD 20 | database->nova_api: done 21 | note over nova_api: record change password action 22 | nova_api->nova_compute: set_admin_password 23 | activate nova_compute 24 | opt new password is None 25 | note over nova_compute: generate a random password 26 | end 27 | alt if current power state is not RUNNING 28 | nova_compute->database: task_state = None 29 | database->nova_api: done 30 | note over nova_compute: raise instance is not running exception 31 | nova_compute->nova_api: raise exception.InstancePasswordSetFailed 32 | end 33 | nova_compute->libvirt: set_admin_password 34 | activate libvirt 35 | alt virt type is not in (kvm, qemu) 36 | libvirt->nova_compute: raise exception.SetAdminPasswdNotSupported 37 | end 38 | 39 | alt 'hw_qemu_guest_agent' not in image properties 40 | libvirt->nova_compute: raise exception.QemuGuestAgentNotEnabled 41 | end 42 | 43 | note over libvirt: get os admin user from image properties\n or set default 44 | note over libvirt: call guest.set_password() 45 | libvirt->nova_compute: done 46 | deactivate libvirt 47 | note over nova_compute: update task state 48 | nova_compute->database: task_state=None 49 | database->nova_compute: done 50 | nova_compute->nova_api: response 51 | deactivate nova_compute 52 | nova_api->client: response 53 | deactivate nova_api 54 | deactivate client 55 | -------------------------------------------------------------------------------- /src/nova/create.wsd: -------------------------------------------------------------------------------- 1 | # nova boot 2 | 3 | title Create Server Workflow 4 | 5 | ### client 6 | client->nova_api:server create request 7 | activate client 8 | activate nova_api 9 | 10 | ### nova-api 11 | ## nova/api/openstack/compute/servers.py 12 | note over nova_api:get nova context 13 | note over nova_api: get server dict 14 | note over nova_api: get or generate password 15 | note over nova_api:Query extensions 16 | note over nova_api:check policy:'create' 17 | note over nova_api:check policy:'create:force_host' 18 | 19 | # block device 20 | opt if block_device_mapping 21 | note over nova_api:check policy 'create:attach_volume' 22 | end 23 | 24 | # image 25 | note over nova_api: get image uuid 26 | 27 | # reservation id 28 | opt if has return_reservation_id 29 | note over nova_api:pop "return_reservation_id" and flag it 30 | end 31 | 32 | # network 33 | note over nova_api: get networks 34 | note over nova_api: check and build network request object 35 | note over nova_api: check policy:'create:attach_network' 36 | 37 | # flavor 38 | note over nova_api: get flavor id 39 | note over nova_api: get instance type 40 | note over nova_api: nova_compute_api 41 | 42 | ## nova/compute/api.py 43 | # create() 44 | note over nova_api: check policies 45 | note over nova_api:check multiple instances and specify ip 46 | note over nova_api:check_multiple_instances_neutron_ports 47 | # _create_instance() 48 | note over nova_api: get or generate reservation id 49 | note over nova_api: get security groups 50 | note over nova_api: check auto disk config 51 | note over nova_api: check policy:"create:forced_host" 52 | note over nova_api: validate and build base options 53 | # bdm:block device mappings 54 | note over nova_api:check and transform bdm 55 | note over nova_api: check metadata properties quota 56 | note over nova_api: check inject file quota 57 | note over nova_api: check request image status,min_ram,min_disk 58 | note over nova_api: get requested instance group(hints) 59 | # _provision_instances() 60 | note over nova_api: check num instances quota 61 | note over nova_api: populate instance for create 62 | note over nova_api: generate instance uuid 63 | note over nova_api: vm_state=BUILDING\ntask_state=SCHEDULING 64 | note over nova_api: populate instance name and hostname 65 | 66 | # database 67 | nova_api->database:create db entry for new instance 68 | nova_api->database:create block device mapping 69 | 70 | note over nova_api:check server group quota 71 | note over nova_api:check limit 72 | note over nova_api: instance group add member 73 | note over nova_api:send BUILDING state update notification 74 | note over nova_api: quota commit 75 | 76 | # _create_instance() 77 | note over nova_api:build filter properties 78 | note over nova_api:update instance state to CREATE 79 | # nova/conductor/api.py 80 | note over nova_api: get compute task api 81 | note over nova_api: ComputeTaskApi 82 | # nova/conductor/rpcapi.py 83 | 84 | # cast 85 | nova_api->nova_conductor: build_instance 86 | activate nova_conductor 87 | nova_api->client:response 88 | deactivate nova_api 89 | deactivate client 90 | 91 | ### nova-conductor 92 | # nova/conductor/manager.py 93 | # build_instance() 94 | note over nova_conductor:build request_spec for the scheduler 95 | note over nova_conductor:setup instance group 96 | note over nova_conductor: check retry policy and populate retry 97 | # nova/scheduler/client/__init__.py 98 | # -- 99 | # nova/scheduler/client/query.py 100 | # nova/scheduler/rpcapi.py 101 | note over nova_conductor: get scheduler rpc client 102 | 103 | ### nova-scheduler 104 | nova_conductor->nova_scheduler:select_destinations 105 | activate nova_scheduler 106 | note over nova_scheduler: load scheduler driver 107 | note over nova_scheduler: get all host states 108 | note over nova_scheduler: get filtered hosts 109 | note over nova_scheduler: get weighed hosts 110 | note over nova_scheduler: chose hosts from weighed hosts 111 | 112 | ### nova-conductor 113 | nova_scheduler->nova_conductor:return selected hosts 114 | deactivate nova_scheduler 115 | # nova/conductor/manager.py 116 | note over nova_conductor: connect instances and hosts 117 | note over nova_conductor: iterate all the instances 118 | # nova/compute.rpcapi.py 119 | note over nova_conductor: prepare rpc client 120 | nova_conductor->nova_compute:build_and_run_instance 121 | activate nova_compute 122 | deactivate nova_conductor 123 | 124 | ### nova-compute 125 | # nova/compute/manager.py 126 | nova_compute->database:vm_state=BUILDING\ntask_state=None 127 | note over nova_compute:decode injected file 128 | note over nova_compute: get available node 129 | note over nova_compute: notify about instance usage 130 | note over nova_compute: get resource tracker 131 | note over nova_compute: resource tracker claim resource 132 | note over nova_compute: validate instance group policy 133 | 134 | # nova/compute/manager.py _build_network_for_instance 135 | note over nova_compute: build network info for instance 136 | note over nova_compute: get macs for instance(None) 137 | note over nova_compute: get dhcp options for instance(None) 138 | nova_compute->database: vm_state=BUILDING\ntask_state=NETWORKING 139 | note over nova_compute: update resource tracker 140 | 141 | ## network 142 | note over nova_compute: get network api class 143 | # nova/network/__init__.py 144 | # nova/network/neutronv2/api.py API() 145 | note over nova_compute: get neutron client 146 | nova_compute->neutron:get available network 147 | note over nova_compute: check external network attach 148 | 149 | nova_compute->neutron:list security groups 150 | note over nova_compute: validate security groups 151 | nova_compute->neutron:create port 152 | note over nova_compute: convert to network model 153 | 154 | ## block device mapping 155 | note over nova_compute:verify or set default devices name 156 | note over nova_compute:ensure root device name \n and is set to first block devices 157 | nova_compute->database:vm_state=BUILDING\n task_state=BLOCK_DEVICE_MAPPING 158 | note over nova_compute:setup the block device for an instance 159 | 160 | nova_compute->database:vm_state=BUILDING\ntask_state=SPAWNING 161 | 162 | ## libvirt 163 | nova_compute->libvirt:spawn 164 | note over libvirt:get image meta 165 | note over libvirt:get disk info 166 | 167 | note over libvirt: ensure directories exist and are writable 168 | note over libvirt: ensure console.log and disk.config 169 | note over libvirt: create image(disk,swap,etc.) 170 | note over libvirt: create config drive 171 | note over libvirt:generate libvirt guest xml 172 | note over libvirt:create domain and network 173 | note over libvirt: wait to boot 174 | ## nova-compute 175 | libvirt->nova_compute:when the instance state is RUNNING 176 | nova_compute->database:update instance after spawn 177 | deactivate nova_compute 178 | -------------------------------------------------------------------------------- /src/nova/delete.wsd: -------------------------------------------------------------------------------- 1 | title server delete workflow 2 | 3 | participant client 4 | participant nova_api 5 | participant glance 6 | participant database 7 | participant nova_compute 8 | participant cinder 9 | participant libvirt 10 | 11 | # nova-api 12 | # nova/api/openstack/compute/servers.py 13 | client->nova_api: delete request 14 | activate client 15 | activate nova_api 16 | note over nova_api: check policy:"delete" 17 | nova_api->nova_api: get server by uuid 18 | # nova/compute/api.py 19 | note over nova_api: check policy:"delete" 20 | note over nova_api: check instance lock 21 | note over nova_api: check instance cell 22 | note over nova_api: check instance state 23 | alt terminate disable 24 | nova_api->client:Failed to delete 25 | end 26 | nova_api->database:get block device mappings 27 | alt instance has snapshot associate and in SHELVED state 28 | note over nova_api: get snapshot id 29 | note over nova_api: get glance client 30 | nova_api->glance:delete snapshot 31 | end 32 | nova_api->database:vm_state->DELETING 33 | nova_api->database:get quota from db 34 | note over nova_api:create reservation 35 | alt cell_type == 'api' 36 | note over nova_api:call the callback 37 | note over nova_api: commit quota 38 | nova_api->client:return 39 | end 40 | 41 | alt not instance.host and not shelved_offloaded 42 | nova_api->database:destroy instance 43 | note over nova_api:quota commit 44 | nova_api->client:response 45 | end 46 | 47 | alt instance resize hasn't been confirmed 48 | nova_api->nova_compute:call confirm resize 49 | end 50 | alt service is down then execute local delete 51 | note over nova_api:clean instance info cache 52 | note over nova_api: detach volume 53 | nova_api->database:delete instance from db 54 | nova_api->database:clean dbms info and network info 55 | note over nova_api: quota commit 56 | nova_api->client:response 57 | end 58 | alt Instance is already in deleting or soft_deleting 59 | nova_api->client:Instance is already in deleting state,ignore 60 | end 61 | nova_api->nova_compute:terminate_instance 62 | deactivate nova_api 63 | deactivate client 64 | activate nova_compute 65 | 66 | note over nova_compute:Remove all pending events 67 | note over nova_compute: notify delete start 68 | note over nova_compute: notify shutdown start 69 | note over nova_compute: get network info for instance 70 | nova_compute->libvirt:get block device info 71 | 72 | nova_compute->libvirt:destry 73 | activate libvirt 74 | # nova/virt/libvirt/driver.py 75 | note over libvirt: get guest(libvirt client) 76 | note over libvirt: power off 77 | note over libvirt: unplug vifs 78 | note over libvirt: wait for power state is shutdown 79 | note over libvirt: disconnect from volumes 80 | note over libvirt: remove disks 81 | note over libvirt: release serial console/port 82 | note over libvirt: undefine domain 83 | libvirt->nova_compute:done 84 | deactivate libvirt 85 | 86 | # nova/compute/manager.py 87 | nova_compute->neutron:deallocate_network 88 | nova_compute->libvirt: get volume connector 89 | nova_compute->cinder:terminate connection 90 | nova_compute->cinder:detach volume 91 | note over nova_compute: notify shutdown end 92 | note over nova_compute: delete cache info 93 | note over nova_compute:clean up volumes that \n delete on termination 94 | nova_compute->database:vm_states.DELETED\npower_state.NOSTATE 95 | note over nova_compute:update resource tracker 96 | 97 | nova_compute->database:destroy instance 98 | note over nova_compute: quota commit 99 | nova_compute->database:destroy bdm 100 | note over nova_compute: notify about delete.end 101 | note over nova_compute: send the uuid to the scheduler 102 | -------------------------------------------------------------------------------- /src/nova/evacuate.wsd: -------------------------------------------------------------------------------- 1 | title evacuate a server from a failed host 2 | 3 | participant client 4 | participant nova_api 5 | 6 | 7 | client->nova_api: evacuate 8 | activate client 9 | activate nova_api 10 | 11 | # nova/api/openstack/compute/evacuate.py _evacuate() 12 | note over nova_api: authrize context 13 | opt if changePassword and on shared storage 14 | note over nova_api: admin password can't be\n changed on existing disk 15 | nova_api->client: HTTPBadRequest 16 | end 17 | 18 | nova_api->database: get instance by uuid 19 | database->nova_api: done 20 | 21 | opt if target host == instance's host 22 | note over nova_api: The target host can't be the same one 23 | nova_api->client: HTTPBadRequest 24 | end 25 | 26 | # nova/compute/api.py evacuate() 27 | note over nova_api: ensure instance state in [ACTIVE,STOPPED,ERROR] 28 | nova_api->database: get service by compute host 29 | database->nova_api: done 30 | 31 | opt service is up 32 | note over nova_api: compute service state is up 33 | nova_api->client: ComputeServiceInUse 34 | end 35 | nova_api->database: task_state = REBUILDING 36 | database->nova_api: done 37 | note over nova_api: record action 'evacuate' 38 | nova_api->database: create a migration record 39 | database->nova_api: done 40 | note over nova_api: notify: evacuate 41 | 42 | #return self.compute_task_api.rebuild_instance(context, 43 | # instance=instance, 44 | # new_pass=admin_password, 45 | # injected_files=None, 46 | # image_ref=None, 47 | # orig_image_ref=None, 48 | # orig_sys_metadata=None, 49 | # bdms=None, 50 | # recreate=True, 51 | # on_shared_storage=on_shared_storage, 52 | # host=host) 53 | # nova/conductor/api.py rebuild_instance() 54 | # nova/conductor/rpcapi.py rebuild_instance() 55 | nova_api->+nova_conductor: rebuild_instance 56 | deactivate nova_api 57 | deactivate client 58 | 59 | # nova/conductor/manager.py 60 | opt if not host 61 | note over nova_conductor: build scheduler spect 62 | note over nova_conductor: setup instance group 63 | nova_conductor->+nova_scheduler: select destinations 64 | # nova/scheduler/manager.py 65 | note over nova_scheduler: notify scheduler.select_destinations.start 66 | note over nova_scheduler: get all hosts state 67 | note over nova_scheduler: get filtered hosts 68 | note over nova_scheduler: get weighed hosts from filtered hosts 69 | note over nova_scheduler: choose hosts from ordered weighed hosts 70 | note over nova_scheduler: notify scheduler.select_destinations.end 71 | nova_scheduler->nova_conductor: selected hosts 72 | deactivate nova_scheduler 73 | end 74 | nova_conductor->+database: get migration record 75 | note over database: get_by_instance_and_status 76 | database->nova_conductor: done 77 | deactivate database 78 | 79 | note over nova_conductor: notify: rebuild.scheduled 80 | nova_conductor->nova_compute: rebuild_instance 81 | deactivate nova_conductor 82 | activate nova_compute 83 | 84 | note over nova_compute: check driver suppert recreate 85 | note over nova_compute: ensure instance not exists 86 | 87 | alt on shared storage 88 | note over nova_compute: log: recreating using existing disk 89 | else not on shared storage 90 | note over nova_compute: log: rebuild from image ref 91 | end 92 | 93 | note over nova_compute: get image meta 94 | note over nova_compute: get image ref url 95 | note over nova_compute: notify: rebuild start 96 | nova_compute->database: task_state=REBUILDING 97 | database->nova_compute: done 98 | note over nova_compute: setup instance network on host 99 | note over nova_compute: get instance network info 100 | nova_compute->database: get block device mapping list 101 | database->nova_compute: done 102 | nova_compute->libvirt: get block device info 103 | note over nova_compute: Transform block devices to \nthe driver block_device format 104 | note over nova_compute: detach volumes 105 | nova_compute->database: task_state=REBUILD_BLOCK_DEVICE_MAPPING 106 | database->nova_compute: done 107 | note over nova_compute: re-attach block devices 108 | nova_compute->+libvirt: spawn 109 | note over libvirt: create image 110 | note over libvirt: get guest xml 111 | note over libvirt: create domain and network 112 | note over libvirt: wait for boot 113 | libvirt->nova_compute: done 114 | deactivate libvirt 115 | 116 | opt original state is STOPPED 117 | nova_compute->database: vm_state = ACTIVE\ntask_state = task_states.POWERING_OFF 118 | database->nova_compute: done 119 | nova_compute->libvirt: power off instance 120 | libvirt->nova_compute: done 121 | end 122 | note over nova_compute: update scheduler instance info 123 | note over nova_compute: notify: rebuild.end 124 | -------------------------------------------------------------------------------- /src/nova/interface-attach.wsd: -------------------------------------------------------------------------------- 1 | title attach an interface to a server 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant neutron 7 | participant nova_compute 8 | participant libvirt 9 | 10 | client->nova_api: interface-attach 11 | activate client 12 | activate nova_api 13 | 14 | note over nova_api: get context 15 | note over nova_api: authorize interface-attach action 16 | opt if body 17 | note over nova_api: get attachment 18 | note over nova_api: get network-id by attachment 19 | note over nova_api: get port-id by attachment 20 | note over nova_api: get fixed-ip by attachment 21 | end 22 | note over nova_api: get instance 23 | nova_api->+nova_compute: attach_interface 24 | nova_compute->libvirt: get bind_host_id by instance 25 | #nova_compute->neutron: allocate_port_for_instance 26 | note over nova_compute: get a NetworkRequestList object:requested_networks 27 | # allocate_for_instance 28 | note over nova_compute: get neuron by context 29 | nova_compute->neutron: validate ports and networks with neutron 30 | note over nova_compute: validate security_groups 31 | nova_compute->neutron: create port if don't have a port_id 32 | neutron->nova_compute: network_info 33 | nova_compute->database: get image_meta 34 | nova_compute->libvirt: attach_interface 35 | 36 | # /nova/virt/libvirt 37 | note over libvirt: get guest 38 | note over libvirt: attach device by guest 39 | -------------------------------------------------------------------------------- /src/nova/interface-detach.wsd: -------------------------------------------------------------------------------- 1 | title detach an interface to a server 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant neutron 7 | participant nova_compute 8 | participant libvirt 9 | 10 | client->nova_api: interface-detach 11 | activate client 12 | activate nova_api 13 | 14 | note over nova_api: get context 15 | note over nova_api: authorize interface-attach action 16 | note over nova_api: get instance 17 | nova_api->+nova_compute: detach_interface 18 | deactivate nova_api 19 | 20 | note over nova_compute: get network_info by instance 21 | note over nova_compute: get condemned 22 | nova_compute->libvirt: detach_interface(instance,condemned) 23 | 24 | note over libvirt: get guest 25 | note over libvirt: get config 26 | note over libvirt: get power_state 27 | note over libvirt: get live 28 | note over libvirt: get xml by config 29 | note over libvirt: change xml of server 30 | 31 | nova_compute->neutron: deallocate port 32 | neutron->database: modify port 33 | 34 | -------------------------------------------------------------------------------- /src/nova/list.wsd: -------------------------------------------------------------------------------- 1 | # nova list 2 | 3 | title List Server Workflow 4 | 5 | participant client 6 | participant nova_api 7 | participant nova_compute_api 8 | participant objects 9 | participant db_api 10 | participant database 11 | 12 | # nova/api/openstack/compute/servers.py 13 | client -> nova_api: GET "/servers" 14 | activate client 15 | activate nova_api 16 | note over nova_api: update search options 17 | note over nova_api: remove invalid search options 18 | note over nova_api: update search options by status 19 | note over nova_api: update search options by changes-since 20 | note over nova_api: update search options by deleted 21 | note over nova_api: update search options by all_tenants 22 | note over nova_api: update search options' project_id and user from context 23 | note over nova_api: get limit and page maker 24 | 25 | # nova/compute/api.py 26 | nova_api->+nova_compute_api:get_all() 27 | note over nova_compute_api:check search options 28 | note over nova_compute_api: build filter mapping 29 | note over nova_compute_api:copy from search options and remap 30 | nova_compute_api->nova_compute_api:call _get_instances_by_filter() 31 | note over nova_compute_api:extend expected attrs 32 | 33 | # nova/objects/instance.py 34 | nova_compute_api->+objects:get_by_filters() 35 | alt sort_keys or sort_dirs 36 | objects->+db_api:instance_get_all_by_filters_sort() 37 | else 38 | objects->+db_api:instance_get_all_by_filters() 39 | end 40 | 41 | # database 42 | note over db_api:get session 43 | note over db_api:build query prefix 44 | db_api->+database:paginate query using sqlalchemy library 45 | 46 | # response 47 | database->db_api:return instances model 48 | deactivate database 49 | note over db_api:fill metadata 50 | db_api->objects:return 51 | deactivate db_api 52 | deactivate db_api 53 | note over objects:make instance list 54 | objects->nova_compute_api:return 55 | deactivate objects 56 | nova_compute_api->nova_api:return 57 | deactivate nova_compute_api 58 | note over nova_api: cache instances 59 | nova_api->client:response 60 | deactivate nova_api 61 | deactivate client 62 | -------------------------------------------------------------------------------- /src/nova/list_simple.wsd: -------------------------------------------------------------------------------- 1 | # nova list 2 | 3 | title List Server Workflow 4 | 5 | participant client 6 | participant nova_api 7 | participant database 8 | 9 | # nova-api 10 | client->nova_api: GET "/servers" 11 | activate client 12 | activate nova_api 13 | note over nova_api: update search options 14 | note over nova_api: remove invalid search options 15 | note over nova_api: update search options by status 16 | note over nova_api: update search options by changes-since 17 | note over nova_api: update search options by deleted 18 | note over nova_api: update search options by all_tenants 19 | note over nova_api: update search options' project_id and user from context 20 | note over nova_api: get limit and page maker 21 | note over nova_api:check search options 22 | note over nova_api: build filter mapping 23 | 24 | # database 25 | nova_api->database:query 26 | activate database 27 | note over database:get session 28 | note over database:build query prefix 29 | note over database:paginate query using sqlalchemy library 30 | 31 | # response 32 | database->nova_api:return instance list 33 | deactivate database 34 | note over nova_api: cache instances 35 | nova_api->client:response 36 | deactivate nova_api 37 | deactivate client 38 | -------------------------------------------------------------------------------- /src/nova/live_migrate.wsd: -------------------------------------------------------------------------------- 1 | title live migrate a server to a new host 2 | participant client 3 | participant nova_api 4 | participant nova_conductor 5 | participant nova_scheduler 6 | participant database 7 | participant nova_compute_src 8 | participant libvirt_src 9 | participant nova_compute_dest 10 | participant libvirt_dest 11 | 12 | client->nova_api: os-migrateLive 13 | activate client 14 | activate nova_api 15 | 16 | # nova/api/openstack/compute/migrate_server.py 17 | note over nova_api: get context 18 | note over nova_api: authorize context: migrate_live 19 | note over nova_api: get migrate option from request 20 | nova_api->database: get instance by uuid 21 | database->nova_api: done 22 | 23 | # nova/compute/api.py live_migrate() 24 | note over nova_api: check instance lock 25 | note over nova_api: check instance state in [ACTIVE, PAUSED] 26 | nova_api->database: task_state = MIGRATING 27 | database->nova_api: done 28 | note over nova_api: record action start:live migration 29 | nova_api->nova_conductor: migrate_server() 30 | activate nova_conductor 31 | # nova/conductor/manager.py _live_migrate() 32 | nova_conductor->database: create migration record 33 | note over nova_conductor: check instance is active 34 | note over nova_conductor: check source host is up 35 | 36 | alt destination is present 37 | note over nova_conductor: check source is not destination 38 | note over nova_conductor: check destination host is up 39 | note over nova_conductor: check destination has enough memory 40 | else 41 | note over nova_conductor: build request spec 42 | note over nova_conductor: check max retries 43 | note over nova_conductor: setup instance group 44 | nova_conductor->+nova_scheduler: select destinations 45 | note over nova_scheduler: notify scheduler.select_destinations.start 46 | note over nova_scheduler: get all hosts state 47 | note over nova_scheduler: get filtered hosts 48 | note over nova_scheduler: get weighed hosts from filtered hosts 49 | note over nova_scheduler: choose hosts from ordered weighed hosts 50 | note over nova_scheduler: notify scheduler.select_destinations.end 51 | nova_scheduler->nova_conductor: selected hosts 52 | deactivate nova_scheduler 53 | end 54 | note over nova_conductor: check destination host compatible with source hypervisor 55 | nova_conductor->+nova_compute_dest: check_can_live_migrate_destination 56 | note over nova_compute_dest: get src compute node info 57 | note over nova_compute_dest: get dest compute node info 58 | nova_compute_dest->+libvirt_dest: check_can_live_migrate_destination 59 | note over libvirt_dest: get disk available 60 | note over libvirt_dest: compare cpu model 61 | note over libvirt_dest: create shared storage test file 62 | libvirt_dest->nova_compute_dest: a dict contain test filename,disk_available_mb,etc. 63 | deactivate libvirt_dest 64 | nova_compute_dest->+nova_compute_src: check_can_live_migrate_source 65 | note over nova_compute_src: check is volume backend 66 | note over nova_compute_src: Transform block devices to the driver block_device format 67 | nova_compute_src->+libvirt_src: check_can_live_migrate_source 68 | note over libvirt_src: check if share storage test file 69 | note over libvirt_src: check if share block storage 70 | note over libvirt_src: get instance disk info 71 | alt block migration 72 | note over libvirt_src: assert not share block_storage and instance path 73 | note over libvirt_src: assert dest node has enough disk 74 | note over libvirt_src: assert instance without mapped volumes 75 | else 76 | note over libvirt_src: check if valid shared storage 77 | end 78 | note over libvirt_src: get instance path 79 | libvirt_src->nova_compute_src: a dict containing migration info 80 | deactivate libvirt_src 81 | nova_compute_src->nova_compute_dest: a dict containing migration info 82 | deactivate nova_compute_src 83 | nova_compute_dest->+libvirt_dest: check_can_live_migrate_destination_cleanup 84 | note over libvirt_dest: cleanup shared storage test file 85 | libvirt_dest->nova_compute_dest: done 86 | deactivate libvirt_dest 87 | nova_compute_dest->nova_conductor: migrate_data 88 | deactivate nova_compute_dest 89 | 90 | nova_conductor->+nova_compute_src: live_migration 91 | deactivate nova_conductor 92 | deactivate nova_api 93 | deactivate client 94 | 95 | nova_compute_src->database: migration.status = 'queued' 96 | database->nova_compute_src: done 97 | 98 | nova_compute_src->database: migration.status = 'queued' 99 | database->nova_compute_src: done 100 | 101 | opt block_migration 102 | note over nova_compute_src: get block device info 103 | note over nova_compute_src: get instance disk info 104 | end 105 | 106 | nova_compute_src->+nova_compute_dest: pre_live_migration 107 | note over nova_compute_dest: get block device info 108 | note over nova_compute_dest: get instance network info from network api 109 | note over nova_compute_dest: notify about instance usage: live_migration.pre.start 110 | nova_compute_dest->+libvirt_dest: pre_live_migration 111 | note over libvirt_dest: get meta from instance 112 | note over libvirt_dest: assert share block storage or share instance path or config driver format is vfat 113 | 114 | opt is not shared instance path 115 | note over libvirt_dest: get instance path 116 | note over libvirt_dest: mkdir instance path 117 | opt has disk.info 118 | note over libvirt_dest: write disk info to dest host 119 | end 120 | 121 | opt is not shared block storage 122 | note over libvirt_dest: create images and backing 123 | end 124 | end 125 | 126 | opt not block migration && not shared instance path 127 | note over libvirt_dest: touch console.log file 128 | note over libvirt_dest: fetch kernel and ramdisk if required 129 | end 130 | 131 | note over libvirt_dest: Connecting volumes before live migration( 132 | note over libvirt_dest: Plugging VIFs before live migration 133 | note over libvirt_dest: Store vncserver_listen and latest disk device info 134 | libvirt_dest->nova_compute_dest: vncserver_listen and latest disk device info 135 | deactivate libvirt_dest 136 | note over libvirt_dest: setup networks on host 137 | 138 | nova_compute_dest->+libvirt_dest: ensure_filtering_rules_for_instance() 139 | note over libvirt_dest: setup basic filters 140 | note over libvirt_dest: prepare instance filter 141 | note over libvirt_dest: wait for instance filter exists 142 | libvirt_dest->nova_compute_dest: done 143 | deactivate libvirt_dest 144 | 145 | note over nova_compute_dest: notify about instance usage: live_migration.pre.end 146 | nova_compute_dest->nova_compute_src: vncserver_listen and latest disk device info 147 | deactivate nova_compute_dest 148 | 149 | nova_compute_src->database: migration.status = 'running' 150 | database->nova_compute_src: done 151 | 152 | nova_compute_src->+libvirt_src: live_migration() 153 | note over libvirt_src: check dest hostname 154 | note over libvirt_src: get guest domain 155 | note over libvirt_src: spawn a new thread 156 | note over libvirt_src: get libvirt migration flags 157 | 158 | alt migratable_flag is None or (listen_addrs is None and not volume) 159 | note over libvirt_src: check graphics addresses can live migrate 160 | note over libvirt_src: verify serial console is disabled 161 | note over libvirt_src: call libvirt migrateToURI() which is legacy live method 162 | else 163 | note over libvirt_src: update domain xml desc 164 | note over libvirt_src: call libvirt migrateToURI2() 165 | opt fail 166 | note over libvirt_src: fallback to legacy live method 167 | end 168 | end 169 | 170 | note over libvirt_src: sync memory and wait for migration finish 171 | libvirt_src->nova_compute_src: done 172 | deactivate libvirt_src 173 | 174 | note over libvirt_src: start post live migration 175 | nova_compute_src->+libvirt_src: post_live_migration 176 | note over libvirt_src: get volume connector 177 | note over libvirt_src: disconnect volume 178 | libvirt_src->nova_compute_src: done 179 | deactivate libvirt_src 180 | note over nova_compute_src: detach volumes 181 | 182 | note over nova_compute_src: get instance network info from network api 183 | note over nova_compute_src: notify about instance usage: live_migration._post.start 184 | note over nova_compute_src: unfilter instance 185 | note over nova_compute_src: migrate instance network start 186 | 187 | 188 | nova_compute_src->+libvirt_src: post_live_migration_at_source 189 | note over libvirt_src: Unplug VIFs from networks at source 190 | libvirt_src->nova_compute_src: done 191 | deactivate libvirt_src 192 | 193 | nova_compute_src->+nova_compute_dest: post_live_migration_at_destination 194 | note over nova_compute_dest: setup network on host via network api 195 | note over nova_compute_dest: migrate instance network finish via network api 196 | note over nova_compute_dest: get instance network info via network api 197 | 198 | 199 | note over nova_compute_dest: notify about instance usage: live_migration.post.dest.start 200 | note over nova_compute_dest: Transform block devices to the driver block_device forma 201 | nova_compute_dest->+libvirt_dest: post_live_migration_at_destination 202 | note over libvirt_dest: write instance xml file to host 203 | libvirt_dest->nova_compute_dest: done 204 | deactivate libvirt_dest 205 | 206 | nova_compute_dest->database: instance.host = dest_host\ninstance.task_state = None\ninstance.node = dest_node 207 | database->nova_compute_dest: done 208 | note over nova_compute_dest: tear down networks on source host via network api 209 | note over nova_compute_dest: setup network on host and update dhcp via network api 210 | 211 | 212 | note over nova_compute_dest: notify about instance usage:live_migration.post.dest.end 213 | nova_compute_dest->nova_compute_src: done 214 | deactivate nova_compute_dest 215 | 216 | note over nova_compute_src: cleanup disks or instance path if need 217 | note over nova_compute_src: clear events for instance 218 | note over nova_compute_src: update src host available resource 219 | note over nova_compute_src: update scheduler instance info 220 | note over nova_compute_src: notify about instance usage: live_migration._post.end 221 | note over nova_compute_src: clean instance console tokens 222 | nova_compute_src->database: migration.status = completed 223 | database->nova_compute_src: done 224 | deactivate nova_compute_src 225 | -------------------------------------------------------------------------------- /src/nova/lock.wsd: -------------------------------------------------------------------------------- 1 | title lock an instance(admin) 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | #nova/api/openstack/compute/lock_server.py _lock() 7 | client->nova_api:lock 8 | activate nova_api 9 | activate client 10 | note over nova_api:get context 11 | note over nova_api:authorize action 'lock' policy 12 | nova_api->database: get instance by id 13 | database->nova_api: done 14 | 15 | # note over nova_api:fetch instance,handling error checking 16 | 17 | #nova/compute/api.py lock() 18 | note over nova_api:check policy 19 | #note over nova_api:call lock() 20 | nova_api->database:instance.locked = True\nlocked_by=owner or admin 21 | database->nova_api: done 22 | 23 | nova_api->client: response 24 | deactivate nova_api 25 | deactivate client 26 | -------------------------------------------------------------------------------- /src/nova/migrate.wsd: -------------------------------------------------------------------------------- 1 | title cold migrate a server to a new host 2 | 3 | participant client 4 | participant nova_api 5 | 6 | client->nova_api: migrate 7 | activate client 8 | activate nova_api 9 | 10 | # nova/api/openstack/compute/migrate_server.py 11 | note over nova_api: get context 12 | note over nova_api: authorize context migrate 13 | nova_api->database: get instance by uuid 14 | # nova/compute/api.py resize() 15 | note over nova_api: check policy 16 | note over nova_api: check instance lock 17 | note over nova_api: check instance state in [ACTIVE, STOPPED] 18 | note over nova_api: check auto_disk_config 19 | nova_api->database: task_state = RESIZE_PREP\n progress=0 20 | database->nova_api: done 21 | note over nova_api: record action start:migrate 22 | # nova/conductor/api.py resize_instance() 23 | nova_api->nova_conductor: migrate_server() 24 | activate nova_conductor 25 | note over nova_conductor: event report: cold migrate 26 | note over nova_conductor: build request spec 27 | note over nova_conductor: setup instance group 28 | note over nova_conductor: populate retry 29 | nova_conductor->+nova_scheduler: select destinations 30 | # nova/scheduler/manager.py 31 | note over nova_scheduler: notify scheduler.select_destinations.start 32 | note over nova_scheduler: get all hosts state 33 | note over nova_scheduler: get filtered hosts 34 | note over nova_scheduler: get weighed hosts from filtered hosts 35 | note over nova_scheduler: choose hosts from ordered weighed hosts 36 | note over nova_scheduler: notify scheduler.select_destinations.end 37 | nova_scheduler->nova_conductor: selected hosts 38 | deactivate nova_scheduler 39 | note over nova_conductor: populate filter properties 40 | nova_conductor->+nova_compute_dest: prep_resize() 41 | deactivate nova_conductor 42 | deactivate nova_api 43 | deactivate client 44 | 45 | note over nova_compute_dest: notify about instance usage: resize.prep.start 46 | nova_compute_dest->database: instance_type='new'\nmetadata['old_vm_state']=vm_state 47 | database->nova_compute_dest: done 48 | note over nova_compute_dest: get resource tracker & resize claim 49 | nova_compute_dest->+nova_compute_src: resize_instance() 50 | deactivate nova_compute_dest 51 | 52 | nova_compute_src->neutron: get network info 53 | neutron->nova_compute_src: done 54 | nova_compute_src->database: migration.status='migrating' 55 | database->nova_compute_src:done 56 | nova_compute_src->database: task_state=RESIZE_MIGRATING 57 | database->nova_compute_src: done 58 | note over nova_compute_src: notify about instance usage: resize.start 59 | nova_compute_src->database: get block device mapping list by instance id 60 | database->nova_compute_src: done 61 | note over nova_compute_src: Transform block devices to the driver block_device format 62 | nova_compute_src->+libvirt: migrate_disk_and_power_off 63 | note over libvirt: get ephemerals disk 64 | note over libvirt: get instance disk info 65 | alt image_type=='lvm' and not boot from volume 66 | note over libvirt: Migration is not implemented for LVM backed instances 67 | end 68 | note over libvirt: get instance base path 69 | alt not shared storage: 70 | note over libvirt: create instance base path to dest host 71 | end 72 | note over libvirt: power off 73 | note over libvirt: get block device mapping info 74 | note over libvirt: disconnect volume 75 | note over libvirt: rename instance base path with suffix of '_resize' 76 | alt shared storage: 77 | note over libvirt: mkdir -p inst_base 78 | end 79 | note over libvirt: copy images to dest host 80 | libvirt->nova_compute_src: return disk info 81 | deactivate libvirt 82 | 83 | nova_compute_src->cinder: terminate volume connections 84 | cinder->nova_compute_src: done 85 | # ->neutron: migrate instance start 86 | nova_compute_src->database: migration.status = 'post-migrating' 87 | database->nova_compute_src: done 88 | nova_compute_src->database: instance.host=migration.dest_compute\ninstance.node = migration.dest_node\ninstance.task_state = task_states.RESIZE_MIGRATED 89 | database->nova_compute_src: done 90 | note over nova_compute_src: notify about instance usage: resize.end 91 | note over nova_compute_src: clear event for instance 92 | deactivate nova_compute_src 93 | nova_compute_src->+nova_compute_dest: finish_resize 94 | note over nova_compute_dest: apply migration context 95 | nova_compute_dest->neutron: setup network on host 96 | neutron->nova_compute_dest: done 97 | nova_compute_dest->neutron: get instance network info 98 | neutron->nova_compute_dest: done 99 | nova_compute_dest->database: task_state=RESIZE_FINISH 100 | database->nova_compute_dest: done 101 | note over nova_compute_dest: notify about instance usage: finish_resize.start 102 | note over nova_compute_dest: Transform block devices to the driver block_device format 103 | nova_compute_dest->libvirt: finish_migration() 104 | activate libvirt 105 | note over libvirt: get disk info 106 | note over libvirt: create image 107 | note over libvirt: create domain and network 108 | alt old vmstate is power on 109 | note over libvirt: wait for running 110 | end 111 | libvirt->nova_compute_dest: done 112 | deactivate libvirt 113 | nova_compute_dest->database: migration.status = 'finished' 114 | database->nova_compute_dest: done 115 | nova_compute_dest->database: vm_state=RESIZED\ntask_state=None\nlaunched_at=now() 116 | database->nova_compute_dest: done 117 | note over nova_compute_dest: update scheduler instance info 118 | note over nova_compute_dest: notify about instance usage: finished_resize.end 119 | -------------------------------------------------------------------------------- /src/nova/pause.wsd: -------------------------------------------------------------------------------- 1 | title pause a server 2 | 3 | participant client 4 | participant nova_api 5 | 6 | 7 | client->nova_api: pause 8 | activate client 9 | activate nova_api 10 | 11 | # nova/api/openstack/compute/pause_server.py _pause() 12 | note over nova_api: authorize context 13 | nova_api->database: get instance by uuid 14 | database->nova_api: done 15 | 16 | # nova/compute/api.py pause() 17 | note over nova_api: check policy 18 | note over nova_api: check instance lock 19 | note over nova_api: check instance cell 20 | note over nova_api: ensure instance state is ACTIVE 21 | nova_api->database: task_state = PAUSING 22 | database->nova_api: done 23 | 24 | note over nova_api: record pause action 25 | # nova/compute/rpcapi.py pause_instance() 26 | nova_api->nova_compute: pause_instance 27 | deactivate nova_api 28 | deactivate client 29 | activate nova_compute 30 | 31 | # nova/compute/manager.py pause_instance() 32 | note over nova_compute: notify: pause.start 33 | nova_compute->libvirt: pause 34 | activate libvirt 35 | 36 | # nova/virt/libvirt/driver.py pause() 37 | note over libvirt: get domain 38 | note over libvirt: domain.suspend() 39 | libvirt->nova_compute: done 40 | deactivate libvirt 41 | # nova/compute/manager.py pause_instance() 42 | nova_compute->database: vm_state = vm_states.PAUSED\ntask_state = None 43 | database->nova_compute: done 44 | note over nova_compute: notify: pause.end 45 | deactivate nova_compute 46 | -------------------------------------------------------------------------------- /src/nova/reboot.wsd: -------------------------------------------------------------------------------- 1 | title reboot an instance 2 | participant client 3 | participant nova_api 4 | participant database 5 | participant glance 6 | participant neutron 7 | participant nova_compute 8 | participant libvirt 9 | 10 | # nova/api/compute/servers.py _stop_server() 11 | client->nova_api:reboot 12 | activate client 13 | activate nova_api 14 | note over nova_api: get reboot type 15 | note over nova_api: get context 16 | nova_api->database: get instance by uuid 17 | database->nova_api: return instance 18 | note over nova_api: authorize reboot action 19 | 20 | # nova/compute/api.py reboot() 21 | note over nova_api: check policy 22 | note over nova_api: check instance lock 23 | note over nova_api: check instance state 24 | note over nova_api: check reboot type and vm state 25 | nova_api->database:task_states = REBOOTING or \n task_states = REBOOTING_HARD 26 | note over database: save instance 27 | database->nova_api: done 28 | note over nova_api: record reboot action 29 | 30 | # nova/compute/rpcapi.py reboot_instance() 31 | nova_api->nova_compute: reboot_instance 32 | deactivate nova_api 33 | deactivate client 34 | activate nova_compute 35 | 36 | # nova/compute/manager.py reboot_instance() 37 | note over nova_compute: reverts task state 38 | nova_compute->database: get instance block device mapping 39 | note over database: get by instance uuid 40 | database->nova_compute: block device mapping 41 | nova_compute->libvirt: get block device info 42 | note over libvirt: get_block_device_info 43 | libvirt->nova_compute: block device info 44 | 45 | nova_compute->neutron: get instance network info 46 | neutron->nova_compute: instance network info 47 | note over nova_compute: notify reboot start 48 | nova_compute->libvirt: get power state 49 | note over libvirt: get info by instance 50 | note over libvirt: retrieve state from instance info 51 | libvirt->nova_compute: power state 52 | nova_compute->database:task_state=REBOOT_PENDING or\ntask_state=REBOOT_PENDING_HARD 53 | note over database: save instance 54 | database->nova_compute:done 55 | note over nova_compute: save current vm state 56 | nova_compute->database: task_state=REBOOT_STARTED or\ntask_state=REBOOT_STARTED_HARD 57 | note over database: save instance 58 | database->nova_compute: done 59 | nova_compute->libvirt: reboot 60 | activate libvirt 61 | alt soft reboot 62 | note over libvirt: get instance guest 63 | note over libvirt: retrieve domain from guest 64 | note over libvirt: get power state 65 | note over libvirt: call domain.shutdown 66 | note over libvirt: prepare pci devices for use 67 | note over libvirt: wait until power state is SHUTDOWN or CRASHED 68 | note over libvirt: create domain 69 | note over libvirt: wait for running 70 | else hard reboot or soft reboot fail 71 | note over libvirt: get instance guest 72 | note over libvirt: call guest.poweroff 73 | note over libvirt: get image meta from instance 74 | note over libvirt: get instance dir 75 | note over libvirt: ensure instance dir tree 76 | note over libvirt: get disk info 77 | note over libvirt: get xml 78 | note over libvirt: Re-populate any missing backing files 79 | note over libvirt: get block device mapping info 80 | note over libvirt: re-establish any and all volume connections 81 | note over libvirt: get neutron events 82 | note over libvirt: plug in virtual interface 83 | note over libvirt: prepare firewall rules 84 | note over libvirt: create domain 85 | note over libvirt: apply instance firewall filters 86 | note over libvirt: wait for running 87 | end 88 | libvirt->nova_compute: done 89 | deactivate libvirt 90 | 91 | nova_compute->database:task_state=None\n set new power state 92 | note over database: save instance 93 | database->nova_compute: done 94 | note over nova_compute: notify reboot end 95 | deactivate nova_compute 96 | -------------------------------------------------------------------------------- /src/nova/rebuild.wsd: -------------------------------------------------------------------------------- 1 | title rebuild an instance 2 | participant client 3 | participant nova_api 4 | participant database 5 | participant glance 6 | participant neutron 7 | participant nova_conductor 8 | participant nova_scheduler 9 | participant nova_compute 10 | participant libvirt 11 | 12 | # nova/api/compute/servers.py _stop_server() 13 | client->nova_api: rebuild 14 | activate client 15 | activate nova_api 16 | 17 | # nova/api/openstack/compute/servers.py _action_rebuild() 18 | note over nova_api: validation rebuild schema 19 | note over nova_api: get image ref 20 | note over nova_api: get or generate admin password 21 | note over nova_api: get context 22 | note over nova_api: authorize action rebuild policy 23 | nova_api->nova_api: get server by uuid 24 | note over nova_api: cache db instance 25 | note over nova_api: build rebuild_kwargs 26 | 27 | # nova/compute/api.py rebuild() 28 | note over nova_api: check policy 29 | note over nova_api: check instance lock 30 | note over nova_api: check instance cell 31 | note over nova_api: ensure instance state in \n [ACTIVE,STOPPED,ERROR] 32 | nova_api->glance: get image by id 33 | activate glance 34 | note over glance: get image by id 35 | glance->nova_api: image object 36 | deactivate glance 37 | note over nova_api: check auto disk config 38 | nova_api->database: get block device mapping list 39 | activate database 40 | note over database: get by instance uuid 41 | database->nova_api: bdms 42 | deactivate database 43 | note over nova_api: get root bdm from bdms 44 | note over nova_api: check metadata quota 45 | note over nova_api: check injected files quota 46 | note over nova_api: check requested image 47 | note over nova_api: handle kernel & ramdisk 48 | nova_api->database: update instance 49 | activate database 50 | note over database: update image properties 51 | note over database: task_states.REBUILDING 52 | database->nova_api: done 53 | deactivate database 54 | note over nova_api: reset image metadata 55 | nova_api->database: get block device mapping list 56 | activate database 57 | note over database: get by instance uuid 58 | database->nova_api: bdms 59 | deactivate database 60 | note over nova_api: record rebuild action 61 | 62 | # nova/conductor/api.py ComputeTaskAPI.rebuild_instance() 63 | # nova/conductor/rpcapi.py 64 | 65 | nova_api->nova_conductor: rebuild instance 66 | deactivate nova_api 67 | deactivate client 68 | 69 | activate nova_conductor 70 | note over nova_conductor: build request spec 71 | note over nova_conductor: setup instance group 72 | nova_conductor->nova_scheduler: select_destinations 73 | activate nova_scheduler 74 | note over nova_scheduler: notify scheduler.select_destinations.start 75 | note over nova_scheduler: get all hosts state 76 | note over nova_scheduler: get filtered hosts 77 | note over nova_scheduler: get weighed hosts from filtered hosts 78 | note over nova_scheduler: choose hosts from ordered weighed hosts 79 | note over nova_scheduler: notify scheduler.select_destinations.end 80 | nova_scheduler->nova_conductor: selected hosts 81 | deactivate nova_scheduler 82 | nova_conductor->database: get migrations 83 | activate database 84 | note over database: get by instance and status 85 | database->nova_conductor: migrations 86 | deactivate database 87 | note over nova_conductor: notify rebuild.scheduled 88 | 89 | # nova/compute/rpcapi.py rebuild_instance 90 | nova_conductor->nova_compute:rebuild_instance 91 | deactivate nova_conductor 92 | activate nova_compute 93 | 94 | # nova/compute/manager.py rebuild_instance() 95 | 96 | nova_compute->glance: get image by uuid 97 | activate glance 98 | note over glance: get image 99 | glance->nova_compute: image instance 100 | deactivate glance 101 | nova_compute->database:get compute node info 102 | activate database 103 | note over database: get_first_node_by_host_for_old_compat 104 | database->nova_compute: compute node info 105 | deactivate database 106 | 107 | note over nova_compute: build rebuild claim 108 | 109 | 110 | alt recreate with the same disk 111 | note over nova_compute: check the driver if support recreate 112 | note over nova_compute: Ensure an instance with the same name is not already present 113 | note over nova_compute: decide if the instance is on shared storage 114 | 115 | # if on_shared_storage,disk on shared storage, recreating using existing disk 116 | # else disk not on shared storage, rebuilding it. 117 | nova_compute->glance: get image by uuid 118 | activate glance 119 | glance->nova_compute: image instance metadata 120 | deactivate glance 121 | note over nova_compute: store origin image ref url 122 | note over nova_compute: notify usage exists 123 | note over nova_compute: notify rebuild.start 124 | nova_compute->database:task_stats=REBUILDING 125 | database->nova_compute: done 126 | nova_compute->+neutron: setup networks on host(only nova-network) 127 | neutron->nova_compute: done 128 | deactivate neutron 129 | nova_compute->+neutron: get network info for instance 130 | neutron->nova_compute: instance's network info 131 | deactivate neutron 132 | 133 | alt bdms is None 134 | nova_compute->+database: get block device mapping list 135 | database->nova_compute: bdms 136 | deactivate database 137 | end 138 | 139 | note over nova_compute: decode injected files 140 | note over nova_compute: libvirt driver not implement rebuild so call rebuild_default_impl 141 | alt preserve_ephemeral 142 | note over nova_compute: raise PreserveEphemeralNotSupported 143 | end 144 | note over nova_compute: detach block devices 145 | 146 | else purge all existing data 147 | nova_compute->+glance: get image by uuid 148 | glance->nova_compute: image metadata 149 | deactivate glance 150 | note over nova_compute: store origin image ref url 151 | note over nova_compute: notify usage exists 152 | note over nova_compute: notify rebuild.start 153 | nova_compute->database:task_stats=REBUILDING 154 | database->nova_compute: done 155 | nova_compute->+neutron: get network info for instance 156 | neutron->nova_compute: instance's network info 157 | deactivate neutron 158 | alt bdms is None 159 | nova_compute->+database: get block device mapping list 160 | database->nova_compute: bdms 161 | deactivate database 162 | end 163 | 164 | note over nova_compute: decode injected files 165 | note over nova_compute: libvirt driver not implement rebuild so call rebuild_default_impl 166 | alt preserve_ephemeral 167 | note over nova_compute: raise PreserveEphemeralNotSupported 168 | end 169 | nova_compute->libvirt: power off instance 170 | activate libvirt 171 | 172 | alt graceful shutdown 173 | note over libvirt: get instance guest 174 | note over libvirt: graceful shutdown 175 | else timeout 176 | note over libvirt: get instance guest 177 | note over libvirt: guest power off 178 | end 179 | libvirt->nova_compute: done 180 | deactivate libvirt 181 | note over nova_compute: detach block devices 182 | nova_compute->libvirt: destroy 183 | activate libvirt 184 | note over libvirt: get instance guest 185 | note over libvirt: guest power off 186 | note over libvirt: unplug virtual interface 187 | note over libvirt: unfilter instance 188 | note over libvirt: disconnect volumes 189 | note over libvirt: destroy disks 190 | note over libvirt: delete instance files 191 | note over libvirt: release serial port 192 | note over libvirt: undefine domain 193 | libvirt->nova_compute: done 194 | deactivate libvirt 195 | end 196 | 197 | nova_compute->+database:task_state=REBUILD_BLOCK_DEVICE_MAPPING 198 | database->nova_compute: done 199 | deactivate database 200 | 201 | note over nova_compute: re-attach block device 202 | note over nova_compute: get new block device info 203 | 204 | nova_compute->+database:task_state=REBUILD_SPAWNING 205 | database->nova_compute: done 206 | deactivate database 207 | 208 | nova_compute->libvirt: spawn 209 | activate libvirt 210 | note over libvirt: create image 211 | note over libvirt: get guest xml 212 | note over libvirt: get connection info and attach volumes 213 | note over libvirt: plug virtual interfaces 214 | note over libvirt: setup basic filter 215 | note over libvirt: prepare instance filter 216 | note over libvirt: create domain 217 | note over libvirt: apply instance filter 218 | note over libvirt: waiting for boot 219 | libvirt->nova_compute: instance is active 220 | deactivate libvirt 221 | 222 | nova_compute->+database:vm_state=ACTIVE, task_state=None 223 | database->nova_compute: done 224 | deactivate database 225 | note over nova_compute: update config driver 226 | 227 | alt instance's original state is stopped 228 | nova_compute->+database: vm_state=ACTIVE, task_state=POWERING_OFF 229 | database->nova_compute:done 230 | deactivate database 231 | note over nova_compute: notify poweroff.start 232 | nova_compute->+libvirt: power off instance 233 | libvirt->nova_compute: done 234 | deactivate libvirt 235 | 236 | nova_compute->+database: vm_state=STOPPED, task_state=None 237 | database->nova_compute:done 238 | deactivate database 239 | note over nova_compute: notify poweroff.end 240 | end 241 | 242 | note over nova_compute: update scheduler instance info 243 | note over nova_compute: notify rebuild.end 244 | 245 | deactivate nova_compute 246 | -------------------------------------------------------------------------------- /src/nova/refresh_network.wsd: -------------------------------------------------------------------------------- 1 | title refresh the server network 2 | participant client 3 | participant nova_api 4 | 5 | client->nova_api: create server-external-events\nevent_name='network-changed' 6 | activate client 7 | activate nova_api 8 | 9 | # nova/api/openstack/compute/server_external_events.py create() 10 | note over nova_api: validate schema: server_external_event.create 11 | note over nova_api: get nova context 12 | note over nova_api: authorize context: server external event create 13 | note over nova_api: get migrate option from request 14 | nova_api->database: get instance by uuid 15 | database->nova_api: done 16 | note over nova_api: assert instance host is present 17 | 18 | # nova/compute/api.py external_instance_event 19 | note over nova_api: collate lists by the host the affected instance is on\nand dispatch them according to host 20 | nova_api->nova_compute: external_instance_event() 21 | deactivate nova_api 22 | deactivate client 23 | nova_compute->network_api: get_instance_nw_info() 24 | network_api->nova_compute: done 25 | deactivate nova_compute 26 | -------------------------------------------------------------------------------- /src/nova/rename.wsd: -------------------------------------------------------------------------------- 1 | title update server's name 2 | participant client 3 | participant nova_api 4 | participant database 5 | 6 | #nova/api/openstack/compute/servers.py update() 7 | client->nova_api:update name 8 | activate client 9 | activate nova_api 10 | note over nova_api:validate update schema 11 | note over nova_api:get context 12 | note over nova_api:authorize action 'update' policy 13 | note over nova_api:get update_dict['display_name'] 14 | nova_api->database:get server by id 15 | activate database 16 | database->nova_api:done 17 | deactivate database 18 | nova_api->database:update(update_dict) 19 | activate database 20 | note over database:save 21 | deactivate database 22 | 23 | nova_api->client:response 24 | deactivate nova_api 25 | deactivate client 26 | -------------------------------------------------------------------------------- /src/nova/rescue.wsd: -------------------------------------------------------------------------------- 1 | title rescue 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant cinder 7 | participant neutron 8 | participant nova_compute 9 | participant libvirt 10 | 11 | 12 | client->nova_api: rescue 13 | activate client 14 | activate nova_api 15 | 16 | note over nova_api: get context 17 | note over nova_api: authorize rescue action 18 | note over nova_api: get password 19 | note over nova_api: get instance 20 | note over nova_api: get rescue_image_ref 21 | 22 | note over nova_api: nova_api 23 | 24 | nova_api->database: get bdms by instance_uuid 25 | 26 | loop for bdm in bdms 27 | nova_api->cinder: get volume from cinder 28 | nova_api->cinder: check attach 29 | end 30 | 31 | nova_api->database: task_state=RESCUING 32 | note over nova_api: record action start 33 | nova_api->+nova_compute: rescue_instance 34 | deactivate nova_api 35 | 36 | nova_compute->neutron: get network_info 37 | note over nova_compute: determine image to use and get image_meta 38 | note over nova_compute: notify rescue start 39 | nova_compute->libvirt: power off 40 | nova_compute->libvirt: rescue 41 | note over libvirt: get xml of instance as unrescue.xml 42 | note over libvirt: save unrescue.xml to instance_dir 43 | note over libvirt: chown console.log 44 | note over libvirt: get disk_info 45 | note over libvirt: create image 46 | note over libvirt: get guest_xml 47 | note over libvirt: power off 48 | note over libvirt: create domain 49 | 50 | note over nova_compute: get power_state by instance 51 | nova_compute->database: vm_state = RESCUED,power_state 52 | 53 | note over nova_compute: notify rescue end 54 | -------------------------------------------------------------------------------- /src/nova/reset_network.wsd: -------------------------------------------------------------------------------- 1 | title reset networking on a server 2 | 3 | participant client 4 | participant nova_api 5 | 6 | client->nova_api: resetNetwork 7 | activate client 8 | activate nova_api 9 | 10 | # nova/api/openstack/compute/legacy_v2/contrib/admin_actions.py _reset_network() 11 | note over nova_api: authorize context 12 | nova_api->database: get instance by uuid 13 | database->nova_api: done 14 | 15 | # nova/compute/api.py reset_network() 16 | note over nova_api: check policy 17 | note over nova_api: check instance lock 18 | note over nova_api: check instance cell 19 | 20 | nova_api->+nova_compute: reset_network 21 | deactivate nova_api 22 | deactivate client 23 | 24 | nova_compute->+libvirt:reset_network() 25 | note over libvirt: pass(do nothing work) 26 | libvirt->nova_compute: do nothing work 27 | deactivate libvirt 28 | deactivate nova_compute 29 | -------------------------------------------------------------------------------- /src/nova/reset_state.wsd: -------------------------------------------------------------------------------- 1 | title reset the state of a server 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | 7 | client->nova_api: os-resetState 8 | activate client 9 | activate nova_api 10 | 11 | # nova/api/openstack/compute/legacy_v2/contrib/admin_actions.py _reset_network() 12 | note over nova_api: valid schema 13 | note over nova_api: authorize context 14 | nova_api->database: get instance by uuid 15 | database->nova_api: done 16 | nova_api->+database: vm_state = newState\ntask_state=None 17 | database->nova_api: done 18 | deactivate database 19 | nova_api->client: response 20 | deactivate nova_api 21 | deactivate client 22 | -------------------------------------------------------------------------------- /src/nova/resize.wsd: -------------------------------------------------------------------------------- 1 | title resize an instance 2 | participant client 3 | participant nova_api 4 | participant database 5 | participant nova_conductor 6 | participant nova_scheduler 7 | participant nova_compute_dest 8 | participant nova_compute_src 9 | participant libvirt 10 | participant glance 11 | participant neutron 12 | 13 | # nova/api/compute/servers.py _action_resize() 14 | client->nova_api: resize 15 | activate client 16 | activate nova_api 17 | 18 | # nova/api/openstack/compute/servers.py _action_resize() 19 | note over nova_api: validation resize schema 20 | note over nova_api: get flavor ref 21 | note over nova_api: get context 22 | note over nova_api: authorize action resize policy 23 | nova_api->nova_api: get server by uuid 24 | note over nova_api: cache db instance 25 | 26 | # nova/compute/api.py rebuild() 27 | note over nova_api: check policy 28 | note over nova_api: check instance lock 29 | note over nova_api: check instance cell 30 | note over nova_api: ensure instance state in \n [ACTIVE,STOPPED] 31 | note over nova_api: check auto disk config 32 | note over nova_api: get current flavor 33 | note over nova_api: get new flavor 34 | opt current flavor is new flavor 35 | note over nova_api: raise CannotResizeToSameFlavor exception 36 | end 37 | note over nova_api: get quota 38 | 39 | nova_api->+database: task_states=RESIZE_PREP 40 | database->nova_api: done 41 | deactivate database 42 | 43 | opt cell.type == 'api' 44 | note over nova_api: commit quota 45 | nova_api->database: create migration record 46 | end 47 | 48 | alt if flavor is None 49 | note over nova_api: record action: MIGRATE 50 | else if flavor is not None 51 | note over nova_api: record action: RESIZE 52 | end 53 | 54 | note over nova_api: get scheduler hint 55 | note over nova_api: ComputeTaskAPI.resize_instance() 56 | note over nova_api: conductorrpcapi.migrate_server()\nlive=False, rebuild=False 57 | nova_api->+nova_conductor:call migrate.server()\nlive=False,rebuild=False 58 | 59 | # nova/conductor/manager.py 60 | note over nova_conductor: event report: cold migrate 61 | note over nova_conductor: build request spect 62 | nova_conductor->+database: get quotas 63 | database->nova_conductor: quotas 64 | deactivate database 65 | note over nova_conductor: setup instance group 66 | note over nova_conductor: populate retry 67 | nova_conductor->+nova_scheduler: select destinations 68 | # nova/scheduler/manager.py 69 | note over nova_scheduler: notify scheduler.select_destinations.start 70 | note over nova_scheduler: get all hosts state 71 | note over nova_scheduler: get filtered hosts 72 | note over nova_scheduler: get weighed hosts from filtered hosts 73 | note over nova_scheduler: choose hosts from ordered weighed hosts 74 | note over nova_scheduler: notify scheduler.select_destinations.end 75 | nova_scheduler->nova_conductor: selected hosts 76 | deactivate nova_scheduler 77 | 78 | note over nova_conductor: populate filter properties 79 | note over nova_conductor: prepare rpc client 80 | 81 | nova_conductor->nova_compute_dest: prep_resize 82 | activate nova_compute_dest 83 | deactivate nova_conductor 84 | deactivate nova_api 85 | deactivate client 86 | 87 | # nova/compute/manager.py 88 | note over nova_compute_dest: notify: resize.prep.start 89 | nova_compute_dest->+database: new flavor 90 | database->nova_compute_dest: done 91 | deactivate database 92 | nova_compute_dest->+nova_compute_src: resize instance 93 | note over nova_compute_dest: get extra usage info 94 | note over nova_compute_dest: notify: resize.prep.end 95 | deactivate nova_compute_dest 96 | 97 | # nova/compute/manager.py 98 | nova_compute_src->+database: get quotas 99 | database->nova_compute_src: done 100 | deactivate database 101 | nova_compute_src->+neutron: get instance network info 102 | neutron->nova_compute_src: done 103 | deactivate neutron 104 | nova_compute_src->+database: migration.status = 'migrating' 105 | database->nova_compute_src: done 106 | deactivate database 107 | nova_compute_src->+database: task_states=RESIZE_MIGRATING 108 | database->nova_compute_src: done 109 | deactivate database 110 | note over nova_compute_src: notify: resize.start 111 | nova_compute_src->+database: get block device mapping list 112 | database->nova_compute_src:done 113 | deactivate database 114 | nova_compute_src->+libvirt: get block device info 115 | libvirt->nova_compute_src: done 116 | deactivate libvirt 117 | note over nova_compute_src: Transform block devices to the driver block_device format 118 | note over nova_compute_src: Get the timing configuration for powering down this instance 119 | nova_compute_src->+libvirt: migrate_disk_and_power_off 120 | 121 | # nova/virt/libvirt/driver.py 122 | note over libvirt: get ephemerals disk 123 | note over libvirt: get instance disk info 124 | opt if root size down and booted from volume 125 | note over libvirt: Unable to resize disk down 126 | note over libvirt: Instance Fault Rollback 127 | end 128 | 129 | opt if image type is lvm and not booted from volume 130 | note over libvirt: Migration is not supported for LVM backed instances 131 | note over libvirt: InstanceFaultRollback 132 | end 133 | 134 | opt if not shared storage 135 | note over libvirt: create dir to destination host using ssh command 136 | end 137 | note over libvirt: power off instance 138 | 139 | note over libvirt: get block device info 140 | note over libvirt: disconnect volumes 141 | note over libvirt: rename instance_base dir to instance_base_resize 142 | note over libvirt: create new instance_base dir 143 | 144 | alt if shared storage 145 | note over libvirt: local copy image using cp 146 | else 147 | note over libvirt: remote copy image using ssh or rsync 148 | end 149 | 150 | libvirt->nova_compute_src: disk info 151 | deactivate libvirt 152 | 153 | nova_compute_src->+volume_api: terminate volume connection 154 | volume_api->nova_compute_src: done 155 | deactivate volume_api 156 | nova_compute_src->+database: migration.status = 'post-migrating' 157 | database->nova_compute_src: done 158 | deactivate database 159 | nova_compute_src->+database: task_states=RESIZE_MIGRATED 160 | database->nova_compute_src: done 161 | deactivate database 162 | 163 | nova_compute_src->+nova_compute_dest: finish resize 164 | note over nova_compute_src: notify: resize.end 165 | note over nova_compute_src: clear event for instance 166 | deactivate nova_compute_src 167 | 168 | nova_compute_dest->+database: get quota from reservations 169 | database -> nova_compute_dest: done 170 | deactivate database 171 | note over nova_compute_dest: setup networks on host 172 | nova_compute_dest->+neutron: update port binding for instance 173 | neutron->nova_compute_dest: done 174 | deactivate neutron 175 | 176 | nova_compute_dest->+neutron: get instance network info 177 | neutron->nova_compute_dest: network info 178 | deactivate neutron 179 | 180 | nova_compute_dest->+database: task_state = RESIZE_FINISH 181 | database->nova_compute_dest: done 182 | deactivate database 183 | 184 | note over nova_compute_dest: notify: finish_resize.start 185 | nova_compute_dest->libvirt: get instance block device info 186 | 187 | nova_compute_dest->+libvirt: finish_migration 188 | note over libvirt: get image meta 189 | note over libvirt: get block info 190 | note over libvirt: create image 191 | note over libvirt: attempt to resize a disk to size 192 | note over libvirt: get guest xml 193 | note over libvirt: get connection info and attach volumes 194 | note over libvirt: plug virtual interfaces 195 | note over libvirt: setup basic filter 196 | note over libvirt: prepare instance filter 197 | note over libvirt: create domain 198 | note over libvirt: apply instance filter 199 | note over libvirt: waiting for boot 200 | 201 | opt old vm state is not STOPPED 202 | note over libvirt: waiting for running 203 | end 204 | 205 | libvirt->nova_compute_dest: done 206 | deactivate libvirt 207 | 208 | nova_compute_src->+database: migration.status = 'finished' 209 | database->nova_compute_src: done 210 | deactivate database 211 | nova_compute_src->+database: task_states=RESIZE_FINISH 212 | database->nova_compute_src: done 213 | deactivate database 214 | note over nova_compute_dest: update scheduler instance info 215 | note over nova_compute_dest: notify: finish_resize.end 216 | note over nova_compute_dest: quota commit 217 | deactivate nova_compute_dest 218 | 219 | -------------------------------------------------------------------------------- /src/nova/shelve.wsd: -------------------------------------------------------------------------------- 1 | title shelve an instance 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant nova_compute 7 | participant libvirt 8 | participant glance_api 9 | participant neutron 10 | participant nova_scheduler 11 | 12 | #nova/openstack/compute/shelve.py 13 | client->nova_api:shelve an instance 14 | activate client 15 | activate nova_api 16 | note over nova_api:get context 17 | note over nova_api:authorize action 'shelve' policy 18 | nova_api->database:get instance by id 19 | activate database 20 | database->nova_api:done 21 | deactivate database 22 | note over nova_api:check policy 23 | note over nova_api:check instance lock 24 | note over nova_api:ensure instance state in [ACTIVE, \n STOPPED,PAUSED,SUSPENDED] 25 | nova_api->database:task_state=SHELVING 26 | activate database 27 | database->nova_api:done 28 | deactivate database 29 | note over nova_api:record 'shelve' start 30 | alt if not is volume_backed_instance 31 | nova_api->glance_api:get image meta 32 | activate glance_api 33 | glance_api->nova_api:done 34 | deactivate glance_api 35 | note over nova_api:get image id 36 | nova_api->nova_compute:shelve_instance() 37 | 38 | activate nova_compute 39 | note over nova_compute:notify shelve.start 40 | nova_compute->+database:task_state=SHELVING 41 | database->-nova_compute:done 42 | nova_compute->+libvirt:power off instance and create snapshot 43 | note over libvirt:get instance guest 44 | note over libvirt:get guest domain 45 | libvirt->glance_api:get snapshot by id 46 | activate glance_api 47 | glance_api->libvirt:snapshot object 48 | deactivate glance_api 49 | note over libvirt:get source type and source format 50 | note over libvirt:get snapshot metadata 51 | note over libvirt: check if we can perform live snapshot 52 | note over libvirt: get image snapshot backend according to image type 53 | note over libvirt: perform image snapshot operation 54 | libvirt->database: task_states=IMAGE_PENDING_UPLOAD 55 | activate database 56 | database->libvirt: done 57 | deactivate database 58 | libvirt->database: task_states=IMAGE_UPLOAD 59 | activate database 60 | database->libvirt: done 61 | deactivate database 62 | alt if not live snapshot 63 | note over libvirt: create snapshot domain 64 | note over libvirt: attach pci devices 65 | note over libvirt: attach sriov ports 66 | end 67 | libvirt->+glance_api: update image 68 | note over glance_api: update image metadata 69 | note over glance_api: upload image 70 | glance_api->libvirt: done 71 | deactivate glance_api 72 | note over libvirt: log snapshot image upload complete 73 | libvirt->nova_compute: done 74 | deactivate libvirt 75 | nova_compute->+database:vm_state=SHELVED \n task_state=None 76 | database->-nova_compute:done 77 | alt if CONF.shelved_offload_time == 0 78 | nova_compute->+database:task_states=SHELVING_OFFLOADING 79 | database->-nova_compute:done 80 | end 81 | nova_compute->+libvirt:get instance power state 82 | libvirt->-nova_compute:done 83 | note over nova_compute:notify:shelve.end 84 | else if is volume_backed_instance 85 | nova_api->nova_compute:shelve_offload_instance() 86 | deactivate nova_api 87 | deactivate client 88 | note over nova_compute:Remove a shelved instance from the hypervisor 89 | note over nova_compute:notify:shelve_offload.start 90 | nova_compute->+libvirt:power off the instance \n and get instance power state 91 | libvirt->-nova_compute:done 92 | 93 | nova_compute->neutron:Cleanup network for specified instance on host 94 | nova_compute->+neutron:get network info of the instance 95 | neutron->-nova_compute:done 96 | 97 | nova_compute->+libvirt:get block device info of an instance 98 | nova_compute->libvirt:destroy() 99 | libvirt->-nova_compute:done 100 | 101 | nova_compute->+database:power_state=current_power_state \n host=None \n node=None \n vm_state=vm_states.SHELVED_OFFLOADED \n task_state=None 102 | database->-nova_compute:done 103 | note over nova_compute:update resource tracker 104 | 105 | nova_compute->+nova_scheduler:delete scheduler info of an instance 106 | nova_scheduler->-nova_compute:done 107 | 108 | note over nova_compute:notify:shelve_offload.end 109 | deactivate nova_compute 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/nova/shelve_offload.wsd: -------------------------------------------------------------------------------- 1 | title shelve-offload an instance 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant nova_compute 7 | participant libvirt 8 | participant neutron 9 | participant nova_scheduler 10 | 11 | #nova/api/openstack/compute/shelve.py _shelve_offload() 12 | client->nova_api:shelve-offload an instance 13 | activate client 14 | activate nova_api 15 | note over nova_api:get context 16 | note over nova_api:authorize action 'shelve_offload' policy 17 | nova_api->+database:get instance by id 18 | database->-nova_api:done 19 | note over nova_api:check policy 20 | note over nova_api:check instance lock 21 | note over nova_api:ensure instance state in [SHELVED] 22 | nova_api->+database:task_state=SHELVING_OFFLOADING 23 | database->-nova_api:done 24 | nova_api->nova_compute:shelve_offload_instance() 25 | deactivate nova_api 26 | deactivate client 27 | activate nova_compute 28 | note over nova_compute:notify:shelve_offload.start 29 | nova_compute->libvirt:power_off_instance() 30 | nova_compute->+libvirt:get current power state 31 | libvirt->-nova_compute:done 32 | nova_compute->neutron:cleanup instance network info 33 | nova_compute->+neutron:get current instance nw info 34 | neutron->-nova_compute:done 35 | nova_compute->+libvirt:get block device info 36 | note over libvirt:get_block_device_info 37 | libvirt->-nova_compute:done 38 | nova_compute->+libvirt:destroy() 39 | # nova/virt/libvirt/driver.py 40 | note over libvirt: get guest(libvirt client) 41 | note over libvirt: power off 42 | note over libvirt: unplug vifs 43 | note over libvirt: wait for power state is shutdown 44 | note over libvirt: disconnect from volumes 45 | note over libvirt: remove disks 46 | note over libvirt: release serial console/port 47 | note over libvirt: undefine domain 48 | libvirt->-nova_compute:done 49 | nova_compute->+database:get current power state 50 | database->-nova_compute:done 51 | 52 | nova_compute->database:host=None,node=None \n vm_state=SHELVED_OFFLOADED 53 | note over nova_compute:update resource tracker 54 | nova_compute->+nova_scheduler:delete scheduler info of an instance 55 | nova_scheduler->-nova_compute:done 56 | 57 | note over nova_compute:notify:shelve_offload.end 58 | deactivate nova_compute 59 | -------------------------------------------------------------------------------- /src/nova/snapshot.wsd: -------------------------------------------------------------------------------- 1 | title create an image(snapshot) 2 | participant client 3 | participant nova_api 4 | 5 | 6 | # nova/api/compute/servers.py _action_create_image() 7 | client->nova_api: createImage 8 | activate client 9 | activate nova_api 10 | 11 | # nova/api/openstack/compute/servers.py _action_create_image() 12 | note over nova_api: validation create image schema 13 | note over nova_api: get context 14 | note over nova_api: authorize action 'create_image' policy 15 | note over nova_api: check image metadata properties 16 | nova_api->nova_api: get server by uuid 17 | note over nova_api: cache db instance 18 | 19 | alt if is volume backend instance 20 | note over nova_api: authorize action 'create_image:allow_volume_backed' policy 21 | note over nova_api: ensure instance state is ACTIVE or STOPPED 22 | note over nova_api: initialize new metadata \nfor a snapshot of the given \ninstance 23 | alt if vm.state is active 24 | nova_api->+nova_compute: quiesce instance 25 | note over nova_compute: get image meta 26 | nova_compute->+libvirt: quiesce 27 | note over libvirt: get instance guest 28 | note over libvirt: get domain 29 | note over libvirt: freeze the domain 30 | libvirt->nova_compute: done 31 | deactivate libvirt 32 | deactivate nova_compute 33 | note over nova_api: quiesced = True 34 | end 35 | nova_api->+database: get block device mapping list 36 | database->nova_api: done 37 | deactivate database 38 | alt if bdm is volume: 39 | nova_api->+cinder_api: get volume by id 40 | cinder_api->nova_api: volume object 41 | deactivate cinder_api 42 | nova_api->+cinder_api: force create volume snapshot 43 | cinder_api->nova_api: snapshot object 44 | deactivate cinder_api 45 | note over nova_api: get image mapping 46 | else if bdm is not volume 47 | note over nova_api: get image mapping 48 | end 49 | alt if quiesced == True 50 | nova_api->+nova_compute: unquiesce instance 51 | note over nova_compute: wait for snapshot completion 52 | note over nova_compute: get image meta 53 | nova_compute->+libvirt: unquiesce 54 | note over libvirt: get instance guest 55 | note over libvirt: get domain 56 | note over libvirt: thaw(unfreeze) the domain 57 | libvirt->nova_compute: done 58 | deactivate libvirt 59 | deactivate nova_compute 60 | end 61 | nova_api->+glance_api: create image with image meta 62 | note over glance_api: create image 63 | glance_api->nova_api: image meta 64 | deactivate glance_api 65 | else if not volume backend instance 66 | note over nova_api: check policy 67 | note over nova_api: check instance cell 68 | note over nova_api: check instance state in [ACTIVE,\nSTOPPED,PAUSED,SUSPENDED] 69 | note over nova_api: initialize new metadata \nfor a snapshot of the given \ninstance 70 | nova_api->+glance_api: create image with image meta 71 | note over glance_api: create image 72 | glance_api->nova_api: image meta 73 | deactivate glance_api 74 | nova_api->+database: task_states=IMAGE_SNAPSHOT_PENDING 75 | database->nova_api: done 76 | deactivate database 77 | nova_api->nova_compute: snapshot_instance 78 | deactivate nova_api 79 | deactivate client 80 | nova_compute->+libvirt: get instance power state 81 | libvirt->nova_compute: done 82 | deactivate libvirt 83 | note over nova_compute: log a warning if power state is not RUNNING 84 | nova_compute->+database: update instance power state 85 | database->nova_compute: done 86 | deactivate database 87 | note over nova_compute: notify: snapshot.start 88 | nova_compute->+libvirt: snapshot 89 | note over libvirt: get instance guest 90 | note over libvirt: get domain 91 | libvirt->+glance_api: get snapshot by id 92 | glance_api->libvirt: snapshot object 93 | deactivate glance_api 94 | note over libvirt: get source type and source format 95 | note over libvirt: get image metadata 96 | note over libvirt: check if we can perform live snapshot 97 | note over libvirt: get image snapshot backend according to image type 98 | note over libvirt: perform image snapshot operation 99 | libvirt->+database: task_states=IMAGE_PENDING_UPLOAD 100 | database->libvirt: done 101 | deactivate database 102 | libvirt->+database: task_states=IMAGE_UPLOAD 103 | database->libvirt: done 104 | deactivate database 105 | alt not live snapshot 106 | note over libvirt: create snapshot domain 107 | note over libvirt: attach pci devices 108 | note over libvirt: attach sriov ports 109 | end 110 | libvirt->+glance_api: update image 111 | note over glance_api: update image metadata 112 | note over glance_api: upload image 113 | glance_api->libvirt: done 114 | deactivate glance_api 115 | 116 | note over libvirt: log snapshot image upload complete 117 | libvirt->nova_compute: done 118 | deactivate libvirt 119 | nova_api->+database: task_states=None 120 | database->nova_api: done 121 | deactivate database 122 | note over nova_compute: notify: snapshot.end 123 | end 124 | nova_api->client: response 125 | -------------------------------------------------------------------------------- /src/nova/start.wsd: -------------------------------------------------------------------------------- 1 | title start an instance 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant glance 7 | participant neutron 8 | participant nova_compute 9 | participant libvirt 10 | 11 | # nova/api/compute/servers.py _start_server() 12 | client->nova_api:os-start 13 | activate client 14 | activate nova_api 15 | note over nova_api: get context 16 | nova_api->database: get instance by uuid 17 | database->nova_api: return instance 18 | note over nova_api: authorize start action 19 | 20 | # nova/compute/api.py start() 21 | note over nova_api: check instance lock 22 | note over nova_api: check instance host 23 | note over nova_api: check instance cell 24 | note over nova_api: check instance state 25 | nova_api->database: task_states = POWERING_ON 26 | database->nova_api: done 27 | note over nova_api: record action 28 | 29 | # nova/compute/rpcapi.py start_instance() 30 | nova_api->nova_compute: start_instance 31 | deactivate nova_api 32 | deactivate client 33 | activate nova_compute 34 | 35 | # nova/compute/manager.py start_instance() 36 | note over nova_compute: notify power on start 37 | nova_compute->neutron: get instance network info 38 | nova_compute->database: get block device mapping list 39 | database->nova_compute: return bdm list 40 | nova_compute->libvirt: get block device info 41 | libvirt->nova_compute: transform to the \n driver block_device format 42 | nova_compute->libvirt: power on 43 | activate libvirt 44 | 45 | # nova/virt/libvirt/driver power_on 46 | note over libvirt: power off instance 47 | note over libvirt: ensure power state is SHUTDOWN 48 | note over libvirt: convert system metadata to image metadata 49 | note over libvirt: get instance dir 50 | note over libvirt: ensure instance dir exists 51 | note over libvirt: get disk info 52 | note over libvirt: regenerate guest xml 53 | note over libvirt: write xml to disk 54 | alt auth token 55 | note over libvirt: get instance backing disk info 56 | note over libvirt: create images and backing 57 | end 58 | note over libvirt: re-establish any and all volume connections 59 | note over libvirt: get neutron events(None here) 60 | note over libvirt: plug vifs 61 | note over libvirt: set up firewall filter 62 | note over libvirt: create domain 63 | note over libvirt: start/launch domain 64 | note over libvirt: apply instance filter 65 | alt instance is paused: 66 | note over libvirt: resume instance 67 | end 68 | note over libvirt: prepare pci devices for use 69 | note over libvirt: wait for reboot 70 | libvirt->nova_compute: when power state is RUNNING 71 | deactivate libvirt 72 | # nova/compute/manager.py 73 | note over nova_compute: get shelved image id 74 | nova_compute->glance: delete shelved image 75 | glance->nova_compute: done 76 | note over nova_compute: remove shelved keys \n from system metadata 77 | nova_compute->database:vm.state=ACTIVE\ntask_state=None 78 | database->nova_compute: done 79 | note over nova_compute: notify power on end 80 | -------------------------------------------------------------------------------- /src/nova/stop.wsd: -------------------------------------------------------------------------------- 1 | title stop an instance 2 | participant client 3 | participant nova_api 4 | participant database 5 | participant glance 6 | participant neutron 7 | participant nova_compute 8 | participant libvirt 9 | 10 | # nova/api/compute/servers.py _stop_server() 11 | client->nova_api:os-stop 12 | activate client 13 | activate nova_api 14 | note over nova_api: get context 15 | nova_api->database: get instance by uuid 16 | database->nova_api: return instance 17 | note over nova_api: authorize stop action 18 | 19 | # nova/compute/api.py stop() 20 | note over nova_api: check instance lock 21 | note over nova_api: check instance host 22 | note over nova_api: check instance cell 23 | note over nova_api: check instance state 24 | note over nova_api: call force_stop() 25 | nova_api->database: task_states = POWERING_OFF 26 | database->nova_api: done 27 | note over nova_api: record stop action 28 | 29 | # nova/compute/rpcapi.py start_instance() 30 | nova_api->nova_compute: stop_instance 31 | deactivate nova_api 32 | deactivate client 33 | activate nova_compute 34 | 35 | # nova/compute/manager.py stop_instance() 36 | note over nova_compute: check current power state 37 | note over nova_compute: notify power off start 38 | note over nova_compute: get timeout & retry_interval value 39 | nova_compute->libvirt: power_off 40 | activate libvirt 41 | 42 | alt try graceful shutdown 43 | note over libvirt: get instance guest 44 | note over libvirt: get power state 45 | note over libvirt: graceful shutdown 46 | note over libvirt: retry until power state is shutdown or timeout 47 | else timeout, then destroy(force power off) 48 | note over libvirt: get instance guest 49 | note over libvirt: guest power off 50 | end 51 | 52 | libvirt->nova_compute: done 53 | deactivate libvirt 54 | 55 | nova_compute->database:vm.state=STOPPED\ntask_state=None 56 | database->nova_compute: done 57 | note over nova_compute: notify power off end 58 | -------------------------------------------------------------------------------- /src/nova/suspend.wsd: -------------------------------------------------------------------------------- 1 | title suspend a server 2 | 3 | participant client 4 | participant nova_api 5 | 6 | client->nova_api: evacuate 7 | activate client 8 | activate nova_api 9 | 10 | # nova/api/openstack/compute/suspend_server.py _suspend() 11 | note over nova_api: authorize context 12 | nova_api->database: get instance by uuid 13 | database->nova_api: done 14 | 15 | # nova/compute/api.py suspend() 16 | note over nova_api: check policy 17 | note over nova_api: check instance lock 18 | note over nova_api: check instance cell 19 | note over nova_api: ensure instance state is ACTIVE 20 | 21 | nova_api->database: task_state = SUSPENDING 22 | database->nova_api: done 23 | note over nova_api: record action 'suspend' 24 | 25 | nova_api->+nova_compute: suspend_instance 26 | deactivate nova_api 27 | deactivate client 28 | 29 | note over nova_compute: notify: suspend.start 30 | nova_compute->+libvirt: suspend 31 | note over libvirt: get instance guest 32 | note over libvirt: detach pci devices 33 | note over libvirt: detach sriov ports 34 | note over libvirt: guest.save_memory_state() 35 | libvirt->nova_compute: done 36 | deactivate libvirt 37 | nova_compute->database:vm_state=SUSPENDED\n task_state=None 38 | note over nova_compute: notify: suspend.end 39 | deactivate nova_compute 40 | -------------------------------------------------------------------------------- /src/nova/unlock.wsd: -------------------------------------------------------------------------------- 1 | title unlock an instance 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | #nova/api/openstack/compute/lock_server.py _unlock() 7 | client->nova_api:unlock 8 | activate nova_api 9 | activate client 10 | note over nova_api:get context 11 | note over nova_api:authorize action 'unlock' policy 12 | 13 | nova_api->database: get instance by id 14 | activate database 15 | database->nova_api: done 16 | deactivate database 17 | 18 | #nova/compute/api.py unlock() 19 | note over nova_api:check policy 20 | nova_api->database:query instance.locked 21 | activate database 22 | database->nova_api:done 23 | deactivate database 24 | 25 | nova_api->database:instance.locked = False\nlocked_by=None 26 | activate database 27 | database->nova_api: done 28 | deactivate database 29 | nova_api->client: response 30 | deactivate nova_api 31 | deactivate client 32 | -------------------------------------------------------------------------------- /src/nova/unpause.wsd: -------------------------------------------------------------------------------- 1 | title unpause a server 2 | participant client 3 | participant nova_api 4 | 5 | 6 | client->nova_api: unpause 7 | activate client 8 | activate nova_api 9 | 10 | # nova/api/openstack/compute/pause_server.py _unpause() 11 | note over nova_api: authorize context 12 | nova_api->database: get instance by uuid 13 | database->nova_api: done 14 | 15 | # nova/compute/api.py unpause() 16 | note over nova_api: check policy 17 | note over nova_api: check instance lock 18 | note over nova_api: check instance cell 19 | note over nova_api: ensure instance state is PAUSED 20 | nova_api->database: task_state = UNPAUSING 21 | database->nova_api: done 22 | 23 | note over nova_api: record action: unpause 24 | # nova/compute/rpcapi.py unpause_instance() 25 | nova_api->nova_compute: unpause_instance 26 | deactivate nova_api 27 | deactivate client 28 | activate nova_compute 29 | 30 | # nova/compute/manager.py unpause_instance() 31 | note over nova_compute: notify: unpause.start 32 | nova_compute->libvirt: unpause 33 | activate libvirt 34 | 35 | # nova/virt/libvirt/driver.py unpause() 36 | note over libvirt: get domain 37 | note over libvirt: domain.resume() 38 | libvirt->nova_compute: done 39 | deactivate libvirt 40 | # nova/compute/manager.py unpause_instance() 41 | nova_compute->database: vm_state = vm_states.ACTIVE\ntask_state = None 42 | database->nova_compute: done 43 | note over nova_compute: notify: unpause.end 44 | deactivate nova_compute 45 | -------------------------------------------------------------------------------- /src/nova/unrescue.wsd: -------------------------------------------------------------------------------- 1 | title unrescue 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant neutron 7 | participant nova_compute 8 | participant libvirt 9 | 10 | 11 | client->nova_api: unrescue 12 | activate client 13 | activate nova_api 14 | 15 | note over nova_api: get context 16 | note over nova_api: authorize unrescue action 17 | note over nova_api: get instance 18 | 19 | note over nova_api: nova_api 20 | nova_api->database: task_state = UNRESCUING 21 | 22 | note over nova_api: record unrescue star 23 | note over nova_api: record_action_start 24 | nova_api->+nova_compute: unrescue_instance 25 | deactivate nova_api 26 | 27 | nova_compute->neutron: get network_info 28 | note over nova_compute: notify unrescue start 29 | nova_compute->libvirt: unrescue 30 | note over libvirt: get unresce.xml 31 | 32 | note over libvirt: get libvirt.xml path 33 | note over libvirt: use unrescue.xml write to libvirt.xml 34 | note over libvirt: get host 35 | note over libvirt: destroy instance 36 | note over libvirt: create domain by xml 37 | note over libvirt: delete unrescue.xml 38 | note over libvirt: remove disk endwith '.rescue' 39 | 40 | note over nova_compute: get power_state 41 | nova_compute->database: vm_state = ACTIVE, power_state 42 | 43 | note over nova_compute: notify rescue end 44 | 45 | -------------------------------------------------------------------------------- /src/nova/unshelve.wsd: -------------------------------------------------------------------------------- 1 | title unshelve an instance 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant nova_conductor 7 | participant nova_compute 8 | participant glance_api 9 | participant libvirt 10 | participant nova_scheduler 11 | 12 | #nova/api/openstack/compute/shelve.py 13 | client->nova_api:Restore a shelved instance 14 | activate client 15 | activate nova_api 16 | nova_api->+database:task_state=UNSHELVING 17 | database->-nova_api:done 18 | 19 | note over nova_api:record action 'UNSHELVE' start 20 | nova_api->+database:get request_spec by instance uuid 21 | database->-nova_api:done 22 | 23 | #nova/conductor/api.py unshelve_instance() 24 | nova_api->+nova_conductor:unshelve_instance() 25 | deactivate nova_api 26 | deactivate client 27 | note over nova_conductor:get sys_meta 28 | nova_conductor->+glance_api:get session and image id 29 | glance_api->-nova_conductor:done 30 | 31 | alt if vm_state=SHELVED 32 | nova_conductor->+database:task_state=POWERING_ON 33 | nova_conductor->database:task_state=UNSHELVING 34 | database->-nova_conductor:done 35 | nova_conductor->+nova_compute:start_instance() 36 | note over nova_compute:notify:power_on.start 37 | note over nova_compute:get network info of an instance 38 | nova_compute->+libvirt:get block device info 39 | nova_compute->libvirt:power_on the specified instance 40 | libvirt->-nova_compute:done 41 | deactivate nova_compute 42 | 43 | else if vm_state=SHELVED_OFFLOADED 44 | note over nova_conductor:EventReporter:get_image_info 45 | nova_conductor->+glance_api:get session and image id 46 | glance_api->-nova_conductor:done 47 | note over nova_conductor:EventReporter:schedule_instances 48 | note over nova_conductor:build request spec 49 | note over nova_conductor:populate retry 50 | note over nova_conductor:get filter hosts 51 | note over nova_conductor:get all hosts state 52 | nova_conductor->nova_compute:unshelve_instance() 53 | activate nova_compute 54 | deactivate nova_conductor 55 | note over nova_compute:notify:unshelve.start 56 | nova_compute->+database:task_state=SPAWNING 57 | database->-nova_compute:done 58 | nova_compute->+database:get block device mapping list 59 | database->-nova_compute:return bdm list 60 | note over nova_compute:remove redundant data 61 | nova_compute->+libvirt:get block device info 62 | libvirt->-nova_compute:Converts block device mappings \n for an instance to driver format 63 | 64 | note over nova_compute:setup network for instance 65 | note over nova_compute:get instance network info 66 | nova_compute->+libvirt:spawn() 67 | libvirt->-nova_compute:done 68 | note over nova_compute:restore redundant data 69 | nova_compute->+database:power_state=current power_state 70 | database->+libvirt:get current power_state 71 | libvirt->-database:done 72 | nova_compute->database:vm_state=ACTIVE,task_state=None 73 | database->-nova_compute:done 74 | note over nova_compute:Delete system_metadata \n for a shelved instance 75 | 76 | nova_compute->+nova_scheduler:update instance info 77 | nova_scheduler->-nova_compute:done 78 | 79 | note over nova_compute:notify:unshelve.end 80 | end 81 | deactivate nova_compute 82 | 83 | 84 | -------------------------------------------------------------------------------- /src/nova/volume_attach.wsd: -------------------------------------------------------------------------------- 1 | title attach a volume to a server 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant cinder 7 | participant nova_compute 8 | 9 | 10 | client->nova_api: volume-attach 11 | activate client 12 | activate nova_api 13 | 14 | # nova/api/openstack/compute/pause_server.py _pause() 15 | note over nova_api: get context 16 | note over nova_api: authorize volume-attach action 17 | note over nova_api: get volume_id 18 | note over nova_api: get device 19 | nova_api->database: get instance 20 | 21 | # nova/api.py 22 | opt if is_shelved_offloaded 23 | note over nova_api: get volume_bdm 24 | # _check_and_reserve_attach 25 | note over nova_api: get volume 26 | nova_api->cinder: check_attach 27 | nova_api->cinder: reserve_attach 28 | nova_api->cinder: attach 29 | else 30 | note over nova_api: get volume_bdm 31 | note over nova_api: _check_and_reserve_attach 32 | nova_api->+nova_compute:attach_volume 33 | end 34 | 35 | nova_api->client:response 36 | deactivate nova_api 37 | 38 | note over nova_compute: get driver_bdm 39 | # driver_bdm.attach 40 | note over nova_compute: driver_bdm.attach 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/nova/volume_detach.wsd: -------------------------------------------------------------------------------- 1 | title detach a volume to a server 2 | 3 | participant client 4 | participant nova_api 5 | participant database 6 | participant cinder 7 | participant nova_compute 8 | participant libvirt 9 | 10 | 11 | client->nova_api: volume-detach 12 | activate client 13 | activate nova_api 14 | 15 | note over nova_api: get context 16 | note over nova_api: authorize volume-detach action 17 | nova_api->database: get instance 18 | nova_api->cinder: get volume by volume_id 19 | 20 | # nova/compute-api 21 | opt if instance.vm_state == SHELVED_OFFLOADED 22 | note over nova_api: check_and_begin_detach 23 | note over nova_api: get bdms by volume_id 24 | loop bdm in bdms 25 | note over nova_api: volume_api.terminate_connection 26 | note over nova_api: volume_api.detach 27 | note over nova_api: bdm.destroy 28 | end 29 | end 30 | 31 | note over nova_api: get attachment_id 32 | nova_api->+nova_compute:detach_volume 33 | deactivate nova_api 34 | 35 | note over nova_compute: get bdm by volume and instance 36 | # _driver_deatah_volume 37 | note over nova_compute: get mp(device_name) 38 | note over nova_compute: get connection_info 39 | note over nova_compute: get encryption 40 | 41 | nova_compute->libvirt:detach_volume 42 | # /virt/libvirt/driver.py 43 | note over libvirt: get guest 44 | note over libvirt: get power_state 45 | # /virt/libvirt/guest.py 46 | note over libvirt: get flags 47 | note over libvirt: get config for device by guest.get_disk 48 | note over libvirt: get device_xml by config.to_xml 49 | note over libvirt: change xml of server 50 | 51 | # /nova/compute-manager 52 | note over nova_compute: get connector 53 | opt if destroy_bdm 54 | note over nova_compute: destroy bdm 55 | end 56 | nova_compute->cinder: terminate_connection 57 | nova_compute->cinder: detach 58 | -------------------------------------------------------------------------------- /src/sahara/create_cluster.wsd: -------------------------------------------------------------------------------- 1 | title create a new CDH cluster 2 | 3 | participant client 4 | participant sahara_api 5 | participant database 6 | participant api_plugin 7 | participant sahara_engine 8 | participant engine 9 | participant engine_plugin 10 | 11 | 12 | # sahara/api/v2/clusters.py clusters_create() 13 | client->sahara_api:data-processing:clusters:create 14 | activate client 15 | activate sahara_api 16 | 17 | note over sahara_api: check cluster_create schema 18 | # sahara/service/api/v2/clusters.py create_cluster() 19 | note over sahara_api: get plugin by name 20 | note over sahara_api: get context 21 | sahara_api->database: conductor:create a new cluster entry 22 | database->sahara_api: done 23 | note over sahara_api: send notify: New 24 | opt auto security group 25 | note over sahara_api: setup auto security group 26 | end 27 | note over sahara_api: setup cluster recommend config 28 | sahara_api->database: status = VALIDATING 29 | database->sahara_api: done 30 | note over sahara_api: check quotas 31 | 32 | sahara_api->+api_plugin: validate cluster 33 | note over api_plugin: ensure namenode == 1 34 | note over api_plugin: ensure secondary namenode == 1 35 | note over api_plugin: ensure datanode >= dfs_replication 36 | note over api_plugin: ensure resourcemanager == 1 37 | note over api_plugin: ensure yarn_jobhistory == 1 38 | note over api_plugin: ensure nodemanager > 0 39 | note over api_plugin: validate oozie 40 | note over api_plugin: validate hive 41 | note over api_plugin: validate hue 42 | note over api_plugin: validate hbase 43 | note over api_plugin: validate other services, flume, solr, sqoop,etc. 44 | api_plugin->sahara_api: done 45 | deactivate api_plugin 46 | 47 | # sahara/service/opts.py RemoteOpt.provision_cluster() 48 | sahara_api->sahara_engine: provision_cluster 49 | deactivate sahara_api 50 | deactivate client 51 | activate sahara_engine 52 | 53 | # sahara/service/opts.py OptServer.provision_cluster() 54 | sahara_engine->database: get cluster by id 55 | database->sahara_engine: done 56 | note over sahara_engine: get plugin by name 57 | note over sahara_engine: get image username 58 | note over sahara_engine: setup trust for cluster 59 | sahara_engine->database: update sahara info, infrastructure_engine,remote,etc. 60 | database->sahara_engine: done 61 | 62 | sahara_engine->database: status = INFRAUPDATING 63 | database->sahara_engine: done 64 | 65 | sahara_engine->+engine_plugin: update_infra 66 | note over engine_plugin: cdh plugin do nothing 67 | engine_plugin->sahara_engine: done 68 | deactivate engine_plugin 69 | 70 | sahara_engine->engine: create_cluster 71 | activate engine 72 | # sahara/sahara/service/direct_engine.py create_cluster() 73 | note over engine: update rollback strategy: cleanup resources = true 74 | engine->database: status = SPAWNING 75 | database->engine: done 76 | 77 | note over engine: create auto security groups 78 | opt cluster.anti_affinity 79 | note over sahara_engine: create anti affinity server group 80 | end 81 | note over engine: add provisioning step: Run instances 82 | note over engine: create and start instances 83 | 84 | engine->database: add instances to cluster 85 | database->engine: done 86 | 87 | engine->database: status = WAITING 88 | database->engine: done 89 | 90 | note over engine: await all instances to be active 91 | note over engine: assign floating ips 92 | note over engine: await_networks: ssh username@manager_ip "ls .ssh/authorized_keys" 93 | note over engine: create attached volumes 94 | note over engine: await all volumes to be available 95 | note over engine: attach volumes 96 | note over engine: mount volumes to instances 97 | 98 | engine->database: status = PREPARING 99 | database->engine: done 100 | 101 | note over engine: setup hostname 102 | note over engine: generate /etc/hosts 103 | note over engine: setup passwordless login 104 | note over engine: update rollback strategy: cleanup resources = false 105 | engine->sahara_engine: done 106 | deactivate engine 107 | 108 | # sahara/service/opts.py OptServer.provision_cluster() 109 | sahara_engine->database: status = CONFIGURING 110 | database->sahara_engine: done 111 | note over sahara_engine: mount shares 112 | sahara_engine->engine_plugin: configure cluster 113 | activate engine_plugin 114 | 115 | # sahara/plugins/cdh/v5_4_0/deploy.py configure_cluster() 116 | note over engine_plugin: configure OS, yum repo,key url,etc. 117 | note over engine_plugin: install package 118 | note over engine_plugin: start cloudera-agent 119 | note over engine_plugin: start cloudera-manager 120 | note over engine_plugin: update cloudera-manager password 121 | note over engine_plugin: await agents 122 | note over engine_plugin: create mgmt service 123 | note over engine_plugin: create and configure services 124 | note over engine_plugin: deploy configs 125 | engine_plugin->sahara_engine: done 126 | deactivate engine_plugin 127 | 128 | # sahara/service/opts.py OptServer.provision_cluster() 129 | note over sahara_engine: configure ntp service 130 | sahara_engine->database: status = STARTING 131 | database->sahara_engine: done 132 | sahara_engine->engine_plugin: start_cluster 133 | activate engine_plugin 134 | # sahara/plugins/cdh/v5_4_0/versionhandler.py start_cluster() 135 | opt deploy oozie 136 | note over engine_plugin: install extjs 137 | end 138 | opt deploy hive 139 | note over engine_plugin: configure hive 140 | end 141 | opt deploy sentry 142 | note over engine_plugin: configure sentry 143 | end 144 | 145 | note over engine_plugin: first run: Prepare and start services in a cluster 146 | note over engine_plugin: configure swift 147 | note over engine_plugin: enable namenode ha 148 | note over engine_plugin: enable resourcemanager ha 149 | note over engine_plugin: put hive hdfs xml if require 150 | note over engine_plugin: create hbase common lib if require 151 | note over engine_plugin: start flume service if require 152 | 153 | opt deploy hue 154 | note over engine_plugin: update hue dashboard WebUI 155 | end 156 | engine_plugin->database: update cluster info 157 | database->engine_plugin: done 158 | engine_plugin->sahara_engine: done 159 | deactivate engine_plugin 160 | # sahara/service/opts.py OptServer.provision_cluster() 161 | sahara_engine->database: status = ACTIVE 162 | database->sahara_engine: done 163 | 164 | note over sahara_engine: schedule execution pending job for cluster 165 | note over sahara_engine: delete trust from cluster 166 | -------------------------------------------------------------------------------- /src/sahara/create_cluster.wsd.backup: -------------------------------------------------------------------------------- 1 | # sahara/api/v2/clusters.py clusters_create() 2 | # sahara/service/api/v2/clusters.py create_cluster() 3 | # sahara/service/opts.py RemoteOpt.provision_cluster() 4 | # sahara/service/opts.py OptServer.provision_cluster() 5 | # sahara/sahara/service/direct_engine.py create_cluster() 6 | # sahara/service/opts.py OptServer.provision_cluster() 7 | # sahara/plugins/cdh/v5_4_0/deploy.py configure_cluster() 8 | # sahara/service/opts.py OptServer.provision_cluster() 9 | # sahara/plugins/cdh/v5_4_0/versionhandler.py start_cluster() 10 | # sahara/service/opts.py OptServer.provision_cluster() 11 | --------------------------------------------------------------------------------