blob: 4006c45925a682e222b4297e360134ebfd513f35 [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
115
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
120 def resubmit_job(self, job_id):
121 """ Re-submit job with provided id. Returns resulting job id,
122 and server url for job"""
123
124 job_id = self.scheduler.resubmit_job(job_id)
125 job_url = self.server_job_prefix % job_id
126 return(job_id, job_url)
127
128 def block_wait_for_job(self, job_id, timeout, poll_freq=1):
129 """ Will block code execution and wait for the job to submit.
130 Returns job status on completion """
131
132 start_t = int(time.time())
133 while(True):
134 cur_t = int(time.time())
135 if cur_t - start_t >= timeout:
136 print("Breaking because of timeout")
137 break
138 # Check if the job is not running
Dean Arnoldf1169b92020-03-11 10:14:14 +0000139 cur_status = self.get_job_state(job_id)
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100140 # If in queue or running wait
Dean Arnoldc1d81b42020-03-11 15:56:36 +0000141 if cur_status not in ["Canceling","Finished"]:
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100142 time.sleep(poll_freq)
143 else:
144 break
Dean Arnoldc1d81b42020-03-11 15:56:36 +0000145 return self.scheduler.job_health(job_id)["job_health"]
Minos Galanakisf4ca6ac2017-12-11 02:39:21 +0100146
147 def test_credentials(self):
148 """ Attempt to querry the back-end and verify that the user provided
149 authentication is valid """
150
151 try:
152 self._rpc_cmd_raw("system.listMethods")
153 return True
154 except Exception as e:
155 print(e)
156 print("Credential validation failed")
157 return False
158
159
160if __name__ == "__main__":
161 pass