Horizon学习笔记

来源:互联网 发布:美工孙伟博时代小区 编辑:程序博客网 时间:2024/06/06 21:00

Horizon吊炸天!之前,一直认为horizon只不过是一个面板,没啥好研究的,而且我对django又不是很熟,一直懒的看horizon,今晚硬着头皮看了下去,没想到,越看越有劲,眼睛差点跟不上我的思路了!我觉得horizon牛不在对django的运用,而是对事物高度的抽象能力:D


程序的入口点在horizon/openstack_dashboard/urls.py中:

url(r'', include(horizon.urls))


然后由Horizon这个单例的Site对象,开始加载urls,自动发现并注册dashboard,然后对每一个dashboard,再自动发现并注册panel:

Horizon._lazy_url

程序的入口看起来那么平常不过,进入之后发现这大千世界,让人惊叹不已!!!




可以在horizon/base/_urls()方法中,一窥全貌:

```    def _urls(self):          """Constructs the URLconf for Horizon from registered Dashboards."""        urlpatterns = self._get_default_urlpatterns()        self._autodiscover() # 自动发现并注册dashboard,其实就是从INSTALL_APPS中加载dashboard                # Discover each dashboard's panels.        for dash in self._registry.values():            dash._autodiscover()  # 自动发现并注册panel,这个是根据路径来发现的                    # Allow for override modules        if self._conf.get("customization_module", None):            customization_module = self._conf["customization_module"]            bits = customization_module.split('.')            mod_name = bits.pop()            package = '.'.join(bits)            mod = import_module(package)            try:                 before_import_registry = copy.copy(self._registry)                import_module('%s.%s' % (package, mod_name))            except Exception:                self._registry = before_import_registry                if module_has_submodule(mod, mod_name):                    raise                         # Compile the dynamic urlconf.        for dash in self._registry.values():            urlpatterns += patterns('',                    url(r'^%s/' % dash.slug, include(dash._decorated_urls)))                            # Return the three arguments to django.conf.urls.defaults.include        return urlpatterns, self.namespace, self.slug```

默认的,一个HorizonSite中有三个Dashboard: project, admin, setting,在HorizonSite的autodiscover过程中,注册在HorizonSite中:
```(Pdb) pp self._registry{<class 'openstack_dashboard.dashboards.project.dashboard.Project'>: <Dashboard: project>, <class 'openstack_dashboard.dashboards.admin.dashboard.Admin'>: <Dashboard: admin>, <class 'openstack_dashboard.dashboards.settings.dashboard.Settings'>: <Dashboard: settings>}```

然后再对每一个Dashboard进行autodiscover,将Panel注册在Dashboard中,从上面的类图中可以看到Dashboard和HorizonSite都是Registry的子类,它们都具有**注册**的能力:
```(Pdb) pp self._registry.values()[0]._registry{<class 'openstack_dashboard.dashboards.project.overview.panel.Overview'>: <Panel: overview>, <class 'openstack_dashboard.dashboards.project.containers.panel.Containers'>: <Panel: containers>, <class 'openstack_dashboard.dashboards.project.instances.panel.Instances'>: <Panel: instances>, <class 'openstack_dashboard.dashboards.project.network_topology.panel.NetworkTopology'>: <Panel: network_topology>, <class 'openstack_dashboard.dashboards.project.images_and_snapshots.panel.ImagesAndSnapshots'>: <Panel: images_and_snapshots>, <class 'openstack_dashboard.dashboards.project.networks.panel.Networks'>: <Panel: networks>, <class 'openstack_dashboard.dashboards.project.access_and_security.panel.AccessAndSecurity'>: <Panel: access_and_security>, <class 'openstack_dashboard.dashboards.project.firewalls.panel.Firewall'>: <Panel: firewalls>, <class 'openstack_dashboard.dashboards.project.volumes.panel.Volumes'>: <Panel: volumes>, <class 'openstack_dashboard.dashboards.project.routers.panel.Routers'>: <Panel: routers>, <class 'openstack_dashboard.dashboards.project.loadbalancers.panel.LoadBalancer'>: <Panel: loadbalancers>, <class 'openstack_dashboard.dashboards.project.vpn.panel.VPN'>: <Panel: vpn>, <class 'openstack_dashboard.dashboards.project.database_backups.panel.Backups'>: <Panel: database_backups>, <class 'openstack_dashboard.dashboards.project.stacks.panel.Stacks'>: <Panel: stacks>, <class 'openstack_dashboard.dashboards.project.databases.panel.Databases'>: <Panel: databases>}```

在注册每一个Panel的时候,还会将每一个Panel的template路径,保存到loaders模块中:
```(Pdb) pp loaders.panel_template_dirs{'admin/defaults': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/defaults/templates', 'admin/flavors': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/flavors/templates', 'admin/hypervisors': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/hypervisors/templates', 'admin/images': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/images/templates', 'admin/info': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/info/templates', 'admin/instances': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/instances/templates', 'admin/metering': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/metering/templates', 'admin/networks': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/networks/templates', 'admin/overview': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/overview/templates', 'admin/projects': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/projects/templates', 'admin/routers': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/routers/templates', 'admin/users': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/users/templates', 'admin/volumes': '/opt/stack/horizon/openstack_dashboard/dashboards/admin/volumes/templates', 'project/access_and_security': '/opt/stack/horizon/openstack_dashboard/dashboards/project/access_and_security/templates', 'project/containers': '/opt/stack/horizon/openstack_dashboard/dashboards/project/containers/templates', 'project/database_backups': '/opt/stack/horizon/openstack_dashboard/dashboards/project/database_backups/templates', 'project/databases': '/opt/stack/horizon/openstack_dashboard/dashboards/project/databases/templates', 'project/firewalls': '/opt/stack/horizon/openstack_dashboard/dashboards/project/firewalls/templates', 'project/images_and_snapshots': '/opt/stack/horizon/openstack_dashboard/dashboards/project/images_and_snapshots/templates', 'project/instances': '/opt/stack/horizon/openstack_dashboard/dashboards/project/instances/templates', 'project/loadbalancers': '/opt/stack/horizon/openstack_dashboard/dashboards/project/loadbalancers/templates', 'project/network_topology': '/opt/stack/horizon/openstack_dashboard/dashboards/project/network_topology/templates', 'project/networks': '/opt/stack/horizon/openstack_dashboard/dashboards/project/networks/templates', 'project/overview': '/opt/stack/horizon/openstack_dashboard/dashboards/project/overview/templates', 'project/routers': '/opt/stack/horizon/openstack_dashboard/dashboards/project/routers/templates', 'project/stacks': '/opt/stack/horizon/openstack_dashboard/dashboards/project/stacks/templates', 'project/volumes': '/opt/stack/horizon/openstack_dashboard/dashboards/project/volumes/templates', 'project/vpn': '/opt/stack/horizon/openstack_dashboard/dashboards/project/vpn/templates', 'settings/password': '/opt/stack/horizon/openstack_dashboard/dashboards/settings/password/templates', 'settings/user': '/opt/stack/horizon/openstack_dashboard/dashboards/settings/user/templates'}```

接下来就是最关键的urlpatterns,整个horizon所有的路径,并不是写到一个url.py文件中的,而是分散在每一个dashboard, 每一个panel中,有层级的关系。首先找dashboard的url,到每一个dashboard,再找每一个panel的url,所以url的路径关系为: ./dashboard/panel
urlpatterns in site:```(Pdb) pp urlpatterns[<RegexURLPattern user_home ^home/$>, <RegexURLPattern jsi18n ^i18n/js/(?P<packages>\S+?)/$>, <RegexURLPattern set_language ^i18n/setlang/$>, <RegexURLResolver <module 'django.conf.urls.i18n' from '/usr/local/lib/python2.7/dist-packages/django/conf/urls/i18n.pyc'> (None:None) ^i18n/>, <RegexURLPattern qunit_tests ^qunit/$>, <RegexURLResolver <RegexURLResolver list> (admin:admin) ^admin/>, <RegexURLResolver <RegexURLResolver list> (settings:settings) ^settings/>, <RegexURLResolver <RegexURLResolver list> (project:project) ^project/>]```urlpatterns in dashboard```(Pdb) pp urlpatterns[-1].urlconf_name[<RegexURLResolver <RegexURLPattern list> (instances:instances) ^instances/>, <RegexURLResolver <RegexURLPattern list> (routers:routers) ^routers/>, <RegexURLResolver <RegexURLPattern list> (databases:databases) ^databases/>, <RegexURLResolver <RegexURLPattern list> (firewalls:firewalls) ^firewalls/>, <RegexURLResolver <RegexURLPattern list> (containers:containers) ^containers/>, <RegexURLResolver <RegexURLPattern list> (access_and_security:access_and_security) ^access_and_security/>, <RegexURLResolver <RegexURLPattern list> (network_topology:network_topology) ^network_topology/>, <RegexURLResolver <RegexURLPattern list> (database_backups:database_backups) ^database_backups/>, <RegexURLResolver <RegexURLPattern list> (loadbalancers:loadbalancers) ^loadbalancers/>, <RegexURLResolver <RegexURLPattern list> (vpn:vpn) ^vpn/>, <RegexURLResolver <RegexURLPattern list> (volumes:volumes) ^volumes/>, <RegexURLResolver <RegexURLPattern list> (stacks:stacks) ^stacks/>, <RegexURLResolver <RegexURLPattern list> (networks:networks) ^networks/>, <RegexURLResolver <RegexURLPattern list> (images_and_snapshots:images_and_snapshots) ^images_and_snapshots/>, <RegexURLResolver <RegexURLPattern list> (overview:overview) >]```urlpatterns in panel```(Pdb) pp urlpatterns[-1].urlconf_name[-1].urlconf_name[<RegexURLPattern index ^$>, <RegexURLPattern warning ^warning$>]```


0 0
原创粉丝点击