Esempio n. 1
0
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')
Esempio n. 2
0
    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")
Esempio n. 3
0
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')
Esempio n. 4
0
    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)
Esempio n. 6
0
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)
Esempio n. 7
0
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)