Added logs

Added "restrained" info to services pool list
This commit is contained in:
Adolfo Gómez 2013-12-17 09:28:36 +00:00
parent bf3dd99b63
commit edc03f4e7e
7 changed files with 105 additions and 24 deletions

View File

@ -40,7 +40,7 @@ from uds.core.util.State import State
from uds.core.util import log
from uds.REST.model import ModelHandler
from uds.REST import NotFound
from user_services import AssignedService, CachedService, Groups, Transports
from user_services import AssignedService, CachedService, Groups, Transports, Publications
import logging
@ -53,6 +53,7 @@ class ServicesPool(ModelHandler):
'cache': CachedService,
'groups': Groups,
'transports': Transports,
'publications': Publications,
}
save_fields = ['name', 'comments', 'service', 'osmanager', 'initial_srvs', 'cache_l1_srvs', 'cache_l2_srvs', 'max_srvs']
@ -78,6 +79,7 @@ class ServicesPool(ModelHandler):
'cache_l2_srvs' : item.cache_l2_srvs,
'max_srvs' : item.max_srvs,
'user_services_count': item.userServices.count(),
'restrained': item.isRestrained(),
}
if item.osmanager is not None:
@ -91,3 +93,8 @@ class ServicesPool(ModelHandler):
return self.addDefaultFields(['name', 'comments'])
except:
raise NotFound('type not found')
# Logs
def getLogs(self, item):
return log.getLogs(item)

View File

@ -172,4 +172,29 @@ class Transports(DetailHandler):
{ 'trans_type': {'title': _('Type') } },
{ 'comments': {'title': _('Comments')}},
]
class Publications(DetailHandler):
def getItems(self, parent, item):
return [{
'id': i.id,
'revision': i.revision,
'publish_date': i.publish_date,
'state': i.state,
'reason': State.isErrored(i.state) and i.getInstance().reasonOfError() or '',
'state_date': i.state_date,
} for i in parent.publications.all()]
def getTitle(self, parent):
return _('Publications')
def getFields(self, parent):
return [
{ 'revision': {'title': _('Revision'), 'type': 'numeric', 'width': '6em' } },
{ 'publish_date': { 'title': _('Publish date'), 'type': 'datetime' } },
{ 'state': { 'title': _('State'), 'type': 'dict', 'dict': State.dictionary() } },
{ 'reason': {'title': _('Reason')}},
]
def getRowStyle(self, parent):
return { 'field': 'state', 'prefix': 'row-state-' }

View File

@ -302,17 +302,17 @@ class UserServiceManager(object):
UserServiceOpChecker.makeUnique(cache, ci, state)
@transaction.atomic
def cancel(self, uService):
'''
Cancels a user service creation
@return: the Uservice canceling
'''
uService = UserService.objects.select_for_update().get(id=uService.id)
logger.debug('Canceling uService {0} creation'.format(uService))
if uService.isPreparing() == False:
logger.INFO(_('Cancel requested for a non running operation, doing remove instead'))
return self.remove(uService)
with transaction.atomic():
uService = UserService.objects.select_for_update().get(id=uService.id)
logger.debug('Canceling uService {0} creation'.format(uService))
if uService.isPreparing() == False:
logger.INFO(_('Cancel requested for a non running operation, doing remove instead'))
return self.remove(uService)
ui = uService.getInstance()
# We simply notify service that it should cancel operation
@ -323,16 +323,16 @@ class UserServiceManager(object):
return uService
@transaction.atomic
def remove(self, uService):
'''
Removes a uService element
@return: the uService removed (marked for removal)
'''
uService = UserService.objects.select_for_update().get(id=uService.id)
logger.debug('Removing uService {0}'.format(uService))
if uService.isUsable() == False and State.isRemovable(uService.state) == False:
raise OperationException(_('Can\'t remove a non active element'))
with transaction.atomic():
uService = UserService.objects.select_for_update().get(id=uService.id)
logger.debug('Removing uService {0}'.format(uService))
if uService.isUsable() == False and State.isRemovable(uService.state) == False:
raise OperationException(_('Can\'t remove a non active element'))
ci = uService.getInstance()
state = ci.destroy()

View File

@ -81,6 +81,8 @@ body {
/* Tables */
/* Tables "styling" */
/* States */
tr.row-state-A, tr.row-state-F, tr.row-state-U, tr.row-state-W {
color: black;
}
@ -93,6 +95,27 @@ tr.row-state-M, tr.row-state-R, tr.row-state-I {
color: #858585;
}
/* Logs */
tr.log-WARN {
color: blue;
}
tr.log-DEBUG {
color: green;
}
tr.log-INFO, tr.log-OTHER {
color: black;
}
tr.log-ERROR, tr.log-FATAL {
color: red;
}
/* End tables styling */
/* Edit Below to Customize Widths > 768px */
@media (min-width:768px) {

View File

@ -70,15 +70,15 @@ gui.servicesPool.link = function(event) {
clearDetails();
},
onRowSelect : function(selected) {
var dps = selected[0];
gui.doLog('Selected services pool', dps);
var servPool = selected[0];
gui.doLog('Selected services pool', servPool);
clearDetails();
$('#detail-placeholder').removeClass('hidden');
// If service does not supports cache, do not show it
var service = null;
try {
service = availableServices[dps.service_id];
service = availableServices[servPool.service_id];
} catch (e) {
gui.doLog('Exception on rowSelect', e);
gui.notify(gettext('Error processing deployed service'), 'danger');
@ -89,7 +89,7 @@ gui.servicesPool.link = function(event) {
// Shows/hides cache
if( service.info.uses_cache || service.info.uses_cache_l2 ) {
$('#cache-placeholder_tab').removeClass('hidden');
cachedItems = new GuiElement(api.servicesPool.detail(dps.id, 'cache'), 'cache');
cachedItems = new GuiElement(api.servicesPool.detail(servPool.id, 'cache'), 'cache');
var cachedItemsTable = cachedItems.table({
container : 'cache-placeholder',
rowSelect : 'single'
@ -102,7 +102,7 @@ gui.servicesPool.link = function(event) {
// Shows/hides groups
if( service.info.must_assign_manually === false ) {
$('#groups-placeholder_tab').removeClass('hidden');
groups = new GuiElement(api.servicesPool.detail(dps.id, 'groups'), 'groups');
groups = new GuiElement(api.servicesPool.detail(servPool.id, 'groups'), 'groups');
var groupsTable = groups.table({
container : 'groups-placeholder',
rowSelect : 'single',
@ -117,14 +117,14 @@ gui.servicesPool.link = function(event) {
$('#groups-placeholder_tab').addClass('hidden');
}
var assignedServices = new GuiElement(api.servicesPool.detail(dps.id, 'services'), 'services');
var assignedServices = new GuiElement(api.servicesPool.detail(servPool.id, 'services'), 'services');
var assignedServicesTable = assignedServices.table({
container: 'assigned-services-placeholder',
rowSelect: 'single',
});
prevTables.push(assignedServicesTable);
var transports = new GuiElement(api.servicesPool.detail(dps.id, 'transports'), 'transports');
var transports = new GuiElement(api.servicesPool.detail(servPool.id, 'transports'), 'transports');
var transportsTable = transports.table({
container: 'transports-placeholder',
rowSelect: 'single',
@ -139,11 +139,25 @@ gui.servicesPool.link = function(event) {
});
prevTables.push(transportsTable);
var publications = null;
if( service.info.needs_publication ) {
$('#publications-placeholder_tab').removeClass('hidden');
publications = new GuiElement(api.servicesPool.detail(servPool.id, 'publications'), 'publications');
var publicationsTable = publications.table({
container : 'publications-placeholder',
rowSelect : 'single',
});
prevTables.push(publicationsTable);
} else {
$('#publications-placeholder_tab').addClass('hidden');
}
}
var logTable = gui.servicesPool.logTable(servPool.id, {
container : 'logs-placeholder',
});
prevTables.push(logTable);
},
// Pre-process data received to add "icon" to deployed service
onData: function(data) {
@ -153,6 +167,11 @@ gui.servicesPool.link = function(event) {
var service = availableServices[value.service_id];
var style = 'display:inline-block; background: url(data:image/png;base64,' +
service.info.icon + '); ' + 'width: 16px; height: 16px; vertical-align: middle;';
if( value.restrained ) {
value.name = '<span class="fa fa-exclamation text-danger"></span> ' + value.name;
value.state = gettext('Restrained');
}
value.name = '<span style="' + style + '"></span> ' + value.name;

View File

@ -136,7 +136,7 @@ GuiElement.prototype = {
// Text transformation, dictionary based
var renderTextTransform = function(dict) {
return function(data, type, full) {
return dict[data] || renderEmptyCell('');
return dict[data] || renderEmptyCell(data);
};
};
@ -544,6 +544,9 @@ GuiElement.prototype = {
return false; // This may be used on button or href, better disable execution of it
};
// Log level "translator" (renderer)
var logRenderer = gui.tools.renderLogLovel();
// Columns description
var columns = [
{
@ -556,7 +559,7 @@ GuiElement.prototype = {
{
"mData" : 'level',
"sTitle" : gettext('level'),
"mRender" : gui.tools.renderLogLovel(),
"mRender" : logRenderer,
"sWidth" : "5em",
"bSortable" : true,
"bSearchable" : true,
@ -601,6 +604,10 @@ GuiElement.prototype = {
"oLanguage" : gui.config.dataTablesLanguage,
"sDom" : "<'row'<'col-xs-8'T><'col-xs-4'f>r>t<'row'<'col-xs-5'i><'col-xs-7'p>>",
"bDeferRender": tblParams.deferedRender || false,
"fnCreatedRow": function( nRow, aData, iDataIndex ) {
var v = 'log-' + logRenderer(this.fnGetData(iDataIndex)['level']);
$(nRow).addClass(v);
},
});
// Fix form

View File

@ -84,7 +84,7 @@
return function(data, type, full) {
return levels[data] || 'OTHER';
}
};
},
};