zoukankan      html  css  js  c++  java
  • openstack components internal relations

    1.  各个组件之间可以互相调用(都是common sense)

    conductor 负责DB的操作。 

    各个组件之间通过RPC, 序列化通过oslo_versionedobjects。

    2. 具体调用:

    Agent(如nova-computer) 访问DB, 通过调用conductor。 实例, 搜索remotable_classmethod

    这个调用比较隐性, 通过versionedobjects (ppt)的remote方法。

    def remotable_classmethod(fn)

    # These are decorators that mark an object's method as remotable.
    # If the metaclass is configured to forward object methods to an
    # indirection service, these will result in making an RPC call
    # instead of directly calling the implementation in the object. Instead,
    # the object implementation on the remote end will perform the
    # requested action and the result will be returned here.
    def remotable_classmethod(fn):
        """Decorator for remotable classmethods."""
        @six.wraps(fn)
        def wrapper(cls, context, *args, **kwargs):
            if cls.indirection_api:
                version_manifest = obj_tree_get_versions(cls.obj_name())
                try:
                   # 需要设置indirection_api, 还需要提供 object_class_action_versions方法
                    result = cls.indirection_api.object_class_action_versions(
                        context, cls.obj_name(), fn.__name__, version_manifest,
                        args, kwargs)
                except NotImplementedError:
                    # FIXME(danms): Maybe start to warn here about deprecation?
                    result = cls.indirection_api.object_class_action(
                        context, cls.obj_name(), fn.__name__, cls.VERSION,
                        args, kwargs)
            else:
                result = fn(cls, context, *args, **kwargs)
                if isinstance(result, VersionedObject):
                    result._context = context
            return result
    
        # NOTE(danms): Make this discoverable
        wrapper.remotable = True
        wrapper.original_fn = fn
        return classmethod(wrapper)

    def remotable(fn)

    # See comment above for remotable_classmethod()
    #
    # Note that this will use either the provided context, or the one
    # stashed in the object. If neither are present, the object is
    # "orphaned" and remotable methods cannot be called.
    def remotable(fn):
        """Decorator for remotable object methods."""
        @six.wraps(fn)
        def wrapper(self, *args, **kwargs):
            ctxt = self._context
            if ctxt is None:
                raise exception.OrphanedObjectError(method=fn.__name__,
                                                    objtype=self.obj_name())
            if self.indirection_api:
                # 需要设置indirection_api 及其 object_action 方法
                updates, result = self.indirection_api.object_action(
                    ctxt, self, fn.__name__, args, kwargs)
                for key, value in updates.items():
                    if key in self.fields:
                        field = self.fields[key]
                        # NOTE(ndipanov): Since VersionedObjectSerializer will have
                        # deserialized any object fields into objects already,
                        # we do not try to deserialize them again here.
                        if isinstance(value, VersionedObject):
                            setattr(self, key, value)
                        else:
                            setattr(self, key,
                                    field.from_primitive(self, key, value))
                self.obj_reset_changes()
                self._changed_fields = set(updates.get('obj_what_changed', []))
                return result
            else:
                return fn(self, *args, **kwargs)
    
        wrapper.remotable = True
        wrapper.original_fn = fn
        return wrapper

     3. Agent调用conductor。

     objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI()

    def main():
        config.parse_args(sys.argv)
        logging.setup(CONF, 'nova')
        priv_context.init(root_helper=shlex.split(utils.get_root_helper()))
        utils.monkey_patch()
        objects.register_all()
        gmr_opts.set_defaults(CONF)
        # Ensure os-vif objects are registered and plugins loaded
        os_vif.initialize()
    
        gmr.TextGuruMeditation.setup_autorun(version, conf=CONF)
    
        cmd_common.block_db_access('nova-compute')
        objects_base.NovaObject.indirection_api = conductor_rpcapi.ConductorAPI()
        objects.Service.enable_min_version_cache()
        server = service.Service.create(binary='nova-compute',
                                        topic=compute_rpcapi.RPC_TOPIC)
        service.serve(server)
        service.wait()

     4. API调用 其他组件

    调用agent(nova-compute):

    class ServersController(wsgi.Controller) 的初始化 def __init__(self, **kwargs)

     self.compute_api = compute.API()

    from nova import compute
    
    class ServersController(wsgi.Controller):
        """The Server API base controller class for the OpenStack API."""
    
        _view_builder_class = views_servers.ViewBuilder
    
        ......
    
        def __init__(self, **kwargs):
    
            super(ServersController, self).__init__(**kwargs)
            self.compute_api = compute.API()

    5. nova objects隐性的调用conductor

    def conductor(self)

    class NovaObjectSerializer(messaging.NoOpSerializer):
        """A NovaObject-aware Serializer.
        This implements the Oslo Serializer interface and provides the
        ability to serialize and deserialize NovaObject entities. Any service
        that needs to accept or return NovaObjects as arguments or result values
        should pass this to its RPCClient and RPCServer objects.
        """
    
        @property
        def conductor(self):
            if not hasattr(self, '_conductor'):
                from nova import conductor
                self._conductor = conductor.API()
            return self._conductor

     class CyborgObjectSerializer 没有实现。

    5. nova 其他地方调用conductor

    $ git grep "from.*conductor"
    cells/scheduler.py:from nova import conductor
    cmd/api_metadata.py:from nova.conductor import rpcapi as conductor_rpcapi
    cmd/compute.py:from nova.conductor import rpcapi as conductor_rpcapi
    cells/scheduler.py:from nova import conductor
    cmd/api_metadata.py:from nova.conductor import rpcapi as conductor_rpcapi
    cmd/compute.py:from nova.conductor import rpcapi as conductor_rpcapi
    cmd/dhcpbridge.py:from nova.conductor import rpcapi as conductor_rpcapi
    cells/scheduler.py:from nova import conductor
    cmd/api_metadata.py:from nova.conductor import rpcapi as conductor_rpcapi
    cmd/compute.py:from nova.conductor import rpcapi as conductor_rpcapi
    cmd/dhcpbridge.py:from nova.conductor import rpcapi as conductor_rpcapi
    cmd/network.py:from nova.conductor import rpcapi as conductor_rpcapi
    compute/api.py:from nova import conductor
    compute/api.py:            # from the conductor LiveMigrationTask. Yes this is tightly-coupled
    compute/manager.py:from nova import conductor
    compute/manager.py:        This is initiated from conductor and runs on the destination host.
    conductor/__init__.py:from nova.conductor import api as conductor_api
    conductor/api.py:from nova.conductor import rpcapi
    conductor/manager.py:from nova.conductor.tasks import live_migrate
    conductor/manager.py:from nova.conductor.tasks import migrate
    conductor/manager.py:                # can't reach the API DB from the cell conductor.
    conductor/tasks/live_migrate.py:from nova.conductor.tasks import base
    conductor/tasks/live_migrate.py:from nova.conductor.tasks import migrate
    conductor/tasks/migrate.py:from nova.conductor.tasks import base
    conf/__init__.py:from nova.conf import conductor
    objects/base.py:            from nova import conductor
    service.py:from nova import conductor
    View Code

     service.py 调用 conductor

    from nova import conductor
    ......
    
    class Service(service.Service):
        """Service object for binaries running on hosts.
        A service takes a manager and enables rpc by listening to queues based
        on topic. It also periodically runs tasks on the manager and reports
        its state to the database services table.
        """
    
        def __init__(self, host, binary, topic, manager, report_interval=None,
                     periodic_enable=None, periodic_fuzzy_delay=None,
                     periodic_interval_max=None, *args, **kwargs):
            super(Service, self).__init__()
            self.host = host
            self.binary = binary
            self.topic = topic
            self.manager_class_name = manager
            self.servicegroup_api = servicegroup.API()
            manager_class = importutils.import_class(self.manager_class_name)
            self.manager = manager_class(host=self.host, *args, **kwargs)
            self.rpcserver = None
            self.report_interval = report_interval
            self.periodic_enable = periodic_enable
            self.periodic_fuzzy_delay = periodic_fuzzy_delay
            self.periodic_interval_max = periodic_interval_max
            self.saved_args, self.saved_kwargs = args, kwargs
            self.backdoor_port = None
            if objects_base.NovaObject.indirection_api:
                conductor_api = conductor.API()
                conductor_api.wait_until_ready(context.get_admin_context())
            setup_profiler(binary, self.host)

     6. conductor 调用了 agent(nova-computer)

    $ cd conductor/ ; git grep "from.*compute"
    -bash: cd: conductor/: No such file or directory
    manager.py:from nova.compute import instance_actions
    manager.py:from nova.compute import rpcapi as compute_rpcapi
    manager.py:from nova.compute import task_states
    manager.py:from nova.compute import utils as compute_utils
    manager.py:from nova.compute.utils import wrap_instance_event
    manager.py:from nova.compute import vm_states
    manager.py:        # or during a reschedule from a pre-Queens compute. In all other cases,
    manager.py:            # could have come from a compute via reschedule and it would
    tasks/live_migrate.py:from nova.compute import power_state
    View Code

     7.  openstack Logical architecture

  • 相关阅读:
    python网络编程之最简单的单工通信
    ruby : Exception Notification
    python学习之操作mysql
    python学习之最简单的获取本机ip信息的小程序
    python学习之最简单的用户注册及登录验证小程序
    mongo数据库的导入导出
    mac安装django1.5.4
    mac安装软件管家homebrew
    关于mac安装rails报错clang: error: unknown argument
    在mac上安装nodejs
  • 原文地址:https://www.cnblogs.com/shaohef/p/8377678.html
Copyright © 2011-2022 走看看