def _get_copr_data(req, user, type=None): if '<title>Sign in Coprs</title>' in req.text: raise exception.CoprError(code=403, error='Invalid API token') if req.status_code == 404: raise exception.CoprError( code=req.status_code, error="404 for user %s" % user.get('username')) try: output = json.loads(req.text) except ValueError: raise exception.CoprError( code=req.status_code, error="Invalid response (not JSON):\n%s" % req.text) if req.status_code != 200: msg = "[%s] %s" % (req.status_code, output['error']) if (type == 'new_build' and req.status_code == 500 and output.get('error') == 'Invalid request'): msg += ("\nThis funny copr response might mean you don't have " "permission to build in this copr. Or not. Hahaha.") raise exception.CoprError(code=req.status_code, copr_msg=output.get('error'), error=msg) return output
def _fetch_build_status(self, build_id): url = self.copr_api_url('coprs/build_status/%s/' % build_id) req = requests.get(url, auth=(self.user['login'], self.user['token'])) output = _get_copr_data(req, self.user) if 'status' in output: return output['status'] if 'error' in output: raise exception.CoprError(error=output['error']) raise exception.CoprError( error="Build status query returned no results.")
def get_copr_user(): config = ConfigParser.ConfigParser() config_fn = get_copr_conf_fn() if not config.read(config_fn): raise exception.CoprError(error="Configuration file %s not found.\n" "See `man copr-cli` for more information" % config_fn) try: username = config.get('copr-cli', 'username', None) login = config.get('copr-cli', 'login', None) token = config.get('copr-cli', 'token', None) except ConfigParser.Error, err: raise exception.CoprError('Bad configuration file %s: %s' % (config_fn, err))
def new_build(self, srpm_url, release, dist, watch=False): copr = rdo_copr_name(release, dist) url = self.copr_api_url('coprs/%s/%s/new_build/' % (self.owner, copr)) data = { 'pkgs': srpm_url, } req = requests.post(url, auth=(self.user['login'], self.user['token']), data=data) output = _get_copr_data(req, self.user, type='new_build') build_ids = output.get('ids') if not build_ids: raise exception.CoprError( error="copr didn't return id of new build.(?!)") build_id = build_ids[0] if watch: log.info("\nWatching build (may be safely interrupted)...") prevstatus = None try: while True: try: status = self._fetch_build_status(build_id) except exception.CoprError as ex: log.warn("Failed to get build status: %s" % ex) break if prevstatus != status: now = datetime.datetime.now() if status in ['pending', 'waiting', 'running']: cstatus = log.term.bold(status) elif status == 'succeeded': cstatus = log.term.good(status) elif status == 'failed': cstatus = log.term.error(status) elif status == 'skipped': cstatus = ("{t.magenta}{st}{t.normal} (build " "already done)".format(t=log.term, st=status)) else: cstatus = log.term.warn(status) log.info("[%s] %s" % (now.strftime('%H:%M:%S'), cstatus)) prevstatus = status if status in [ 'succeeded', 'failed', 'canceled', 'skipped']: break time.sleep(60) except KeyboardInterrupt: pass except Exception as ex: log.warn("Error during copr build monitoring: %s" % ex) return build_id