Remove djblets package from murano-dashboard.

Use horizon.tables package instead for drawing the tables (old term is
datagrid).  Now columns attribute is configurable in Service
YAML-markup (it should be consistent with initial data for
table). Last thing to be done is to somehow employ Actions from
horizon.tables (if this can be done at all) - this eliminates need in
custom js-code which adds and deletes table rows on client-side.

Change-Id: I6e6cd41b717d48eafd7e4a5e1fc907d2f1ebf12d
Closes-bug: #1234194
This commit is contained in:
Timur Sufiev 2013-09-26 16:09:24 +04:00
parent b3213e54e9
commit 7955c21359
16 changed files with 191 additions and 316 deletions

View File

@ -1,123 +0,0 @@
# Copyright (c) 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from djblets.datagrid.grids import Column, DataGrid
from models import Node, FakeQuerySet
import floppyforms as forms
import json
import re
from django.contrib.auth.models import SiteProfileNotAvailable
class PK(object):
def __init__(self, value=0):
self.value = value
def next(self):
self.value += 1
return self.value
def current(self):
return self.value
class CheckColumn(Column):
def render_data(self, item):
checked = getattr(item, self.field_name)
checked = 'checked="checked"' if checked else ''
return '<input type="checkbox" %s/>' % (checked,)
class RadioColumn(Column):
def __init__(self, *args, **kwargs):
self.name = kwargs.get('name', 'default')
super(RadioColumn, self).__init__(*args, **kwargs)
def render_data(self, item):
checked = getattr(item, self.field_name)
checked = 'checked="checked"' if checked else ''
name = 'name="%s"' % (self.name,)
return '<input type="radio" %s %s/>' % (name, checked)
class NodeDataGrid(DataGrid):
name = Column('Node', sortable=False)
isSync = CheckColumn('Sync')
isMaster = RadioColumn('Primary')
def __init__(self, request, data):
self.pk = PK()
items = []
if type(data) in (str, unicode):
# BEWARE, UGLY HACK!!! Data should be list there already!
data = json.loads(data)
for kwargs in data:
items.append(Node(**dict(kwargs.items() +
[('id', self.pk.next())])))
super(NodeDataGrid, self).__init__(request, FakeQuerySet(
Node, items=items), optimize_sorts=False)
self.default_sort = []
self.default_columns = ['name', 'isSync', 'isMaster']
# hack
def load_state(self, render_context=None):
if self.request.user.is_authenticated():
def get_profile():
raise SiteProfileNotAvailable
setattr(self.request.user, 'get_profile', get_profile)
super(NodeDataGrid, self).load_state(render_context)
class DataGridWidget(forms.widgets.Input):
template_name = 'data_grid_field.html'
def get_context(self, name, value, attrs=None):
ctx = super(DataGridWidget, self).get_context_data()
ctx['data_grid'] = NodeDataGrid(self.request, data=value)
return ctx
def value_from_datadict(self, data, files, name):
base, match = None, re.match('(.*)_[0-9]+', name)
if match:
base = match.group(1)
if base:
pattern = re.compile(base + '_[0-9]+')
for key in data:
if re.match(pattern, key):
return data[key]
return super(DataGridWidget, self).value_from_datadict(
data, files, name)
class Media:
css = {'all': ('css/datagrid.css',
'muranodashboard/css/datagridfield.css')}
js = ('js/jquery.gravy.js',
'js/datagrid.js',
'muranodashboard/js/datagridfield.js')
class DataGridCompound(forms.MultiWidget):
def __init__(self, attrs=None):
_widgets = (DataGridWidget(),
forms.HiddenInput(attrs={'class': 'gridfield-hidden'}))
super(DataGridCompound, self).__init__(_widgets, attrs)
def update_request(self, request):
self.widgets[0].request = request
def decompress(self, value):
if value != '':
return [json.loads(value), value]
else:
return [None, None]

View File

@ -1,77 +1,3 @@
""" """
Stub file to work around django bug: https://code.djangoproject.com/ticket/7198 Stub file to work around django bug: https://code.djangoproject.com/ticket/7198
""" """
from django.db import models
from django.db.models.query import EmptyQuerySet
import copy
class FakeQuerySet(EmptyQuerySet):
"""Turn a list into a Django QuerySet... kind of."""
def __init__(self, model=None, query=None, using=None, items=[]):
super(FakeQuerySet, self).__init__(model, query, using)
self._result_cache = items
def __getitem__(self, k):
if isinstance(k, slice):
obj = self._clone()
obj._result_cache = super(FakeQuerySet, self).__getitem__(k)
return obj
else:
return super(FakeQuerySet, self).__getitem__(k)
def count(self):
return len(self)
def _clone(self, klass=None, setup=False, **kwargs):
c = super(FakeQuerySet, self)._clone(klass, setup=setup, **kwargs)
c._result_cache = copy.copy(self._result_cache)
return c
def iterator(self):
# This slightly odd construction is because we need an empty generator
# (it raises StopIteration immediately).
yield iter(self._result_cache).next()
def order_by(self, *fields):
obj = self._clone()
cache = obj._result_cache
for field in fields:
reverse = False
if field[0] == '-':
reverse = True
field = field[1:]
cache = sorted(cache, None, lambda item: getattr(item, field),
reverse=reverse)
obj._result_cache = cache
return obj
def distinct(self, *fields):
obj = self._clone()
return obj
def values_list(self, *fields, **kwargs):
obj = self._clone()
cache = []
for item in self._result_cache:
value = []
for field in fields:
value.append(getattr(item, field))
cache.append(tuple(value))
if kwargs.get('flat', False) and len(fields) == 1:
cache = [item[0] for item in cache]
obj._result_cache = cache
return obj
def add(self, item):
self._result_cache.append(item)
def remove(self):
self._result_cache.pop()
class Node(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=20)
isMaster = models.BooleanField(default=False)
isSync = models.BooleanField(default=False)

View File

@ -23,11 +23,14 @@ from muranodashboard.panel import api
from horizon import exceptions, messages from horizon import exceptions, messages
from openstack_dashboard.api import glance from openstack_dashboard.api import glance
from openstack_dashboard.api.nova import novaclient from openstack_dashboard.api.nova import novaclient
from muranodashboard.datagrids import DataGridCompound
from django.template.defaultfilters import pluralize from django.template.defaultfilters import pluralize
import copy import copy
import types import types
import logging import logging
import itertools
import horizon.tables as tables
import floppyforms
from django.template.loader import render_to_string
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -168,24 +171,127 @@ class InstanceCountField(IntegerField):
return interpolate(spec) return interpolate(spec)
class DataGridField(forms.MultiValueField, CustomPropertiesField): class Column(tables.Column):
def __init__(self, *args, **kwargs): template_name = 'common/form-fields/data-grid/input.html'
kwargs['widget'] = DataGridCompound
super(DataGridField, self).__init__(
(forms.CharField(required=False), forms.CharField()),
*args, **kwargs)
def compress(self, data_list): def __init__(self, transform, **kwargs):
return data_list[1] table_name = kwargs.pop('table_name', False)
if hasattr(self, 'template_name'):
def _transform(datum):
context = {'data': getattr(datum, self.name, None),
'row_index': str(datum.id),
'table_name': table_name,
'column_name': self.name}
return render_to_string(self.template_name, context)
_transform.__name__ = transform
transform = _transform
super(Column, self).__init__(transform, **kwargs)
class CheckColumn(Column):
template_name = 'common/form-fields/data-grid/checkbox.html'
class RadioColumn(Column):
template_name = 'common/form-fields/data-grid/radio.html'
def DataTableFactory(name, columns):
class Object(object):
row_name_re = re.compile(r'.*\{0}.*')
def __init__(self, id, **kwargs):
self.id = id
for key, value in kwargs.iteritems():
if isinstance(value, basestring) and \
re.match(self.row_name_re, value):
setattr(self, key, value.format(id))
else:
setattr(self, key, value)
class DataTableBase(tables.DataTable):
def __init__(self, request, data, **kwargs):
super(DataTableBase, self).__init__(
request,
[Object(i, **item) for (i, item) in enumerate(data, 1)],
**kwargs)
class Meta:
template = 'common/form-fields/data-grid/data_table.html'
name = ''
footer = False
attrs = dict((col_id, cls(col_id, verbose_name=col_name, table_name=name))
for (col_id, cls, col_name) in columns)
attrs['Meta'] = Meta
return tables.base.DataTableMetaclass('DataTable', (DataTableBase,), attrs)
class TableWidget(floppyforms.widgets.Input):
template_name = 'common/form-fields/data-grid/table_field.html'
delimiter_re = re.compile('([\w-]*)@@([0-9]*)@@([\w-]*)')
types = {'label': Column,
'radio': RadioColumn,
'checkbox': CheckColumn}
def __init__(self, columns_spec, *args, **kwargs):
columns = []
for spec in columns_spec:
name = spec['column_name']
columns.append((name,
self.types[spec['column_type']],
spec.get('title', None) or name.title()))
self.columns = columns
super(TableWidget, self).__init__(*args, **kwargs)
def get_context(self, name, value, attrs=None):
ctx = super(TableWidget, self).get_context_data()
if value:
ctx['data_table'] = DataTableFactory(name, self.columns)(
self.request, value)
return ctx
def value_from_datadict(self, data, files, name):
def extract_value(row_idx, col_id, col_cls):
if col_cls == CheckColumn:
val = data.get("{0}@@{1}@@{2}".format(name, row_idx, col_id),
False)
return val and val == 'on'
elif col_cls == RadioColumn:
row_id = data.get("{0}@@@@{1}".format(name, col_id), False)
if row_id:
return int(row_id) == row_idx
return False
else:
return data.get("{0}@@{1}@@{2}".format(
name, row_idx, col_id), None)
items = []
main_column, rest_columns = self.columns[0], self.columns[1:]
for row_index in itertools.count(1):
if not extract_value(row_index, *main_column[:2]):
break
item = {}
for column_id, column_instance, column_name in self.columns:
value = extract_value(row_index, column_id, column_instance)
item[column_id] = value
items.append(item)
print items
return items
class Media:
css = {'all': ('muranodashboard/css/tablefield.css',)}
js = ('muranodashboard/js/tablefield.js',)
class TableField(CustomPropertiesField):
def __init__(self, *args, **kwargs):
kwargs['widget'] = TableWidget(kwargs.pop('columns'))
super(TableField, self).__init__(*args, **kwargs)
@with_request @with_request
def update(self, request, **kwargs): def update(self, request, **kwargs):
self.widget.update_request(request) self.widget.request = request
# hack to use json string instead of python dict get by YAQL
data = kwargs['form'].service.cleaned_data
if 'clusterConfiguration' in data:
conf = data['clusterConfiguration']
conf['dcInstances'] = json.dumps(conf['dcInstances'])
class ChoiceField(forms.ChoiceField, CustomPropertiesField): class ChoiceField(forms.ChoiceField, CustomPropertiesField):

View File

@ -27,8 +27,7 @@ log = logging.getLogger(__name__)
class UpdatableFieldsForm(forms.Form): class UpdatableFieldsForm(forms.Form):
def update_fields(self): def update_fields(self):
# Create 'Confirm Password' fields by duplicating password fields
#Create 'Confirm Password' fields by duplicating" Password fields
while True: while True:
index, inserted = 0, False index, inserted = 0, False
for name, field in self.fields.iteritems(): for name, field in self.fields.iteritems():
@ -60,7 +59,7 @@ class ServiceConfigurationForm(UpdatableFieldsForm):
'password': fields.PasswordField, 'password': fields.PasswordField,
'integer': fields.IntegerField, 'integer': fields.IntegerField,
'databaselist': fields.DatabaseListField, 'databaselist': fields.DatabaseListField,
'datagrid': fields.DataGridField, 'table': fields.TableField,
'flavor': fields.FlavorChoiceField, 'flavor': fields.FlavorChoiceField,
'image': fields.ImageChoiceField, 'image': fields.ImageChoiceField,
'azone': fields.AZoneChoiceField, 'azone': fields.AZoneChoiceField,
@ -74,6 +73,7 @@ class ServiceConfigurationForm(UpdatableFieldsForm):
super(ServiceConfigurationForm, self).__init__(*args, **kwargs) super(ServiceConfigurationForm, self).__init__(*args, **kwargs)
self.attribute_mappings = {} self.attribute_mappings = {}
self.insert_fields(self.fields_template) self.insert_fields(self.fields_template)
self.initial = kwargs.get('initial', self.initial)
self.update_fields() self.update_fields()
@staticmethod @staticmethod
@ -203,6 +203,7 @@ class ServiceConfigurationForm(UpdatableFieldsForm):
return 'validators', [prepare_regexp(spec)] return 'validators', [prepare_regexp(spec)]
else: else:
return key, spec return key, spec
for spec in field_specs: for spec in field_specs:
append_field(spec) append_field(spec)

View File

@ -60,11 +60,6 @@ class Wizard(ModalFormMixin, SessionWizardView):
for form in form_list[1:]: for form in form_list[1:]:
form.extract_attributes(attributes) form.extract_attributes(attributes)
# hack to destringify nodes into units
if 'nodes' in attributes:
attributes['units'] = json.loads(attributes['nodes'])
del attributes['nodes']
try: try:
api.service_create(self.request, environment_id, attributes) api.service_create(self.request, environment_id, attributes)
except HTTPForbidden: except HTTPForbidden:

View File

@ -8,13 +8,13 @@ description: >-
unitTemplates: unitTemplates:
- isMaster: true - isMaster: true
isSync: true isSync: true
name: 'node#' name: 'node-#'
- isMaster: false - isMaster: false
isSync: true isSync: true
name: 'node#' name: 'node-#'
- isMaster: false - isMaster: false
isSync: false isSync: false
name: 'node#' name: 'node-#'
forms: forms:
- serviceConfiguration: - serviceConfiguration:
@ -169,8 +169,19 @@ forms:
- unitsConfiguration: - unitsConfiguration:
fields: fields:
- name: nodes - name: nodes
type: datagrid type: table
label: Nodes label: Nodes
attributeNames: units
columns:
- columnName: name
columnType: label
title: Node
- columnName: isSync
columnType: checkbox
title: Sync
- columnName: isMaster
columnType: radio
title: Master
initial: {YAQL: $.clusterConfiguration.dcInstances} initial: {YAQL: $.clusterConfiguration.dcInstances}
description: >- description: >-
Configure cluster instances. Cluster node quantity can be set Configure cluster instances. Cluster node quantity can be set

View File

@ -1,3 +0,0 @@
.left {
overflow: hidden;
}

View File

@ -0,0 +1,10 @@
input[type=radio].data-grid, input[type=checkbox].data-grid {
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
width: auto !important;
}
.data-grid table {
margin-bottom: 5px ! important;;
}

View File

@ -24,11 +24,11 @@ $(function() {
var labels = [], var labels = [],
max = 0, max = 0,
base = ''; base = '';
$('table.datagrid tbody tr td:first-child').each(function(i, td) { $('.data-grid table tbody tr td:first-child').each(function(i, td) {
labels.push(trimLabel($(td).text())); labels.push(trimLabel($(td).text()));
}); });
labels.forEach(function(label) { labels.forEach(function(label) {
var match = /([a-zA-z]+)([0-9]+)/.exec(label), var match = /([a-zA-z]+)-([0-9]+)/.exec(label),
n = +match[2]; n = +match[2];
base = match[1]; base = match[1];
if ( n > max ) if ( n > max )
@ -39,12 +39,12 @@ $(function() {
function getNextLabel() { function getNextLabel() {
var baseMax = getMaxLabel(); var baseMax = getMaxLabel();
return baseMax[0]+(+baseMax[1]+1); return baseMax[0]+'-'+(+baseMax[1]+1);
} }
function getNumOfSync() { function getNumOfSync() {
var checked = 0; var checked = 0;
$('table.datagrid tbody td input:checkbox').each(function(index, cb) { $('.data-grid table tbody td input:checkbox').each(function(index, cb) {
if ( $(cb).attr('checked') ) if ( $(cb).attr('checked') )
checked++; checked++;
}); });
@ -65,7 +65,7 @@ $(function() {
} }
} }
var primary = $('table.datagrid tbody input:radio[checked="checked"]').parents().eq(1); var primary = $('.data-grid table tbody input:radio[checked="checked"]').parents().eq(1);
function validate_primary(event) { function validate_primary(event) {
var radio = $(event.target), var radio = $(event.target),
@ -78,19 +78,25 @@ $(function() {
primary = radio.parents().eq(1); primary = radio.parents().eq(1);
} }
$('table.datagrid tbody td input:checkbox').click(validate_sync); $('.data-grid table tbody td input:checkbox').click(validate_sync);
$('table.datagrid tbody td input:radio').click(validate_primary); $('.data-grid table tbody td input:radio').click(validate_primary);
$('button#node-add').click(function() { $('button#node-add').click(function() {
//debugger; if ( $('.data-grid table tbody tr').length >= MAX_NODES ) {
if ( $('table.datagrid tbody tr').length >= MAX_NODES ) {
alert('Maximum number of nodes ('+MAX_NODES+') already reached.'); alert('Maximum number of nodes ('+MAX_NODES+') already reached.');
return; return;
} }
var lastRow = $('table.datagrid tbody tr:last-child'), var lastRow = $('.data-grid table tbody tr:last-child'),
clone = lastRow.clone(); clone = lastRow.clone(),
clone.toggleClass('even').toggleClass('odd'); nameCell = clone.find('td:first-child'),
clone.find('td:first-child').text(getNextLabel()); hidden = nameCell.find('input:hidden'),
match = /([^@]+)@@([0-9]+)@@(.+)/.exec(hidden.attr('name')),
index = +match[2]+1,
nextLabel = getNextLabel();
nameCell.text(nextLabel);
hidden.val(nextLabel);
hidden.attr('name', match[1]+'@@'+index+'@@'+match[3]);
nameCell.append(hidden);
// toggle of sync and primary buttons of clone // toggle of sync and primary buttons of clone
clone.find('input:checkbox').attr('checked', false); clone.find('input:checkbox').attr('checked', false);
clone.find('input:checkbox').click(validate_sync); clone.find('input:checkbox').click(validate_sync);
@ -100,37 +106,18 @@ $(function() {
}); });
$('button#node-remove').click(function() { $('button#node-remove').click(function() {
if ( $('table.datagrid tbody tr').length <= MIN_NODES ) { if ( $('.data-grid table tbody tr').length <= MIN_NODES ) {
alert('There cannot be less than ' + MIN_NODES + ' nodes'); alert('There cannot be less than ' + MIN_NODES + ' nodes');
return; return;
} }
var labelNum = getMaxLabel(), var labelNum = getMaxLabel(),
label = labelNum.join(''), label = labelNum.join('-'),
rowRef = 'table.datagrid tbody tr:contains('+label+')'; rowRef = '.data-grid table tbody tr:contains('+label+')';
if ( rowRef + ' :radio[checked="checked"]' ) { if ( $(rowRef + ' :radio[checked="checked"]') ) {
label = labelNum[0] + (labelNum[1] - 1); label = labelNum[0] + '-' + (labelNum[1] - 1);
$('table.datagrid tbody tr:contains('+label+') :radio').attr( $('.data-grid table tbody tr:contains('+label+') :radio').attr(
'checked', 'checked'); 'checked', 'checked');
} }
$(rowRef).remove(); $(rowRef).remove();
}); });
$('.modal-footer input.btn-primary').click(function() {
var data = [];
$('table.datagrid tbody tr').each(function(i, tr) {
function getInputVal(td) {
return td.find('input').attr('checked') == 'checked';
}
data.push({
name: trimLabel($(tr).children().eq(0).text()),
isSync: getInputVal($(tr).children().eq(1)),
isMaster: getInputVal($(tr).children().eq(2))
})
});
$('input.gridfield-hidden').val(JSON.stringify(data));
})
// temporarily disable all controls which are bugged
$('table.datagrid th.edit-columns').remove();
$('div.datagrid-titlebox').remove();
}); });

View File

@ -0,0 +1,3 @@
<input type="checkbox" class="data-grid"
{% if data %}checked="checked"{% endif %}
name="{{ table_name }}@@{{ row_index }}@@{{ column_name }}"/>

View File

@ -0,0 +1,2 @@
{% extends 'horizon/common/_data_table.html' %}
{% block table_caption %}{% endblock table_caption %}

View File

@ -0,0 +1,4 @@
{{ data }}
<input type="hidden" class="data-grid"
name="{{ table_name }}@@{{ row_index }}@@{{ column_name }}"
value="{{ data }}"/>

View File

@ -0,0 +1,4 @@
<input type="radio" class="data-grid"
{% if data %}checked="checked"{% endif %}
name="{{ table_name }}@@@@{{ column_name }}"
value="{{ row_index }}"/>

View File

@ -1,3 +1,3 @@
{{ data_grid.render_listview }} <div class="data-grid">{{ data_table.render }}</div>
<button type="button" id="node-add" class="btn btn-small">Add node</button> <button type="button" id="node-add" class="btn btn-small">Add node</button>
<button type="button" id="node-remove" class="btn btn-small">Remove node</button> <button type="button" id="node-remove" class="btn btn-small">Remove node</button>

View File

@ -23,7 +23,6 @@ PIPCMD=""
SERVICE_SRV_NAME="murano-dashboard" SERVICE_SRV_NAME="murano-dashboard"
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"` GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
HORIZON_CONFIGS="/opt/stack/horizon/openstack_dashboard/settings.py,/usr/share/openstack-dashboard/openstack_dashboard/settings.py" HORIZON_CONFIGS="/opt/stack/horizon/openstack_dashboard/settings.py,/usr/share/openstack-dashboard/openstack_dashboard/settings.py"
NON_PIP_PACKAGES_BASE_URL=https://github.com
# Functions # Functions
# Loger function # Loger function
log() log()
@ -117,7 +116,7 @@ HORIZON_CONFIG['exceptions']['recoverable'] = EXTENDED_RECOVERABLE_EXCEPTIONS
HORIZON_CONFIG['exceptions']['not_found'] = EXTENDED_NOT_FOUND_EXCEPTIONS HORIZON_CONFIG['exceptions']['not_found'] = EXTENDED_NOT_FOUND_EXCEPTIONS
HORIZON_CONFIG['exceptions']['unauthorized'] = EXTENDED_UNAUTHORIZED_EXCEPTIONS HORIZON_CONFIG['exceptions']['unauthorized'] = EXTENDED_UNAUTHORIZED_EXCEPTIONS
HORIZON_CONFIG['customization_module'] = 'muranodashboard.panel.overrides' HORIZON_CONFIG['customization_module'] = 'muranodashboard.panel.overrides'
INSTALLED_APPS += ('muranodashboard','djblets','djblets.datagrid','djblets.util','floppyforms',) INSTALLED_APPS += ('muranodashboard','floppyforms',)
MIDDLEWARE_CLASSES += ('muranodashboard.settings.ExceptionMiddleware',) MIDDLEWARE_CLASSES += ('muranodashboard.settings.ExceptionMiddleware',)
LOGGING['formatters'] = {'verbose': {'format': '[%(asctime)s] [%(levelname)s] [pid=%(process)d] %(message)s'}} LOGGING['formatters'] = {'verbose': {'format': '[%(asctime)s] [%(levelname)s] [pid=%(process)d] %(message)s'}}
LOGGING['handlers']['file'] = {'level': 'DEBUG', 'formatter': 'verbose', 'class': 'logging.FileHandler', 'filename': '/var/log/murano-dashboard.log'} LOGGING['handlers']['file'] = {'level': 'DEBUG', 'formatter': 'verbose', 'class': 'logging.FileHandler', 'filename': '/var/log/murano-dashboard.log'}
@ -256,29 +255,6 @@ CLONE_FROM_GIT=$1
log "$PIPCMD install \"$TRBL_FILE\" FAILS, exiting!!!" log "$PIPCMD install \"$TRBL_FILE\" FAILS, exiting!!!"
exit 1 exit 1
fi fi
# NON PIP PACKAGES INSTALL START
for pkg in tsufiev.djblets; do
PACKAGE=${pkg##*.}
OWNER=${pkg%.*}
SUFFIX=master.zip
PACKAGE_OUTARCH_FILENAME=$PACKAGE-$SUFFIX
cd $SERVICE_CONTENT_DIRECTORY/dist && wget $NON_PIP_PACKAGES_BASE_URL/$OWNER/$PACKAGE/archive/$SUFFIX -O $PACKAGE_OUTARCH_FILENAME
if [ $? -ne 0 ];then
log " Can't download \"$PACKAGE_OUTARCH_FILENAME\", exiting!!!"
exit 1
fi
cd $SERVICE_CONTENT_DIRECTORY/dist && unzip $PACKAGE_OUTARCH_FILENAME
if [ $? -ne 0 ];then
log " Can't unzip \"$SERVICE_CONTENT_DIRECTORY/dist/$PACKAGE_OUTARCH_FILENAME\", exiting!!!"
exit 1
fi
cd $SERVICE_CONTENT_DIRECTORY/dist/$PACKAGE-${SUFFIX%.*} && python setup.py install
if [ $? -ne 0 ]; then
log "\"$SERVICE_CONTENT_DIRECTORY/dist/$PACKAGE-${SUFFIX%.*}/setup.py\" python setup FAILS, exiting!"
exit 1
fi
done
# NON PIP PACKAGES INSTALL END
else else
log "$MRN_CND_SPY not found!" log "$MRN_CND_SPY not found!"
fi fi

View File

@ -21,7 +21,6 @@ PREREQ_PKGS="wget make git python-pip python-dev python-mysqldb libxml2-dev libx
SERVICE_SRV_NAME="murano-dashboard" SERVICE_SRV_NAME="murano-dashboard"
GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"` GIT_CLONE_DIR=`echo $SERVICE_CONTENT_DIRECTORY | sed -e "s/$SERVICE_SRV_NAME//"`
HORIZON_CONFIGS="/opt/stack/horizon/openstack_dashboard/settings.py,/usr/share/openstack-dashboard/openstack_dashboard/settings.py" HORIZON_CONFIGS="/opt/stack/horizon/openstack_dashboard/settings.py,/usr/share/openstack-dashboard/openstack_dashboard/settings.py"
NON_PIP_PACKAGES_BASE_URL=https://github.com
# Functions # Functions
# Logger function # Logger function
@ -98,7 +97,7 @@ HORIZON_CONFIG['exceptions']['recoverable'] = EXTENDED_RECOVERABLE_EXCEPTIONS
HORIZON_CONFIG['exceptions']['not_found'] = EXTENDED_NOT_FOUND_EXCEPTIONS HORIZON_CONFIG['exceptions']['not_found'] = EXTENDED_NOT_FOUND_EXCEPTIONS
HORIZON_CONFIG['exceptions']['unauthorized'] = EXTENDED_UNAUTHORIZED_EXCEPTIONS HORIZON_CONFIG['exceptions']['unauthorized'] = EXTENDED_UNAUTHORIZED_EXCEPTIONS
HORIZON_CONFIG['customization_module'] = 'muranodashboard.panel.overrides' HORIZON_CONFIG['customization_module'] = 'muranodashboard.panel.overrides'
INSTALLED_APPS += ('muranodashboard','djblets','djblets.datagrid','djblets.util','floppyforms',) INSTALLED_APPS += ('muranodashboard','floppyforms',)
MIDDLEWARE_CLASSES += ('muranodashboard.settings.ExceptionMiddleware',) MIDDLEWARE_CLASSES += ('muranodashboard.settings.ExceptionMiddleware',)
LOGGING['formatters'] = {'verbose': {'format': '[%(asctime)s] [%(levelname)s] [pid=%(process)d] %(message)s'}} LOGGING['formatters'] = {'verbose': {'format': '[%(asctime)s] [%(levelname)s] [pid=%(process)d] %(message)s'}}
LOGGING['handlers']['file'] = {'level': 'DEBUG', 'formatter': 'verbose', 'class': 'logging.FileHandler', 'filename': '/var/log/murano-dashboard.log'} LOGGING['handlers']['file'] = {'level': 'DEBUG', 'formatter': 'verbose', 'class': 'logging.FileHandler', 'filename': '/var/log/murano-dashboard.log'}
@ -192,29 +191,6 @@ CLONE_FROM_GIT=$1
log "pip install \"$TRBL_FILE\" FAILS, exiting!!!" log "pip install \"$TRBL_FILE\" FAILS, exiting!!!"
exit 1 exit 1
fi fi
# NON PIP PACKAGES INSTALL START
for pkg in tsufiev.djblets; do
PACKAGE=${pkg##*.}
OWNER=${pkg%.*}
SUFFIX=master.zip
PACKAGE_OUTARCH_FILENAME=$PACKAGE-$SUFFIX
cd $SERVICE_CONTENT_DIRECTORY/dist && wget $NON_PIP_PACKAGES_BASE_URL/$OWNER/$PACKAGE/archive/$SUFFIX -O $PACKAGE_OUTARCH_FILENAME
if [ $? -ne 0 ];then
log " Can't download \"$PACKAGE_OUTARCH_FILENAME\", exiting!!!"
exit 1
fi
cd $SERVICE_CONTENT_DIRECTORY/dist && unzip $PACKAGE_OUTARCH_FILENAME
if [ $? -ne 0 ];then
log " Can't unzip \"$SERVICE_CONTENT_DIRECTORY/dist/$PACKAGE_OUTARCH_FILENAME\", exiting!!!"
exit 1
fi
cd $SERVICE_CONTENT_DIRECTORY/dist/$PACKAGE-${SUFFIX%.*} && python setup.py install
if [ $? -ne 0 ]; then
log "\"$SERVICE_CONTENT_DIRECTORY/dist/$PACKAGE-${SUFFIX%.*}/setup.py\" python setup FAILS, exiting!"
exit 1
fi
done
# NON PIP PACKAGES INSTALL END
else else
log "$MRN_CND_SPY not found!" log "$MRN_CND_SPY not found!"
fi fi