Enhancing OpenStack Horizon with 
AngularJS 
#socalangularjs 
David Lapsley 
@devlaps, david.lapsley@metacloud.com 
October 2, 2014
OpenStack Horizon in Action
Launching an Instance
Admin Overview
Project Overview
Launching an Instance
Launching an Instance
Launching an Instance
Launching an Instance
Launching an Instance
Launching an Instance
OpenStack Clouds 
Architecture and Model
Cloud Computing Model
Virtualization 
Server 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Virtual+ 
Machine 
Hypervisor 
(KVM) 
Physical+Hardware 
(CPU,+Disk,+Network)
OpenStack 
● Open Source Cloud Platform 
o Build public/private clouds 
o Multi-tenant 
o Virtual machines on demand 
o Storage volumes 
● Founded in 2010 by Rackspace and NASA 
● Since then, enormous growth…
Some interesting OpenStack facts …
OpenStack Source Code
OpenStack Source Code
OpenStack Contributors
19,410 People 
144 Countries 
http://www.openstack.org
“Linux for the Cloud”
OpenStack Model 
http://docs.openstack.org/openstack-ops/content/example_architecture.html 
http://docs.openstack.org/training-guides/content/module001-ch004-openstack-architecture.html
OpenStack Projects 
● Compute (Nova) 
● Network (Nova, Neutron) 
● VM Registration (Glance) 
● Identity (Keystone) 
● Object Storage (Swift, …) 
● Block Storage (Cinder) 
● Dashboard (Horizon)
OpenStack Horizon 
Architecture
Horizon Overview 
● Django-based application deployed via 
Apache and WSGI 
● Provides access to OpenStack services 
● Leverages existing technologies 
o Bootstrap, jQuery, Underscore.js, 
AngularJS, D3.js, Rickshaw, LESS CSS 
● Extends Django to enhance extensibility
Django Stack
Horizon Stack
Horizon UI 
Nav entries Column sorting 
Linking 
Filtering Table actions 
Data retrieval RPC 
Row actions 
Multi-select
Customized UI
AngularJS
AngularJS lets you extend HTML vocabulary 
for your application. The resulting environment 
is extraordinarily expressive, readable, and 
quick to develop. 
https://angularjs.org
Develop smaller, lighter web apps that are 
simple to create and easy to test, extend and 
maintain as they grow 
Brad Green, Shyam Seshadri, “AngularJS”
Core concepts 
● Model View Controller framework 
● Client-side templates 
● Data binding 
● Dependency injection
Hello World 
index.html 
<html ng-app> 
<head> 
<script src="angular.js"></script> 
<script src="controllers.js"></script> 
</head> 
<body> 
<div ng-controller='HelloController'> 
<p>{{greeting.text}}, World</p> 
<button ng-click="action()">Alert</button> 
</div> 
</body> 
</html> 
controllers.js 
function HelloController($scope) { 
$scope.greeting = { text: 'Hello' }; 
$scope.action = function() { 
alert('Action!'); 
}; 
} 
AngularJS 
By: Brad Green; Shyam Seshadri 
Publisher: O'Reilly Media, Inc. 
Pub. Date: April 23, 2013
Hello World
Hello World 
Controller 
function HelloController($scope) { 
$scope.greeting = { text: 'Hello' }; 
$scope.action = function() { 
alert('Action!'); 
}; 
} 
Scope 
View 
<html ng-app> 
<head> 
<script src="angular.js"></script> 
<script src="controllers.js"></script> 
</head> 
<body> 
<div ng-controller='HelloController'> 
<p>{{greeting.text}}, World</p> 
<button ng-click="action()">Alert</button> 
</div> 
</body> 
</html> 
{ 
greeting: { text: 'Hello' }; 
action: function; 
}
AngularJS + Horizon
Horizon Stack Extended
Adding a new Panel 
Using current Horizon
Dashboards & Panels 
● Horizon provides a flexible framework for 
creating Dashboards and Panels 
● Panels grouped into PanelGroups 
● PanelGroups into Dashboards
Dashboard App 
● Dashboards created as Django Applications 
● Dashboard modules partitioned into: 
o static 
o templates 
o python modules
Directory Structure 
socalangularjs/ 
__init__.py 
dashboard.py 
templates/ 
socalangularjs/ 
static/ 
socalangularjs/ 
css/ 
img/ 
js/
_10_socalangularjs.py 
DASHBOARD = 'socalangularjs' 
DISABLED = False 
ADD_INSTALLED_APPS = [ 
'openstack_dashboard.dashboards.socalangularjs', 
]
dashboard.py 
class BasePanelGroup(horizon.PanelGroup): 
slug = "overview" 
name = _("Overview") 
panels = ("hypervisors",) 
class OpenstackOC(horizon.Dashboard): 
name = _(”SoCalAngularJS") 
slug = ”SoCalAngularJS" 
panels = (BasePanelGroup,) 
default_panel = "hypervisors" 
roles = ("admin",) 
horizon.register(SoCalAngularJS)
Dashboard 
Dashboard 
PanelGroup
Panel 
● Panels are created as Python Modules 
● Panel modules partitioned into: 
o static/ 
o templates/ 
o python modules: 
 urls.py, views.py, panel.py 
 tables.py, forms.py, tabs.py, tests.py
Directory Structure 
socalangularjs/ 
hypervisors/ 
__init__.py 
panel.py 
urls.py 
views.py 
tests.py 
tables.py 
templates/ 
socalangularjs/ 
hypervisors/ 
index.html 
static/ 
socalangularjs/ 
hypervisors/
panel.py 
from django.utils.translation import ugettext_lazy as _ 
import horizon 
from openstack_dashboard.dashboards.socalangularjs import dashboard 
class Hypervisors(horizon.Panel): 
name = _("Hypervisors") 
slug = 'hypervisors' 
dashboard.socalangularjs.register(Hypervisors)
Dashboard 
Dashboard 
PanelGroup 
Panel
View Module 
● View module ties together everything: 
o Tables, Templates, API Calls 
● Horizon base views: 
o APIView, LoginView, MultiTableView, 
DataTableView, MixedDataTableView, 
TabView, TabbedTableView, WorkflowView
views.py 
from horizon import tables 
class HypervisorsIndexView(tables.DataTableView): 
table_class = hv_tables.AdminHypervisorsTable 
template_name = ’socalangularjs/hypervisors/index.html’ 
def get_data(self): 
hypervisors = [] 
states = {} 
hypervisors = api.nova.hypervisor_list(self.request) 
… 
return hypervisors
Table Module 
● Table classes provide framework for tables: 
o consistent look and feel 
o configurable table_actions and row_actions 
o select/multi-select column 
o sorting 
o pagination 
● Functionality is split server- and client-side
tables.py 
class EnableAction(tables.BatchAction): 
… 
class DisableAction(tables.BatchAction): 
name = 'disable' 
classes = ('btn-danger',) 
def allowed(self, request, hv): 
return hv.service.get('status') == 'enabled' 
def action(self, request, obj_id): 
hv = api.nova.hypervisor_get(request, obj_id) 
host = getattr(hv, hv.NAME_ATTR) 
return api.nova.service_disable(request, host, 'nova-compute') 
def search_link(x): 
return '/admin/instances?q={0}'.format(x.hypervisor_hostname)
tables.py 
class AdminHypervisorsTable(tables.DataTable): 
hypervisor_hostname = tables.Column( 
'hypervisor_hostname', verbose_name=_('Hostname')) 
state = tables.Column( 
lambda hyp: hyp.service.get('state', _('UNKNOWN')).title(), 
verbose_name=_('State')) 
running_vms = tables.Column( 
'running_vms', link=search_link, verbose_name=_('Instances')) 
... 
class Meta: 
name = 'hypervisors' 
verbose_name = _('Hypervisors') 
row_actions = (EnableAction, DisableAction)
Template 
● Standard Django template format 
● Typically leverage base horizon templates 
(e.g. base.html)
index.html 
{% extends 'base.html' %} 
{% load i18n horizon humanize sizeformat %} 
{% block title %}{% trans 'Hypervisors' %}{% endblock %} 
{% block page_header %} 
{% include 'horizon/common/_page_header.html' with title=_('All 
Hypervisors') %} 
{% endblock page_header %} 
{% block main %} 
<div class="quota-dynamic"> 
<h3>{% trans "Hypervisor Summary" %}</h3> 
<div class="d3_quota_bar"> 
<div class="d3_pie_chart" …></div> 
</div> 
… 
</div> 
<div class="row-fluid"> 
<div class="col-sm-12"> 
{{ tab_group.render }} 
</div> 
</div> 
{% endblock %}
URLs Modules 
● Provides URL to View mappings
urls.py 
from django.conf.urls import patterns 
from django.conf.urls import url 
from openstack_dashboard.dashboards.socalangularjs.hypervisors import views 
urlpatterns = patterns( 
'openstack_dashboard.dashboards.socalangularjs.hypervisors.views' 
url(r'^$', views.IndexView.as_view(), name='index'), 
)
Completed Dashboard 
Nav entries 
Column sorting 
Panel rendering 
Linking 
Data retrieval RPC
Adding a new Panel 
with AngularJS
Directory Structure 
socalangularjs/ 
hypervisors/ 
__init__.py 
panel.py 
urls.py 
views.py 
tables.py 
tests.py 
templates/socalangularjs/hypervisors/ 
index.html 
static/socalangularjs/hypervisors/js/ 
hypervisors-controller.js 
rest/nova/ 
__init__.py 
hypervisor.py 
instance.py
REST Resource 
● Provides the source of data via RESTful API 
● Resource includes/provides: 
o entity data/state 
o configurable table_actions and row_actions 
o sorting 
o pagination 
o CRUD operations
hypervisors.py 
class HypervisorResource(resource.BaseNovaResource): 
pk = fields.CharField(attribute="pk", 
_("Primary Key"), 
hidden=True) 
hypervisor_hostname = fields.CharField(attribute='hypervisor_hostname', 
sortable=True, 
searchable=True) 
… 
actions = fields.ActionsField(attribute='actions', 
actions=[HypervisorViewLiveStats, 
HypervisorEnableAction, 
HypervisorDisableAction], 
title=_("Actions"), 
sortable=True) 
class Meta: 
authorization = auth.RestAuthorization() 
list_allowed_methods = ['get'] 
resource_name = '^hypervisor' 
field_order = ['pk', 'hypervisor_hostname', 'hypervisor_type', 'vcpus', 
'vcpus_used', 'memory_mb', 'memory_mb_used', 
'running_vms', 'state', 'status', 'actions']
Controller 
● Controls view logic
hypervisor-controller.js 
horizonApp.controller('TableController', 
function($scope, $http) { 
$scope.headers = headers; 
$scope.title = title; 
$http.get('/rest/api/v1/nova/instance/').success( 
function(data, status, headers, config) { 
$scope.instances = transform(data.objects); 
}); 
}); 
horizonApp.controller('ActionDropdownController', 
function($scope) { 
$scope.status = { 
isopen: false 
}; 
$scope.toggleDropdown = function($event) { 
$event.preventDefault(); 
$event.stopPropagation(); 
$scope.status.isopen = !$scope.status.isopen; 
}; 
$scope.action = function(action, id) { 
// Perform action. 
}; 
… 
});
View 
● In AngularJS, view is defined in the HTML 
template
index.html 
{% extends 'base.html' %} 
{% load i18n horizon humanize sizeformat %} 
{% block title %}{% trans 'Hypervisors' %}{% endblock %} 
{% block page_header %} 
{% include 'horizon/common/_page_header.html' with title=_('All 
Hypervisors') %} 
{% endblock page_header %} 
{% block main %}
index.html 
<div ng-controller="TableController"> 
<table class="..."> 
<thead> 
<tr class="..."> 
<th class="..."> 
<h3 class="...">{$ title $}</h3> 
</th> 
</tr> 
<tr class="..."> 
<th class="..." ng-repeat='header in headers'> 
<div class="...">{$ header.name $}</div> 
</th> 
</tr> 
</thead>
index.html 
<tr ng-repeat="instance in instances"> 
<td ng-repeat="datum in instance.data">{$ datum $}</td> 
<td class="..."> 
<div ng-controller="ActionDropdownController"> 
<div class="..." dropdown> 
<button class="..." 
ng-click="action(instance.actions[0], instance.name)"> 
{$ instance.actions[0].verbose_name $} 
</button> 
... 
<div class="..."> 
<li class="..." ng-repeat="action in instance.actions"> 
<a href="#" class="..." 
ng-click="$parent.action(action,parent.instance.name)"> 
{$ action.verbose_name $} 
</a> 
</li> 
</ul> 
</div> 
</td> 
</tr> 
</table>
Advantages 
● Clean split between server and client side 
● Significantly cleaner, terser, easier to 
understand client-side code 
● Significant easier to improve UX 
● Client- and server-side code can be 
developed and tested independently 
● Faster feature velocity
AngularJS + Horizon in Production
Client-side Rendering 
“Full” dataset search 
“Full” pagination Cache up to 1K records client-side
Real-time Data 
Updates every 5s 
Increased platform visibility 
Every node instrumented
Historical Metrics 
Up to 1 year of data 
Convenient access 
Increased platform visibility Every node instrumented
OpenStack Horizon 
Contributing
Devstack and Contributing 
● Devstack: 
o “A documented shell script to build complete 
OpenStack development environments.” 
o http://devstack.org 
● Contributing to Horizon: 
– http://docs.openstack.org/developer/horizo 
n/contributing.html
References 
• IRC channels (freenode.net) 
– #openstack-dev 
– #openstack-horizon 
– #openstack-meeting 
• Web: 
– http://docs.openstack.org/developer/horizon/ 
– https://launchpad.net/horizon 
– http://devstack.org 
– https://github.com/openstack 
– https://github.com/openstack/horizon 
– http://docs.openstack.org/developer/horizon/ 
– http://docs.openstack.org/developer/horizon/topics/settings.html 
– https://wiki.openstack.org/wiki/Gerrit_Workflow
References 
● Web: 
o http://www.stackalytics.com 
o http://activity.openstack.org/dash/browser/ 
o http://gabrielhurley.github.io/slides/openstac 
k/building_on_horizon/ 
o http://www.solinea.com/blog/openstack-grizzly- 
architecture-revisited
Thank You 
David Lapsley 
@devlaps, david.lapsley@metacloud.com
If this sounds interesting… 
http://jobs.metacloud.com 
We are hiring!
20141002 delapsley-socalangularjs-final

20141002 delapsley-socalangularjs-final

  • 1.
    Enhancing OpenStack Horizonwith AngularJS #socalangularjs David Lapsley @devlaps, david.lapsley@metacloud.com October 2, 2014
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
    Virtualization Server Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Virtual+ Machine Hypervisor (KVM) Physical+Hardware (CPU,+Disk,+Network)
  • 15.
    OpenStack ● OpenSource Cloud Platform o Build public/private clouds o Multi-tenant o Virtual machines on demand o Storage volumes ● Founded in 2010 by Rackspace and NASA ● Since then, enormous growth…
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
    19,410 People 144Countries http://www.openstack.org
  • 21.
  • 22.
    OpenStack Model http://docs.openstack.org/openstack-ops/content/example_architecture.html http://docs.openstack.org/training-guides/content/module001-ch004-openstack-architecture.html
  • 23.
    OpenStack Projects ●Compute (Nova) ● Network (Nova, Neutron) ● VM Registration (Glance) ● Identity (Keystone) ● Object Storage (Swift, …) ● Block Storage (Cinder) ● Dashboard (Horizon)
  • 24.
  • 25.
    Horizon Overview ●Django-based application deployed via Apache and WSGI ● Provides access to OpenStack services ● Leverages existing technologies o Bootstrap, jQuery, Underscore.js, AngularJS, D3.js, Rickshaw, LESS CSS ● Extends Django to enhance extensibility
  • 26.
  • 27.
  • 28.
    Horizon UI Naventries Column sorting Linking Filtering Table actions Data retrieval RPC Row actions Multi-select
  • 29.
  • 30.
  • 31.
    AngularJS lets youextend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop. https://angularjs.org
  • 32.
    Develop smaller, lighterweb apps that are simple to create and easy to test, extend and maintain as they grow Brad Green, Shyam Seshadri, “AngularJS”
  • 33.
    Core concepts ●Model View Controller framework ● Client-side templates ● Data binding ● Dependency injection
  • 34.
    Hello World index.html <html ng-app> <head> <script src="angular.js"></script> <script src="controllers.js"></script> </head> <body> <div ng-controller='HelloController'> <p>{{greeting.text}}, World</p> <button ng-click="action()">Alert</button> </div> </body> </html> controllers.js function HelloController($scope) { $scope.greeting = { text: 'Hello' }; $scope.action = function() { alert('Action!'); }; } AngularJS By: Brad Green; Shyam Seshadri Publisher: O'Reilly Media, Inc. Pub. Date: April 23, 2013
  • 35.
  • 36.
    Hello World Controller function HelloController($scope) { $scope.greeting = { text: 'Hello' }; $scope.action = function() { alert('Action!'); }; } Scope View <html ng-app> <head> <script src="angular.js"></script> <script src="controllers.js"></script> </head> <body> <div ng-controller='HelloController'> <p>{{greeting.text}}, World</p> <button ng-click="action()">Alert</button> </div> </body> </html> { greeting: { text: 'Hello' }; action: function; }
  • 37.
  • 38.
  • 39.
    Adding a newPanel Using current Horizon
  • 40.
    Dashboards & Panels ● Horizon provides a flexible framework for creating Dashboards and Panels ● Panels grouped into PanelGroups ● PanelGroups into Dashboards
  • 41.
    Dashboard App ●Dashboards created as Django Applications ● Dashboard modules partitioned into: o static o templates o python modules
  • 42.
    Directory Structure socalangularjs/ __init__.py dashboard.py templates/ socalangularjs/ static/ socalangularjs/ css/ img/ js/
  • 43.
    _10_socalangularjs.py DASHBOARD ='socalangularjs' DISABLED = False ADD_INSTALLED_APPS = [ 'openstack_dashboard.dashboards.socalangularjs', ]
  • 44.
    dashboard.py class BasePanelGroup(horizon.PanelGroup): slug = "overview" name = _("Overview") panels = ("hypervisors",) class OpenstackOC(horizon.Dashboard): name = _(”SoCalAngularJS") slug = ”SoCalAngularJS" panels = (BasePanelGroup,) default_panel = "hypervisors" roles = ("admin",) horizon.register(SoCalAngularJS)
  • 45.
  • 46.
    Panel ● Panelsare created as Python Modules ● Panel modules partitioned into: o static/ o templates/ o python modules:  urls.py, views.py, panel.py  tables.py, forms.py, tabs.py, tests.py
  • 47.
    Directory Structure socalangularjs/ hypervisors/ __init__.py panel.py urls.py views.py tests.py tables.py templates/ socalangularjs/ hypervisors/ index.html static/ socalangularjs/ hypervisors/
  • 48.
    panel.py from django.utils.translationimport ugettext_lazy as _ import horizon from openstack_dashboard.dashboards.socalangularjs import dashboard class Hypervisors(horizon.Panel): name = _("Hypervisors") slug = 'hypervisors' dashboard.socalangularjs.register(Hypervisors)
  • 49.
  • 50.
    View Module ●View module ties together everything: o Tables, Templates, API Calls ● Horizon base views: o APIView, LoginView, MultiTableView, DataTableView, MixedDataTableView, TabView, TabbedTableView, WorkflowView
  • 51.
    views.py from horizonimport tables class HypervisorsIndexView(tables.DataTableView): table_class = hv_tables.AdminHypervisorsTable template_name = ’socalangularjs/hypervisors/index.html’ def get_data(self): hypervisors = [] states = {} hypervisors = api.nova.hypervisor_list(self.request) … return hypervisors
  • 52.
    Table Module ●Table classes provide framework for tables: o consistent look and feel o configurable table_actions and row_actions o select/multi-select column o sorting o pagination ● Functionality is split server- and client-side
  • 53.
    tables.py class EnableAction(tables.BatchAction): … class DisableAction(tables.BatchAction): name = 'disable' classes = ('btn-danger',) def allowed(self, request, hv): return hv.service.get('status') == 'enabled' def action(self, request, obj_id): hv = api.nova.hypervisor_get(request, obj_id) host = getattr(hv, hv.NAME_ATTR) return api.nova.service_disable(request, host, 'nova-compute') def search_link(x): return '/admin/instances?q={0}'.format(x.hypervisor_hostname)
  • 54.
    tables.py class AdminHypervisorsTable(tables.DataTable): hypervisor_hostname = tables.Column( 'hypervisor_hostname', verbose_name=_('Hostname')) state = tables.Column( lambda hyp: hyp.service.get('state', _('UNKNOWN')).title(), verbose_name=_('State')) running_vms = tables.Column( 'running_vms', link=search_link, verbose_name=_('Instances')) ... class Meta: name = 'hypervisors' verbose_name = _('Hypervisors') row_actions = (EnableAction, DisableAction)
  • 55.
    Template ● StandardDjango template format ● Typically leverage base horizon templates (e.g. base.html)
  • 56.
    index.html {% extends'base.html' %} {% load i18n horizon humanize sizeformat %} {% block title %}{% trans 'Hypervisors' %}{% endblock %} {% block page_header %} {% include 'horizon/common/_page_header.html' with title=_('All Hypervisors') %} {% endblock page_header %} {% block main %} <div class="quota-dynamic"> <h3>{% trans "Hypervisor Summary" %}</h3> <div class="d3_quota_bar"> <div class="d3_pie_chart" …></div> </div> … </div> <div class="row-fluid"> <div class="col-sm-12"> {{ tab_group.render }} </div> </div> {% endblock %}
  • 57.
    URLs Modules ●Provides URL to View mappings
  • 58.
    urls.py from django.conf.urlsimport patterns from django.conf.urls import url from openstack_dashboard.dashboards.socalangularjs.hypervisors import views urlpatterns = patterns( 'openstack_dashboard.dashboards.socalangularjs.hypervisors.views' url(r'^$', views.IndexView.as_view(), name='index'), )
  • 59.
    Completed Dashboard Naventries Column sorting Panel rendering Linking Data retrieval RPC
  • 60.
    Adding a newPanel with AngularJS
  • 61.
    Directory Structure socalangularjs/ hypervisors/ __init__.py panel.py urls.py views.py tables.py tests.py templates/socalangularjs/hypervisors/ index.html static/socalangularjs/hypervisors/js/ hypervisors-controller.js rest/nova/ __init__.py hypervisor.py instance.py
  • 62.
    REST Resource ●Provides the source of data via RESTful API ● Resource includes/provides: o entity data/state o configurable table_actions and row_actions o sorting o pagination o CRUD operations
  • 63.
    hypervisors.py class HypervisorResource(resource.BaseNovaResource): pk = fields.CharField(attribute="pk", _("Primary Key"), hidden=True) hypervisor_hostname = fields.CharField(attribute='hypervisor_hostname', sortable=True, searchable=True) … actions = fields.ActionsField(attribute='actions', actions=[HypervisorViewLiveStats, HypervisorEnableAction, HypervisorDisableAction], title=_("Actions"), sortable=True) class Meta: authorization = auth.RestAuthorization() list_allowed_methods = ['get'] resource_name = '^hypervisor' field_order = ['pk', 'hypervisor_hostname', 'hypervisor_type', 'vcpus', 'vcpus_used', 'memory_mb', 'memory_mb_used', 'running_vms', 'state', 'status', 'actions']
  • 64.
  • 65.
    hypervisor-controller.js horizonApp.controller('TableController', function($scope,$http) { $scope.headers = headers; $scope.title = title; $http.get('/rest/api/v1/nova/instance/').success( function(data, status, headers, config) { $scope.instances = transform(data.objects); }); }); horizonApp.controller('ActionDropdownController', function($scope) { $scope.status = { isopen: false }; $scope.toggleDropdown = function($event) { $event.preventDefault(); $event.stopPropagation(); $scope.status.isopen = !$scope.status.isopen; }; $scope.action = function(action, id) { // Perform action. }; … });
  • 66.
    View ● InAngularJS, view is defined in the HTML template
  • 67.
    index.html {% extends'base.html' %} {% load i18n horizon humanize sizeformat %} {% block title %}{% trans 'Hypervisors' %}{% endblock %} {% block page_header %} {% include 'horizon/common/_page_header.html' with title=_('All Hypervisors') %} {% endblock page_header %} {% block main %}
  • 68.
    index.html <div ng-controller="TableController"> <table class="..."> <thead> <tr class="..."> <th class="..."> <h3 class="...">{$ title $}</h3> </th> </tr> <tr class="..."> <th class="..." ng-repeat='header in headers'> <div class="...">{$ header.name $}</div> </th> </tr> </thead>
  • 69.
    index.html <tr ng-repeat="instancein instances"> <td ng-repeat="datum in instance.data">{$ datum $}</td> <td class="..."> <div ng-controller="ActionDropdownController"> <div class="..." dropdown> <button class="..." ng-click="action(instance.actions[0], instance.name)"> {$ instance.actions[0].verbose_name $} </button> ... <div class="..."> <li class="..." ng-repeat="action in instance.actions"> <a href="#" class="..." ng-click="$parent.action(action,parent.instance.name)"> {$ action.verbose_name $} </a> </li> </ul> </div> </td> </tr> </table>
  • 70.
    Advantages ● Cleansplit between server and client side ● Significantly cleaner, terser, easier to understand client-side code ● Significant easier to improve UX ● Client- and server-side code can be developed and tested independently ● Faster feature velocity
  • 71.
    AngularJS + Horizonin Production
  • 72.
    Client-side Rendering “Full”dataset search “Full” pagination Cache up to 1K records client-side
  • 73.
    Real-time Data Updatesevery 5s Increased platform visibility Every node instrumented
  • 74.
    Historical Metrics Upto 1 year of data Convenient access Increased platform visibility Every node instrumented
  • 75.
  • 76.
    Devstack and Contributing ● Devstack: o “A documented shell script to build complete OpenStack development environments.” o http://devstack.org ● Contributing to Horizon: – http://docs.openstack.org/developer/horizo n/contributing.html
  • 77.
    References • IRCchannels (freenode.net) – #openstack-dev – #openstack-horizon – #openstack-meeting • Web: – http://docs.openstack.org/developer/horizon/ – https://launchpad.net/horizon – http://devstack.org – https://github.com/openstack – https://github.com/openstack/horizon – http://docs.openstack.org/developer/horizon/ – http://docs.openstack.org/developer/horizon/topics/settings.html – https://wiki.openstack.org/wiki/Gerrit_Workflow
  • 78.
    References ● Web: o http://www.stackalytics.com o http://activity.openstack.org/dash/browser/ o http://gabrielhurley.github.io/slides/openstac k/building_on_horizon/ o http://www.solinea.com/blog/openstack-grizzly- architecture-revisited
  • 79.
    Thank You DavidLapsley @devlaps, david.lapsley@metacloud.com
  • 80.
    If this soundsinteresting… http://jobs.metacloud.com We are hiring!

Editor's Notes

  • #2 Intro Horizon in Action Overview of how Horizon works with other services in OpenStack Horizon architecture Horizon UI structure, features Interesting design patterns (work through an example) Pluggable settings Customization Advanced features How to contribute
  • #23 LOGICAL MODEL * Dashboard ("Horizon") provides a web front end to the other OpenStack services * Compute ("Nova") Create, delete, and manipulate virtual machines. Stores and retrieves virtual disks ("images") and associated metadata in Image ("Glance") * Network ("Quantum") provides virtual networking for Compute. * Block Storage ("Cinder") provides storage volumes for Compute. * Image ("Glance") can store the actual virtual disk files in the Object Store("Swift") All the services authenticate with Identity ("Keystone") NODE TYPES: Controller: Responsible for running the management software services needed for the OpenStack environment to function. API services, MysQL Compute Compute nodes run the virtual machine instances in OpenStack. Run the bare minimum of services needed to facilitate these instances. Storage Store all the data required for the environment, including disk images in the Image Service library, and the persistent storage volumes created by the Block Storage service. Network Responsible for doing all the virtual networking needed for people to create public or private networks and uplink their virtual machines into external networks. Utility Basic system administration functions needed to get the environment up and running and to maintain Provisioning, configuration management, monitoring Compute Most complicated and distributed component of OpenStack. Turn end user API requests into running virtual machines. Interacts with many other OpenStack services: Keystone for authentication, Glance for images and Horizon for web interface. Image Store Image discovery, image retrieval and image storage. Accepts API requests for images (or image metadata) from end users or Nova components and can store its disk files in the object storage service Object Store Accepts files to upload, modifications to metadata or container creation. Serves files or container listings to web browsers. Identity Keystone provides a single point of integration for OpenStack Policy, Catalog, Token and Authentication keystone handles API requests as well as providing configurable catalog, policy, token and identity services. Network Quantum provides "network connectivity as a service" between interface devices managed by other OpenStack services (most likely Nova). Allows users to create their own networks and then attach interfaces to them. Interacts mainly Nova, where it will provide networks and connectivity for its instances. Block Storage Cinder implements persistent block storage functionality Allows for Manipulation of volumes, volume types, and volume snapshots. Mainly interacts with Nova, providing volumes for its instances. NODE TYPES: Controller Responsible for running the management software services needed for the OpenStack environment to function. API services Run a number of services in a highly available fashion Supply highly available "infrastructure" services, such as MySQL Compute Compute nodes run the virtual machine instances in OpenStack. Run the bare minimum of services needed to facilitate these instances. Storage Store all the data required for the environment, including disk images in the Image Service library, and the persistent storage volumes created by the Block Storage service. Network Responsible for doing all the virtual networking needed for people to create public or private networks and uplink their virtual machines into external networks. Utility Used by internal administration staff only to provide a number of basic system administration functions needed to get the environment up and running and to maintain the hardware, OS, and software on which it runs. provisioning, configuration management, monitoring
  • #28 Add client-side…
  • #32 Open source web framework Maintained by Google and community Single Page Applications Client-side Model-View-Controller pattern Been around since 2010
  • #35  ----- Meeting Notes (8/20/14 20:59) ----- 30 mins
  • #45  ----- Meeting Notes (8/20/14 20:59) ----- 30 mins
  • #49  ----- Meeting Notes (8/20/14 20:59) ----- 30 mins
  • #73 Server provides data over RESTful API – json data Client responsible for rendering and presenting Much more interactive, client can now take immediate action on data it knows about instead of round tripping to server Faster feature velocity, server and client can be developed in parallel Simpler code
  • #74 Instrument each node with livestastd Controllers and Hypervisors Pull information about processes, network, disk, cpu Updates every 5 seconds Using the same client-side rendering pattern as before Aggregating real-time data Greatly increases visibility into platform..
  • #75 Our customers also wanted to see more historical data. We instrumented all of our nodes and push data into Graphite Very high performance and flexiblie time series tool Evolution of RRD Tool Graphite provides data over RESTful API, so we just pull that data and use it to populate these charts.. Easy access for the user (simply click on controller or hypervisor row and chart will drop down) Data from 1 hour range to 1 year range..