blob: e7571db21e4c5ae6ff46be5e570ec5cb2e1db012 [file] [log] [blame]
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +01001#!/usr/bin/env python3
2
3""" lava_rpc_connector.py:
4
5 class that extends xmlrpc in order to add LAVA specific functionality.
6 Used in managing communication with the back-end. """
7
8from __future__ import print_function
9
10__copyright__ = """
11/*
Dean Arnoldf1169b92020-03-11 10:14:14 +000012 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010013 *
14 * SPDX-License-Identifier: BSD-3-Clause
15 *
16 */
17 """
18__author__ = "Minos Galanakis"
19__email__ = "minos.galanakis@linaro.org"
20__project__ = "Trusted Firmware-M Open CI"
21__status__ = "stable"
Minos Galanakisea421232019-06-20 17:11:28 +010022__version__ = "1.1"
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010023
24import xmlrpc.client
25import time
26
27
28class LAVA_RPC_connector(xmlrpc.client.ServerProxy, object):
29
30 def __init__(self,
31 username,
32 token,
33 hostname,
34 rest_prefix="RPC2",
35 https=False):
36
37 # If user provides hostname with http/s prefix
38 if "://" in hostname:
39 htp_pre, hostname = hostname.split("://")
40 server_addr = "%s://%s:%s@%s/%s" % (htp_pre,
41 username,
42 token,
43 hostname,
44 rest_prefix)
45 self.server_url = "%s://%s" % (htp_pre, hostname)
46 else:
47 server_addr = "%s://%s:%s@%s/%s" % ("https" if https else "http",
48 username,
49 token,
50 hostname,
51 rest_prefix)
52 self.server_url = "%s://%s" % ("https" if https else "http",
53 hostname)
54
55 self.server_job_prefix = "%s/scheduler/job/%%s" % self.server_url
56 super(LAVA_RPC_connector, self).__init__(server_addr)
57
58 def _rpc_cmd_raw(self, cmd, params=None):
59 """ Run a remote comand and return the result. There is no constrain
60 check on the syntax of the command. """
61
62 cmd = "self.%s(%s)" % (cmd, params if params else "")
63 return eval(cmd)
64
65 def ls_cmd(self):
66 """ Return a list of supported commands """
67
68 print("\n".join(self.system.listMethods()))
69
70 def get_job_results(self, job_id, yaml_out_file=None):
71 results = self.results.get_testjob_results_yaml(job_id)
72 if yaml_out_file:
73 with open(yaml_out_file, "w") as F:
74 F.write(results)
75 return results
76
77 def get_job_state(self, job_id):
78 return self.scheduler.job_state(job_id)["job_state"]
79
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +010080 def cancel_job(self, job_id):
81 """ Cancell job with id=job_id. Returns True if successfull """
82
83 return self.scheduler.jobs.cancel(job_id)
84
85 def validate_job_yaml(self, job_definition, print_err=False):
86 """ Validate a job definition syntax. Returns true is server considers
87 the syntax valid """
88
89 try:
90 with open(job_definition) as F:
91 input_yaml = F.read()
92 self.scheduler.validate_yaml(input_yaml)
93 return True
94 except Exception as E:
95 if print_err:
96 print(E)
97 return False
98
99 def submit_job(self, job_definition):
100 """ Will submit a yaml definition pointed by job_definition after
101 validating it againist the remote backend. Returns resulting job id,
102 and server url for job"""
103
104 try:
105 if not self.validate_job_yaml(job_definition):
106 print("Served rejected job's syntax")
107 raise Exception("Invalid job")
108 with open(job_definition, "r") as F:
109 job_data = F.read()
110 except Exception as e:
111 print("Cannot submit invalid job. Check %s's content" %
112 job_definition)
113 print(e)
114 return None, None
Dean Bircha6ede7e2020-03-13 14:00:33 +0000115 try:
116 job_id = self.scheduler.submit_job(job_data)
117 job_url = self.server_job_prefix % job_id
118 return(job_id, job_url)
119 except Exception as e:
120 print(e)
121 return(None, None)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100122
123 def resubmit_job(self, job_id):
124 """ Re-submit job with provided id. Returns resulting job id,
125 and server url for job"""
126
127 job_id = self.scheduler.resubmit_job(job_id)
128 job_url = self.server_job_prefix % job_id
129 return(job_id, job_url)
130
131 def block_wait_for_job(self, job_id, timeout, poll_freq=1):
132 """ Will block code execution and wait for the job to submit.
133 Returns job status on completion """
134
135 start_t = int(time.time())
136 while(True):
137 cur_t = int(time.time())
138 if cur_t - start_t >= timeout:
139 print("Breaking because of timeout")
140 break
141 # Check if the job is not running
Dean Arnoldf1169b92020-03-11 10:14:14 +0000142 cur_status = self.get_job_state(job_id)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100143 # If in queue or running wait
Dean Arnoldc1d81b42020-03-11 15:56:36 +0000144 if cur_status not in ["Canceling","Finished"]:
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100145 time.sleep(poll_freq)
146 else:
147 break
Dean Arnoldc1d81b42020-03-11 15:56:36 +0000148 return self.scheduler.job_health(job_id)["job_health"]
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100149
150 def test_credentials(self):
151 """ Attempt to querry the back-end and verify that the user provided
152 authentication is valid """
153
154 try:
155 self._rpc_cmd_raw("system.listMethods")
156 return True
157 except Exception as e:
158 print(e)
159 print("Credential validation failed")
160 return False
161
162
163if __name__ == "__main__":
164 pass