nova/api/openstack/__init__.py
apirouter class: def __init__ (self, ext_mgr=none, Init_only=none): if ext_mgr None: if self. Extensionmanager: ext_mgr = self. Extensionmanager () else : raise Exception (_ ( " must Specify an Extensionmanager class )) ...
where Extensionmanager is specified as nova/api/in the subclass nova/api/openstack/computer/__init__.py Apirouter openstack/computer/extensions.py in the Extensionmanager class, see its constructor:
class Extensionmanager (base_extensions. Extensionmanager): def __init__ " initializing extension Manager. = conf.osapi_compute_extension Self.extensions = {} self.sorted_ext_list = [] self._load_extensions ()
Where Self.cls_list is the list of boot classes for the expansion pack, [nova.api.openstack.compute.contrib.standard_extensions]. Then look at the contents of Self._load_extensions (), the function is nova.api.openstack due to the Extensionmanager class inheritance relationship. The functions of the extensions Extensionmanager are as follows:
def _load_extensions(self): extensions=list (self.cls_list) forExt_factoryinchExtensions:Try: self.load_extension (ext_factory) exceptException as Exc:LOG.warn (_ ('Failed to load extension% (ext_factory) s:' '% (exc) s'), {'ext_factory': Ext_factory,'exc': exc})
The contents of the Self.load_extension function are as follows:
def Load_ Extension (Self, ext_factory): Log.debug (_ ( " loading extension%s " ), ext_factory)
if Isinstance (Ext_factory, basestring): Factory = Importutils.import_class (ext_factory) else : Factory = Ext_factory Log.debug (_ ( calling Extension factory%s " factory (self)
The whole process is to call nova.api.openstack.compute.contrib.standard_extensions. Next look at the Standard_extensions function, which reads as follows:
def standard_extensions(ext_mgr): extensions. Load_standard_extensions__path____package__)
Where extensions for nova.api.openstack.extensions, see Load_standard_extensions content as follows:
def load_standard_extensions(Ext_mgr, logger, path, package, ext_list=None): Our_dir=Path[0] forDirpath, Dirnames, filenamesinchOs.walk (our_dir): RelPath=Os.path.relpath (Dirpath, Our_dir)ifRelPath = ='.': Relpkg="' Else: Relpkg='.%s'%'.'. Join (Relpath.split (OS.SEP)) forFNameinchFilenames:root, ext=Os.path.splitext (fname)ifExt! ='. PY' orRoot = ='__init__': ContinueClassName="%s%s"% (Root[0].upper (), root[1:]) Classpath= ("%s%s.%s.%s"%(Package, relpkg, Root, classname))ifExt_list is notNone andClassName not inchExt_list:logger.debug ("skipping extension:%s"%classpath)Continue Try: Ext_mgr.load_extension (classpath)exceptException as Exc:logger.warn (_ ('Failed to load extension% (classpath) s:' '% (exc) s'), {'Classpath': Classpath,'exc': Exc}) ...
This is actually called the Load_extension function load module before Extensionmanager, and constructs the class corresponding to the module name in the module, Because these classes are subclasses of Nova.api.openstack.extensions.ExtensionDescriptor and look at their __init__ functions:
def __init__ (self, ext_mgr): Ext_mgr.register (self) = Ext_mgr
It is known that the construction of these extension classes will be registered in Extensionmanager, the registration process is to save an instance of the extension class in the Extensionmanag Extensionmanager extensions list. The corresponding key is the alias of the extension class.
In summary, the Extensionmanager construct is to load the self.cls_list of the call, Self.cls_list contains the extension package of the boot class or boot function, This is nova.api.openstack.compute.contrib.standard_extensions, which is responsible for loading modules in the expansion pack and constructing the corresponding class instances. These class instances are registered to Extensionmanager when they are constructed.
The structure of Extensionmanager in Nova-api