default=False, help='enable debug information') parser.add_argument('-A', '--apiurl', metavar='URL', help='API URL') args = parser.parse_args() osc.conf.get_config(override_apiurl=args.apiurl) osc.conf.config['debug'] = args.debug apiurl = osc.conf.config['apiurl'] config = Config(apiurl, args.project) api = StagingAPI(apiurl, args.project) staging_report = InstallChecker(api, config) if args.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) result = True if args.staging: result = staging_report.staging(api.prj_from_short(args.staging), force=True) else: for staging in api.get_staging_projects(): if api.is_adi_project(staging): result = staging_report.staging(staging) and result if not result: sys.exit(1)
class Project(object): def __init__(self, name): self.name = name Config(apiurl, name) self.api = StagingAPI(apiurl, name) self.staging_projects = dict() self.listener = None self.logger = logging.getLogger(__name__) self.replace_string = self.api.attribute_value_load('OpenQAMapping') def init(self): for p in self.api.get_staging_projects(): if self.api.is_adi_project(p): continue self.staging_projects[p] = self.initial_staging_state(p) self.update_staging_status(p) def staging_letter(self, name): return name.split(':')[-1] def map_iso(self, staging_project, iso): parts = self.replace_string.split('/') if parts[0] != 's': raise Exception("{}'s iso_replace_string does not start with s/".format(self.name)) old = parts[1] new = parts[2] new = new.replace('$LETTER', self.staging_letter(staging_project)) return re.compile(old).sub(new, iso) def gather_isos(self, name, repository): url = self.api.makeurl(['published', name, repository, 'iso']) f = self.api.retried_GET(url) root = ET.parse(f).getroot() ret = [] for entry in root.findall('entry'): if entry.get('name').endswith('iso'): ret.append(self.map_iso(name, entry.get('name'))) return ret def gather_buildid(self, name, repository): url = self.api.makeurl(['published', name, repository], {'view': 'status'}) f = self.api.retried_GET(url) id = ET.parse(f).getroot().find('buildid') if id is not None: return id.text def initial_staging_state(self, name): return {'isos': self.gather_isos(name, 'images'), 'id': self.gather_buildid(name, 'images')} def fetch_openqa_jobs(self, staging, iso): buildid = self.staging_projects[staging].get('id') if not buildid: self.logger.info("I don't know the build id of " + staging) return # all openQA jobs are created at the same URL url = self.api.makeurl(['status_reports', 'published', staging, 'images', 'reports', buildid]) openqa = self.listener.jobs_for_iso(iso) # collect job infos to pick names openqa_infos = dict() for job in openqa: print(staging, iso, job['id'], job['state'], job['result'], job['settings']['MACHINE'], job['settings']['TEST']) openqa_infos[job['id']] = {'url': self.listener.test_url(job)} openqa_infos[job['id']]['state'] = self.map_openqa_result(job) openqa_infos[job['id']]['name'] = job['settings']['TEST'] openqa_infos[job['id']]['machine'] = job['settings']['MACHINE'] # make sure the names are unique taken_names = dict() for id in openqa_infos: name = openqa_infos[id]['name'] if name in taken_names: openqa_infos[id]['name'] = openqa_infos[id]['name'] + "@" + openqa_infos[id]['machine'] # the other id id = taken_names[name] openqa_infos[id]['name'] = openqa_infos[id]['name'] + "@" + openqa_infos[id]['machine'] taken_names[name] = id for info in openqa_infos.values(): xml = self.openqa_check_xml(info['url'], info['state'], 'openqa:' + info['name']) try: http_POST(url, data=xml) except HTTPError: self.logger.error('failed to post status to ' + url) def update_staging_status(self, project): for iso in self.staging_projects[project]['isos']: self.fetch_openqa_jobs(project, iso) def update_staging_buildid(self, project, repository, buildid): self.staging_projects[project]['id'] = buildid self.staging_projects[project]['isos'] = self.gather_isos(project, repository) self.update_staging_status(project) def check_published_repo(self, project, repository, buildid): if repository != 'images': return for p in self.staging_projects: if project == p: self.update_staging_buildid(project, repository, buildid) def matching_project(self, iso): for p in self.staging_projects: if iso in self.staging_projects[p]['isos']: return p def map_openqa_result(self, job): if job['result'] in ['passed', 'softfailed']: return 'success' if job['result'] == 'none': return 'pending' return 'failure' def openqa_job_change(self, iso): staging = self.matching_project(iso) if not staging: return # we fetch all openqa jobs so we can avoid long job names self.fetch_openqa_jobs(staging, iso) def openqa_check_xml(self, url, state, name): check = ET.Element('check') se = ET.SubElement(check, 'url') se.text = url se = ET.SubElement(check, 'state') se.text = state se = ET.SubElement(check, 'name') se.text = name return ET.tostring(check)
help='project to check (ex. openSUSE:Factory, openSUSE:Leap:15.1)') parser.add_argument('-d', '--debug', action='store_true', default=False, help='enable debug information') parser.add_argument('-A', '--apiurl', metavar='URL', help='API URL') args = parser.parse_args() osc.conf.get_config(override_apiurl=args.apiurl) osc.conf.config['debug'] = args.debug apiurl = osc.conf.config['apiurl'] config = Config(apiurl, args.project) api = StagingAPI(apiurl, args.project) staging_report = InstallChecker(api, config) if args.debug: logging.basicConfig(level=logging.DEBUG) else: logging.basicConfig(level=logging.INFO) result = True if args.staging: result = staging_report.staging(api.prj_from_short(args.staging), force=True) else: for staging in api.get_staging_projects(): if api.is_adi_project(staging): result = staging_report.staging(staging) and result if not result: sys.exit( 1 )