=== modified file 'lava_scheduler_app/models.py'
--- lava_scheduler_app/models.py	2012-06-22 05:06:06 +0000
+++ lava_scheduler_app/models.py	2012-06-29 03:26:14 +0000
@@ -321,7 +321,7 @@
         return ("lava.scheduler.job.detail", [self.pk])
 
     @classmethod
-    def from_json_and_user(cls, json_data, user):
+    def from_json_and_user(cls, json_data, user, health_check=False):
         job_data = simplejson.loads(json_data)
         validate_job_data(job_data)
         if 'target' in job_data:
@@ -350,10 +350,12 @@
                         raise ValueError(
                             "%r is not a valid email address." % address)
 
+        if job_data.get('health_check', False) and not health_check:
+            raise ValueError(
+                "cannot submit a job with health_check: true via the api.")
+
         job_name = job_data.get('job_name', '')
 
-        is_check = job_data.get('health_check', False)
-
         submitter = user
         group = None
         is_public = True
@@ -383,7 +385,7 @@
         job = TestJob(
             definition=json_data, submitter=submitter,
             requested_device=target, requested_device_type=device_type,
-            description=job_name, health_check=is_check, user=user,
+            description=job_name, health_check=health_check, user=user,
             group=group, is_public=is_public)
         job.save()
         for tag in tags:

=== modified file 'lava_scheduler_daemon/dbjobsource.py'
--- lava_scheduler_daemon/dbjobsource.py	2012-06-22 05:07:18 +0000
+++ lava_scheduler_daemon/dbjobsource.py	2012-06-29 03:14:32 +0000
@@ -1,5 +1,4 @@
 import datetime
-import json
 import logging
 import urlparse
 
@@ -14,11 +13,17 @@
 
 from linaro_django_xmlrpc.models import AuthToken
 
+import simplejson
+
 from twisted.internet.threads import deferToThread
 
 from zope.interface import implements
 
-from lava_scheduler_app.models import Device, DeviceStateTransition, TestJob
+from lava_scheduler_app.models import (
+    Device,
+    DeviceStateTransition,
+    JSONDataError,
+    TestJob)
 from lava_scheduler_daemon.jobsource import IJobSource
 
 
@@ -89,7 +94,7 @@
         return self.deferForDB(self.getBoardList_impl)
 
     def _get_json_data(self, job):
-        json_data = json.loads(job.definition)
+        json_data = simplejson.loads(job.definition)
         json_data['target'] = job.actual_device.hostname
         for action in json_data['actions']:
             if not action['command'].startswith('submit_results'):
@@ -103,23 +108,31 @@
             parsed = list(parsed)
             parsed[1] = netloc
             params['server'] = urlparse.urlunsplit(parsed)
+        json_data['health_check'] = job.health_check
         return json_data
 
     def _getHealthCheckJobForBoard(self, device):
         job_json = device.device_type.health_check_job
         if not job_json:
+            # This should never happen, it's a logic error.
             self.logger.error(
                 "no job_json in getHealthCheckJobForBoard for %r", device)
+            device.put_into_maintenance_mode(
+                None, "no job_json in getHealthCheckJobForBoard")
             return None
         else:
             user = User.objects.get(username='lava-health')
-            job_data = json.loads(job_json)
-            job_name = job_data.get('job_name')
-            job = TestJob(
-                definition=job_json, submitter=user, description=job_name,
-                health_check=True, owner=user, is_public=True)
-            job.save()
-            return job
+            job_data = simplejson.loads(job_json)
+            job_data['target'] = device.hostname
+            job_json = simplejson.dumps(job_data)
+            try:
+                return TestJob.from_json_and_user(job_json, user, True)
+            except (JSONDataError, ValueError) as e:
+                self.logger.exception(
+                    "TestJob.from_json_and_user failed in _getHealthCheckJobForBoard")
+                device.put_into_maintenance_mode(
+                    None, "TestJob.from_json_and_user failed for health job: %s" % e)
+                return None
 
     def _getJobFromQueue(self, device):
         jobs_for_device = TestJob.objects.all().filter(
@@ -197,6 +210,9 @@
                     transaction.commit()
                     return json_data
             else:
+                # _getHealthCheckJobForBoard can offline the board, so commit
+                # in this branch too.
+                transaction.commit()
                 return None
 
     def getJobForBoard(self, board_name):

