Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 1 | from __future__ import print_function |
Dmitry Tyzhnenko | 5a5d8da | 2017-12-14 14:14:42 +0200 | [diff] [blame] | 2 | |
| 3 | import jenkins |
Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 4 | import requests |
Dmitry Tyzhnenko | 5a5d8da | 2017-12-14 14:14:42 +0200 | [diff] [blame] | 5 | |
| 6 | from devops.helpers import helpers |
| 7 | |
| 8 | |
| 9 | class JenkinsClient(object): |
| 10 | |
| 11 | def __init__(self, host=None, username=None, password=None): |
| 12 | host = host or 'http://172.16.44.33:8081' |
| 13 | username = username or 'admin' |
| 14 | password = password or 'r00tme' |
| 15 | self.__client = jenkins.Jenkins( |
| 16 | host, |
| 17 | username=username, |
| 18 | password=password) |
| 19 | |
| 20 | def jobs(self): |
| 21 | return self.__client.get_jobs() |
| 22 | |
| 23 | def find_jobs(self, name): |
| 24 | return filter(lambda x: name in x['fullname'], self.jobs()) |
| 25 | |
| 26 | def job_info(self, name): |
| 27 | return self.__client.get_job_info(name) |
| 28 | |
| 29 | def list_builds(self, name): |
| 30 | return self.job_info(name).get('builds') |
| 31 | |
| 32 | def build_info(self, name, build_id): |
| 33 | return self.__client.get_build_info(name, build_id) |
| 34 | |
| 35 | def job_params(self, name): |
| 36 | job = self.job_info(name) |
| 37 | job_params = next( |
| 38 | p for p in job['property'] if |
| 39 | 'hudson.model.ParametersDefinitionProperty' == p['_class']) |
| 40 | job_params = job_params['parameterDefinitions'] |
| 41 | return job_params |
| 42 | |
| 43 | def make_defults_params(self, name): |
| 44 | job_params = self.job_params(name) |
| 45 | def_params = dict( |
| 46 | [(j['name'], j['defaultParameterValue']['value']) |
| 47 | for j in job_params]) |
| 48 | return def_params |
| 49 | |
Dennis Dmitriev | a5bd165 | 2018-05-31 20:57:19 +0300 | [diff] [blame^] | 50 | def run_build(self, name, params=None, timeout=600, verbose=False): |
Dmitry Tyzhnenko | 5a5d8da | 2017-12-14 14:14:42 +0200 | [diff] [blame] | 51 | params = params or self.make_defults_params(name) |
Dennis Dmitriev | a5bd165 | 2018-05-31 20:57:19 +0300 | [diff] [blame^] | 52 | num = self.__client.build_job(name, params) |
| 53 | |
| 54 | def is_blocked(): |
| 55 | queued = self.__client.get_queue_item(num) |
| 56 | status = not queued['blocked'] |
| 57 | if not status and verbose: |
| 58 | print("pending the job [{}] : {}".format(name, queued['why'])) |
| 59 | return status |
| 60 | |
| 61 | helpers.wait( |
| 62 | is_blocked, |
| 63 | timeout=timeout, |
| 64 | interval=30, |
| 65 | timeout_msg='Timeout waiting to run the job [{}]'.format(name)) |
| 66 | |
| 67 | build_id = self.__client.get_queue_item(num)['executable']['number'] |
Dmitry Tyzhnenko | 5a5d8da | 2017-12-14 14:14:42 +0200 | [diff] [blame] | 68 | return name, build_id |
| 69 | |
Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 70 | def wait_end_of_build(self, name, build_id, timeout=600, |
Dennis Dmitriev | a5bd165 | 2018-05-31 20:57:19 +0300 | [diff] [blame^] | 71 | verbose=False): |
Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 72 | start = [0] |
Dmitry Tyzhnenko | 5a5d8da | 2017-12-14 14:14:42 +0200 | [diff] [blame] | 73 | |
| 74 | def building(): |
Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 75 | status = not self.build_info(name, build_id)['building'] |
Dennis Dmitriev | a5bd165 | 2018-05-31 20:57:19 +0300 | [diff] [blame^] | 76 | if verbose: |
Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 77 | res = self.get_progressive_build_output(name, |
| 78 | build_id, |
| 79 | start=start[0]) |
| 80 | if 'X-Text-Size' in res.headers: |
| 81 | text_size = int(res.headers['X-Text-Size']) |
| 82 | if start[0] < text_size: |
| 83 | print(res.content, end='') |
| 84 | start[0] = text_size |
| 85 | return status |
Dmitry Tyzhnenko | 5a5d8da | 2017-12-14 14:14:42 +0200 | [diff] [blame] | 86 | |
| 87 | helpers.wait( |
| 88 | building, |
| 89 | timeout=timeout, |
| 90 | timeout_msg='Timeout waiting, job {0} are not finished "{1}" build' |
| 91 | ' still'.format(name, build_id)) |
Dmitry Tyzhnenko | b610afd | 2018-02-19 15:43:45 +0200 | [diff] [blame] | 92 | |
| 93 | def get_build_output(self, name, build_id): |
| 94 | return self.__client.get_build_console_output(name, build_id) |
Dennis Dmitriev | 6111511 | 2018-05-31 06:48:43 +0300 | [diff] [blame] | 95 | |
| 96 | def get_progressive_build_output(self, name, build_id, start=0, |
| 97 | raise_on_err=False): |
| 98 | '''Get build console text. |
| 99 | |
| 100 | :param name: Job name, ``str`` |
| 101 | :param name: Build id, ``int`` |
| 102 | :param name: Start offset, ``int`` |
| 103 | :returns: requests object with headers and console output, ``obj`` |
| 104 | ''' |
| 105 | folder_url, short_name = self.__client._get_job_folder(name) |
| 106 | |
| 107 | PROGRESSIVE_CONSOLE_OUTPUT = ( |
| 108 | '%(folder_url)sjob/%(short_name)s/%(build_id)d/' |
| 109 | 'logText/progressiveHtml?start=%(start)d') |
| 110 | url = self.__client._build_url(PROGRESSIVE_CONSOLE_OUTPUT, locals()) |
| 111 | return(requests.get(url)) |