From patchwork Mon Aug 22 03:29:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael-Doyle Hudson X-Patchwork-Id: 3588 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 15DCA23F4D for ; Mon, 22 Aug 2011 03:29:17 +0000 (UTC) Received: from mail-gy0-f180.google.com (mail-gy0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id BB06CA185DC for ; Mon, 22 Aug 2011 03:29:16 +0000 (UTC) Received: by gyc15 with SMTP id 15so4814475gyc.11 for ; Sun, 21 Aug 2011 20:29:16 -0700 (PDT) Received: by 10.150.170.13 with SMTP id s13mr1806718ybe.48.1313983756156; Sun, 21 Aug 2011 20:29:16 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.150.157.17 with SMTP id f17cs181257ybe; Sun, 21 Aug 2011 20:29:15 -0700 (PDT) Received: by 10.227.11.70 with SMTP id s6mr1595691wbs.42.1313983754309; Sun, 21 Aug 2011 20:29:14 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com [91.189.90.7]) by mx.google.com with ESMTPS id fn2si4386048wbb.125.2011.08.21.20.29.13 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 21 Aug 2011 20:29:14 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QvLCL-0002Hz-GM for ; Mon, 22 Aug 2011 03:29:13 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 6E953E0342 for ; Mon, 22 Aug 2011 03:29:13 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: lava-scheduler X-Launchpad-Branch: ~linaro-validation/lava-scheduler/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 69 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-validation/lava-scheduler/trunk] Rev 69: * add a simple device view Message-Id: <20110822032913.9098.51063.launchpad@ackee.canonical.com> Date: Mon, 22 Aug 2011 03:29:13 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13697"; Instance="initZopeless config overlay" X-Launchpad-Hash: 1a61e5d15656ecfe0c3b258752805183b284cb78 Merge authors: Michael Hudson-Doyle (mwhudson) ------------------------------------------------------------ revno: 69 [merge] committer: Michael-Doyle Hudson branch nick: trunk timestamp: Mon 2011-08-22 15:28:24 +1200 message: * add a simple device view * add buttons to allow privileged people to move devices in and out of maintenance mode added: lava_scheduler_app/templates/lava_scheduler_app/device.html modified: lava_scheduler_app/models.py lava_scheduler_app/templates/lava_scheduler_app/index.html lava_scheduler_app/urls.py lava_scheduler_app/views.py lava_scheduler_daemon/dbjobsource.py --- lp:lava-scheduler https://code.launchpad.net/~linaro-validation/lava-scheduler/trunk You are subscribed to branch lp:lava-scheduler. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-scheduler/trunk/+edit-subscription === modified file 'lava_scheduler_app/models.py' --- lava_scheduler_app/models.py 2011-08-19 03:24:11 +0000 +++ lava_scheduler_app/models.py 2011-08-22 03:08:56 +0000 @@ -26,11 +26,13 @@ OFFLINE = 0 IDLE = 1 RUNNING = 2 + OFFLINING = 3 STATUS_CHOICES = ( (OFFLINE, 'Offline'), (IDLE, 'Idle'), (RUNNING, 'Running'), + (OFFLINING, 'Going offline'), ) hostname = models.CharField( @@ -51,6 +53,20 @@ verbose_name = _(u"Device status"), ) + def can_admin(self, user): + return user.has_perm('lava_scheduler_app.change_device') + + def put_into_maintenance_mode(self): + if self.status == self.RUNNING: + self.status = self.OFFLINING + else: + self.status = self.OFFLINE + self.save() + + def put_into_online_mode(self): + self.status = self.IDLE + self.save() + def __unicode__(self): return self.hostname === added file 'lava_scheduler_app/templates/lava_scheduler_app/device.html' --- lava_scheduler_app/templates/lava_scheduler_app/device.html 1970-01-01 00:00:00 +0000 +++ lava_scheduler_app/templates/lava_scheduler_app/device.html 2011-08-22 03:22:22 +0000 @@ -0,0 +1,98 @@ +{% extends "lava_scheduler_app/_content.html" %} + +{% block extrahead %} +{{ block.super }} + +{% endblock %} + +{% block content %} +

Device {{ device.hostname }}

+ +{% if show_maintenance %} +
+ {% csrf_token %} + +
+{% endif %} +{% if show_online %} +
+ {% csrf_token %} + +
+{% endif %} + +
+
+
Hostname:
+
{{ device.hostname }}
+ +
Device type:
+
{{ device.device_type }}
+
+
+
Status:
+
{{ device.get_status_display }}
+ +{% if device.current_job %} +
Currently running:
+
+ + Job {{ device.current_job.id }} + +
+{% endif %} +
+
+
+ + + + + + + + + + + + + + {% for job in recent_jobs %} + + + + + + + + + {% endfor %} + +
IDStatusDeviceSubmitterStart TimeFinish Time
{{ job.id }}{{ job.get_status_display }}{{ job.actual_device }}{{ job.submitter }}{{ job.start_time }}{{ job.end_time|default:"not finished" }}
+ + + +{% endblock %} === modified file 'lava_scheduler_app/templates/lava_scheduler_app/index.html' --- lava_scheduler_app/templates/lava_scheduler_app/index.html 2011-08-04 09:28:39 +0000 +++ lava_scheduler_app/templates/lava_scheduler_app/index.html 2011-08-22 03:24:30 +0000 @@ -15,7 +15,11 @@ {% for device in devices %} {{ device.device_type }} - {{ device.hostname }} + + + {{ device.hostname }} + + {{ device.get_status_display }} {% endfor %} === modified file 'lava_scheduler_app/urls.py' --- lava_scheduler_app/urls.py 2011-08-19 03:24:11 +0000 +++ lava_scheduler_app/urls.py 2011-08-22 03:08:56 +0000 @@ -4,6 +4,9 @@ 'lava_scheduler_app.views', url(r'^$', 'index'), url(r'^alljobs$', 'alljobs'), + url(r'^device/(?P[-_a-zA-Z0-9]+)$', 'device'), + url(r'^device/(?P[-_a-zA-Z0-9]+)/maintenance$', 'device_maintenance_mode'), + url(r'^device/(?P[-_a-zA-Z0-9]+)/online$', 'device_online'), url(r'^job/(?P[0-9]+)$', 'job'), url(r'^job/(?P[0-9]+)/output$', 'job_output'), url(r'^job/(?P[0-9]+)/cancel$', 'job_cancel'), === modified file 'lava_scheduler_app/views.py' --- lava_scheduler_app/views.py 2011-08-22 03:01:17 +0000 +++ lava_scheduler_app/views.py 2011-08-22 03:26:03 +0000 @@ -94,3 +94,42 @@ else: return HttpResponseForbidden( "you cannot cancel this job", content_type="text/plain") + + +def device(request, pk): + device = Device.objects.get(pk=pk) + recent_jobs = TestJob.objects.all().filter( + actual_device=device).order_by('-start_time') + return render_to_response( + "lava_scheduler_app/device.html", + { + 'device': device, + 'recent_jobs': recent_jobs, + '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], + }, + RequestContext(request)) + + +@post_only +def device_maintenance_mode(request, pk): + device = Device.objects.get(pk=pk) + if device.can_admin(request.user): + device.put_into_maintenance_mode() + return redirect('lava_scheduler_app.views.device', pk=device.pk) + else: + return HttpResponseForbidden( + "you cannot administer this device", content_type="text/plain") + + +@post_only +def device_online(request, pk): + device = Device.objects.get(pk=pk) + if device.can_admin(request.user): + device.put_into_online_mode() + return redirect('lava_scheduler_app.views.device', pk=device.pk) + else: + return HttpResponseForbidden( + "you cannot administer this device", content_type="text/plain") === modified file 'lava_scheduler_daemon/dbjobsource.py' --- lava_scheduler_daemon/dbjobsource.py 2011-08-19 02:38:22 +0000 +++ lava_scheduler_daemon/dbjobsource.py 2011-08-22 03:20:17 +0000 @@ -124,7 +124,14 @@ def jobCompleted_impl(self, board_name): self.logger.debug('marking job as complete on %s', board_name) device = Device.objects.get(hostname=board_name) - device.status = Device.IDLE + if device.status == Device.RUNNING: + device.status = Device.IDLE + elif device.status == Device.OFFLINING: + device.status = Device.OFFLINE + else: + self.logger.error( + "Unexpected device state in jobCompleted: %s" % device.status) + device.status = Device.IDLE job = device.current_job device.current_job = None if job.status == TestJob.RUNNING: