cli: show log urls for failed tasks

Fixes: https://pagure.io/koji/issue/2188
This commit is contained in:
Tomas Kopecek 2020-09-22 09:45:15 +02:00 committed by Mike McLean
parent 30e87348b8
commit bc478c2d68
17 changed files with 86 additions and 59 deletions

View file

@ -537,7 +537,7 @@ def handle_build(options, session, args):
if build_opts.wait or (build_opts.wait is None and not _running_in_bg()):
session.logout()
return watch_tasks(session, [task_id], quiet=build_opts.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_chain_build(options, session, args):
@ -612,7 +612,7 @@ def handle_chain_build(options, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=build_opts.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_maven_build(options, session, args):
@ -713,7 +713,7 @@ def handle_maven_build(options, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=build_opts.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_wrapper_rpm(options, session, args):
@ -785,7 +785,7 @@ def handle_wrapper_rpm(options, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_maven_chain(options, session, args):
@ -837,7 +837,7 @@ def handle_maven_chain(options, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_resubmit(goptions, session, args):
@ -865,7 +865,7 @@ def handle_resubmit(goptions, session, args):
else:
session.logout()
return watch_tasks(session, [newID], quiet=options.quiet,
poll_interval=goptions.poll_interval)
poll_interval=goptions.poll_interval, topurl=goptions.topurl)
def handle_call(goptions, session, args):
@ -1152,7 +1152,7 @@ def handle_restart_hosts(options, session, args):
if my_opts.wait or (my_opts.wait is None and not _running_in_bg()):
session.logout()
return watch_tasks(session, [task_id], quiet=my_opts.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_import(goptions, session, args):
@ -5889,7 +5889,7 @@ def _build_image_indirection(options, task_opts, session, args):
print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id))
if task_opts.wait or (task_opts.wait is None and not _running_in_bg()):
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet)
return watch_tasks(session, [task_id], quiet=options.quiet, topurl=options.topurl)
def handle_image_build(options, session, args):
@ -6085,7 +6085,7 @@ def _build_image(options, task_opts, session, args, img_type):
if task_opts.wait or (task_opts.wait is None and not _running_in_bg()):
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def _build_image_oz(options, task_opts, session, args):
@ -6154,7 +6154,7 @@ def _build_image_oz(options, task_opts, session, args):
if task_opts.wait or (task_opts.wait is None and not _running_in_bg()):
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_win_build(options, session, args):
@ -6229,7 +6229,7 @@ def handle_win_build(options, session, args):
if build_opts.wait or (build_opts.wait is None and not _running_in_bg()):
session.logout()
return watch_tasks(session, [task_id], quiet=build_opts.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_free_task(goptions, session, args):
@ -6476,7 +6476,7 @@ def anon_handle_watch_task(goptions, session, args):
parser.error(_("at least one task id must be specified"))
return watch_tasks(session, tasks, quiet=options.quiet,
poll_interval=goptions.poll_interval)
poll_interval=goptions.poll_interval, topurl=goptions.topurl)
def anon_handle_watch_logs(goptions, session, args):
@ -6540,7 +6540,7 @@ def handle_make_task(goptions, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=goptions.quiet,
poll_interval=goptions.poll_interval)
poll_interval=goptions.poll_interval, topurl=goptions.topurl)
def handle_tag_build(opts, session, args):
@ -6566,7 +6566,7 @@ def handle_tag_build(opts, session, args):
else:
session.logout()
return watch_tasks(session, tasks, quiet=opts.quiet,
poll_interval=opts.poll_interval)
poll_interval=opts.poll_interval, topurl=opts.topurl)
def handle_move_build(opts, session, args):
@ -6617,7 +6617,7 @@ def handle_move_build(opts, session, args):
else:
session.logout()
return watch_tasks(session, tasks, quiet=opts.quiet,
poll_interval=opts.poll_interval)
poll_interval=opts.poll_interval, topurl=opts.topurl)
def handle_untag_build(goptions, session, args):
@ -6981,7 +6981,7 @@ def anon_handle_download_task(options, session, args):
koji.TASK_STATES['CANCELED'],
koji.TASK_STATES['FAILED']):
watch_tasks(session, [base_task_id], quiet=suboptions.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def check_downloadable(task):
return task["method"] == "buildArch"
@ -7188,7 +7188,7 @@ def handle_regen_repo(options, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
def handle_dist_repo(options, session, args):
@ -7327,7 +7327,7 @@ def handle_dist_repo(options, session, args):
else:
session.logout()
return watch_tasks(session, [task_id], quiet=options.quiet,
poll_interval=options.poll_interval)
poll_interval=options.poll_interval, topurl=options.topurl)
_search_types = ('package', 'build', 'tag', 'target', 'user', 'host', 'rpm',

View file

@ -139,12 +139,13 @@ def print_task_recurse(task, depth=0):
class TaskWatcher(object):
def __init__(self, task_id, session, level=0, quiet=False):
def __init__(self, task_id, session, level=0, quiet=False, topurl=None):
self.id = task_id
self.session = session
self.info = None
self.level = level
self.quiet = quiet
self.topurl = topurl
# XXX - a bunch of this stuff needs to adapt to different tasks
@ -198,7 +199,7 @@ class TaskWatcher(object):
else:
# First time we're seeing this task, so just show the current state
if not self.quiet:
print("%s: %s" % (self.str(), self.display_state(self.info)))
print("%s: %s" % (self.str(), self.display_state(self.info, level=self.level)))
return False
def is_done(self):
@ -213,7 +214,7 @@ class TaskWatcher(object):
state = koji.TASK_STATES[self.info['state']]
return (state == 'CLOSED')
def display_state(self, info):
def display_state(self, info, level=0):
# We can sometimes be passed a task that is not yet open, but
# not finished either. info would be none.
if not info:
@ -225,7 +226,25 @@ class TaskWatcher(object):
else:
return 'open'
elif info['state'] == koji.TASK_STATES['FAILED']:
return 'FAILED: %s' % self.get_failure()
s = 'FAILED: %s' % self.get_failure()
if self.topurl:
# add relevant logs if there are any
output = list_task_output_all_volumes(self.session, self.id)
files = []
for filename, volumes in six.iteritems(output):
files += [(filename, volume) for volume in volumes]
files = [file_volume for file_volume in files if file_volume[0].endswith('log')]
pi = koji.PathInfo(topdir=self.topurl)
# indent more than current level
level += 1
logs = [' ' * level + os.path.join(pi.task(self.id, f[1]), f[0]) for f in files]
if logs:
s += '\n' + ' ' * level + 'Relevant logs:\n'
s += '\n'.join(logs)
return s
else:
return koji.TASK_STATES[info['state']].lower()
@ -264,7 +283,7 @@ def display_task_results(tasks):
print('%s has not completed' % task_label)
def watch_tasks(session, tasklist, quiet=False, poll_interval=60, ki_handler=None):
def watch_tasks(session, tasklist, quiet=False, poll_interval=60, ki_handler=None, topurl=None):
if not tasklist:
return
if not quiet:
@ -272,7 +291,7 @@ def watch_tasks(session, tasklist, quiet=False, poll_interval=60, ki_handler=Non
if ki_handler is None:
def ki_handler(progname, tasks, quiet):
if not quiet:
tlist = ['%s: %s' % (t.str(), t.display_state(t.info))
tlist = ['%s: %s' % (t.str(), t.display_state(t.info, level=t.level))
for t in tasks.values() if not t.is_done()]
print(
"Tasks still running. You can continue to watch with the"
@ -283,7 +302,7 @@ def watch_tasks(session, tasklist, quiet=False, poll_interval=60, ki_handler=Non
try:
tasks = {}
for task_id in tasklist:
tasks[task_id] = TaskWatcher(task_id, session, quiet=quiet)
tasks[task_id] = TaskWatcher(task_id, session, quiet=quiet, topurl=topurl)
while True:
all_done = True
for task_id, task in list(tasks.items()):
@ -301,7 +320,7 @@ def watch_tasks(session, tasklist, quiet=False, poll_interval=60, ki_handler=Non
child_id = child['id']
if child_id not in tasks.keys():
tasks[child_id] = TaskWatcher(child_id, session, task.level + 1,
quiet=quiet)
quiet=quiet, topurl=topurl)
tasks[child_id].update()
# If we found new children, go through the list again,
# in case they have children also