-from django.core.exceptions import ObjectDoesNotExist
from django.utils import timezone
from django.utils.deprecation import MiddlewareMixin
+from account.models import UserProfile
+
class TimezoneMiddleware(MiddlewareMixin):
"""
"""
def process_request(self, request):
if request.user.is_authenticated:
- timezone.activate(request.user.userprofile.timezone)
+ try:
+ tz = request.user.userprofile.timezone
+ timezone.activate(tz)
+ except UserProfile.DoesNotExist:
+ UserProfile.objects.create(user=request.user)
+ tz = request.user.userprofile.timezone
+ timezone.activate(tz)
else:
timezone.deactivate()
# -*- coding: utf-8 -*-
-# Generated by Django 1.10 on 2016-08-12 09:51
+# Generated by Django 1.10 on 2016-08-15 12:19
from __future__ import unicode_literals
from django.conf import settings
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
- ('dashboard', '0001_initial'),
]
operations = [
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('sshkey', models.CharField(max_length=1024)),
+ ('timezone', models.CharField(default='UTC', max_length=100)),
+ ('sshkey', models.CharField(max_length=2048)),
+ ('pgpkey', models.CharField(max_length=2048)),
('company', models.CharField(max_length=200)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
'db_table': 'user_profile',
},
),
- migrations.CreateModel(
- name='UserResource',
- fields=[
- ('id', models.AutoField(primary_key=True, serialize=False)),
- ('resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='dashboard.Resource')),
- ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
- ],
- options={
- 'db_table': 'user_resource',
- },
- ),
]
# -*- coding: utf-8 -*-
-# Generated by Django 1.10 on 2016-08-12 09:51
+# Generated by Django 1.10 on 2016-08-15 12:19
from __future__ import unicode_literals
from django.conf import settings
initial = True
dependencies = [
- migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('dashboard', '0001_initial'),
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
name='Booking',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
- ('deleted', models.BooleanField(default=False)),
('start', models.DateTimeField()),
('end', models.DateTimeField()),
- ('status', models.CharField(max_length=20)),
('purpose', models.CharField(max_length=300)),
('resource', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='dashboard.Resource')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
from booking.models import Booking
from dashboard.models import Resource
+from jenkins.models import JenkinsSlave
class BookingModelTestCase(TestCase):
def setUp(self):
- self.res1 = Resource.objects.create(name='res1', slavename='s1', description='x', url='x')
- self.res2 = Resource.objects.create(name='res2', slavename='s2', description='x', url='x')
+ self.slave = JenkinsSlave.objects.create(name='test', url='test')
+
+ self.res1 = Resource.objects.create(name='res1', slave=self.slave, description='x', url='x')
+ self.res2 = Resource.objects.create(name='res2', slave=self.slave, description='x', url='x')
self.user1 = User.objects.create(username='user1')
from account.models import UserProfile
from booking.models import Booking
from dashboard.models import Resource
+from jenkins.models import JenkinsSlave
class BookingViewTestCase(TestCase):
def setUp(self):
self.client = Client()
- self.res1 = Resource.objects.create(name='res1', slavename='s1', description='x', url='x')
+ self.slave = JenkinsSlave.objects.create(name='test', url='test')
+ self.res1 = Resource.objects.create(name='res1', slave=self.slave, description='x', url='x')
self.user1 = User.objects.create(username='user1')
self.user1.set_password('user1')
self.user1profile = UserProfile.objects.create(user=self.user1)
"name": "Linux Foundation POD 1",
"slavename": "lf-pod1",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Lf+Lab",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Lf+Lab"
}
},
{
"name": "Linux Foundation POD 2",
"slavename": "lf-pod2",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Lf+Lab",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Lf+Lab"
}
},
{
"name": "Ericsson POD 2",
"slavename": "ericsson-pod2",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Ericsson+Hosting+and+Request+Process",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Ericsson+Hosting+and+Request+Process"
}
},
{
"name": "Intel POD 2",
"slavename": "intel-pod2",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod2",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod2"
}
},
{
"name": "Intel POD 5",
"slavename": "intel-pod5",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod5",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod5"
}
},
{
"name": "Intel POD 6",
"slavename": "intel-pod6",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod6",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod6"
}
},
{
"name": "Intel POD 8",
"slavename": "intel-pod8",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod8",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod8"
}
},
{
"name": "Huawei POD 1",
"slavename": "huawei-pod1",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting",
- "bookable": false,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting"
}
},
{
"name": "Intel POD 3",
"slavename": "intel-pod3",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod3",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod3"
}
},
{
"name": "Dell POD 1",
"slavename": "dell-pod1",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Dell+Hosting",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Dell+Hosting"
}
},
{
"name": "Dell POD 2",
"slavename": "dell-pod2",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Dell+Hosting",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Dell+Hosting"
}
},
{
"name": "Orange POD 2",
"slavename": "orange-pod2",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Opnfv-orange-pod2",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Opnfv-orange-pod2"
}
},
{
"name": "Arm POD 1",
"slavename": "arm-build1",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Enea-pharos-lab",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Enea-pharos-lab"
}
},
{
"name": "Ericsson POD 1",
"slavename": "ericsson-pod1",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Ericsson+Hosting+and+Request+Process",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Ericsson+Hosting+and+Request+Process"
}
},
{
"name": "Huawei POD 2",
"slavename": "huawei-pod2",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting"
}
},
{
"name": "Huawei POD 3",
"slavename": "huawei-pod3",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting"
}
},
{
"name": "Huawei POD 4",
"slavename": "huawei-pod4",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Huawei+Hosting"
}
},
{
"name": "Intel POD 9",
"slavename": "intel-pod9",
"description": "Some description",
- "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod9",
- "bookable": true,
- "active": true
+ "url": "https://wiki.opnfv.org/display/pharos/Intel+Pod9"
}
}
]
# -*- coding: utf-8 -*-
-# Generated by Django 1.10 on 2016-08-12 09:51
+# Generated by Django 1.10 on 2016-08-15 12:19
from __future__ import unicode_literals
+from django.conf import settings
from django.db import migrations, models
initial = True
dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
('slavename', models.CharField(blank=True, max_length=50, null=True)),
('description', models.CharField(blank=True, max_length=300, null=True)),
('url', models.CharField(blank=True, max_length=100, null=True)),
- ('bookable', models.BooleanField(default=False)),
- ('active', models.BooleanField(default=True)),
+ ('owners', models.ManyToManyField(to=settings.AUTH_USER_MODEL)),
],
options={
'db_table': 'resource',
},
),
+ migrations.CreateModel(
+ name='ResourceUtilization',
+ fields=[
+ ('timestamp', models.DateTimeField(auto_created=True)),
+ ('id', models.AutoField(primary_key=True, serialize=False)),
+ ('pod_status', models.IntegerField()),
+ ],
+ ),
]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-08-15 15:11
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('jenkins', '0002_auto_20160815_1226'),
+ ('dashboard', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='resource',
+ name='slavename',
+ ),
+ migrations.AddField(
+ model_name='resource',
+ name='slave',
+ field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, to='jenkins.JenkinsSlave'),
+ preserve_default=False,
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-08-15 15:12
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('dashboard', '0002_auto_20160815_1511'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='resource',
+ name='slave',
+ ),
+ migrations.AddField(
+ model_name='resource',
+ name='slavename',
+ field=models.CharField(blank=True, max_length=50, null=True),
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-08-15 15:13
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('jenkins', '0002_auto_20160815_1226'),
+ ('dashboard', '0003_auto_20160815_1512'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='resource',
+ name='slave',
+ field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, to='jenkins.JenkinsSlave'),
+ preserve_default=False,
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-08-15 15:17
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('dashboard', '0004_resource_slave'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='resource',
+ name='slavename',
+ ),
+ ]
from django.contrib.auth.models import User
from django.db import models
+from django.utils import timezone
+
+from jenkins.models import JenkinsSlave
class Resource(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=100, unique=True)
- slavename = models.CharField(max_length=50, blank=True, null=True)
description = models.CharField(max_length=300, blank=True, null=True)
url = models.CharField(max_length=100, blank=True, null=True)
owners = models.ManyToManyField(User)
+ slave = models.ForeignKey(JenkinsSlave, on_delete=models.DO_NOTHING)
class Meta:
db_table = 'resource'
def __str__(self):
return self.name
+
class ResourceUtilization(models.Model):
POD_STATUS = {
'online': 1,
id = models.AutoField(primary_key=True)
timestamp = models.DateTimeField(auto_created=True)
- pod_status = models.IntegerField()
\ No newline at end of file
+ pod_status = models.IntegerField()
--- /dev/null
+from django.template.defaultfilters import register
+
+
+@register.filter
+def jenkins_job_color(job_result):
+ if job_result == 'SUCCESS':
+ return '#5cb85c'
+ if job_result == 'FAILURE':
+ return '#d9534f'
+ if job_result == 'UNSTABLE':
+ return '#EDD62B'
+ return '#646F73' # job is still building
+
+
+@register.filter
+def jenkins_status_color(slave_status):
+ if slave_status == 'offline':
+ return '#d9534f'
+ if slave_status == 'online':
+ return '#5cb85c'
+ if slave_status == 'online / idle':
+ return '#5bc0de'
+
+@register.filter
+def jenkins_job_blink(job_result):
+ if job_result == '': # job is still building
+ return 'class=blink_me'
\ No newline at end of file
+from datetime import timedelta
from django.utils import timezone
from django.views.generic import TemplateView
from booking.models import Booking
from dashboard.models import Resource
from jenkins import adapter as jenkins
+from jenkins.models import JenkinsSlave, JenkinsStatistic
class JenkinsSlavesView(TemplateView):
template_name = "dashboard/jenkins_slaves.html"
def get_context_data(self, **kwargs):
- slaves = jenkins.get_all_slaves()
- for slave in slaves:
- jenkins.parse_slave_data(slave, slave)
-
+ slaves = JenkinsSlave.objects.all()
context = super(JenkinsSlavesView, self).get_context_data(**kwargs)
context.update({'title': "Jenkins Slaves", 'slaves': slaves})
return context
template_name = "dashboard/ci_pods.html"
def get_context_data(self, **kwargs):
- resources = Resource.objects.filter().values() # get resources as a set of dicts
- ci_pods = []
- for resource in resources:
- if not jenkins.is_ci_slave(resource['slavename']):
- continue
- ci_slave = jenkins.get_slave(resource['slavename'])
- jenkins.parse_slave_data(resource, ci_slave)
- ci_pods.append(resource)
-
+ ci_pods = Resource.objects.filter(slave__ci_slave=True)
context = super(CIPodsView, self).get_context_data(**kwargs)
context.update({'title': "CI Pods", 'ci_pods': ci_pods})
return context
template_name = "dashboard/dev_pods.html"
def get_context_data(self, **kwargs):
- resources = Resource.objects.filter().values() # get resources as a set of dicts
- dev_pods = []
+ resources = Resource.objects.filter(slave__dev_pod=True)
- current_bookings = Booking.objects.filter(start__lte=timezone.now())
- current_bookings = current_bookings.filter(end__gt=timezone.now())
+ bookings = Booking.objects.filter(start__lte=timezone.now())
+ bookings = bookings.filter(end__gt=timezone.now())
+ dev_pods = []
for resource in resources:
- if not jenkins.is_dev_pod(resource['slavename']):
- continue
- dev_pod = jenkins.get_slave(resource['slavename'])
- jenkins.parse_slave_data(resource, dev_pod)
- for booking in current_bookings:
- if booking.resource.slavename == resource['slavename']:
- resource['current_booking'] = booking
- dev_pods.append(resource)
+ dev_pod = (resource, None)
+ for booking in bookings:
+ if booking.resource == resource:
+ dev_pod = (resource, booking)
+ dev_pods.append(dev_pod)
context = super(DevelopmentPodsView, self).get_context_data(**kwargs)
context.update({'title': "Development Pods", 'dev_pods': dev_pods})
response = requests.get(url)
json = response.json()
cache.set(url, json, 180) # cache result for 180 seconds
- return response.json()
+ return json
except requests.exceptions.RequestException as e:
logger.exception(e)
except ValueError as e:
return True
return False
-def parse_slave_data(slave_dict, slave):
- slave_dict['status'] = get_slave_status(slave)
- slave_dict['status_color'] = get_status_color(slave)
- slave_dict['slaveurl'] = get_slave_url(slave)
- job = get_jenkins_job(slave['displayName'])
- if job is not None:
- slave_dict['last_job'] = parse_job(job)
-
def parse_job(job):
result = parse_job_string(job['lastBuild']['fullDisplayName'])
+ result['building'] = job['lastBuild']['building']
+ result['result'] = ''
+ if not job['lastBuild']['building']:
+ result['result'] = job['lastBuild']['result']
result['url'] = job['url']
- result['color'] = get_job_color(job)
- if job['lastBuild']['building']:
- result['blink'] = 'class=blink_me'
return result
def parse_job_string(full_displayname):
job = {}
+ job['scenario'] = ''
+ job['installer'] = ''
+ job['branch'] = ''
tokens = re.split(r'[ -]', full_displayname)
for i in range(len(tokens)):
if tokens[i] == 'os':
job['installer'] = tokens[i]
elif tokens[i] in ['master', 'arno', 'brahmaputra', 'colorado']:
job['branch'] = tokens[i]
-
tokens = full_displayname.split(' ')
job['name'] = tokens[0]
return job
-
-# TODO: use css
-def get_job_color(job):
- if job['lastBuild']['building'] is True:
- return '#646F73'
- result = job['lastBuild']['result']
- if result == 'SUCCESS':
- return '#5cb85c'
- if result == 'FAILURE':
- return '#d9534f'
- if result == 'UNSTABLE':
- return '#EDD62B'
-
-
-# TODO: use css
-def get_status_color(slave):
- if not slave['offline'] and slave['idle']:
- return '#5bc0de'
- if not slave['offline']:
- return '#5cb85c'
- return '#d9534f'
-
-
def get_slave_url(slave):
return 'https://build.opnfv.org/ci/computer/' + slave['displayName']
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-08-15 12:19
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='JenkinsSlave',
+ fields=[
+ ('id', models.AutoField(primary_key=True, serialize=False)),
+ ('name', models.CharField(max_length=100, unique=True)),
+ ('status', models.CharField(default='offline', max_length=30)),
+ ('url', models.CharField(max_length=1024)),
+ ('ci_slave', models.BooleanField(default=False)),
+ ('dev_pod', models.BooleanField(default=False)),
+ ('building', models.BooleanField(default=False)),
+ ('last_job_name', models.CharField(default='', max_length=1024)),
+ ('last_job_url', models.CharField(default='', max_length=1024)),
+ ('last_job_scenario', models.CharField(default='', max_length=50)),
+ ('last_job_branch', models.CharField(default='', max_length=50)),
+ ('last_job_installer', models.CharField(default='', max_length=50)),
+ ('last_job_result', models.CharField(default='', max_length=30)),
+ ],
+ options={
+ 'db_table': 'jenkins_slave',
+ },
+ ),
+ migrations.CreateModel(
+ name='JenkinsStatistic',
+ fields=[
+ ('timestamp', models.DateTimeField(auto_created=True)),
+ ('id', models.AutoField(primary_key=True, serialize=False)),
+ ('offline', models.BooleanField(default=False)),
+ ('idle', models.BooleanField(default=False)),
+ ('online', models.BooleanField(default=False)),
+ ('slave', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='jenkins.JenkinsSlave')),
+ ],
+ options={
+ 'db_table': 'jenkins_statistic',
+ },
+ ),
+ ]
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.10 on 2016-08-15 12:26
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('jenkins', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='jenkinsstatistic',
+ name='timestamp',
+ field=models.DateTimeField(auto_now_add=True),
+ ),
+ ]
--- /dev/null
+from django.db import models
+
+
+class JenkinsSlave(models.Model):
+ id = models.AutoField(primary_key=True)
+ name = models.CharField(max_length=100, unique=True)
+ status = models.CharField(max_length=30, default='offline')
+ url = models.CharField(max_length=1024)
+ ci_slave = models.BooleanField(default=False)
+ dev_pod = models.BooleanField(default=False)
+
+ building = models.BooleanField(default=False)
+
+ last_job_name = models.CharField(max_length=1024, default='')
+ last_job_url = models.CharField(max_length=1024, default='')
+ last_job_scenario = models.CharField(max_length=50, default='')
+ last_job_branch = models.CharField(max_length=50, default='')
+ last_job_installer = models.CharField(max_length=50, default='')
+ last_job_result = models.CharField(max_length=30, default='')
+
+ class Meta:
+ db_table = 'jenkins_slave'
+
+
+class JenkinsStatistic(models.Model):
+ id = models.AutoField(primary_key=True)
+ slave = models.ForeignKey(JenkinsSlave, on_delete=models.CASCADE)
+ offline = models.BooleanField(default=False)
+ idle = models.BooleanField(default=False)
+ online = models.BooleanField(default=False)
+ timestamp = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ db_table = 'jenkins_statistic'
--- /dev/null
+from celery import shared_task
+
+from jenkins.models import JenkinsSlave, JenkinsStatistic
+from .adapter import *
+
+
+@shared_task
+def sync_jenkins():
+ update_jenkins_slaves()
+
+
+def update_jenkins_slaves():
+ jenkins_slaves = get_all_slaves()
+ for slave in jenkins_slaves:
+ jenkins_slave, created = JenkinsSlave.objects.get_or_create(name=slave['displayName'],
+ url=get_slave_url(slave))
+ jenkins_slave.ci_slave = is_ci_slave(slave['displayName'])
+ jenkins_slave.dev_pod = is_dev_pod(slave['displayName'])
+ jenkins_slave.status = get_slave_status(slave)
+
+ last_job = get_jenkins_job(jenkins_slave.name)
+ if last_job is not None:
+ last_job = parse_job(last_job)
+ jenkins_slave.last_job_name = last_job['name']
+ jenkins_slave.last_job_url = last_job['url']
+ jenkins_slave.last_job_scenario = last_job['scenario']
+ jenkins_slave.last_job_branch = last_job['branch']
+ jenkins_slave.last_job_installer = last_job['installer']
+ jenkins_slave.last_job_result = last_job['result']
+ jenkins_slave.save()
+
+ jenkins_statistic = JenkinsStatistic(slave=jenkins_slave)
+ if jenkins_slave.status == 'online' or jenkins_slave.status == 'building':
+ jenkins_statistic.online = True
+ if jenkins_slave.status == 'offline':
+ jenkins_statistic.offline = True
+ if jenkins_slave.status == 'online / idle':
+ jenkins_statistic.idle = True
+ jenkins_statistic.save()
+# This will make sure the app is always imported when
+# Django starts so that shared_task will use this app.
+from .celery import app as celery_app # noqa
--- /dev/null
+import os
+
+from celery import Celery
+
+# set the default Django settings module for the 'celery' program.
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'pharos_dashboard.settings')
+
+from django.conf import settings # noqa
+
+app = Celery('pharos_dashboard')
+
+# Using a string here means the worker will not have to
+# pickle the object when using Windows.
+app.config_from_object('django.conf:settings')
+app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
+
+
+@app.task(bind=True)
+def debug_task(self):
+ print('Request: {0!r}'.format(self.request))
\ No newline at end of file
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
ALLOWED_HOSTS = []
-
# Application definition
INSTALLED_APPS = [
'django.contrib.staticfiles',
'django.contrib.humanize',
'bootstrap3',
+ 'djcelery',
+ 'kombu.transport.django',
]
MIDDLEWARE = [
WSGI_APPLICATION = 'pharos_dashboard.wsgi.application'
-
# Database
# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
}
}
-
# Password validation
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
USE_TZ = True
-
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.10/howto/static-files/
}
LOGIN_REDIRECT_URL = '/'
+
+import djcelery
+
+djcelery.setup_loader()
+# django broker, NOT SAFE FOR PRODUCTION
+BROKER_URL = 'django://'
+CELERYBEAT_SCHEDULER = 'djcelery.schedulers.DatabaseScheduler'
+
{% extends "dashboard/table.html" %}
{% load staticfiles %}
+{% load jenkins_filters %}
{% block table %}
<thead>
<a target='_blank' href={{ pod.url }}>{{ pod.name }}</a>
</th>
<th>
- <a target='_blank' href={{ pod.slaveurl }}>{{ pod.slavename }}</a>
+ <a target='_blank' href={{ pod.slave.url }}>{{ pod.slave.name }}</a>
</th>
- <th style="background-color:{{ pod.status_color }}">
- {{ pod.status }}
+ <th style="background-color:{{ pod.slave.status | jenkins_status_color }}">
+ {{ pod.slave.status }}
</th>
- <th {{ pod.last_job.blink }}>
- {{ pod.last_job.installer }}
+ <th {{ pod.slave.last_job_result | jenkins_job_blink }}>
+ {{ pod.slave.last_job_installer }}
</th>
- <th {{ pod.last_job.blink }}>
- {{ pod.last_job.scenario }}
+ <th {{ pod.slave.last_job_result | jenkins_job_blink }}>
+ {{ pod.slave.last_job_scenario }}
</th>
- <th {{ pod.last_job.blink }}>
- {{ pod.last_job.branch }}
+ <th {{ pod.slave.last_job_result | jenkins_job_blink }}>
+ {{ pod.slave.last_job_branch }}
</th>
- <th><a {{ pod.last_job.blink }} style="color:{{ pod.last_job.color }}"
- target='_blank'
- href={{ pod.last_job.url }}>{{ pod.last_job.name }}</a>
+ <th><a {{ pod.slave.last_job_result | jenkins_job_blink }}
+ style="color:{{ pod.slave.last_job_result | jenkins_job_color }}"
+ target='_blank'
+ href={{ pod.slave.last_job_url }}>{{ pod.slave.last_job_name }}</a>
</th>
</tr>
{% endfor %}`
{% extends "dashboard/table.html" %}
{% load staticfiles %}
+{% load jenkins_filters %}
{% block table %}
<thead>
</tr>
</thead>
<tbody>
- {% for resource in dev_pods %}
+ {% for pod, booking in dev_pods %}
<tr>
<th>
- <a target='_blank' href={{ resource.url }}>{{ resource.name }}</a>
+ <a target='_blank' href={{ pod.url }}>{{ pod.name }}</a>
</th>
<th>
- <a target='_blank' href={{ resource.slaveurl }}>{{ resource.slavename }}</a>
+ <a target='_blank' href={{ pod.slave.url }}>{{ pod.slave.name }}</a>
</th>
<th>
- {{ resource.current_booking.user.username }}
+ {{ booking.user.username }}
</th>
<th>
- {{ resource.current_booking.end }}
+ {{ booking.end }}
</th>
<th>
- {{ resource.current_booking.purpose }}
+ {{ booking.purpose }}
</th>
- <th style="background-color:{{ resource.status_color }}">
- {{ resource.status }}
+ <th style="background-color:{{ pod.slave.status | jenkins_status_color }}">
+ {{ pod.slave.status }}
</th>
<th>
- <a href="{% url 'booking:create' resource_id=resource.id %}" class="btn btn-primary">
+ <a href="{% url 'booking:create' resource_id=pod.id %}" class="btn btn-primary">
Book
</a>
</th>
{% extends "dashboard/table.html" %}
{% load staticfiles %}
+{% load jenkins_filters %}
+
{% block table %}
<thead>
<tr>
{% for slave in slaves %}
<tr>
<th><a target='_blank'
- href={{ slave.slaveurl }}>{{ slave.displayName }}</a>
+ href={{ slave.url }}>{{ slave.name }}</a>
</th>
- <th style="background-color:{{ slave.status_color }}">
+ <th style="background-color:{{ slave.status | jenkins_status_color }}">
{{ slave.status }}
</th>
- <th><a {{ slave.last_job.blink }} style="color:{{ slave.last_job.color }}"
- target="_blank" href={{ slave.last_job.url }}>
- {{ slave.last_job.name }}</a>
+ <th><a {{ slave.last_job_result | jenkins_job_blink }}
+ style="color:{{ slave.last_job_result | jenkins_job_color }}"
+ target="_blank" href={{ slave.last_job_url }}>
+ {{ slave.last_job_name }}</a>
</th>
</tr>
{% endfor %}