1 | #!/usr/bin/env python |
---|
2 | |
---|
3 | import argparse |
---|
4 | from csv import DictReader |
---|
5 | from glob import glob |
---|
6 | import logging |
---|
7 | import os |
---|
8 | from pprint import pprint,pformat |
---|
9 | import jenkinsapi.custom_exceptions |
---|
10 | from jenkinsapi.jenkins import Jenkins |
---|
11 | import shlex |
---|
12 | import subprocess |
---|
13 | import sys |
---|
14 | import xml.etree.ElementTree as etree |
---|
15 | |
---|
16 | |
---|
17 | osc="osc" |
---|
18 | #osc_paramter="--apiurl=https://obs.dass-it" |
---|
19 | #prj="bareos:playground" |
---|
20 | #pkg="bareos" |
---|
21 | osc_paramter="" |
---|
22 | prj="" |
---|
23 | pkg="" |
---|
24 | destdir="" |
---|
25 | wait=False |
---|
26 | |
---|
27 | class STATE: |
---|
28 | disabled="DISABLED" |
---|
29 | unknown="UNKNOWN" |
---|
30 | pending="PENDING" |
---|
31 | failed="FAILED" |
---|
32 | succeeded="SUCCEEDED" |
---|
33 | |
---|
34 | |
---|
35 | jenkins_status = { |
---|
36 | 'status': STATE.disabled, |
---|
37 | 'jobname': "", |
---|
38 | } |
---|
39 | |
---|
40 | def format_command( cmd ): |
---|
41 | logger=logging.getLogger(__name__) |
---|
42 | #logger.debug( "cmd1:" + str(cmd) ) |
---|
43 | cmd2=" ".join( cmd ) |
---|
44 | logger.debug( "cmd2:" + str(cmd2) ) |
---|
45 | cmd3=shlex.split( cmd2 ) |
---|
46 | #logger.debug( "cmd3:" + str(cmd3) ) |
---|
47 | return cmd3 |
---|
48 | |
---|
49 | def show( string, array ): |
---|
50 | if array: |
---|
51 | print string + ":" |
---|
52 | for i in array: |
---|
53 | print " ", i |
---|
54 | |
---|
55 | def write_status(obs, jenkins_status): |
---|
56 | filename = "status.succeeded" |
---|
57 | status = STATE.succeeded |
---|
58 | component="" |
---|
59 | if obs.get_state() != STATE.succeeded and obs.get_state() != STATE.disabled: |
---|
60 | component = "obs" |
---|
61 | status = obs.get_state() |
---|
62 | elif jenkins_status['status'] != STATE.succeeded and jenkins_status['status'] != STATE.disabled: |
---|
63 | component = "jenkins" |
---|
64 | status = jenkins_status['status'] |
---|
65 | |
---|
66 | if component: |
---|
67 | filename="status." + status.lower() + "." + component |
---|
68 | |
---|
69 | if destdir: |
---|
70 | filepath=destdir + "/" + filename |
---|
71 | out=open(filepath, 'w') |
---|
72 | logger.info("status will be written to " + filepath) |
---|
73 | # remove outdated files |
---|
74 | for i in glob(destdir + "/status*"): |
---|
75 | if not os.path.samefile(i, filepath): |
---|
76 | logger.debug("remove outdated status file " + i) |
---|
77 | os.remove(i) |
---|
78 | else: |
---|
79 | out=sys.stdout |
---|
80 | |
---|
81 | out.write( "#\n" ) |
---|
82 | out.write( "STATUS="+status+"\n" ) |
---|
83 | out.write( "#\n" ) |
---|
84 | out.write( "NAME="+filename+"\n" ) |
---|
85 | obs_status = obs.get_status() |
---|
86 | for key in sorted(obs_status): |
---|
87 | out.write( "#\n" ) |
---|
88 | if key == "status": |
---|
89 | out.write( "OBS_STATUS" +"="+ obs_status[key] +"\n" ) |
---|
90 | else: |
---|
91 | out.write( "OBS_STATUS_" + key.upper() +"="+",".join(get_repo_list(obs_status[key]))+"\n" ) |
---|
92 | |
---|
93 | out.write( "#\n" ) |
---|
94 | version = obs.get_pkg_info() |
---|
95 | for key in sorted(version): |
---|
96 | out.write( "BUILD_" + key.upper() +"="+str(version[key])+"\n") |
---|
97 | |
---|
98 | out.write( "#\n" ) |
---|
99 | out.write("PACKAGES_SUCCESSFUL='%s'\n" % (get_packages_string(obs.get_successful_packages()))) |
---|
100 | |
---|
101 | out.write( "#\n" ) |
---|
102 | out.write("PACKAGES_FAILED='%s'\n" % (get_packages_string(obs.get_failed_packages()))) |
---|
103 | |
---|
104 | out.write( "#\n" ) |
---|
105 | for key in sorted(jenkins_status): |
---|
106 | out.write( "JENKINS_" + key.upper() +"="+str(jenkins_status[key])+"\n") |
---|
107 | |
---|
108 | |
---|
109 | |
---|
110 | def get_repo_name(repository, arch, jenkins=False): |
---|
111 | # obs: DISTRIBUTION_VERSION |
---|
112 | # jenkins: DISTRIBUTION-VERSION-ARCH |
---|
113 | # |
---|
114 | # use "-" as separator between repository and arch, |
---|
115 | # because repository and arch can contain: |
---|
116 | # repository: "." and "_" (openSUSE_13.1) |
---|
117 | # arch: "_" (x86_64) |
---|
118 | if jenkins: |
---|
119 | repo = str(repository).replace( "_", "-", 1 ) + "-" + str(arch) |
---|
120 | else: |
---|
121 | repo = str(repository) + "-" + str(arch) |
---|
122 | return repo |
---|
123 | |
---|
124 | def get_repo_list(array, jenkins=False): |
---|
125 | result=[] |
---|
126 | for i in sorted( array, key=lambda k: ( k['repository'], k['arch'] ) ): |
---|
127 | repo = get_repo_name(i['repository'], i['arch'], jenkins) |
---|
128 | result.append(repo) |
---|
129 | return result |
---|
130 | |
---|
131 | def get_packages_string(packages): |
---|
132 | pkg = '' |
---|
133 | for dist in packages: |
---|
134 | pkg += '%s:%s\n' % (dist, ','.join(packages[dist])) |
---|
135 | return pkg |
---|
136 | |
---|
137 | class ObsStatus: |
---|
138 | def __init__(self, prj, pkg): |
---|
139 | self.logger = logging.getLogger() |
---|
140 | self.prj = prj |
---|
141 | self.pkg = pkg |
---|
142 | self.state = STATE.unknown |
---|
143 | self.status = { |
---|
144 | 'broken': [], |
---|
145 | 'building': [], |
---|
146 | 'disabled': [], |
---|
147 | 'failed': [], |
---|
148 | 'finished': [], |
---|
149 | 'other': [], |
---|
150 | 'unresolvable': [], |
---|
151 | } |
---|
152 | self.pkg_info = { |
---|
153 | 'srcmd5': "", |
---|
154 | 'version': "", |
---|
155 | 'rev': -1, |
---|
156 | 'time': "", |
---|
157 | } |
---|
158 | self.packages_successful = {} |
---|
159 | self.packages_failed = {} |
---|
160 | |
---|
161 | #def get_repo_name(self, repository, arch): |
---|
162 | #return get_repo_name(repository, arch, jenkins=False): |
---|
163 | |
---|
164 | def __get_obs_results(self): |
---|
165 | # get results of a project: |
---|
166 | # %(repository)s|%(arch)s|%(state)s|%(dirty)s|%(code)s|%(details)s |
---|
167 | # Debian_5.0|i586|published|False|succeeded| |
---|
168 | # Debian_5.0|x86_64|published|False|succeeded| |
---|
169 | cmd = format_command( [ osc, osc_paramter, "results", "--csv", "--format='%(state)s|%(repository)s|%(arch)s|%(dirty)s|%(code)s|%(details)s'", "--verbose", self.prj, self.pkg ] ) |
---|
170 | # "--last-build": NO, because if --last-build, disabled in 'code' is replaced by succeeded/failed |
---|
171 | results=subprocess.Popen( cmd, stdout=subprocess.PIPE) |
---|
172 | rc=results.wait() |
---|
173 | if rc != 0: |
---|
174 | logger.error( "failed to get osc results: " + str(rc) ) |
---|
175 | exit( rc ) |
---|
176 | |
---|
177 | reader = DictReader(results.stdout, |
---|
178 | delimiter='|', |
---|
179 | fieldnames=['state', 'repository', |
---|
180 | 'arch', 'dirty', |
---|
181 | 'code', 'details']) |
---|
182 | return reader |
---|
183 | |
---|
184 | |
---|
185 | def __get_obs_last_build(self, repository, arch): |
---|
186 | # {'rev': '99', 'version': '1.2.1170-1.3', 'srcmd5': '611f626d431d06dc81a32e0e021da0d7', 'time': '2014-03-12 16:43:55'} |
---|
187 | cmd = format_command( [ osc, osc_paramter, "buildhist", "--csv", self.prj, self.pkg, repository, arch ] ) |
---|
188 | buildhist=subprocess.Popen( cmd, stdout=subprocess.PIPE ) |
---|
189 | rc=buildhist.wait() |
---|
190 | reader={} |
---|
191 | if rc != 0: |
---|
192 | logger.error( "failed: " + rc ) |
---|
193 | else: |
---|
194 | buildhist2 = subprocess.Popen(['tail', '-n', '1'], |
---|
195 | stdin=buildhist.stdout, |
---|
196 | stdout=subprocess.PIPE, |
---|
197 | ) |
---|
198 | reader = DictReader(buildhist2.stdout, |
---|
199 | delimiter='|', |
---|
200 | fieldnames=['time', 'srcmd5', 'rev', 'version']) |
---|
201 | try: |
---|
202 | # there should only be one entry |
---|
203 | return reader.next() |
---|
204 | except StopIteration: |
---|
205 | return |
---|
206 | |
---|
207 | |
---|
208 | def __update_packages(self): |
---|
209 | cmd = format_command( [ osc, osc_paramter, "results", "--xml", self.prj ] ) |
---|
210 | # "--last-build": NO, because if --last-build, disabled in 'code' is replaced by succeeded/failed |
---|
211 | results=subprocess.Popen(cmd, stdout=subprocess.PIPE) |
---|
212 | #rc=results.wait() |
---|
213 | (xmldata, stderr) = results.communicate() |
---|
214 | rc=results.returncode |
---|
215 | if rc != 0: |
---|
216 | logger.error("failed to get osc results: " + str(rc)) |
---|
217 | return False |
---|
218 | #root = etree.parse(xmldata).getroot() |
---|
219 | root = etree.fromstring(xmldata) |
---|
220 | #print etree.dump(root) |
---|
221 | for result in root.getiterator('result'): |
---|
222 | #print result.attrib |
---|
223 | #print result.attrib['repository'], result.attrib['arch'] |
---|
224 | dist = get_repo_name(result.attrib['repository'], result.attrib['arch'], jenkins=True) |
---|
225 | self.packages_successful[dist] = [] |
---|
226 | self.packages_failed[dist] = [] |
---|
227 | for status in result.getiterator('status'): |
---|
228 | #print status.attrib |
---|
229 | if status.attrib['code'] == 'succeeded': |
---|
230 | self.packages_successful[dist].append(status.attrib['package']) |
---|
231 | elif status.attrib['code'] == 'disabled': |
---|
232 | pass |
---|
233 | else: |
---|
234 | logger.error("%s %s (%s) = %s" % (self.prj, status.attrib['package'], result.attrib['repository'], status.attrib['code'])) |
---|
235 | self.packages_failed[dist].append(status.attrib['package']) |
---|
236 | # if no failed packages are added to the dist, remove the dist |
---|
237 | if not self.packages_failed[dist]: |
---|
238 | del(self.packages_failed[dist]) |
---|
239 | return True |
---|
240 | |
---|
241 | |
---|
242 | def __update_status(self): |
---|
243 | obs_results=self.__get_obs_results() |
---|
244 | |
---|
245 | for i in obs_results: |
---|
246 | logger.debug( i ) |
---|
247 | if i['state'] == 'published' and i['dirty'] == 'False' and i['code'] == 'succeeded': |
---|
248 | self.status['finished'].append(i) |
---|
249 | elif i['state'] == 'building': |
---|
250 | self.status['building'].append(i) |
---|
251 | elif i['code'] == 'disabled': |
---|
252 | self.status['disabled'].append(i) |
---|
253 | elif i['code'] == 'failed': |
---|
254 | self.status['failed'].append(i) |
---|
255 | elif i['code'] == 'broken': |
---|
256 | self.status['broken'].append(i) |
---|
257 | elif i['code'] == 'unresolvable': |
---|
258 | self.status['unresolvable'].append(i) |
---|
259 | else: |
---|
260 | self.status['other'].append(i) |
---|
261 | return True |
---|
262 | |
---|
263 | |
---|
264 | def __update_pkg_info(self): |
---|
265 | rv=[] |
---|
266 | # get max 'rev' and 'time' from finished builds |
---|
267 | for i in self.status['finished']: |
---|
268 | last_build=self.__get_obs_last_build(i['repository'], i['arch']) |
---|
269 | self.logger.debug( str(last_build) ) |
---|
270 | #rv.append( dict(i.items() + j.items() ) ) |
---|
271 | if last_build: |
---|
272 | rev=int(last_build['rev']) |
---|
273 | time=last_build['time'].replace(" ","_") |
---|
274 | if ( rev > self.pkg_info['rev'] ) or ( rev == self.pkg_info['rev'] and time > self.pkg_info['time'] ): |
---|
275 | self.pkg_info['rev'] = rev |
---|
276 | self.pkg_info['time'] = time |
---|
277 | self.pkg_info['srcmd5'] = last_build['srcmd5'] |
---|
278 | self.pkg_info['version'] = last_build['version'] |
---|
279 | rv.append( { 'result': i, 'buildhist': last_build } ) |
---|
280 | else: |
---|
281 | self.logger.warn( "no buildhistory definied for " + i['repository'] + "-" + i['arch'] ) |
---|
282 | self.logger.debug( "result (max): " + str(self.pkg_info) ) |
---|
283 | |
---|
284 | for i in rv: |
---|
285 | if int(i['buildhist']['rev']) != self.pkg_info['rev']: |
---|
286 | self.logger.error( "UNKNOWN: " + pformat( i ) ) |
---|
287 | self.logger.debug( "finished:" ) |
---|
288 | for i in rv: |
---|
289 | if int(i['buildhist']['rev']) == self.pkg_info['rev']: |
---|
290 | self.logger.debug( pformat( i ) ) |
---|
291 | return True |
---|
292 | |
---|
293 | |
---|
294 | def __update_state(self): |
---|
295 | if self.status['building'] or self.status['other']: |
---|
296 | self.state = STATE.pending |
---|
297 | elif self.status['failed'] or self.status['broken'] or self.status['unresolvable'] or self.packages_failed: |
---|
298 | self.state = STATE.failed |
---|
299 | else: |
---|
300 | self.state = STATE.succeeded |
---|
301 | return True |
---|
302 | |
---|
303 | |
---|
304 | def update(self): |
---|
305 | self.__update_status() |
---|
306 | self.__update_packages() |
---|
307 | self.__update_pkg_info() |
---|
308 | self.__update_state() |
---|
309 | return True |
---|
310 | |
---|
311 | def get_state(self): |
---|
312 | return self.state |
---|
313 | |
---|
314 | def get_status(self, statustype=None): |
---|
315 | result = None |
---|
316 | if statustype == None: |
---|
317 | result = self.status |
---|
318 | else: |
---|
319 | result = self.status[statustype] |
---|
320 | return result |
---|
321 | |
---|
322 | def get_pkg_info(self): |
---|
323 | return self.pkg_info |
---|
324 | |
---|
325 | def get_pkg_version(self): |
---|
326 | return self.pkg_info['version'] |
---|
327 | |
---|
328 | def get_successful_packages(self): |
---|
329 | return self.packages_successful |
---|
330 | |
---|
331 | def get_failed_packages(self): |
---|
332 | return self.packages_failed |
---|
333 | |
---|
334 | |
---|
335 | |
---|
336 | def add_jenkins_build_parameter( xmlConfig, build_params_add ): |
---|
337 | logger=logging.getLogger(__name__) |
---|
338 | |
---|
339 | # check, if build_params_add are already parameter of Jenkins job |
---|
340 | for child in xmlConfig.findall("./properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.StringParameterDefinition"): |
---|
341 | name=child.find('name').text |
---|
342 | if name in build_params_add.keys(): |
---|
343 | # remove item from configuration parameter |
---|
344 | logger.debug( "build parameter " + name + " already in jenkins build configuration" ) |
---|
345 | build_params_add.pop( name ) |
---|
346 | |
---|
347 | #etree.dump( xmlConfig ) |
---|
348 | |
---|
349 | # add remaining build parameter |
---|
350 | parameterDefinitions = xmlConfig.find("./properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions") |
---|
351 | |
---|
352 | if len(parameterDefinitions) == 0: |
---|
353 | logger.error( "no jenkins build paramter defined. This should not happen. Skipping adding build parameter" ) |
---|
354 | return |
---|
355 | |
---|
356 | #etree.dump( parameterDefinitions ) |
---|
357 | |
---|
358 | for item in build_params_add: |
---|
359 | |
---|
360 | logger.debug( "add build parameter " + str(item) ) |
---|
361 | |
---|
362 | # example: |
---|
363 | #<hudson.model.StringParameterDefinition> |
---|
364 | #<name>BUILD_VERSION</name> |
---|
365 | #<description>automatically set by obs-status</description> |
---|
366 | #<defaultValue /> |
---|
367 | #</hudson.model.StringParameterDefinition> |
---|
368 | |
---|
369 | new = etree.Element('hudson.model.StringParameterDefinition') |
---|
370 | |
---|
371 | # add name |
---|
372 | name = etree.Element( 'name' ) |
---|
373 | name.text = item |
---|
374 | new.append(name) |
---|
375 | |
---|
376 | # add description |
---|
377 | description = etree.Element( 'description' ) |
---|
378 | description.text = "BUILD parameter, required by and added from repo-status" |
---|
379 | new.append(description) |
---|
380 | |
---|
381 | # add defaultValue |
---|
382 | defaultValue = etree.Element( 'defaultValue' ) |
---|
383 | # no default value |
---|
384 | new.append(defaultValue) |
---|
385 | |
---|
386 | parameterDefinitions.append(new) |
---|
387 | return |
---|
388 | |
---|
389 | |
---|
390 | def get_jenkins_build_parameter( job, parameter ): |
---|
391 | logger=logging.getLogger(__name__) |
---|
392 | try: |
---|
393 | build=job.get_last_build() |
---|
394 | parameters = build.get_actions()['parameters'] |
---|
395 | for i in parameters: |
---|
396 | if i['name'] == parameter: |
---|
397 | return i['value'] |
---|
398 | except jenkinsapi.custom_exceptions.NoBuildData: |
---|
399 | pass |
---|
400 | logger.warn( "jenkins build parameter " + parameter + " not defined" ) |
---|
401 | return |
---|
402 | |
---|
403 | def set_jenkins_matrix_distrelease( xmlConfig, distreleases ): |
---|
404 | logger=logging.getLogger(__name__) |
---|
405 | for child in xmlConfig.findall("./axes/hudson.matrix.TextAxis"): |
---|
406 | name=child.find('name').text |
---|
407 | if name == "DISTRELEASE": |
---|
408 | #etree.dump( child ) |
---|
409 | values=child.find('values') |
---|
410 | for value in child.findall('values/string'): |
---|
411 | logger.debug( "distrelease old: " + value.text ) |
---|
412 | values.remove( value ) |
---|
413 | for i in distreleases: |
---|
414 | new = etree.Element('string') |
---|
415 | new.text=i |
---|
416 | values.append( new ) |
---|
417 | #etree.dump( child ) |
---|
418 | #print "new:" |
---|
419 | for value in child.findall('values/string'): |
---|
420 | logger.debug( "distrelease new: " + str(value.text) ) |
---|
421 | return |
---|
422 | |
---|
423 | |
---|
424 | |
---|
425 | def check_jenkins_status(url, jobname, status, distreleases, version, project_packages): |
---|
426 | logger=logging.getLogger(__name__) |
---|
427 | logger.debug( "check_jenkins_status" ) |
---|
428 | logger.debug( str(distreleases) ) |
---|
429 | |
---|
430 | jenkins = Jenkins( url ) |
---|
431 | |
---|
432 | # J.keys() # Jenkins objects appear to be dict-like, mapping keys (job-names) to |
---|
433 | #['foo', 'test_jenkinsapi'] |
---|
434 | |
---|
435 | job=jenkins.get_job( jobname ) |
---|
436 | try: |
---|
437 | build=job.get_last_build() |
---|
438 | status['BUILD_NUMBER']=build.get_number() |
---|
439 | status['BUILD_URL']=build.get_result_url() |
---|
440 | except jenkinsapi.custom_exceptions.NoBuildData: |
---|
441 | #except NoBuildData: |
---|
442 | pass |
---|
443 | |
---|
444 | if job.is_queued_or_running(): |
---|
445 | # TODO: if job is queue, but not running, BUILD_NUMBER is wrong |
---|
446 | logger.debug( "jenkins job " + jobname + " is running" ) |
---|
447 | status['status']=STATE.pending |
---|
448 | return status['status'] |
---|
449 | |
---|
450 | # jenkins job is not running |
---|
451 | logger.debug( "no jenkins job is running for " + jobname ) |
---|
452 | jenkins_job_build_version=get_jenkins_build_parameter( job, 'BUILD_VERSION' ) |
---|
453 | |
---|
454 | logger.debug( "OBS version: " + str(version['version']) + ", " + "jenkins version: " + str(jenkins_job_build_version) ) |
---|
455 | |
---|
456 | if jenkins_job_build_version == version['version']: |
---|
457 | # TODO: check if number DISTRELEASES have changed |
---|
458 | logger.debug( "skipped jenkins, as it has already tested the current OBS version" ) |
---|
459 | if build.is_good(): |
---|
460 | # success |
---|
461 | status['status']=STATE.succeeded |
---|
462 | else: |
---|
463 | status['status']=STATE.failed |
---|
464 | return status['status'] |
---|
465 | |
---|
466 | # jenkins job is not running and last_build has not been for current version |
---|
467 | |
---|
468 | # get config data in xml format |
---|
469 | configString=job.get_config() |
---|
470 | |
---|
471 | # https://docs.python.org/2.7/library/xml.etree.elementtree.html |
---|
472 | xmlConfig=etree.fromstring( configString ) |
---|
473 | #etree.dump( xmlConfig ) |
---|
474 | |
---|
475 | pkg = get_packages_string(project_packages) |
---|
476 | build_params={ 'BUILD_VERSION': version['version'], 'BUILD_REV': version['rev'], 'BUILD_SRCMD5': version['srcmd5'], 'PACKAGES': pkg } |
---|
477 | # build paramter that must be present as Jenkins parameter configuration |
---|
478 | add_jenkins_build_parameter( xmlConfig, build_params.copy() ) |
---|
479 | set_jenkins_matrix_distrelease( xmlConfig, distreleases ) |
---|
480 | |
---|
481 | #etree.dump(xmlConfig) |
---|
482 | |
---|
483 | xmlString=etree.tostring( xmlConfig ) |
---|
484 | job.update_config( xmlString ) |
---|
485 | |
---|
486 | #for i in b.get_matrix_runs(): |
---|
487 | |
---|
488 | logger.info( "starting jenkins for obs build " + version['version'] ) |
---|
489 | invocation=job.invoke( build_params=build_params ) |
---|
490 | |
---|
491 | if wait: |
---|
492 | try: |
---|
493 | invocation.block() |
---|
494 | except jenkinsapi.custom_exceptions.TimeOut as e: |
---|
495 | logger.exception( "timeout while waiting for jenkins job" ) |
---|
496 | |
---|
497 | # recusive |
---|
498 | return check_jenkins_status( url, jobname, status, distreleases, version, project_packages ) |
---|
499 | |
---|
500 | #b.is_good() |
---|
501 | |
---|
502 | #pprint( dir(invocation) ) |
---|
503 | |
---|
504 | #pprint( dir(invocation.job) ) |
---|
505 | |
---|
506 | #build=invocation.get_build() |
---|
507 | |
---|
508 | #if invocation.is_queued_or_running(): |
---|
509 | #status['status']=STATE.pending |
---|
510 | #else: |
---|
511 | #logger.debug( "duration: " + build.get_duration() ) |
---|
512 | ##print build.get_actions() |
---|
513 | ## recusive |
---|
514 | |
---|
515 | #return status['status'] |
---|
516 | |
---|
517 | |
---|
518 | |
---|
519 | if __name__ == '__main__': |
---|
520 | logging.basicConfig(level=logging.INFO) |
---|
521 | logger=logging.getLogger(__name__) |
---|
522 | |
---|
523 | parser = argparse.ArgumentParser(description='check overall build status of an OBS package.' ) |
---|
524 | |
---|
525 | parser.add_argument( '--debug', action='store_true', help="enable debugging output" ) |
---|
526 | parser.add_argument( '--obsapiurl', help="OBS API url" ) |
---|
527 | parser.add_argument( '--jenkinsurl', help="Jenkins base url" ) |
---|
528 | parser.add_argument( '--jenkinsjob', help="Jenkins job name" ) |
---|
529 | parser.add_argument( '--destdir', help="directory to write status info to. If not given, status will be written to stdout" ) |
---|
530 | parser.add_argument( '--wait', action='store_true', help="wait untils jobs are finished (currently only jenkins)" ) |
---|
531 | parser.add_argument( 'project', help="OBS project" ) |
---|
532 | parser.add_argument( 'package', help="OBS package" ) |
---|
533 | |
---|
534 | args = parser.parse_args() |
---|
535 | |
---|
536 | if args.debug: |
---|
537 | logger.setLevel(logging.DEBUG) |
---|
538 | |
---|
539 | wait=args.wait |
---|
540 | |
---|
541 | prj=args.project |
---|
542 | pkg=args.package |
---|
543 | |
---|
544 | if args.obsapiurl: |
---|
545 | osc_paramter="--apiurl=" + args.obsapiurl |
---|
546 | |
---|
547 | if args.destdir: |
---|
548 | destdir=args.destdir |
---|
549 | |
---|
550 | if args.jenkinsjob: |
---|
551 | jenkins_status['jobname'] = args.jenkinsjob |
---|
552 | |
---|
553 | if args.jenkinsurl and args.jenkinsjob: |
---|
554 | # enable jenkins |
---|
555 | jenkins_status['status']=STATE.unknown |
---|
556 | |
---|
557 | # check obs |
---|
558 | obs = ObsStatus(prj, pkg) |
---|
559 | obs.update() |
---|
560 | if obs.get_state() == STATE.succeeded and obs.get_pkg_version(): |
---|
561 | if args.jenkinsurl and args.jenkinsjob: |
---|
562 | # run and check jenkins |
---|
563 | check_jenkins_status(args.jenkinsurl, args.jenkinsjob, jenkins_status, get_repo_list( obs.get_status('finished'), jenkins=True ), obs.get_pkg_info(), obs.get_successful_packages()) |
---|
564 | else: |
---|
565 | logger.info( "skipped jenkins tests, because prior steps" ) |
---|
566 | |
---|
567 | logger.debug( "write status" ) |
---|
568 | write_status(obs, jenkins_status) |
---|