在horizon中创建一个dashboard
1.在mydashboard中自动添加一个mypanel的文件
2.mydashboard tree中应该如下
mydashboard
├── dashboard.py
├── dashboard.pyc
├── __init__.py
├── __init__.pyc
├── mypanel
│ ├── __init__.py
│ ├── panel.py
│ ├── templates
│ │ └── mypanel
│ │ └── index.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── static
│ └── mydashboard
│ ├── css
│ │ └── mydashboard.css
│ └── js
│ └── mydashboard.js
└── templates
└── mydashboard
└── base.html
3.dashboard.py有一些代码已经自动生成,定义Mygroup的类,添加一个mypanel
4.定义一个table,在mypanel的目录下,创建tables.py文件
5.定义tabs,在mypanel的目录下,创建tabs.py文件
6 .view.py
7.urls.py
8.template,打开mydashboard/mypanel/templates/mypanel下的index.html
9.enable中显示dashboard,在openstack_dashboard/enabled 下创建_50_mydashboard.py
10.测试
Horizon Policy
Horizon policy的基础是oslo_policy
IRC
Horizon有两个meeting,分别是Horizon Drivers Meeting和Horizon Team Meeting,开会的时间考虑到时差问题。可以参加的会议20:00CST #openstack-meeting-3
[url]http://eavesdrop.openstack.org/[/url]
dashboard代码
dashboard代码分为两部分:openstack_dashboard和horizon。openstack_dashboard中存放了系统用到的所有资源文件。针对于当界面新建的一些实例生成的view,Apache也是映射这部分代码;horizon是系统具体显示的代码实现,定义了一些可以在Django项目中使用的通用库和组件。
django的基础知识
project vs app
app是一个web应用程序,它是实际用来做事的。但是一个project是配置文件和app的集合,相当于一个容器。project和app的关系是多对多。
syncdb
python manage.py syncdb会为该project内的所有app进行数据库初始化,创建表结构,初始化数据,创建索引等。若有app改变了数据库结构,或者是有新的app增加进来,要创建新的表结构,再次运行syncdb,会为这些app进行数据库变更。django怎么识别哪个app是关联了数据库的?要知道自定义的model都是继承自django.db.models.Model这个类的
Django Model API
Django提供了非常丰富的对Model进行操作的接口,增删改查,比如get(),all(),save().filter(),delete(),还有外键xxx_set等
程序的入口点在horizon/openstack_dashboard/urls.py中
然后Horizon这个单利的site对象,开始加载urls,自动大仙并注册dashboard,然后对每一个dashboard,再自动发现并注册panel
js文件
js文件一般是这样开头的(function(){...})(),这是javascrtip立即执行函数的常见写法。为什么要在function外加一个括号呢?这样的写法有什么用?
JavaScript中没有私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中什么了一些变量,可能会被其他人不小心用同名变量给覆盖掉,根据JavaScript作用域链的特性,可以使用这种技术模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,所以(function(){...})()内部定义的变量不会和外部的变量发生冲突,俗称"匿名包裹器"或“命名空间”。
i18n相关的翻译问题不能直接在horizon代码中修改。i18n的翻译是从Zanata中导入的,直接的修改在下一次导入是时候被覆盖
Tox
1.安装 apt-get install python-pip
pip install tox
2.运行测试,每个项目的根目录下有tox.ini文件
tox -e py27
tox第一次运行的时间很长,因为第一次需要创建一个虚拟的环境。
风格测试(Style checks)
集成测试(Integration tests)
集成测试要运行在一个完整的部署环境中,比如一个完整的部署了OpenStack的环境。集成测试专注在系统功能,完整性,以及和真实硬件环境的集成。
打开一个OpenStack服务
更新horizon.conf中的配置文件
参考链接:
[url]https://wiki.openstack.org/wiki/Horizon/Testing/UI[/url]
[url]http://www.linuxidc.com/Linux/2014-09/106053.htm[/url]
[url]http://www.jianshu.com/p/28d669085adc[/url]
1.在mydashboard中自动添加一个mypanel的文件
mkdir openstack_dashboard/dashboards/mydashboard
./run_tests.sh -m startdash mydashboard \
--target openstack_dashboard/dashboards/mydashboard
mkdir openstack_dashboard/dashboards/mydashboard/mypanel
./run_tests.sh -m startpanel mypanel \
--dashboard=openstack_dashboard.dashboards.mydashboard \
--target=openstack_dashboard/dashboards/mydashboard/mypanel
2.mydashboard tree中应该如下
mydashboard
├── dashboard.py
├── dashboard.pyc
├── __init__.py
├── __init__.pyc
├── mypanel
│ ├── __init__.py
│ ├── panel.py
│ ├── templates
│ │ └── mypanel
│ │ └── index.html
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── static
│ └── mydashboard
│ ├── css
│ │ └── mydashboard.css
│ └── js
│ └── mydashboard.js
└── templates
└── mydashboard
└── base.html
3.dashboard.py有一些代码已经自动生成,定义Mygroup的类,添加一个mypanel
from django.utils.translation import ugettext_lazy as _
import horizon
class Mygroup(horizon.PanelGroup):
slug = "mygroup"
name = _("My Group")
panels = ('mypanel',)
class Mydashboard(horizon.Dashboard):
name = _("My Dashboard")
slug = "mydashboard"
panels = (Mygroup,) # Add your panels here.
default_panel = 'mypanel' # Specify the slug of the default panel.
horizon.register(Mydashboard)
4.定义一个table,在mypanel的目录下,创建tables.py文件
from django.utils.translation import ugettext_lazy as _
from horizon import tables
class InstancesTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Name"))
status = tables.Column("status", verbose_name=_("Status"))
zone = tables.Column('availability_zone',
verbose_name=_("Availability Zone"))
image_name = tables.Column('image_name', verbose_name=_("Image Name"))
class Meta:
name = "instances"
verbose_name = _("Instances")
5.定义tabs,在mypanel的目录下,创建tabs.py文件
from django.utils.translation import ugettext_lazy as _
from horizon import exceptions
from horizon import tabs
from openstack_dashboard import api
from openstack_dashboard.dashboards.mydashboard.mypanel import tables
class InstanceTab(tabs.TableTab):
name = _("Instances Tab")
slug = "instances_tab"
table_classes = (tables.InstancesTable,)
template_name = ("horizon/common/_detail_table.html")
preload = False
def has_more_data(self, table):
return self._has_more
def get_instances_data(self):
try:
marker = self.request.GET.get(
tables.InstancesTable._meta.pagination_param, None)
instances, self._has_more = api.nova.server_list(
self.request,
search_opts={'marker': marker, 'paginate': True})
return instances
except Exception:
self._has_more = False
error_message = _('Unable to get instances')
exceptions.handle(self.request, error_message)
return []
class MypanelTabs(tabs.TabGroup):
slug = "mypanel_tabs"
tabs = (InstanceTab,)
sticky = True
6 .view.py
from horizon import tabs
from openstack_dashboard.dashboards.mydashboard.mypanel \
import tabs as mydashboard_tabs
class IndexView(tabs.TabbedTableView):
tab_group_class = mydashboard_tabs.MypanelTabs
template_name = 'mydashboard/mypanel/index.html'
def get_data(self, request, context, *args, **kwargs):
# Add data to the context here...
return context
7.urls.py
from django.conf.urls import patterns
from django.conf.urls import url
from openstack_dashboard.dashboards.mydashboard.mypanel import views
urlpatterns = patterns('',
url(r'^$',
views.IndexView.as_view(), name='index'),
)
8.template,打开mydashboard/mypanel/templates/mypanel下的index.html
{% extends 'base.html' %}
{% load i18n %}
{% block title %}{% trans "My Panel" %}{% endblock %}
{% block page_header %}
{% include "horizon/common/_page_header.html" with title=_("My Panel") %}
{% endblock page_header %}
{% block main %}
<div class="row">
<div class="col-sm-12">
{{ tab_group.render }}
</div>
</div>
{% endblock %}
9.enable中显示dashboard,在openstack_dashboard/enabled 下创建_50_mydashboard.py
# The name of the dashboard to be added to HORIZON['dashboards']. Required.
DASHBOARD = 'mydashboard'
# If set to True, this dashboard will not be added to the settings.
DISABLED = False
# A list of applications to be added to INSTALLED_APPS.
ADD_INSTALLED_APPS = [
'openstack_dashboard.dashboards.mydashboard',
]
10.测试
source .venv/bin/activate
python manage.py runserver 0.0.0.0:2222
Horizon Policy
Horizon policy的基础是oslo_policy
IRC
Horizon有两个meeting,分别是Horizon Drivers Meeting和Horizon Team Meeting,开会的时间考虑到时差问题。可以参加的会议20:00CST #openstack-meeting-3
[url]http://eavesdrop.openstack.org/[/url]
dashboard代码
dashboard代码分为两部分:openstack_dashboard和horizon。openstack_dashboard中存放了系统用到的所有资源文件。针对于当界面新建的一些实例生成的view,Apache也是映射这部分代码;horizon是系统具体显示的代码实现,定义了一些可以在Django项目中使用的通用库和组件。
django的基础知识
project vs app
app是一个web应用程序,它是实际用来做事的。但是一个project是配置文件和app的集合,相当于一个容器。project和app的关系是多对多。
syncdb
python manage.py syncdb会为该project内的所有app进行数据库初始化,创建表结构,初始化数据,创建索引等。若有app改变了数据库结构,或者是有新的app增加进来,要创建新的表结构,再次运行syncdb,会为这些app进行数据库变更。django怎么识别哪个app是关联了数据库的?要知道自定义的model都是继承自django.db.models.Model这个类的
Django Model API
Django提供了非常丰富的对Model进行操作的接口,增删改查,比如get(),all(),save().filter(),delete(),还有外键xxx_set等
程序的入口点在horizon/openstack_dashboard/urls.py中
url(r'', include(horizon.urls))
然后Horizon这个单利的site对象,开始加载urls,自动大仙并注册dashboard,然后对每一个dashboard,再自动发现并注册panel
js文件
js文件一般是这样开头的(function(){...})(),这是javascrtip立即执行函数的常见写法。为什么要在function外加一个括号呢?这样的写法有什么用?
JavaScript中没有私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中什么了一些变量,可能会被其他人不小心用同名变量给覆盖掉,根据JavaScript作用域链的特性,可以使用这种技术模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,所以(function(){...})()内部定义的变量不会和外部的变量发生冲突,俗称"匿名包裹器"或“命名空间”。
naming convention
suffix.module.js--angular module
suffix.spex.js--unit tests
suffix.mock.js–mock objects for test
all other angular prociders should be named to something else
Files will be organized in the order of:
-production: modules + providers
-test runner: modules + providers + mocks + specs
i18n相关的翻译问题不能直接在horizon代码中修改。i18n的翻译是从Zanata中导入的,直接的修改在下一次导入是时候被覆盖
OpenStack中的测试可以分为以下的类型
单元测试(small test/ unit tests):函数级别
nose
1.安装: sudo apt-get install python-nose
2.安装完成后测试一下:nosetests
3.写测试文件,在该目录下执行nosestests test_filename
4.nosetest常用的命令行参数
a) -s,不捕获输出,会让你的程序里面的一些命
令行上的输出显示出来。例如print所输出的内
容。
b) -v,查看nose的运行信息和调试信息。例如会
给出当前正在运行哪个测试。
c) -x,在第一次失败时就停止执行。
Tox
1.安装 apt-get install python-pip
pip install tox
2.运行测试,每个项目的根目录下有tox.ini文件
tox -e py27
tox第一次运行的时间很长,因为第一次需要创建一个虚拟的环境。
风格测试(Style checks)
集成测试(Integration tests)
集成测试要运行在一个完整的部署环境中,比如一个完整的部署了OpenStack的环境。集成测试专注在系统功能,完整性,以及和真实硬件环境的集成。
打开一个OpenStack服务
更新horizon.conf中的配置文件
运行测试 ./run_test.sh --integration
参考链接:
[url]https://wiki.openstack.org/wiki/Horizon/Testing/UI[/url]
[url]http://www.linuxidc.com/Linux/2014-09/106053.htm[/url]
[url]http://www.jianshu.com/p/28d669085adc[/url]