=== modified file 'doc/conf.py'
@@ -178,8 +178,8 @@
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, documentclass [howto/manual]).
latex_documents = [
- ('index', 'LAVAScheduler.tex', u'LAVA Scheduler Documentation',
- u'Linaro Validation Team', 'manual'),
+ ('index', 'LAVAScheduler.tex', u'LAVA Scheduler Documentation',
+ u'Linaro Validation Team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
=== modified file 'lava_scheduler_app/admin.py'
@@ -1,23 +1,26 @@
from django.contrib import admin
from lava_scheduler_app.models import (
Device, DeviceStateTransition, DeviceType, TestJob, Tag, JobFailureTag,
- )
+)
# XXX These actions should really go to another screen that asks for a reason.
# Sounds tedious to implement though.
+
def offline_action(modeladmin, request, queryset):
for device in queryset.filter(status__in=[Device.IDLE, Device.RUNNING]):
if device.can_admin(request.user):
device.put_into_maintenance_mode(request.user, "admin action")
offline_action.short_description = "take offline"
+
def online_action(modeladmin, request, queryset):
for device in queryset.filter(status__in=[Device.OFFLINE, Device.OFFLINING]):
if device.can_admin(request.user):
device.put_into_online_mode(request.user, "admin action")
online_action.short_description = "take online"
+
def retire_action(modeladmin, request, queryset):
for device in queryset:
if device.can_admin(request.user):
@@ -29,12 +32,14 @@
device.save()
retire_action.short_description = "retire"
+
def health_unknown(modeladmin, request, queryset):
for device in queryset.filter(health_status=Device.HEALTH_PASS):
device.health_status = Device.HEALTH_UNKNOWN
device.save()
health_unknown.short_description = "set health_status to unknown"
+
class DeviceAdmin(admin.ModelAdmin):
actions = [online_action, offline_action, health_unknown, retire_action]
list_filter = ['device_type', 'status']
=== modified file 'lava_scheduler_app/api.py'
@@ -7,9 +7,8 @@
DeviceType,
JSONDataError,
TestJob,
- )
+)
from lava_scheduler_app.views import (
- SumIfSQL,
SumIf
)
@@ -146,12 +145,12 @@
device_type_list = []
keys = ['busy', 'name', 'idle', 'offline']
- device_types = DeviceType.objects.filter(display=True).annotate(
- idle=SumIf('device', condition='status=%s' % Device.IDLE),
- offline=SumIf('device', condition='status in (%s,%s)' % (
- Device.OFFLINE, Device.OFFLINING)),
- busy=SumIf('device', condition='status=%s' % Device.RUNNING),
- ).order_by('name')
+ device_types = DeviceType.objects.filter(display=True)\
+ .annotate(idle=SumIf('device', condition='status=%s' % Device.IDLE),
+ offline=SumIf('device', condition='status in (%s,%s)'
+ % (Device.OFFLINE, Device.OFFLINING)),
+ busy=SumIf('device', condition='status=%s'
+ % Device.RUNNING), ).order_by('name')
for dev_type in device_types:
device_type = {}
@@ -186,9 +185,9 @@
pending_jobs_by_device = {}
- jobs = TestJob.objects.filter(status=TestJob.SUBMITTED).values_list(
- 'requested_device_type_id').annotate(
- pending_jobs=(Count('id')))
+ jobs = TestJob.objects.filter(status=TestJob.SUBMITTED)\
+ .values_list('requested_device_type_id')\
+ .annotate(pending_jobs=(Count('id')))
pending_jobs_by_device.update(dict(jobs))
# Get rest of the devices and put number of pending jobs as 0.
@@ -196,7 +195,7 @@
for device_type in device_types:
if device_type not in pending_jobs_by_device:
pending_jobs_by_device[device_type] = 0
-
+
return pending_jobs_by_device
def job_details(self, job_id):
@@ -252,7 +251,7 @@
------------
This function returns an XML-RPC structures of job status with the follwing fields.
The user is authenticated with an username and token.
-
+
`job_status`: string
['Submitted'|'Running'|'Complete'|'Incomplete'|'Canceled'|'Canceling']
@@ -271,7 +270,6 @@
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
-
bundle_sha1 = ""
try:
bundle_sha1 = job.results_link.split('/')[-2]
@@ -279,9 +277,8 @@
pass
job_status = {
- 'job_status': job.get_status_display(),
- 'bundle_sha1': bundle_sha1
- }
+ 'job_status': job.get_status_display(),
+ 'bundle_sha1': bundle_sha1
+ }
return job_status
-
=== modified file 'lava_scheduler_app/extension.py'
@@ -72,11 +72,11 @@
'LOG_FILE_PATH': None,
'LOG_LEVEL': "WARNING",
# 500 megs should be enough for anyone
- 'LOG_FILE_SIZE_LIMIT': 500*1024*1024,
+ 'LOG_FILE_SIZE_LIMIT': 500 * 1024 * 1024,
# Jobs always specify a timeout, but I suspect its often too low.
# So we don't let it go below this value, which defaults to a day.
- 'MIN_JOB_TIMEOUT': 24*60*60,
- }
+ 'MIN_JOB_TIMEOUT': 24 * 60 * 60,
+ }
settings_module['SCHEDULER_DAEMON_OPTIONS'].update(from_module)
prepend_label_apps = settings_module.get('STATICFILES_PREPEND_LABEL_APPS', [])
if self.app_name in prepend_label_apps:
=== modified file 'lava_scheduler_app/logfile_helper.py'
@@ -1,14 +1,16 @@
import re
+
def getDispatcherErrors(logfile):
errors = ""
for line in logfile:
if line.find("CriticalError:") != -1 or \
- line.find("Lava failed on test:") != -1 :
+ line.find("Lava failed on test:") != -1:
errors += line
return errors
+
def getDispatcherLogMessages(logfile):
logs = []
log_prefix = '<LAVA_DISPATCHER>'
@@ -17,9 +19,9 @@
for line in logfile:
# log_prefix not always start at beginning of the line
pos = line.find(log_prefix)
- if (pos == -1): # log_prefix not found
+ if pos == -1: # log_prefix not found
continue
- if (pos > 0): # remove log_prefix leading characters
+ if pos > 0: # remove log_prefix leading characters
line = line[pos:-1]
line = line[len(log_prefix):].strip()
@@ -35,16 +37,19 @@
logs.append((match.group(2), line, ""))
return logs
+
class Sections:
def __init__(self):
self.sections = []
self.cur_section_type = None
self.cur_section = []
- def push(self, type, line):
- if type != self.cur_section_type:
+
+ def push(self, sect_type, line):
+ if sect_type != self.cur_section_type:
self.close()
- self.cur_section_type = type
+ self.cur_section_type = sect_type
self.cur_section.append(line)
+
def close(self):
if self.cur_section_type is not None:
self.sections.append(
@@ -54,6 +59,7 @@
self.cur_section_type = None
self.cur_section = []
+
def formatLogFile(logfile):
if not logfile:
return [('log', 1, "Log file is missing")]
@@ -72,9 +78,9 @@
if not line.startswith(' '):
sections.close()
continue
- elif line.find("<LAVA_DISPATCHER>") != -1 or \
- line.find("lava_dispatcher") != -1 or \
- line.find("CriticalError:") != -1 :
+ elif line.find("<LAVA_DISPATCHER>") != -1 \
+ or line.find("lava_dispatcher") != -1 \
+ or line.find("CriticalError:") != -1:
sections.push('log', line)
else:
sections.push('console', line)
=== modified file 'lava_scheduler_app/management/commands/__init__.py'
@@ -15,11 +15,10 @@
action='store',
default=None,
help="Path to log file, default is taken from settings."),
- )
+ )
log_prefix = ''
-
_DEFAULT_LOGGING = {
'version': 1,
'disable_existing_loggers': True,
@@ -41,7 +40,6 @@
},
}
-
def _configure(self, options):
from django.conf import settings
@@ -56,20 +54,19 @@
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'default',
- }
+ }
else:
handler = {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': daemon_options['LOG_FILE_PATH'],
'formatter': 'default'
- }
+ }
fmt = "%(asctime)s [%(levelname)s] [%(name)s] %(message)s"
if self.log_prefix:
fmt = self.log_prefix + ' ' + fmt
-
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
@@ -79,7 +76,7 @@
},
'formatters': {'default': {'format': fmt}},
'handlers': {'default': handler}
- }
+ }
try:
import lava.raven
@@ -92,8 +89,6 @@
}
LOGGING['root']['handlers'].append('sentry')
-
logging.config.dictConfig(LOGGING)
return daemon_options
-
=== modified file 'lava_scheduler_app/management/commands/scheduler.py'
@@ -21,6 +21,7 @@
from lava_scheduler_app.management.commands import SchedulerCommand
+
class Command(SchedulerCommand):
help = "Run the LAVA test job scheduler"
=== modified file 'lava_scheduler_app/migrations/0001_initial.py'
@@ -1,13 +1,12 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding model 'DeviceType'
db.create_table('lava_scheduler_app_devicetype', (
('name', self.gf('django.db.models.fields.SlugField')(max_length=50, primary_key=True, db_index=True)),
@@ -37,9 +36,8 @@
))
db.send_create_signal('lava_scheduler_app', ['TestJob'])
-
def backwards(self, orm):
-
+
# Deleting model 'DeviceType'
db.delete_table('lava_scheduler_app_devicetype')
@@ -49,7 +47,6 @@
# Deleting model 'TestJob'
db.delete_table('lava_scheduler_app_testjob')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0002_auto__chg_field_testjob_device_type.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Changing field 'TestJob.device_type'
db.alter_column('lava_scheduler_app_testjob', 'device_type_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.DeviceType'], null=True))
-
def backwards(self, orm):
-
+
# User chose to not deal with backwards NULL issues for 'TestJob.device_type'
raise RuntimeError("Cannot reverse this migration. 'TestJob.device_type' and its values cannot be restored.")
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0003_auto__add_field_testjob_requested_device__add_field_testjob_requested_.py'
@@ -1,13 +1,12 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.requested_device'
db.add_column('lava_scheduler_app_testjob', 'requested_device', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='+', null=True, to=orm['lava_scheduler_app.Device']), keep_default=False)
@@ -17,9 +16,8 @@
# Adding field 'TestJob.actual_device'
db.add_column('lava_scheduler_app_testjob', 'actual_device', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='+', null=True, to=orm['lava_scheduler_app.Device']), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.requested_device'
db.delete_column('lava_scheduler_app_testjob', 'requested_device_id')
@@ -29,7 +27,6 @@
# Deleting field 'TestJob.actual_device'
db.delete_column('lava_scheduler_app_testjob', 'actual_device_id')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0004_fill_out_device_fields.py'
@@ -1,8 +1,6 @@
# encoding: utf-8
-import datetime
-from south.db import db
from south.v2 import DataMigration
-from django.db import models
+
class Migration(DataMigration):
@@ -23,7 +21,6 @@
job.device_type = job.requested_device.device_type
job.save()
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0005_auto__del_field_testjob_device_type__del_field_testjob_target.py'
@@ -1,29 +1,26 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Deleting field 'TestJob.device_type'
db.delete_column('lava_scheduler_app_testjob', 'device_type_id')
# Deleting field 'TestJob.target'
db.delete_column('lava_scheduler_app_testjob', 'target_id')
-
def backwards(self, orm):
-
+
# Adding field 'TestJob.device_type'
db.add_column('lava_scheduler_app_testjob', 'device_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.DeviceType'], null=True), keep_default=False)
# Adding field 'TestJob.target'
db.add_column('lava_scheduler_app_testjob', 'target', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['lava_scheduler_app.Device'], null=True), keep_default=False)
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0006_auto__add_field_testjob_log_file.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.log_file'
db.add_column('lava_scheduler_app_testjob', 'log_file', self.gf('django.db.models.fields.files.FileField')(default=None, max_length=100, null=True), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.log_file'
db.delete_column('lava_scheduler_app_testjob', 'log_file')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0007_merged_migration.py'
@@ -1,19 +1,15 @@
# encoding: utf-8
-import datetime
-from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
pass
-
def backwards(self, orm):
pass
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0008_auto__add_field_testjob_results_link.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.results_link'
db.add_column('lava_scheduler_app_testjob', 'results_link', self.gf('django.db.models.fields.CharField')(default=None, max_length=400, null=True, blank=True), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.results_link'
db.delete_column('lava_scheduler_app_testjob', 'results_link')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0009_auto__add_field_testjob_description.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.description'
db.add_column('lava_scheduler_app_testjob', 'description', self.gf('django.db.models.fields.CharField')(default='', max_length=200), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.description'
db.delete_column('lava_scheduler_app_testjob', 'description')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0010_auto__chg_field_testjob_description.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Changing field 'TestJob.description'
db.alter_column('lava_scheduler_app_testjob', 'description', self.gf('django.db.models.fields.CharField')(max_length=200, null=True))
-
def backwards(self, orm):
-
+
# Changing field 'TestJob.description'
db.alter_column('lava_scheduler_app_testjob', 'description', self.gf('django.db.models.fields.CharField')(max_length=200))
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0011_auto__add_tag.py'
@@ -1,13 +1,13 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding model 'Tag'
db.create_table('lava_scheduler_app_tag', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
@@ -32,9 +32,8 @@
))
db.create_unique('lava_scheduler_app_testjob_tags', ['testjob_id', 'tag_id'])
-
def backwards(self, orm):
-
+
# Deleting model 'Tag'
db.delete_table('lava_scheduler_app_tag')
@@ -44,7 +43,6 @@
# Removing M2M table for field tags on 'TestJob'
db.delete_table('lava_scheduler_app_testjob_tags')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0012_auto__add_field_testjob_submit_token.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.submit_token'
db.add_column('lava_scheduler_app_testjob', 'submit_token', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['linaro_django_xmlrpc.AuthToken'], null=True), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.submit_token'
db.delete_column('lava_scheduler_app_testjob', 'submit_token_id')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0013_auto__add_devicestatetransition.py'
@@ -1,13 +1,12 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding model 'DeviceStateTransition'
db.create_table('lava_scheduler_app_devicestatetransition', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
@@ -21,13 +20,11 @@
))
db.send_create_signal('lava_scheduler_app', ['DeviceStateTransition'])
-
def backwards(self, orm):
-
+
# Deleting model 'DeviceStateTransition'
db.delete_table('lava_scheduler_app_devicestatetransition')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0014_auto__add_field_device_health_status__add_field_device_last_health_rep.py'
@@ -1,29 +1,26 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'Device.health_status'
db.add_column('lava_scheduler_app_device', 'health_status', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
# Adding field 'Device.last_health_report_job'
db.add_column('lava_scheduler_app_device', 'last_health_report_job', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name=u'Health Report Job', unique=True, null=True, to=orm['lava_scheduler_app.TestJob']), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'Device.health_status'
db.delete_column('lava_scheduler_app_device', 'health_status')
# Deleting field 'Device.last_health_report_job'
db.delete_column('lava_scheduler_app_device', 'last_health_report_job_id')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0015_auto__add_field_testjob_health_check.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.health_check'
db.add_column('lava_scheduler_app_testjob', 'health_check', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.health_check'
db.delete_column('lava_scheduler_app_testjob', 'health_check')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0016_auto__add_field_devicetype_health_check_job.py'
@@ -1,23 +1,20 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'DeviceType.health_check_job'
db.add_column('lava_scheduler_app_devicetype', 'health_check_job', self.gf('django.db.models.fields.TextField')(default=None, null=True, blank=True), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'DeviceType.health_check_job'
db.delete_column('lava_scheduler_app_devicetype', 'health_check_job')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0017_add_lava_health_user.py'
@@ -1,8 +1,7 @@
# encoding: utf-8
import datetime
-from south.db import db
from south.v2 import DataMigration
-from django.db import models
+
class Migration(DataMigration):
=== modified file 'lava_scheduler_app/migrations/0018_auto__add_field_testjob_user__add_field_testjob_group__add_field_testj.py'
@@ -1,13 +1,12 @@
# encoding: utf-8
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
+
class Migration(SchemaMigration):
def forwards(self, orm):
-
+
# Adding field 'TestJob.user'
db.add_column('lava_scheduler_app_testjob', 'user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True), keep_default=False)
@@ -17,9 +16,8 @@
# Adding field 'TestJob.is_public'
db.add_column('lava_scheduler_app_testjob', 'is_public', self.gf('django.db.models.fields.BooleanField')(default=True), keep_default=False)
-
def backwards(self, orm):
-
+
# Deleting field 'TestJob.user'
db.delete_column('lava_scheduler_app_testjob', 'user_id')
@@ -29,7 +27,6 @@
# Deleting field 'TestJob.is_public'
db.delete_column('lava_scheduler_app_testjob', 'is_public')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0019_set_testjob_owner.py'
@@ -1,9 +1,8 @@
# encoding: utf-8
-import datetime
-from south.db import db
from south.v2 import DataMigration
from django.db import models
+
class Migration(DataMigration):
def forwards(self, orm):
@@ -11,13 +10,11 @@
orm['lava_scheduler_app.TestJob'].objects.update(
user=models.F('submitter'))
-
def backwards(self, orm):
"Write your backwards methods here."
orm['lava_scheduler_app.TestJob'].objects.update(
user=None)
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0020_auto__add_field_testjob__results_bundle.py'
@@ -1,15 +1,13 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
depends_on = [
('dashboard_app', '0001_initial'),
- ]
+ ]
def forwards(self, orm):
# Adding field 'TestJob._results_bundle'
@@ -17,12 +15,10 @@
self.gf('django.db.models.fields.related.OneToOneField')(to=orm['dashboard_app.Bundle'], unique=True, null=True, db_column='results_bundle_id', blank=True),
keep_default=False)
-
def backwards(self, orm):
# Deleting field 'TestJob._results_bundle'
db.delete_column('lava_scheduler_app_testjob', 'results_bundle_id')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
=== modified file 'lava_scheduler_app/migrations/0021_rename_results_link.py'
@@ -1,8 +1,5 @@
# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -22,7 +19,6 @@
about this change without actually touching the db at all.
"""
-
def forwards(self, orm):
pass
=== modified file 'lava_scheduler_app/migrations/0022_auto__chg_field_testjob__results_bundle__add_unique_testjob__results_b.py'
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -14,12 +12,10 @@
# Adding unique constraint on 'TestJob', fields ['_results_bundle']
db.create_unique('lava_scheduler_app_testjob', ['results_bundle_id'])
-
def backwards(self, orm):
# Removing unique constraint on 'TestJob', fields ['_results_bundle']
db.delete_unique('lava_scheduler_app_testjob', ['results_bundle_id'])
-
# Changing field 'TestJob._results_bundle'
db.alter_column('lava_scheduler_app_testjob', 'results_bundle_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.Bundle'], null=True, db_column='results_bundle_id'))
@@ -149,4 +145,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0023_auto__add_field_devicetype_use_celery.py'
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -13,12 +11,10 @@
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
-
def backwards(self, orm):
# Deleting field 'DeviceType.use_celery'
db.delete_column('lava_scheduler_app_devicetype', 'use_celery')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@@ -146,4 +142,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0024_auto__add_field_devicetype_display.py'
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -13,12 +11,10 @@
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
-
def backwards(self, orm):
# Deleting field 'DeviceType.display'
db.delete_column('lava_scheduler_app_devicetype', 'display')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@@ -147,4 +143,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0025_auto__chg_field_testjob__results_bundle__chg_field_testjob_submit_toke.py'
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
@@ -175,4 +174,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0026_auto__add_field_device_device_version.py'
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -13,12 +11,10 @@
self.gf('django.db.models.fields.CharField')(default=None, max_length=200, null=True),
keep_default=False)
-
def backwards(self, orm):
# Deleting field 'Device.device_version'
db.delete_column('lava_scheduler_app_device', 'device_version')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@@ -148,4 +144,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0027_auto__add_field_testjob_priority.py'
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -13,12 +11,10 @@
self.gf('django.db.models.fields.IntegerField')(default=50),
keep_default=False)
-
def backwards(self, orm):
# Deleting field 'TestJob.priority'
db.delete_column('lava_scheduler_app_testjob', 'priority')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@@ -149,4 +145,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0028_auto__del_field_devicetype_use_celery.py'
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
-from django.db import models
class Migration(SchemaMigration):
@@ -11,14 +9,12 @@
# Deleting field 'DeviceType.use_celery'
db.delete_column('lava_scheduler_app_devicetype', 'use_celery')
-
def backwards(self, orm):
# Adding field 'DeviceType.use_celery'
db.add_column('lava_scheduler_app_devicetype', 'use_celery',
self.gf('django.db.models.fields.BooleanField')(default=False),
keep_default=False)
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@@ -148,4 +144,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/migrations/0029_auto__add_jobfailuretag__add_field_testjob_failure_comment.py'
@@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
-import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
@@ -29,7 +28,6 @@
))
db.create_unique('lava_scheduler_app_testjob_failure_tags', ['testjob_id', 'jobfailuretag_id'])
-
def backwards(self, orm):
# Deleting model 'JobFailureTag'
db.delete_table('lava_scheduler_app_jobfailuretag')
@@ -40,7 +38,6 @@
# Removing M2M table for field failure_tags on 'TestJob'
db.delete_table('lava_scheduler_app_testjob_failure_tags')
-
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
@@ -178,4 +175,4 @@
}
}
- complete_apps = ['lava_scheduler_app']
\ No newline at end of file
+ complete_apps = ['lava_scheduler_app']
=== modified file 'lava_scheduler_app/models.py'
@@ -58,9 +58,9 @@
null=True, blank=True, default=None, validators=[validate_job_json])
display = models.BooleanField(default=True,
- help_text=("Should this be displayed in the GUI or not. This can be " \
- "useful if you are removing all devices of this type but don't " \
- "want to loose the test results generated by the devices."))
+ help_text=("Should this be displayed in the GUI or not. This can be "
+ "useful if you are removing all devices of this type but don't "
+ "want to loose the test results generated by the devices."))
@models.permalink
def get_absolute_url(self):
@@ -96,20 +96,20 @@
)
hostname = models.CharField(
- verbose_name = _(u"Hostname"),
- max_length = 200,
- primary_key = True,
+ verbose_name=_(u"Hostname"),
+ max_length=200,
+ primary_key=True,
)
device_type = models.ForeignKey(
DeviceType, verbose_name=_(u"Device type"))
device_version = models.CharField(
- verbose_name = _(u"Device Version"),
- max_length = 200,
- null = True,
- default = None,
- blank = True,
+ verbose_name=_(u"Device Version"),
+ max_length=200,
+ null=True,
+ default=None,
+ blank=True,
)
current_job = models.ForeignKey(
@@ -119,15 +119,15 @@
tags = models.ManyToManyField(Tag, blank=True)
status = models.IntegerField(
- choices = STATUS_CHOICES,
- default = IDLE,
- verbose_name = _(u"Device status"),
+ choices=STATUS_CHOICES,
+ default=IDLE,
+ verbose_name=_(u"Device status"),
)
health_status = models.IntegerField(
- choices = HEALTH_CHOICES,
- default = HEALTH_UNKNOWN,
- verbose_name = _(u"Device Health"),
+ choices=HEALTH_CHOICES,
+ default=HEALTH_UNKNOWN,
+ verbose_name=_(u"Device Health"),
)
last_health_report_job = models.ForeignKey(
@@ -247,19 +247,19 @@
submitter = models.ForeignKey(
User,
- verbose_name = _(u"Submitter"),
- related_name = '+',
+ verbose_name=_(u"Submitter"),
+ related_name='+',
)
submit_token = models.ForeignKey(
AuthToken, null=True, blank=True, on_delete=models.SET_NULL)
description = models.CharField(
- verbose_name = _(u"Description"),
- max_length = 200,
- null = True,
- blank = True,
- default = None
+ verbose_name=_(u"Description"),
+ max_length=200,
+ null=True,
+ blank=True,
+ default=None
)
health_check = models.BooleanField(default=False)
@@ -277,25 +277,25 @@
Device, null=True, default=None, related_name='+', blank=True)
submit_time = models.DateTimeField(
- verbose_name = _(u"Submit time"),
- auto_now = False,
- auto_now_add = True
+ verbose_name=_(u"Submit time"),
+ auto_now=False,
+ auto_now_add=True
)
start_time = models.DateTimeField(
- verbose_name = _(u"Start time"),
- auto_now = False,
- auto_now_add = False,
- null = True,
- blank = True,
- editable = False
+ verbose_name=_(u"Start time"),
+ auto_now=False,
+ auto_now_add=False,
+ null=True,
+ blank=True,
+ editable=False
)
end_time = models.DateTimeField(
- verbose_name = _(u"End time"),
- auto_now = False,
- auto_now_add = False,
- null = True,
- blank = True,
- editable = False
+ verbose_name=_(u"End time"),
+ auto_now=False,
+ auto_now_add=False,
+ null=True,
+ blank=True,
+ editable=False
)
@property
@@ -305,19 +305,19 @@
return self.end_time - self.start_time
status = models.IntegerField(
- choices = STATUS_CHOICES,
- default = SUBMITTED,
- verbose_name = _(u"Status"),
+ choices=STATUS_CHOICES,
+ default=SUBMITTED,
+ verbose_name=_(u"Status"),
)
priority = models.IntegerField(
- choices = PRIORITY_CHOICES,
- default = MEDIUM,
- verbose_name = _(u"Priority"),
+ choices=PRIORITY_CHOICES,
+ default=MEDIUM,
+ verbose_name=_(u"Priority"),
)
definition = models.TextField(
- editable = False,
+ editable=False,
)
log_file = models.FileField(
@@ -452,7 +452,6 @@
if parsed_server.hostname is None:
raise ValueError("invalid server: %s" % server)
-
tags = []
for tag_name in job_data.get('device_tags', []):
try:
=== modified file 'lava_scheduler_app/tests.py'
@@ -227,13 +227,13 @@
return self.factory.make_job_json(
actions=[
{
- 'command':'submit_results',
+ 'command': 'submit_results',
'parameters': {
'server': '...',
'stream': stream_name,
- }
}
- ])
+ }
+ ])
def test_from_json_and_user_sets_group_from_bundlestream(self):
group = Group.objects.create(name='group')
=== modified file 'lava_scheduler_app/urls.py'
@@ -79,14 +79,14 @@
'job_definition',
name='lava.scheduler.job.definition'),
url(r'^job/(?P<pk>[0-9]+)/definition/plain$',
- 'job_definition_plain',
- name='lava.scheduler.job.definition.plain'),
+ 'job_definition_plain',
+ name='lava.scheduler.job.definition.plain'),
url(r'^job/(?P<pk>[0-9]+)/log_file$',
- 'job_log_file',
- name='lava.scheduler.job.log_file'),
+ 'job_log_file',
+ name='lava.scheduler.job.log_file'),
url(r'^job/(?P<pk>[0-9]+)/log_file/plain$',
- 'job_log_file_plain',
- name='lava.scheduler.job.log_file.plain'),
+ 'job_log_file_plain',
+ name='lava.scheduler.job.log_file.plain'),
url(r'^job/(?P<pk>[0-9]+)/cancel$',
'job_cancel',
name='lava.scheduler.job.cancel'),
@@ -111,4 +111,4 @@
url(r'^get-remote-json',
'get_remote_json',
name='lava.scheduler.get_remote_json'),
- )
+)
=== modified file 'lava_scheduler_app/views.py'
@@ -18,7 +18,7 @@
HttpResponseBadRequest,
HttpResponseForbidden,
HttpResponseNotAllowed,
- )
+)
from django.shortcuts import (
get_object_or_404,
redirect,
@@ -45,17 +45,14 @@
formatLogFile,
getDispatcherErrors,
getDispatcherLogMessages
- )
+)
from lava_scheduler_app.models import (
- Tag,
Device,
DeviceType,
DeviceStateTransition,
- JobFailureTag,
- JSONDataError,
TestJob,
validate_job_json,
- )
+)
def post_only(func):
@@ -105,11 +102,9 @@
def all_jobs_with_device_sort():
return TestJob.objects.select_related(
"actual_device", "requested_device", "requested_device_type",
- "submitter", "user", "group").extra(
- select={
- 'device_sort': 'coalesce(actual_device_id, requested_device_id, requested_device_type_id)'
- }).all()
-
+ "submitter", "user", "group")\
+ .extra(select={'device_sort': 'coalesce(actual_device_id, requested_device_id, '
+ 'requested_device_type_id)'}).all()
class JobTable(DataTablesTable):
@@ -141,14 +136,14 @@
datatable_opts = {
'aaSorting': [[0, 'desc']],
- }
- searchable_columns=['description']
+ }
+ searchable_columns = ['description']
class IndexJobTable(JobTable):
def get_queryset(self):
- return all_jobs_with_device_sort().filter(
- status__in=[TestJob.SUBMITTED, TestJob.RUNNING])
+ return all_jobs_with_device_sort()\
+ .filter(status__in=[TestJob.SUBMITTED, TestJob.RUNNING])
class Meta:
exclude = ('end_time',)
@@ -168,19 +163,22 @@
status = Column()
health_status = Column()
- searchable_columns=['hostname']
+ searchable_columns = ['hostname']
def index_devices_json(request):
return DeviceTable.json(request)
+
def health_jobs_in_hr(hr=-24):
return TestJob.objects.filter(health_check=True,
- start_time__gte=(datetime.datetime.now()
- + relativedelta(hours=hr))).exclude(status__in=[TestJob.SUBMITTED, TestJob.RUNNING])
+ start_time__gte=(datetime.datetime.now() +
+ relativedelta(hours=hr)))\
+ .exclude(status__in=[TestJob.SUBMITTED, TestJob.RUNNING])
+
def _online_total():
- ''' returns a tuple of (num_online, num_not_retired) '''
+ """ returns a tuple of (num_online, num_not_retired) """
r = Device.objects.all().values('status').annotate(count=Count('status'))
offline = total = 0
for res in r:
@@ -189,7 +187,8 @@
if res['status'] != Device.RETIRED:
total += res['count']
- return (total-offline,total)
+ return total - offline, total
+
@BreadCrumb("Scheduler", parent=lava_index)
def index(request):
@@ -208,20 +207,16 @@
},
RequestContext(request))
+
def job_report(start_day, end_day, health_check):
now = datetime.datetime.now()
start_date = now + datetime.timedelta(start_day)
end_date = now + datetime.timedelta(end_day)
- res = TestJob.objects.filter(
- health_check=health_check,
- start_time__range=(start_date, end_date),
- status__in=(
- TestJob.COMPLETE,
- TestJob.INCOMPLETE, TestJob.CANCELED, TestJob.CANCELING),
- ).values(
- 'status'
- )
+ res = TestJob.objects.filter(health_check=health_check,
+ start_time__range=(start_date, end_date),
+ status__in=(TestJob.COMPLETE, TestJob.INCOMPLETE,
+ TestJob.CANCELED, TestJob.CANCELING),).values('status')
url = reverse('lava.scheduler.failure_report')
params = 'start=%s&end=%s&health_check=%d' % (start_day, end_day, health_check)
return {
@@ -231,6 +226,7 @@
'failure_url': '%s?%s' % (url, params),
}
+
@BreadCrumb("Reports", parent=lava_index)
def reports(request):
health_day_report = []
@@ -238,15 +234,14 @@
job_day_report = []
job_week_report = []
for day in reversed(range(7)):
- health_day_report.append(job_report(day*-1-1, day*-1, True))
- job_day_report.append(job_report(day*-1-1, day*-1, False))
+ health_day_report.append(job_report(day * -1 - 1, day * -1, True))
+ job_day_report.append(job_report(day * -1 - 1, day * -1, False))
for week in reversed(range(10)):
- health_week_report.append(job_report(week*-7-7, week*-7, True))
- job_week_report.append(job_report(week*-7-7, week*-7, False))
+ health_week_report.append(job_report(week * -7 - 7, week * -7, True))
+ job_week_report.append(job_report(week * -7 - 7, week * -7, False))
- long_running = TestJob.objects.filter(
- status__in = [TestJob.RUNNING, TestJob.CANCELING]
- ).order_by('start_time')[:5]
+ long_running = TestJob.objects.filter(status__in=[TestJob.RUNNING,
+ TestJob.CANCELING]).order_by('start_time')[:5]
return render_to_response(
"lava_scheduler_app/reports.html",
@@ -306,8 +301,8 @@
return FailedJobTable.json(request, params=(request,))
-def _str_to_bool(str):
- return str.lower() in ['1', 'true', 'yes']
+def _str_to_bool(string):
+ return string.lower() in ['1', 'true', 'yes']
@BreadCrumb("Failure Report", parent=reports)
@@ -335,41 +330,45 @@
},
RequestContext(request))
+
def get_restricted_job(user, pk):
- job = get_object_or_404(TestJob.objects, pk=pk)
+ job = get_object_or_404(TestJob.objects, pk=pk)
if not job.is_accessible_by(user):
raise PermissionDenied()
return job
+
class SumIfSQL(models.sql.aggregates.Aggregate):
is_ordinal = True
sql_function = 'SUM'
sql_template = 'SUM((%(condition)s)::int)'
+
class SumIf(models.Aggregate):
name = 'SumIf'
+
def add_to_query(self, query, alias, col, source, is_summary):
- aggregate = SumIfSQL(
- col, source=source, is_summary=is_summary, **self.extra)
+ aggregate = SumIfSQL(col,
+ source=source, is_summary=is_summary, **self.extra)
query.aggregates[alias] = aggregate
+
class DeviceTypeTable(DataTablesTable):
def get_queryset(self):
- return DeviceType.objects.filter(display=True).annotate(
- idle=SumIf('device', condition='status=%s' % Device.IDLE),
- offline=SumIf('device', condition='status in (%s,%s)' % (
- Device.OFFLINE, Device.OFFLINING)),
- busy=SumIf('device', condition='status=%s' % Device.RUNNING),
- ).order_by('name')
+ return DeviceType.objects.filter(display=True)\
+ .annotate(idle=SumIf('device', condition='status=%s' % Device.IDLE),
+ offline=SumIf('device', condition='status in (%s,%s)' %
+ (Device.OFFLINE, Device.OFFLINING)),
+ busy=SumIf('device', condition='status=%s' % Device.RUNNING),).order_by('name')
def render_status(self, record):
- return "%s idle, %s offline, %s busy" % (record.idle, record.offline,
- record.busy)
+ return "%s idle, %s offline, %s busy" % (record.idle,
+ record.offline, record.busy)
datatable_opts = {
"iDisplayLength": 25
- }
+ }
name = IDLinkColumn("name")
status = Column()
@@ -384,31 +383,31 @@
"""
def render_Duration(self, record):
- matrix = {-24:"24hours", -24*7:"Week", -24*7*30:"Month"}
+ matrix = {-24: "24hours", -24 * 7: "Week", -24 * 7 * 30: "Month"}
return matrix[record]
def render_Complete(self, record):
device_type = self.params[0]
- num = health_jobs_in_hr(record).filter(
- actual_device__in=Device.objects.filter(
- device_type=device_type), status=TestJob.COMPLETE).count()
+ num = health_jobs_in_hr(record).filter(actual_device__in=Device.objects.filter(device_type=device_type),
+ status=TestJob.COMPLETE).count()
return num
def render_Failed(self, record):
device_type = self.params[0]
- num = health_jobs_in_hr(record).filter(
- actual_device__in=Device.objects.filter(
- device_type=device_type), status__in=[TestJob.INCOMPLETE,
- TestJob.CANCELED, TestJob.CANCELING]).count()
+ num = health_jobs_in_hr(record).filter(actual_device__in=Device.objects.filter(device_type=device_type),
+ status__in=[TestJob.INCOMPLETE,
+ TestJob.CANCELED, TestJob.CANCELING]).count()
return num
Duration = Column()
Complete = Column()
Failed = Column()
+
def device_type_json(request):
return DeviceTypeTable.json(request)
+
class NoDTDeviceTable(DeviceTable):
def get_queryset(self, device_type):
return Device.objects.filter(device_type=device_type)
@@ -416,10 +415,12 @@
class Meta:
exclude = ('device_type',)
+
def index_nodt_devices_json(request, pk):
device_type = get_object_or_404(DeviceType, pk=pk)
return NoDTDeviceTable.json(request, params=(device_type,))
+
@BreadCrumb("Device Type {pk}", parent=index, needs=['pk'])
def device_type_detail(request, pk):
dt = get_object_or_404(DeviceType, pk=pk)
@@ -432,13 +433,12 @@
status=TestJob.RUNNING).count(),
'queued_jobs_num': TestJob.objects.filter(
Q(status=TestJob.SUBMITTED), Q(requested_device_type=dt)
- | Q(requested_device__in=Device.objects.filter(device_type=dt))
- ).count(),
+ | Q(requested_device__in=Device.objects.filter(device_type=dt))).count(),
# data return 1 day, 1 week, 1 month offset
- 'health_job_summary_table': HealthJobSummaryTable(
- 'device_type', params=(dt,), data=[-24, -24*7, -24*7*30]),
- 'devices_table_no_dt': NoDTDeviceTable('devices',
- reverse(index_nodt_devices_json, kwargs=dict(pk=pk)), params=(dt,)),
+ 'health_job_summary_table': HealthJobSummaryTable('device_type',
+ params=(dt,), data=[-24, -24 * 7, -24 * 7 * 30]),
+ 'devices_table_no_dt': NoDTDeviceTable('devices', reverse(index_nodt_devices_json,
+ kwargs=dict(pk=pk)), params=(dt,)),
'bread_crumb_trail': BreadCrumbTrail.leading_to(device_type_detail, pk=pk),
},
RequestContext(request))
@@ -468,10 +468,10 @@
accessor="last_health_report_job.end_time")
last_health_report_job = Column("last report job")
- searchable_columns=['hostname']
+ searchable_columns = ['hostname']
datatable_opts = {
"iDisplayLength": 25
- }
+ }
def lab_health_json(request):
@@ -493,11 +493,8 @@
class HealthJobTable(JobTable):
def get_queryset(self, device):
- return TestJob.objects.select_related(
- "submitter",
- ).filter(
- actual_device=device,
- health_check=True)
+ return TestJob.objects.select_related("submitter",)\
+ .filter(actual_device=device, health_check=True)
class Meta:
exclude = ('description', 'device')
@@ -522,10 +519,10 @@
'health_job_table': HealthJobTable(
'health_jobs', reverse(health_jobs_json, kwargs=dict(pk=pk)),
params=(device,)),
- 'show_maintenance': device.can_admin(request.user) and \
- device.status in [Device.IDLE, Device.RUNNING],
- 'show_online': device.can_admin(request.user) and \
- device.status in [Device.OFFLINE, Device.OFFLINING],
+ 'show_maintenance': device.can_admin(request.user) and
+ device.status in [Device.IDLE, Device.RUNNING],
+ 'show_online': device.can_admin(request.user) and
+ device.status in [Device.OFFLINE, Device.OFFLINING],
'bread_crumb_trail': BreadCrumbTrail.leading_to(health_job_list, pk=pk),
},
RequestContext(request))
@@ -540,7 +537,7 @@
datatable_opts.update({
'iDisplayLength': 25,
- })
+ })
def alljobs_json(request):
@@ -569,7 +566,7 @@
response_data = {
'is_authorized': is_authorized,
'bread_crumb_trail': BreadCrumbTrail.leading_to(job_submit),
- }
+ }
if request.method == "POST" and is_authorized:
if request.is_ajax():
@@ -583,7 +580,7 @@
else:
try:
job = TestJob.from_json_and_user(
- request.POST.get("json-input"), request.user)
+ request.POST.get("json-input"), request.user)
response_data["job_id"] = job.id
return render_to_response(
@@ -627,22 +624,22 @@
levels[kl] = 0
for level, msg, _ in job_log_messages:
levels[level] += 1
- levels = sorted(levels.items(), key=lambda (k,v):logging._levelNames.get(k))
+ levels = sorted(levels.items(), key=lambda (k, v): logging._levelNames.get(k))
with job.output_file() as f:
f.seek(0, 2)
job_file_size = f.tell()
data.update({
'job_file_present': True,
- 'job_errors' : job_errors,
- 'job_has_error' : len(job_errors) > 0,
- 'job_log_messages' : job_log_messages,
+ 'job_errors': job_errors,
+ 'job_has_error': len(job_errors) > 0,
+ 'job_log_messages': job_log_messages,
'levels': levels,
- 'job_file_size' : job_file_size,
- })
+ 'job_file_size': job_file_size,
+ })
else:
data.update({
'job_file_present': False,
- })
+ })
return render_to_response(
"lava_scheduler_app/job.html", data, RequestContext(request))
@@ -663,7 +660,7 @@
def job_definition_plain(request, pk):
job = get_restricted_job(request.user, pk)
response = HttpResponse(job.definition, mimetype='text/plain')
- response['Content-Disposition'] = "attachment; filename=job_%d.json"%job.id
+ response['Content-Disposition'] = "attachment; filename=job_%d.json" % job.id
return response
@@ -679,8 +676,8 @@
{
'job': TestJob.objects.get(pk=pk),
'job_file_present': bool(job.output_file()),
- 'sections' : content,
- 'job_file_size' : job_file_size,
+ 'sections': content,
+ 'job_file_size': job_file_size,
},
RequestContext(request))
@@ -688,7 +685,7 @@
def job_log_file_plain(request, pk):
job = get_restricted_job(request.user, pk)
response = HttpResponse(job.output_file(), mimetype='text/plain')
- response['Content-Disposition'] = "attachment; filename=job_%d.log"%job.id
+ response['Content-Disposition'] = "attachment; filename=job_%d.log" % job.id
return response
@@ -715,7 +712,7 @@
new_content = log_file.read()
nl_index = new_content.rfind('\n', -NEWLINE_SCAN_SIZE)
if nl_index >= 0:
- new_content = new_content[:nl_index+1]
+ new_content = new_content[:nl_index + 1]
m = formatLogFile(StringIO.StringIO(new_content))
response = HttpResponse(
simplejson.dumps(m), content_type='application/json')
@@ -725,7 +722,7 @@
return response
-LOG_CHUNK_SIZE = 512*1024
+LOG_CHUNK_SIZE = 512 * 1024
NEWLINE_SCAN_SIZE = 80
@@ -753,7 +750,7 @@
content = log_file.read(size - start)
nl_index = content.rfind('\n', -NEWLINE_SCAN_SIZE)
if nl_index >= 0 and not count_present:
- content = content[:nl_index+1]
+ content = content[:nl_index + 1]
response = HttpResponse(content)
if skipped:
response['X-Skipped-Bytes'] = str(skipped)
@@ -819,10 +816,10 @@
json_text = simplejson.dumps({
'status': job.get_status_display(),
'results_link': request.build_absolute_uri(job.results_link),
- })
+ })
content_type = 'application/json'
if 'callback' in request.GET:
- json_text = '%s(%s)'%(request.GET['callback'], json_text)
+ json_text = '%s(%s)' % (request.GET['callback'], json_text)
content_type = 'text/javascript'
return HttpResponse(json_text, content_type=content_type)
@@ -896,7 +893,7 @@
datatable_opts = {
'aaSorting': [[0, 'desc']],
- }
+ }
def transition_json(request, pk):
@@ -925,10 +922,10 @@
'recent_job_table': RecentJobsTable(
'jobs', reverse(recent_jobs_json, kwargs=dict(pk=device.pk)),
params=(device,)),
- 'show_maintenance': device.can_admin(request.user) and \
- device.status in [Device.IDLE, Device.RUNNING],
- 'show_online': device.can_admin(request.user) and \
- device.status in [Device.OFFLINE, Device.OFFLINING],
+ 'show_maintenance': device.can_admin(request.user) and
+ device.status in [Device.IDLE, Device.RUNNING],
+ 'show_online': device.can_admin(request.user) and
+ device.status in [Device.OFFLINE, Device.OFFLINING],
'bread_crumb_trail': BreadCrumbTrail.leading_to(device_detail, pk=pk),
},
RequestContext(request))
@@ -955,6 +952,7 @@
return HttpResponseForbidden(
"you cannot administer this device", content_type="text/plain")
+
@post_only
def device_looping_mode(request, pk):
device = Device.objects.get(pk=pk)
@@ -964,4 +962,3 @@
else:
return HttpResponseForbidden(
"you cannot administer this device", content_type="text/plain")
-
=== modified file 'lava_scheduler_daemon/board.py'
@@ -17,7 +17,6 @@
return eb
-
class DispatcherProcessProtocol(ProcessProtocol):
def __init__(self, deferred, job):
@@ -34,15 +33,15 @@
def childConnectionLost(self, childFD):
self.logger.info("childConnectionLost for %s: %s",
- self.job.board_name, childFD)
+ self.job.board_name, childFD)
def processExited(self, reason):
self.logger.info("processExited for %s: %s",
- self.job.board_name, reason.value)
+ self.job.board_name, reason.value)
def processEnded(self, reason):
self.logger.info("processEnded for %s: %s",
- self.job.board_name, reason.value)
+ self.job.board_name, reason.value)
self.deferred.callback(reason.value.exitCode)
@@ -70,8 +69,8 @@
self.cancel()
else:
return self._source_lock.run(
- self.source.jobCheckForCancellation, self.board_name).addCallback(
- self._maybeCancel)
+ self.source.jobCheckForCancellation,
+ self.board_name).addCallback(self._maybeCancel)
def cancel(self, reason=None):
if not self._killing:
@@ -117,7 +116,7 @@
self.reactor.spawnProcess(
self._protocol, self.dispatcher, args=[
self.dispatcher, self._json_file, '--output-dir', output_dir],
- childFDs={0:0, 1:'r', 2:'r'}, env=None)
+ childFDs={0: 0, 1: 'r', 2: 'r'}, env=None)
self._checkCancel_call.start(10)
timeout = max(
json_data['timeout'], self.daemon_options['MIN_JOB_TIMEOUT'])
@@ -139,7 +138,7 @@
self.board_name,
exit_code,
self._killing).addCallback(
- lambda r:exit_code)
+ lambda r: exit_code)
class SchedulerMonitorPP(ProcessProtocol):
@@ -164,7 +163,6 @@
class MonitorJob(object):
-
def __init__(self, job_data, dispatcher, source, board_name, reactor,
daemon_options):
self.logger = logging.getLogger(__name__ + '.MonitorJob')
=== modified file 'lava_scheduler_daemon/config.py'
@@ -6,12 +6,13 @@
defaults = {
'logging': StringIO(
-'''
+ '''
[logging]
level = INFO
destination = -
'''),
- }
+}
+
# python xdg isn't installable via pip, so...
def load_config_paths(name):
=== modified file 'lava_scheduler_daemon/dbjobsource.py'
@@ -36,6 +36,7 @@
except ImportError:
class InterfaceError(Exception):
pass
+
class OperationalError(Exception):
pass
@@ -68,10 +69,10 @@
except (DatabaseError, OperationalError, InterfaceError), error:
message = str(error)
if message == 'connection already closed' or \
- message.startswith(
- 'terminating connection due to administrator command') or \
- message.startswith(
- 'could not connect to server: Connection refused'):
+ message.startswith(
+ 'terminating connection due to administrator command') or \
+ message.startswith(
+ 'could not connect to server: Connection refused'):
self.logger.warning(
'Forcing reconnection on next db access attempt')
if connection.connection:
@@ -152,7 +153,7 @@
jobs_for_device = jobs_for_device.extra(
select={
'is_targeted': 'requested_device_id is not NULL',
- },
+ },
where=[
# In human language, this is saying "where the number of
# tags that are on the job but not on the device is 0"
@@ -162,7 +163,7 @@
from lava_scheduler_app_device_tags
where device_id = '%s')) = 0'''
% device.hostname,
- ],
+ ],
order_by=['-is_targeted', '-priority', 'submit_time'])
jobs = jobs_for_device[:1]
if jobs:
@@ -315,6 +316,7 @@
def jobCheckForCancellation(self, board_name):
return self.deferForDB(self.jobCheckForCancellation_impl, board_name)
+
def _get_device_version(bundle):
if bundle is None:
return None
=== modified file 'lava_scheduler_daemon/jobsource.py'
@@ -6,7 +6,7 @@
from zope.interface import (
implements,
Interface,
- )
+)
logger = logging.getLogger(__name__)
=== modified file 'lava_scheduler_daemon/tests/test_board.py'
@@ -7,11 +7,13 @@
from lava_scheduler_daemon.board import Board
+
def stub_method(method_name):
def method_impl(self, board_name, *args):
assert method_name not in self._requests[board_name], (
'overlapping call to %s on %s' % (method_name, board_name))
d = self._requests[method_name][board_name] = defer.Deferred()
+
def _remove_request(result):
del self._requests[method_name][board_name]
return result
@@ -24,7 +26,7 @@
class TestJobSource(object):
def __init__(self):
- self._calls = defaultdict(lambda :defaultdict(list))
+ self._calls = defaultdict(lambda: defaultdict(list))
self._requests = defaultdict(dict)
jobCompleted = stub_method('jobCompleted')
@@ -166,5 +168,5 @@
b = self.make_board('board')
b.start()
self.source._completeCall('getJobForBoard', 'board', None)
- self.clock.advance(10000) # hack: the delay should be config data
+ self.clock.advance(10000) # hack: the delay should be config data
self.assertEqual('C', b._state_name())