ottertune/server/website/website/admin.py

207 lines
7.5 KiB
Python
Raw Normal View History

2019-08-23 08:47:19 -07:00
#
# OtterTune - admin.py
#
# Copyright (c) 2017-18, Carnegie Mellon University Database Group
#
from django.contrib import admin
from django.db.utils import ProgrammingError
from django.utils.html import format_html
from django_db_logger.admin import StatusLogAdmin
from django_db_logger.models import StatusLog
from djcelery import models as djcelery_models
2019-08-23 08:47:19 -07:00
from .models import (BackupData, DBMSCatalog, ExecutionTime,
KnobCatalog, KnobData, MetricCatalog,
MetricData, PipelineData, PipelineRun,
Project, Result, Session, Workload, Hardware,
2019-08-23 08:47:19 -07:00
SessionKnob)
from .types import VarType
2019-08-23 08:47:19 -07:00
class DBMSCatalogAdmin(admin.ModelAdmin):
pass
2019-08-23 08:47:19 -07:00
class KnobCatalogAdmin(admin.ModelAdmin):
list_display = ('name', 'dbms', 'tunable')
list_filter = (('dbms', admin.RelatedOnlyFieldListFilter), 'tunable')
ordering = ('dbms', '-tunable', 'name')
2019-08-23 08:47:19 -07:00
def get_form(self, request, obj=None, **kwargs):
exclude = ['category', 'summary', 'description', 'context']
if obj:
if obj.vartype not in (VarType.INTEGER, VarType.REAL):
exclude += ['minval', 'maxval']
if obj.vartype != VarType.ENUM:
exclude.append('enumvals')
kwargs['exclude'] = exclude
form = super().get_form(request, obj, **kwargs)
for field_name in ('minval', 'maxval', 'enumvals'):
if field_name in form.base_fields:
form.base_fields[field_name].required = False
return form
2019-08-23 08:47:19 -07:00
class MetricCatalogAdmin(admin.ModelAdmin):
list_display = ('name', 'dbms', 'metric_type')
list_filter = (('dbms', admin.RelatedOnlyFieldListFilter), 'metric_type')
ordering = ('dbms', 'name')
2019-08-23 08:47:19 -07:00
def get_form(self, request, obj=None, **kwargs):
kwargs['exclude'] = ('summary',)
return super().get_form(request, obj, **kwargs)
2019-08-23 08:47:19 -07:00
class ProjectAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'last_update', 'creation_time')
list_filter = (('user', admin.RelatedOnlyFieldListFilter),)
ordering = ('name', 'user__username')
2019-08-23 08:47:19 -07:00
class SessionAdmin(admin.ModelAdmin):
list_display = ('name', 'user', 'project', 'last_update', 'creation_time')
list_filter = (('user', admin.RelatedOnlyFieldListFilter),
('project', admin.RelatedOnlyFieldListFilter))
ordering = ('name', 'user__username', 'project__name')
2019-08-23 08:47:19 -07:00
class SessionKnobAdmin(admin.ModelAdmin):
list_display = ('knob', 'dbms', 'session', 'minval', 'maxval', 'tunable')
list_filter = (('session__dbms', admin.RelatedOnlyFieldListFilter),
('session', admin.RelatedOnlyFieldListFilter),
'tunable')
ordering = ('session__dbms', 'session__name', '-tunable', 'knob__name')
def dbms(self, instance): # pylint: disable=no-self-use
return instance.session.dbms
2019-08-23 08:47:19 -07:00
class HardwareAdmin(admin.ModelAdmin):
pass
2019-08-23 08:47:19 -07:00
class KnobDataAdmin(admin.ModelAdmin):
list_display = ('name', 'dbms', 'session', 'creation_time')
list_filter = (('dbms', admin.RelatedOnlyFieldListFilter),
('session', admin.RelatedOnlyFieldListFilter))
ordering = ('creation_time',)
2019-08-23 08:47:19 -07:00
class MetricDataAdmin(admin.ModelAdmin):
list_display = ('name', 'dbms', 'session', 'creation_time')
list_filter = (('dbms', admin.RelatedOnlyFieldListFilter),
('session', admin.RelatedOnlyFieldListFilter))
ordering = ('creation_time',)
2019-08-23 08:47:19 -07:00
class ResultAdmin(admin.ModelAdmin):
readonly_fields = ('dbms', 'knob_data', 'metric_data', 'session', 'workload')
list_display = ('id', 'dbms', 'session', 'workload', 'creation_time')
list_select_related = ('dbms', 'session', 'workload')
list_filter = (('dbms', admin.RelatedOnlyFieldListFilter),
('session', admin.RelatedOnlyFieldListFilter),
('workload', admin.RelatedOnlyFieldListFilter))
ordering = ('creation_time',)
2019-08-23 08:47:19 -07:00
class BackupDataAdmin(admin.ModelAdmin):
readonly_fields = ('id', 'result')
ordering = ('id',)
2019-08-23 08:47:19 -07:00
class PipelineDataAdmin(admin.ModelAdmin):
readonly_fields = ('pipeline_run',)
list_display = ('id', 'pipeline_run', 'task_type', 'workload', 'creation_time')
list_filter = ('task_type', ('workload', admin.RelatedOnlyFieldListFilter))
ordering = ('pipeline_run', 'creation_time')
2019-08-23 08:47:19 -07:00
class PipelineRunAdmin(admin.ModelAdmin):
list_display = ('id', 'start_time', 'end_time')
ordering = ('id', 'start_time')
2019-08-23 08:47:19 -07:00
class WorkloadAdmin(admin.ModelAdmin):
list_display = ('name', 'dbms', 'hardware')
list_filter = (('dbms', admin.RelatedOnlyFieldListFilter),
('hardware', admin.RelatedOnlyFieldListFilter))
2019-08-23 08:47:19 -07:00
class TaskMetaAdmin(admin.ModelAdmin):
list_display = ('colored_status', 'task_result', 'date_done', 'task_traceback')
list_display_links = ('colored_status', 'task_result')
readonly_fields = ('id', 'task_id', 'status', 'result', 'date_done',
'traceback', 'hidden', 'meta')
fields = readonly_fields
list_filter = ('status',)
list_per_page = 10
ordering = ('date_done',)
max_field_length = 1000
@staticmethod
def color_field(text, status):
if status == 'SUCCESS':
color = 'green'
elif status in ('PENDING', 'RECEIVED', 'STARTED'):
color = 'orange'
else:
color = 'red'
return format_html('<span style="color: {};">{}</span>'.format(color, text))
def format_field(self, field):
text = str(field) if field else ''
if len(text) > self.max_field_length:
text = text[:self.max_field_length] + '...'
return text
def colored_status(self, instance):
return self.color_field(instance.status, instance.status)
colored_status.short_description = 'Status'
def task_traceback(self, instance):
text = self.format_field(instance.traceback)
return format_html('<pre><code>{}</code></pre>'.format(text))
task_traceback.short_description = 'Traceback'
def task_result(self, instance):
res = self.format_field(instance.result)
return res
task_result.short_description = 'Result'
class CustomStatusLogAdmin(StatusLogAdmin):
list_display = ('logger_name', 'colored_msg', 'traceback', 'create_datetime_format')
list_display_links = ('logger_name',)
list_filter = ('logger_name', 'level')
class ExecutionTimeAdmin(admin.ModelAdmin):
list_display = ('event', 'result', 'exec_time')
def exec_time(self, instance): # pylint: disable=no-self-use
return '{:.0f} sec'.format(instance.execution_time)
exec_time.short_description = 'Execution Time'
# Admin classes for website models
2019-08-23 08:47:19 -07:00
admin.site.register(DBMSCatalog, DBMSCatalogAdmin)
admin.site.register(KnobCatalog, KnobCatalogAdmin)
admin.site.register(MetricCatalog, MetricCatalogAdmin)
admin.site.register(Session, SessionAdmin)
admin.site.register(Project, ProjectAdmin)
admin.site.register(KnobData, KnobDataAdmin)
admin.site.register(MetricData, MetricDataAdmin)
admin.site.register(Result, ResultAdmin)
admin.site.register(BackupData, BackupDataAdmin)
admin.site.register(PipelineData, PipelineDataAdmin)
admin.site.register(PipelineRun, PipelineRunAdmin)
admin.site.register(Workload, WorkloadAdmin)
admin.site.register(SessionKnob, SessionKnobAdmin)
admin.site.register(Hardware, HardwareAdmin)
admin.site.register(ExecutionTime, ExecutionTimeAdmin)
# Admin classes for 3rd party models
admin.site.unregister(StatusLog)
admin.site.register(StatusLog, CustomStatusLogAdmin)
admin.site.register(djcelery_models.TaskMeta, TaskMetaAdmin)