def _get_bodhi_history(username): """ Print the last action performed on bodhi by the given FAS user. :arg username, the fas username whose action is searched. """ from fedora.client.bodhi import BodhiClient bodhiclient = BodhiClient("https://bodhi.fedoraproject.org/") log.debug('Querying Bodhi for user: {0}'.format(username)) json_obj = bodhiclient.send_request("updates/?user=%s" % username, verb='GET') def dategetter(field): def getter(item): return datetime.datetime.strptime(item[field], "%Y-%m-%d %H:%M:%S") return getter print('Last package update on bodhi:') if json_obj['updates']: latest = sorted(json_obj['updates'], key=dategetter("date_submitted"))[-1] print(' {0} on package {1}'.format(latest["date_submitted"], latest["title"])) else: print(' No activity found on bodhi')
def bodhi(self, irc, msg, args, package): """<package> returns a list of latest builds for <package>. If the resultant number of packages is greater than 5, the reply will be sent in a /PRIVMSG """ channel = None msgargs = "" if irc.isChannel(msg.args[0]): channel = msg.args[0] try: yb = BodhiClient() res = yb.latest_builds(package) res = res.items() if len(res)==0: irc.reply("sorry, I was unable to locate a package.") elif 3 < len(res) < 20: irc.reply("the number of packages was greater than 3 (%s in total), I will send the result in a /PRIVMSG" % len(res)) thisreply="" for dist,build in res: # thisreply=thisreply+i.ui_envra+" "+i.repo.name+"|size "+str((i.size/1024)/1024)+"MB|Date "+time.ctime(i.committime) irc.reply(str(dist)+" : "+str(build), prefixNick=msg.nick,private=msg.nick) elif len(res)>20: irc.reply("the number of results was greater than 20 (%s in total), I would suggest using yum locally" % len(res)) else: for i in res: irc.reply(i.keys+" : "+i.values) except: irc.reply("Something went wrong")
def _get_bodhi_history(username): """ Print the last action performed on bodhi by the given FAS user. :arg username, the fas username whose action is searched. """ from fedora.client.bodhi import BodhiClient bodhiclient = BodhiClient("https://bodhi.fedoraproject.org/") log.debug('Querying Bodhi for user: {0}'.format(username)) json_obj = bodhiclient.send_request( "updates/?user=%s" % username, verb='GET') def dategetter(field): def getter(item): return datetime.datetime.strptime(item[field], "%Y-%m-%d %H:%M:%S") return getter print('Last package update on bodhi:') if json_obj['updates']: latest = sorted(json_obj['updates'], key=dategetter("date_submitted") )[-1] print(' {0} on package {1}'.format( latest["date_submitted"], latest["title"])) else: print(' No activity found on bodhi')
def run(self): bc = BodhiClient() bc.username = self.username bc.password = self.password # Try send it 3 times if ServerError occours for retry in range(3): try: # Send comment to bodhi bc.comment(self.package["title"], self.message, karma=self.karma) message = "Comment submitted successfully." message2 = ("Reloading bodhi update for " + str(self.package['itemlist_name']) + "...") main_thread_call(self.main_thread.add_status_item, message) main_thread_call(self.main_thread.add_status_item, message2) # Reload bodhi update main_thread_call(self.main_thread.bodhi_workers_queue.put, ['package_update', self.package['dnf_package']]) # Clean up after sending main_thread_call(self.main_thread.sending_done, self.username, self.password) return except AuthError: message = "Invalid username or password. Please try again." main_thread_call(self.main_thread.add_status_item, message) break except ServerError, e: message = "Server error %s" % str(e) main_thread_call(self.main_thread.add_status_item, message)
def run(self): bc = BodhiClient() bc.username = self.username bc.password = self.password # Try send it 3 times if ServerError occours for retry in range(3): try: # Send comment to bodhi bc.comment(self.package["title"], self.message, karma=self.karma) message = "Comment submitted successfully." message2 = ("Reloading bodhi update for " + str(self.package['itemlist_name']) + "...") main_thread_call(self.main_thread.add_status_item, message) main_thread_call(self.main_thread.add_status_item, message2) # Reload bodhi update main_thread_call(self.main_thread.bodhi_workers_queue.put, ['package_update', self.package['yum_package']]) # Clean up after sending main_thread_call(self.main_thread.sending_done, self.username, self.password) return except AuthError: message = "Invalid username or password. Please try again." main_thread_call(self.main_thread.add_status_item, message) break except ServerError, e: message = "Server error %s" % str(e) main_thread_call(self.main_thread.add_status_item, message)
def main(): parser = get_parser() opts, args = parser.parse_args() setup_logger(opts.verbose) bodhi = BodhiClient(opts.bodhi_url, username=opts.username, debug=opts.verbose) def verify_args(args): if not args and len(args) != 1: log.error("Please specifiy a comma-separated list of builds") sys.exit(-1) override_notes = None while True: try: if opts.new: # Note: All options are ignored if you're passing input from a file. if opts.input_file: updates = bodhi.parse_file(input_file=opts.input_file) for update_args in updates: if not update_args['type_']: log.error("Error: No update type specified (ie: " "type=bugfix), skipping.") continue if update_args['type_'] not in update_types: log.error('Error: Invalid update type %r. Must be one of %r' % ( update_args['type_'], update_types)) continue if update_args['request'] not in update_requests: log.error('Error: Invalid update request %r. Must be one of %r' % ( update_args['request'], update_requests)) continue log.info("Creating a new update for %s" % update_args['builds']) data = bodhi.save(**update_args) if data.get('tg_flash'): log.info(data['tg_flash']) if 'updates' in data: for update in data['updates']: print(bodhi.update_str(update).encode("UTF-8")) else: builds = ",".join(args) extra_args = { 'builds': builds, 'type_': opts.type_, 'bugs': opts.bugs, 'notes': opts.notes, 'request': opts.request or 'testing', 'stable_karma': opts.stablekarma, 'unstable_karma': opts.unstablekarma, 'autokarma': not opts.disable_autokarma, 'close_bugs': opts.close_bugs, } if not extra_args['type_']: log.error("Error: No update type specified (ie: -t bugfix)") sys.exit(-1) log.info("Creating a new update for %s" % builds) data = bodhi.save(**extra_args) if data.get('tg_flash'): log.info(data['tg_flash']) if 'updates' in data: for update in data['updates']: print(bodhi.update_str(update).encode("UTF-8")) elif opts.edit: verify_args(args) log.info("Editing update for %s" % args[0]) data = bodhi.save(builds=args[0], type_=opts.type_, bugs=opts.bugs, notes=opts.notes, request=opts.request) log.info(data['tg_flash']) if data.has_key('update'): print(bodhi.update_str(data['update']).encode("UTF-8")) elif opts.request: verify_args(args) data = bodhi.request(update=args[0], request=opts.request) log.info(data['tg_flash']) if data.has_key('update'): print(bodhi.update_str(data['update']).encode("UTF-8")) elif opts.delete: verify_args(args) data = bodhi.delete(update=args[0]) log.info(data['tg_flash']) elif opts.push: data = bodhi.push() if not data: log.error("The masher did not return anything :(") raise AuthError if not data.get('updates', None): log.info(data.get('message', 'Unknown masher reply')) raise AuthError if opts.push_type: fupdates = [] for ptype in opts.push_type: fdata = filter(lambda x: x['type'] == ptype, data['updates']) fupdates += fdata data['updates'] = fupdates if opts.push_request: fupdates = [] for req in opts.push_request: fdata = filter(lambda x: x['request'] == req, data['updates']) fupdates += fdata data['updates'] = fupdates if opts.push_release: fupdates = [] for prel in opts.push_release: fdata = filter(lambda x: x['release']['name'] == prel, data['updates']) fupdates += fdata data['updates'] = fupdates if opts.push_build: data['updates'] = filter(lambda x: x['title'].split(',')[0] in opts.push_build, data['updates']) log.info("[ %d Pending Requests ]" % len(data['updates'])) for status in ('testing', 'stable', 'obsolete'): updates = filter(lambda x: x['request'] == status, data['updates']) releases = {} for update in updates: releases.setdefault(update['release']['name'], []) \ .append(update) if len(updates): log.info("\n" + status.title() + "\n========") for release in releases: f = open(status.title() + '-' + release, 'w') log.info(release) for update in releases[release]: log.info("%s" % update['title']) s = "%s" % update['title'] s = s.replace(',','\n') f.write(s + "\n") log.info('') f.write('') f.close() ## Confirm that we actually want to push these updates sys.stdout.write("\nPush these updates? [n]") sys.stdout.flush() yes = sys.stdin.readline().strip() if yes.lower() in ('y', 'yes'): log.info("Pushing!") params = {'updates': [update['title'] for update in data['updates']]} if opts.resume_push: params['resume'] = True data = bodhi.send_request('admin/mash', auth=True, req_params=params) log.info(data['tg_flash']) elif opts.masher: data = bodhi.masher() log.info(data['masher_str']) elif opts.testable: for update in bodhi.testable(): # Allow for some basic filtering of installed updates if opts.critpath: if not update['critpath']: continue if opts.type_: if not update['type'] == opts.type_: continue print(bodhi.update_str(update, minimal=opts.verbose).encode("UTF-8")) elif opts.candidates: for build in bodhi.candidates(): log.info("%-40s %-20s" % (build['nvr'], build['tag_name'])) elif opts.comment or opts.karma: if not len(args) or not args[0]: log.error("Please specify an update to comment on") sys.exit(-1) data = bodhi.comment(update=args[0], comment=opts.comment, karma=opts.karma) if data['tg_flash']: log.info(data['tg_flash']) if data.has_key('update'): print(bodhi.update_str(data['update']).encode("UTF-8")) elif opts.latest: data = bodhi.latest_builds(package=opts.latest) if 'tg_flash' in data: if data['tg_flash']: log.info(data['tg_flash']) del(data['tg_flash']) data = data.items() data.sort(cmp=lambda x, y: cmp(x[0].replace('dist-','').split('-')[0], y[0].replace('dist-','').split('-')[0])) for dist, build in data: print('%26s %s' % (dist, build)) elif opts.critpath: log.info("Getting a list of critical path updates...") data = bodhi.send_request('critpath', req_params={ 'untested': opts.untested, 'release': opts.release, }) if data['tg_flash']: log.info(data['tg_flash']) for update in data['updates']: print(bodhi.update_str(update, minimal=not opts.verbose).encode("UTF-8")) log.info("%d pending critical path updates found" % ( len(data['updates']))) elif opts.mine and not args: data = bodhi.query(mine=opts.mine) for update in data['updates']: print(bodhi.update_str(update, minimal=True).encode("UTF-8")) log.debug(data) log.info(data['title']) ## Buildroot Overrides commands elif opts.override or opts.edit_override: controller = 'override/save' if opts.edit_override: controller = 'override/save_edit_cli' builds = opts.edit_override else: builds = opts.override expiration = None if opts.duration: expiration = (datetime.utcnow() + timedelta(days=int(opts.duration))).strftime('%m/%d/%Y') if opts.notes: override_notes = opts.notes if not override_notes and not opts.edit_override: override_notes = raw_input('Notes: ').strip() data = bodhi.send_request(controller, req_params={ 'builds': builds, 'notes': override_notes, 'expiration': expiration, }, auth=True) if data.get('tg_flash'): log.info(data['tg_flash']) else: log.info("No data returned from bodhi?") elif opts.expire_override: data = bodhi.send_request('override/expire', req_params={ 'build': opts.expire_override, }, auth=True) if data.get('tg_flash'): log.info(data['tg_flash']) else: log.info("No data returned from bodhi?") elif opts.list_overrides or opts.my_overrides: data = bodhi.send_request('override/list', req_params={ 'mine': opts.my_overrides, 'release': opts.release, 'show_expired': opts.show_expired, }, auth=True) print data['title'] + '\n' + '=' * len(data['title']) + '\n' for override in data['overrides']: print "[ %s ]" % override['build'] print " * Notes: %s" % override['notes'] print " * Submitter: %s" % override['submitter'] print " * Submitted: %s" % override['date_submitted'] if override['expiration']: print " * Expiration: %s" % override['expiration'] if override['date_expired']: print " * Expired: %s" % override['date_expired'] print ## Query updates elif opts.status or opts.bugs or opts.release or opts.type_ or \ opts.mine or args: def print_query(data): if data.has_key('tg_flash') and data['tg_flash']: log.error(data['tg_flash']) sys.exit(-1) if data['num_items'] > 1: for update in data['updates']: print(bodhi.update_str(update, minimal=True).encode("UTF-8")) log.info("%d updates found (%d shown)" % ( data['num_items'], len(data['updates']))) else: for update in data['updates']: print(bodhi.update_str(update).encode("UTF-8")) if args: for arg in args: data = bodhi.query(package=arg, release=opts.release, status=opts.status, type_=opts.type_, bugs=opts.bugs, request=opts.request, mine=opts.mine, limit=opts.limit) print_query(data) else: data = bodhi.query(release=opts.release, status=opts.status, type_=opts.type_, bugs=opts.bugs, request=opts.request, mine=opts.mine, limit=opts.limit) print_query(data) elif opts.download: data = bodhi.query(release=opts.release, status=opts.status, type_=opts.type_, bugs=opts.bugs, request=opts.request, mine=opts.mine, limit=opts.limit, package=opts.download) if len(data['updates']) > 1: log.info("%d possible updates were found" % len(data['updates'])) for update in data['updates']: print(bodhi.update_str(update, minimal=True).encode("UTF-8")) else: update = data['updates'][0] log.info("Downloading %s..." % update['title']) p = subprocess.Popen('uname -m', shell=True, stdout=subprocess.PIPE) arch = p.communicate()[0].strip() for build in update['builds']: subprocess.call('koji download-build --arch=%s ' '--arch=noarch%s %s' % (arch, arch == 'i686' and ' --arch=i386 --arch=i586' or '', build['nvr']), shell=True) else: parser.print_help() break except AuthError, e: log.debug('Caught AuthError: %s' % to_bytes(e)) bodhi.password = getpass('Password for %s: ' % opts.username) except ServerError, e: log.exception(e) #log.error(e.message) sys.exit(-1)
def main(): parser = get_parser() opts, args = parser.parse_args() setup_logger(opts.verbose) bodhi = BodhiClient(opts.bodhi_url, username=opts.username, debug=opts.verbose) def verify_args(args): if not args and len(args) != 1: log.error("Please specifiy a comma-separated list of builds") sys.exit(-1) override_notes = None while True: try: if opts.new: # Note: All options are ignored if you're passing input from a file. if opts.input_file: updates = bodhi.parse_file(input_file=opts.input_file) for update_args in updates: if not update_args['type_']: log.error("Error: No update type specified (ie: " "type=bugfix), skipping.") continue if update_args['type_'] not in update_types: log.error( 'Error: Invalid update type %r. Must be one of %r' % (update_args['type_'], update_types)) continue if update_args['request'] not in update_requests: log.error( 'Error: Invalid update request %r. Must be one of %r' % (update_args['request'], update_requests)) continue log.info("Creating a new update for %s" % update_args['builds']) data = bodhi.save(**update_args) if data.get('tg_flash'): log.info(data['tg_flash']) if 'updates' in data: for update in data['updates']: print(bodhi.update_str(update).encode("UTF-8")) else: builds = ",".join(args) extra_args = { 'builds': builds, 'type_': opts.type_, 'bugs': opts.bugs, 'notes': opts.notes, 'request': opts.request or 'testing', 'stable_karma': opts.stablekarma, 'unstable_karma': opts.unstablekarma, 'autokarma': not opts.disable_autokarma, } if not extra_args['type_']: log.error( "Error: No update type specified (ie: -t bugfix)") sys.exit(-1) log.info("Creating a new update for %s" % builds) data = bodhi.save(**extra_args) if data.get('tg_flash'): log.info(data['tg_flash']) if 'updates' in data: for update in data['updates']: print(bodhi.update_str(update).encode("UTF-8")) elif opts.edit: verify_args(args) log.info("Editing update for %s" % args[0]) data = bodhi.save(builds=args[0], type_=opts.type_, bugs=opts.bugs, notes=opts.notes, request=opts.request) log.info(data['tg_flash']) if data.has_key('update'): print(bodhi.update_str(data['update']).encode("UTF-8")) elif opts.request: verify_args(args) data = bodhi.request(update=args[0], request=opts.request) log.info(data['tg_flash']) if data.has_key('update'): print(bodhi.update_str(data['update']).encode("UTF-8")) elif opts.delete: verify_args(args) data = bodhi.delete(update=args[0]) log.info(data['tg_flash']) elif opts.push: data = bodhi.push() if not data: log.error("The masher did not return anything :(") raise AuthError if not data.get('updates', None): log.info(data.get('message', 'Unknown masher reply')) raise AuthError if opts.push_type: fupdates = [] for ptype in opts.push_type: fdata = filter(lambda x: x['type'] == ptype, data['updates']) fupdates += fdata data['updates'] = fupdates if opts.push_request: fupdates = [] for req in opts.push_request: fdata = filter(lambda x: x['request'] == req, data['updates']) fupdates += fdata data['updates'] = fupdates if opts.push_release: fupdates = [] for prel in opts.push_release: fdata = filter(lambda x: x['release']['name'] == prel, data['updates']) fupdates += fdata data['updates'] = fupdates if opts.push_build: data['updates'] = filter( lambda x: x['title'].split(',')[0] in opts.push_build, data['updates']) log.info("[ %d Pending Requests ]" % len(data['updates'])) for status in ('testing', 'stable', 'obsolete'): updates = filter(lambda x: x['request'] == status, data['updates']) releases = {} for update in updates: releases.setdefault(update['release']['name'], []) \ .append(update) if len(updates): log.info("\n" + status.title() + "\n========") for release in releases: f = open(status.title() + '-' + release, 'w') log.info(release) for update in releases[release]: log.info("%s" % update['title']) s = "%s" % update['title'] s = s.replace(',', '\n') f.write(s + "\n") log.info('') f.write('') f.close() ## Confirm that we actually want to push these updates sys.stdout.write("\nPush these updates? [n]") sys.stdout.flush() yes = sys.stdin.readline().strip() if yes.lower() in ('y', 'yes'): log.info("Pushing!") params = { 'updates': [update['title'] for update in data['updates']] } if opts.resume_push: params['resume'] = True data = bodhi.send_request('admin/mash', auth=True, req_params=params) log.info(data['tg_flash']) elif opts.masher: data = bodhi.masher() log.info(data['masher_str']) elif opts.testable: for update in bodhi.testable(): # Allow for some basic filtering of installed updates if opts.critpath: if not update['critpath']: continue if opts.type_: if not update['type'] == opts.type_: continue print( bodhi.update_str(update, minimal=opts.verbose).encode("UTF-8")) elif opts.candidates: for build in bodhi.candidates(): log.info("%-40s %-20s" % (build['nvr'], build['tag_name'])) elif opts.comment or opts.karma: if not len(args) or not args[0]: log.error("Please specify an update to comment on") sys.exit(-1) data = bodhi.comment(update=args[0], comment=opts.comment, karma=opts.karma) if data['tg_flash']: log.info(data['tg_flash']) if data.has_key('update'): print(bodhi.update_str(data['update']).encode("UTF-8")) elif opts.latest: data = bodhi.latest_builds(package=opts.latest) if 'tg_flash' in data: if data['tg_flash']: log.info(data['tg_flash']) del (data['tg_flash']) data = data.items() data.sort(cmp=lambda x, y: cmp(x[0].split('-')[1], y[0].split( '-')[1])) for dist, build in data: print('%26s %s' % (dist, build)) elif opts.critpath: log.info("Getting a list of critical path updates...") data = bodhi.send_request('critpath', req_params={ 'untested': opts.untested, 'release': opts.release, }) if data['tg_flash']: log.info(data['tg_flash']) for update in data['updates']: print( bodhi.update_str( update, minimal=not opts.verbose).encode("UTF-8")) log.info("%d pending critical path updates found" % (len(data['updates']))) elif opts.mine and not args: data = bodhi.query(mine=opts.mine) for update in data['updates']: print( bodhi.update_str(update, minimal=True).encode("UTF-8")) log.debug(data) log.info(data['title']) ## Buildroot Overrides commands elif opts.override or opts.edit_override: controller = 'override/save' if opts.edit_override: controller = 'override/save_edit_cli' builds = opts.edit_override else: builds = opts.override expiration = None if opts.duration: expiration = (datetime.utcnow() + timedelta( days=int(opts.duration))).strftime('%m/%d/%Y') if opts.notes: override_notes = opts.notes if not override_notes and not opts.edit_override: override_notes = raw_input('Notes: ').strip() data = bodhi.send_request(controller, req_params={ 'builds': builds, 'notes': override_notes, 'expiration': expiration, }, auth=True) if data.get('tg_flash'): log.info(data['tg_flash']) else: log.info("No data returned from bodhi?") elif opts.expire_override: data = bodhi.send_request('override/expire', req_params={ 'build': opts.expire_override, }, auth=True) if data.get('tg_flash'): log.info(data['tg_flash']) else: log.info("No data returned from bodhi?") elif opts.list_overrides or opts.my_overrides: data = bodhi.send_request('override/list', req_params={ 'mine': opts.my_overrides, 'release': opts.release, 'show_expired': opts.show_expired, }, auth=True) print data['title'] + '\n' + '=' * len(data['title']) + '\n' for override in data['overrides']: print "[ %s ]" % override['build'] print " * Notes: %s" % override['notes'] print " * Submitter: %s" % override['submitter'] print " * Submitted: %s" % override['date_submitted'] if override['expiration']: print " * Expiration: %s" % override['expiration'] if override['date_expired']: print " * Expired: %s" % override['date_expired'] print ## Query updates elif opts.status or opts.bugs or opts.release or opts.type_ or \ opts.mine or args: def print_query(data): if data.has_key('tg_flash') and data['tg_flash']: log.error(data['tg_flash']) sys.exit(-1) if data['num_items'] > 1: for update in data['updates']: print( bodhi.update_str(update, minimal=True).encode("UTF-8")) log.info("%d updates found (%d shown)" % (data['num_items'], len(data['updates']))) else: for update in data['updates']: print(bodhi.update_str(update).encode("UTF-8")) if args: for arg in args: data = bodhi.query(package=arg, release=opts.release, status=opts.status, type_=opts.type_, bugs=opts.bugs, request=opts.request, mine=opts.mine, limit=opts.limit) print_query(data) else: data = bodhi.query(release=opts.release, status=opts.status, type_=opts.type_, bugs=opts.bugs, request=opts.request, mine=opts.mine, limit=opts.limit) print_query(data) elif opts.download: data = bodhi.query(release=opts.release, status=opts.status, type_=opts.type_, bugs=opts.bugs, request=opts.request, mine=opts.mine, limit=opts.limit, package=opts.download) if len(data['updates']) > 1: log.info("%d possible updates were found" % len(data['updates'])) for update in data['updates']: print( bodhi.update_str(update, minimal=True).encode("UTF-8")) else: update = data['updates'][0] log.info("Downloading %s..." % update['title']) p = subprocess.Popen('uname -m', shell=True, stdout=subprocess.PIPE) arch = p.communicate()[0].strip() for build in update['builds']: subprocess.call( 'koji download-build --arch=%s ' '--arch=noarch%s %s' % (arch, arch == 'i686' and ' --arch=i386 --arch=i586' or '', build['nvr']), shell=True) else: parser.print_help() break except AuthError, e: log.debug('Caught AuthError: %s' % to_bytes(e)) bodhi.password = getpass('Password for %s: ' % opts.username) except ServerError, e: log.exception(e) #log.error(e.message) sys.exit(-1)