最近工作的主要内容是在dashboard中启动虚拟机的时候加一个cache静态划分的功能,是在隔离区还是在共享区,这就需要对整个虚拟机的启动流程代码非常熟悉,并且还要适当的改前端。但是在看源码包括实践的过程发现了一件很神奇的时候,网上的教程大多是IceHose版本的,其启动虚拟机走的是正常的workflow中的handle函数,但是也不知道是我们装的Mitaka版本OpenStack有问题还是怎么样,起虚拟机偏偏不走那里,第一天遇到这个问题的时候我就给hcch师兄说我见鬼了。。 但好在,用了三天时间调出来了,同时也记录一下Mitaka版本的虚拟机启动的流程。
在查资料的时候找到了这么一个图,侵删。。
1. Dashboard中
1. /usr/share/openstack-dashboard/openstack_dashboard/dashboards/project/instances/workflows/create_instance.py
是关于创建虚拟机的workflow,但是不走LaunchInstance中的handle进行处理
class LaunchInstance(workflows.Workflow):
slug = "launch_instance"
name = _("Launch Instance")
finalize_button_name = _("Launch")
success_message = _('Launched %(count)s named "%(name)s".')
failure_message = _('Unable to launch %(count)s named "%(name)s".')
success_url = "horizon:project:instances:index"
multipart = True
default_steps = (SelectProjectUser,
SetInstanceDetails,
SetAccessControls,
SetNetwork,
SetNetworkPorts,
PostCreationStep,
SetAdvanced)
这里面定义了7个Steps,每个Steps中都有对应的表单显示。其中每个标签卡显示的具体内容和相应的html和js相对应。
具体的js和html的文件放在以下目录
/usr/share/openstack-dashboard/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance
2. /usr/share/openstack-dashboard/openstack_dashboard/dashboards/project/static/dashboard/project/workflow/launch-instance/launch-instance-model.service.js
当在dashboard中把创建虚拟机的表单填写好后,所有的数据都通过这个js文件中的 createInstance()
函数进行请求的进一步发送
function createInstance() {
var finalSpec = angular.copy(model.newInstanceSpec);
cleanNullProperties(finalSpec);
setFinalSpecBootsource(finalSpec);
setFinalSpecFlavor(finalSpec);
setFinalSpecNetworks(finalSpec);
setFinalSpecPorts(finalSpec);
setFinalSpecKeyPairs(finalSpec);
setFinalSpecSecurityGroups(finalSpec);
setFinalSpecMetadata(finalSpec);
return novaAPI.createServer(finalSpec).then(successMessage);
}
3. /usr/share/openstack-dashboard/openstack_dashboard/static/app/core/openstack-service-api/nova.service.js
第二步中的请求发送到这个js文件中的 createServer(newServer)
函数中,其中newServer参数中放了创建虚拟机的参数
function createServer(newServer) {
return apiService.post('/api/nova/servers/', newServer) # 向api/rest/nova.py 发请求
.error(function () {
toastService.add('error', gettext('Unable to create the server.'));
});
}
4. /usr/share/openstack-dashboard/openstack_dashboard/api/rest/nova.py
请求发送到了 Servers
类下的 Post
函数中,其中所有的参数在request中
@rest_utils.ajax(data_required=True)
def post(self, request):
try:
args = (
request,
request.DATA['name'],
request.DATA['source_id'],
request.DATA['flavor_id'],
request.DATA['key_name'],
request.DATA['user_data'],
request.DATA['security_groups'],
)
except KeyError as e:
raise rest_utils.AjaxError(400, 'missing required parameter '
"'%s'" % e.args[0])
kw = {}
for name in self._optional_create:
if name in request.DATA:
kw[name] = request.DATA[name]
new = api.nova.server_create(*args, **kw)
return rest_utils.CreatedResponse(
'/api/nova/servers/%s' % utils_http.urlquote(new.id),
new.to_dict()
)
5. /usr/share/openstack-dashboard/openstack_dashboard/api/nova.py
通过 server_create
函数调用novaclient
def server_create(request, name, image, flavor, k