Commit 198283ab authored by Neil Williams's avatar Neil Williams
Browse files

Drop Python2 xmlrpc support

No need for the check to Python2 or the mapping of a
Python3 module to a Python2 name.

Change-Id: I1c2df55c9d68cd2ccf0927a6dcc1c28240a03b0e
parent 13fa6bde
......@@ -26,7 +26,7 @@ import re
import hashlib
import os
import subprocess
import sys
import xmlrpc.client
from django.contrib.auth.models import User, Group
from django.core.urlresolvers import reverse
from django.db import IntegrityError
......@@ -40,13 +40,6 @@ from lava_scheduler_app.models import (
TestJob,
)
if sys.version_info[0] == 2:
# Python 2.x
import xmlrpclib
elif sys.version_info[0] == 3:
# For Python 3.0 and later
import xmlrpc.client as xmlrpclib
class errors:
"""
......
......@@ -45,20 +45,22 @@ snippet:
.. code-block:: python
import xmlrpclib
# Python3
import xmlrpc.client
import simplejson
config = simplejson.dumps({ ... })
server=xmlrpclib.ServerProxy("http://username:API-Key@localhost:8001/RPC2/")
server=xmlrpc.client.ServerProxy("http://username:API-Key@localhost:8001/RPC2/")
jobid=server.scheduler.submit_job(config)
XML-RPC can also be used to query data anonymously:
.. code-block:: python
import xmlrpclib
# Python3
import xmlrpc.client
server = xmlrpclib.ServerProxy("http://sylvester.codehelp/RPC2")
server = xmlrpc.client.ServerProxy("http://sylvester.codehelp/RPC2")
print server.system.listMethods()
Individual XML-RPC commands are documented on the `API Help
......
......@@ -783,7 +783,7 @@ functionality using :ref:`XML-RPC <xml_rpc>`.
self._authenticate()
#. Catch exceptions for all errors, ``SubmissionException``, ``DoesNotExist``
and others, then re-raise as ``xmlrpclib.Fault``.
and others, then re-raise as ``xmlrpc.client.Fault``.
#. Move as much of the work into the relevant app as possible, either in
``models.py`` or in ``dbutils.py``. Wherever possible, re-use existing
......
#!/usr/bin/env python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# incomplete-results.py
......@@ -27,10 +27,7 @@
import sys
import yaml
if sys.version_info < (3, 0):
import xmlrpclib
else:
import xmlrpc.client as xmlrpclib
import xmlrpc.client
# configuration
USER = 'neil.williams'
......@@ -60,7 +57,7 @@ STATUS_CHOICES = (
# main_function
def main(args):
# change https to http when testing with localhost
connection = xmlrpclib.ServerProxy("https://%s:%s@%s/RPC2" % (USER, TOKEN, HOSTNAME))
connection = xmlrpc.client.ServerProxy("https://%s:%s@%s/RPC2" % (USER, TOKEN, HOSTNAME))
data = connection.results.run_query(QUERY, 20, QUERY_USER)
if not data:
return 0
......@@ -82,5 +79,4 @@ def main(args):
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
......@@ -584,12 +584,13 @@ specified Device hostname:
.. code-block:: python
import xmlrpclib
# Python3
import xmlrpc.client
username = "USERNAME"
token = "TOKEN_STRING"
hostname = "HOSTNAME"
protocol = "PROTOCOL" # http or preferably https
server = xmlrpclib.ServerProxy("%s://%s:%s@%s/RPC2" % (protocol, username, token, hostname))
server = xmlrpc.client.ServerProxy("%s://%s:%s@%s/RPC2" % (protocol, username, token, hostname))
server.scheduler.import_device_dictionary(device_hostname, jinja_string)
If the dictionary did not exist for this hostname, it will be created. The
......
......@@ -19,7 +19,7 @@
import csv
import io
import yaml
import sys
import xmlrpc.client
from linaro_django_xmlrpc.models import ExposedAPI
......@@ -44,13 +44,6 @@ from lava_results_app.models import (
from lava_results_app.utils import get_testcases_with_limit
from lava_scheduler_app.models import TestJob
if sys.version_info[0] == 2:
# Python 2.x
import xmlrpclib
elif sys.version_info[0] == 3:
# For Python 3.0 and later
import xmlrpc.client as xmlrpclib
class ResultsAPI(ExposedAPI):
......@@ -103,12 +96,12 @@ class ResultsAPI(ExposedAPI):
try:
content_type = Query.get_content_type(entity)
except InvalidContentTypeError:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
400, "Wrong table name in entity parameter. "
"Please refer to query docs.")
if content_type.model_class() not in QueryCondition.RELATION_MAP:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
400, "Wrong table name in entity parameter. "
"Please refer to query docs.")
......@@ -118,9 +111,9 @@ class ResultsAPI(ExposedAPI):
results = Query.get_queryset(content_type,
conditions).visible_by_user(self.user)
except FieldDoesNotExist:
raise xmlrpclib.Fault(400,
"Conditions URL incorrect: Field does not exist. "
"Please refer to query docs.")
raise xmlrpc.client.Fault(
400, "Conditions URL incorrect: Field does not exist. "
"Please refer to query docs.")
return list(results[:limit])
def run_query(self, query_name, limit=200, username=None):
......@@ -163,12 +156,12 @@ class ResultsAPI(ExposedAPI):
query = Query.objects.get(name=query_name,
owner__username=username)
except Query.DoesNotExist:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
404, "Query with name %s owned by user %s does not exist." %
(query_name, username))
if not query.is_accessible_by(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
403, "Permission denied for user to query %s" % query_name)
return list(query.get_results(self.user)[:limit])
......@@ -207,24 +200,24 @@ class ResultsAPI(ExposedAPI):
query = Query.objects.get(name=query_name,
owner__username=username)
except Query.DoesNotExist:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
400, "Query with name %s owned by user %s does not exist." %
(query_name, username))
if not query.is_accessible_by(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to query %s" % query_name)
try:
query.refresh_view()
except QueryUpdatedError as e:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
400, "Query with name %s owned by user %s was recently refreshed." % (query_name, username))
except RefreshLiveQueryError as e:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
400, "Query with name %s owned by user %s cannot be refreshed since it's a live query." % (query_name, username))
except Exception as e:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Query refresh failed. Please contact system administrator: %s" % str(e))
def refresh_all_queries(self):
......@@ -248,7 +241,7 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not self.user.is_superuser:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user %s. Must be a superuser to "
"refresh all queries." % self.user.username)
......@@ -256,10 +249,10 @@ class ResultsAPI(ExposedAPI):
try:
query.refresh_view()
except QueryUpdatedError as e:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
400, "Query with name %s owned by user %s was recently refreshed." % (query_name, username))
except Exception as e:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Refresh operation for query with name %s owned by user %s failed. Please contact system administrator. Error: %s" % (query.name, query.owner.username, str(e)))
def get_testjob_results_yaml(self, job_id):
......@@ -285,12 +278,12 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
yaml_list = []
for test_suite in job.testsuite_set.all():
......@@ -298,7 +291,7 @@ class ResultsAPI(ExposedAPI):
yaml_list.append(export_testcase(test_case))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
return yaml.dump(yaml_list)
......@@ -338,15 +331,15 @@ class ResultsAPI(ExposedAPI):
"""
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
return job.get_metadata_dict()
......@@ -373,12 +366,12 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
output = io.BytesIO()
writer = csv.DictWriter(
......@@ -392,7 +385,7 @@ class ResultsAPI(ExposedAPI):
writer.writerow(export_testcase(row))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
return output.getvalue()
......@@ -420,12 +413,12 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
output = io.BytesIO()
writer = csv.DictWriter(
......@@ -438,7 +431,7 @@ class ResultsAPI(ExposedAPI):
writer.writerow(export_testsuite(test_suite))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
return output.getvalue()
......@@ -466,19 +459,19 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
yaml_list = []
for test_suite in job.testsuite_set.all():
yaml_list.append(export_testsuite(test_suite))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
return yaml.dump(yaml_list)
......@@ -512,12 +505,12 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
yaml_list = []
test_suite = job.testsuite_set.get(name=suite_name)
......@@ -526,9 +519,9 @@ class ResultsAPI(ExposedAPI):
yaml_list.append(export_testcase(test_case))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
except TestSuite.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test suite not found.")
raise xmlrpc.client.Fault(404, "Specified test suite not found.")
return yaml.dump(yaml_list)
......@@ -562,12 +555,12 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
output = io.BytesIO()
writer = csv.DictWriter(
......@@ -581,9 +574,9 @@ class ResultsAPI(ExposedAPI):
writer.writerow(export_testcase(row))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
except TestSuite.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test suite not found.")
raise xmlrpc.client.Fault(404, "Specified test suite not found.")
return output.getvalue()
......@@ -612,21 +605,21 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
test_suite = job.testsuite_set.get(name=suite_name)
test_case_count = test_suite.testcase_set.all().count()
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
except TestSuite.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test suite not found.")
raise xmlrpc.client.Fault(404, "Specified test suite not found.")
return test_case_count
......@@ -659,23 +652,23 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
test_suite = job.testsuite_set.get(name=suite_name)
test_cases = test_suite.testcase_set.filter(name=case_name)
yaml_list = [export_testcase(test_case) for test_case in test_cases]
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
except TestSuite.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test suite not found.")
raise xmlrpc.client.Fault(404, "Specified test suite not found.")
except TestCase.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test case not found.")
raise xmlrpc.client.Fault(404, "Specified test case not found.")
return yaml.dump(yaml_list)
......@@ -708,12 +701,12 @@ class ResultsAPI(ExposedAPI):
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
try:
job = TestJob.get_by_job_number(job_id)
if not job.can_view(self.user):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
output = io.BytesIO()
......@@ -728,10 +721,10 @@ class ResultsAPI(ExposedAPI):
writer.writerow(export_testcase(test_case))
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
except TestSuite.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test suite not found.")
raise xmlrpc.client.Fault(404, "Specified test suite not found.")
except TestCase.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified test case not found.")
raise xmlrpc.client.Fault(404, "Specified test case not found.")
return output.getvalue()
......@@ -2,7 +2,7 @@ from functools import wraps
from simplejson import JSONDecodeError
import yaml
import sys
import xmlrpc.client
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.db.models import Count, Q
......@@ -28,13 +28,6 @@ from lava_scheduler_app.schema import (
SubmissionException,
)
if sys.version_info[0] == 2:
# Python 2.x
import xmlrpclib
elif sys.version_info[0] == 3:
# For Python 3.0 and later
import xmlrpc.client as xmlrpclib
# functions need to be members to be exposed in the API
# pylint: disable=no-self-use
......@@ -48,7 +41,7 @@ def check_superuser(f):
def wrapper(self, *args, **kwargs):
self._authenticate()
if not self.user.is_superuser:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
403,
"User '%s' is not superuser." % self.user.username
)
......@@ -97,21 +90,21 @@ class SchedulerAPI(ExposedAPI):
"""
self._authenticate()
if not self.user.has_perm('lava_scheduler_app.add_testjob'):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
403, "Permission denied. User %r does not have the "
"'lava_scheduler_app.add_testjob' permission. Contact "
"the administrators." % self.user.username)
try:
job = testjob_submission(job_data, self.user)
except SubmissionException as exc:
raise xmlrpclib.Fault(400, "Problem with submitted job data: %s" % exc)
raise xmlrpc.client.Fault(400, "Problem with submitted job data: %s" % exc)
# FIXME: json error is not needed anymore
except (JSONDataError, JSONDecodeError, ValueError) as exc:
raise xmlrpclib.Fault(400, "Decoding job submission failed: %s." % exc)
raise xmlrpc.client.Fault(400, "Decoding job submission failed: %s." % exc)
except (Device.DoesNotExist, DeviceType.DoesNotExist):
raise xmlrpclib.Fault(404, "Specified device or device type not found.")
raise xmlrpc.client.Fault(404, "Specified device or device type not found.")
except DevicesUnavailableException as exc:
raise xmlrpclib.Fault(400, "Device unavailable: %s" % str(exc))
raise xmlrpc.client.Fault(400, "Device unavailable: %s" % str(exc))
if isinstance(job, type(list())):
return [j.sub_id for j in job]
else:
......@@ -140,14 +133,14 @@ class SchedulerAPI(ExposedAPI):
"""
self._authenticate()
if not self.user.has_perm('lava_scheduler_app.add_testjob'):
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
403, "Permission denied. User %r does not have the "
"'lava_scheduler_app.add_testjob' permission. Contact "
"the administrators." % self.user.username)
try:
job = get_restricted_job(self.user, job_id)
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
if job.is_multinode:
return self.submit_job(job.multinode_definition)
......@@ -175,23 +168,23 @@ class SchedulerAPI(ExposedAPI):
"""
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")
raise xmlrpc.client.Fault(
400, "Bad request: TestJob id was not specified.")
with transaction.atomic():
try:
job = get_restricted_job(self.user, job_id, for_update=True)
except PermissionDenied:
raise xmlrpclib.Fault(
raise xmlrpc.client.Fault(
401, "Permission denied for user to job %s" % job_id)
except TestJob.DoesNotExist:
raise xmlrpclib.Fault(404, "Specified job not found.")
raise xmlrpc.client.Fault(404, "Specified job not found.")
if job.state in [TestJob.STATE_CANCELING, TestJob.STATE_FINISHED]:
# Don't do anything for jobs that ended already
return True
if not job.can_cancel(self.user):
raise xmlrpclib.Fault(403, "Permission denied.")
raise xmlrpc.client.Fault(403, "Permission denied.")
if job.is_multinode:
multinode_jobs = TestJob.objects.select_for_update().filter(
......@@ -232,12 +225,12 @@ class SchedulerAPI(ExposedAPI):
# YAML can parse JSON as YAML, JSON cannot parse YAML at all
yaml_data = yaml.load(yaml_string)
except yaml.YAMLError as exc:
raise xmlrpclib.Fault(400, "Decoding job submission failed: %s." % exc)
raise xmlrpc.client.Fault(400, "Decoding job submission failed: %s." % exc)
try:
# validate against the submission schema.
validate_submission(yaml_data) # raises SubmissionException if invalid.
except SubmissionException as exc:
raise xmlrpclib.Fault(400, "Invalid YAML submission: %s" % exc)
raise xmlrpc.client.Fault(400, "Invalid YAML submission: %s" % exc)
def job_output(self, job_id, offset=0):
"""
......@@ -264,22 +257,22 @@ class SchedulerAPI(ExposedAPI):
"""
self._authenticate()
if not job_id:
raise xmlrpclib.Fault(400, "Bad request: TestJob id was not "
"specified.")