Heat的核心是stack,stack又是由各种各样的资源组成的,heat除了自定义的大量资源外,还允许用户自定义自己需要的资源。
heat资源加载流程
我们先从heat-engine的启动脚本来看:
heat/cmd/engine.py
if __name__ == '__main__':
cfg.CONF(project='heat', prog='heat-engine')
logging.setup('heat')
messaging.setup()
mgr = None
try:
#加载heat的模板类
mgr = template._get_template_extension_manager()
except template.TemplatePluginNotRegistered as ex:
LOG.critical(_LC("%s"), ex)
if not mgr or not mgr.names():
sys.exit("ERROR: No template format plugins registered")
from heat.engine import service as engine
srv = engine.EngineService(cfg.CONF.host, rpc_api.ENGINE_TOPIC)
上面为heat-egine进程启动的代码,在创建EngineService的时候,这里面有个resources初始化的步骤,
这里应该就是完成资源加载的关键,如下面的代码所示
heat/engine/service.py EngineService.__init__():
def __init__(self, host, topic, manager=None):
super(EngineService, self).__init__()
resources.initialise() #对资源进行初始化,分析代码可以除了初始化资源,此处还会初始化clients.
self.host = host
self.topic = topic
首先是有个全局变量_environment,由于是初次加载,所以会执行clients.initialise()
heat/engine/resources/__init__.py
def initialise():
global _environment
if _environment is not None:
return
clients.initialise()
global_env = environment.Environment({}, user_env=False)
_load_global_environment(global_env)
_environment = global_env
clients其实就是heat与各个openstack组件通信的关键,类似的,这里采用了全局_mgr来管理clients的加载,
初次加载的时候由于全局变量_mgr为None,所以采用stevedore加载heat需要用到的各种clients,
_mgr = None
def has_client(name):
return _mgr and name in _mgr.names()
heat/engine/clients/__init__.py
def initialise():
global _mgr
if _mgr:
return
_mgr = extension.ExtensionManager(
namespace='heat.clients',
invoke_on_load=False,
verify_requirements=False)
这里的clients为entrypoints中定义的名称空间为heat.clients中的各种client,具体可以查看heat的api-paste.ini文件。