From d1ab4ed2876a362afbd4eb8c3534fd526564666c Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Wed, 29 Mar 2017 21:31:24 -0400 Subject: [PATCH] refactor --- cli/koji | 59 ++++++++++++++++++----------- plugins/builder/save_failed_tree.py | 44 ++++++++++++--------- plugins/hub/save_failed_tree.py | 10 +++-- 3 files changed, 69 insertions(+), 44 deletions(-) diff --git a/cli/koji b/cli/koji index 5d782ad6..5a234fd5 100755 --- a/cli/koji +++ b/cli/koji @@ -7202,50 +7202,63 @@ def handle_runroot(options, session, args): sys.exit(1) return + def handle_save_failed_tree(options, session, args): "Create tarball with whole buildtree" - usage = _("usage: %prog save-failed-tree [options] taskID") + usage = _("usage: %prog save-failed-tree [options] ID") usage += _("\n(Specify the --help global option for a list of other help options)") parser = OptionParser(usage=usage) parser.add_option("-f", "--full", action="store_true", default=False, help=_("Download whole tree, if not specified, only builddir will be downloaded")) - parser.add_option("--quiet", action="store_true", - help=_("Do not print the task information"), default=options.quiet) + parser.add_option("-t", "--task", action="store_const", dest="mode", + const="task", default="task", + help=_("Treat ID as a task ID (the default)")) + parser.add_option("-r", "--buildroot", action="store_const", dest="mode", + const="buildroot", + help=_("Treat ID as a buildroot ID")) + parser.add_option("--quiet", action="store_true", default=options.quiet, + help=_("Do not print the task information")) parser.add_option("--nowait", action="store_true", help=_("Don't wait on build")) (opts, args) = parser.parse_args(args) if len(args) != 1: - parser.error(_("List exactly one taskID")) + parser.error(_("List exactly one task or buildroot ID")) try: - taskID = int(args[0]) + id_val = int(args[0]) except ValueError: - parser.error(_("Task ID must be an integer.")) + parser.error(_("ID must be an integer")) activate_session(session) + + if opts.mode == "buildroot": + br_id = id_val + else: + brs = [b['id'] for b in session.listBuildroots(taskID=id_val)] + if not brs: + print(_("No buildroots for task %s") % id_val) + return 1 + br_id = max(brs) + if len(brs) > 1: + print(_("Multiple buildroots for task. Choosing last one (%s)") % br_id) + try: - task_id = session.saveFailedTree(taskID, opts.full) + task_id = session.saveFailedTree(br_id, opts.full) except koji.GenericError as e: m = str(e) - if 'Only failed tasks can upload their buildroots.' in m: - print(_("Only failed tasks can upload their buildroots.")) - elif 'tasks can upload their buildroots (Task' in m: - print(_("Task of this type has disabled support for uploading" \ - " buildroot. (configurable on hub)")) - elif 'Invalid method' in m: - print(_("* The save_failed_tree plugin appears to not be installed" \ - " on the koji hub. Please contact the administrator.")) - else: - raise - return 1 - except koji.ActionNotAllowed: - print(_("Only task owner or admin can run this task.")) - return 1 + if 'Invalid method' in m: + print(_("* The save_failed_tree plugin appears to not be " + "installed on the koji hub. Please contact the " + "administrator.")) + return 1 + raise + if not opts.quiet: - print("Created task:", task_id) - print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) + print(_("Created task %s for buildroot %s") % (task_id, br_id)) + print("Task info: %s/taskinfo?taskID=%s" + % (options.weburl, task_id)) if opts.nowait: return diff --git a/plugins/builder/save_failed_tree.py b/plugins/builder/save_failed_tree.py index 1a22db6d..d9b325cf 100644 --- a/plugins/builder/save_failed_tree.py +++ b/plugins/builder/save_failed_tree.py @@ -12,12 +12,14 @@ __all__ = ('SaveFailedTreeTask',) CONFIG_FILE = '/etc/kojid/plugins/save_failed_tree.conf' config = None + def omit_paths(tarinfo): if any([fnmatch.fnmatch(tarinfo.name, f) for f in config['path_filters']]): return None else: return tarinfo + def read_config(): global config cp = ConfigParser.SafeConfigParser() @@ -31,29 +33,37 @@ def read_config(): if cp.has_option('general', 'volume'): config['volume'] = cp.get('general', 'volume').strip() + class SaveFailedTreeTask(tasks.BaseTaskHandler): Methods = ['saveFailedTree'] _taskWeight = 3.0 - def handler(self, taskID, full=False): - self.logger.debug("Starting saving buildroots for task %d [full=%s]" % (taskID, full)) + def handler(self, buildrootID, full=False): + self.logger.debug("Saving buildroot %d [full=%s]", buildrootID, full) read_config() - tar_path = os.path.join(self.workdir, 'broots-task-%s.tar.gz' % taskID) - f = tarfile.open(tar_path, "w:gz") + + brinfo = self.session.getBuildroot(buildrootID) host_id = self.session.host.getHost()['id'] - for broot in self.session.listBuildroots(taskID=taskID): - if broot['host_id'] != host_id: - raise koji.GenericError("Task is run on wrong builder.") - broot = BuildRoot(self.session, self.options, broot['id']) - path = broot.rootdir() - if full: - self.logger.debug("Adding buildroot (full): %s" % path) - else: - path = os.path.join(path, 'builddir') - self.logger.debug("Adding buildroot: %s" % path) - f.add(path, filter=omit_paths) + if brinfo['host_id'] != host_id: + raise koji.GenericError("Task is run on wrong builder") + broot = BuildRoot(self.session, self.options, brinfo['id']) + path = broot.rootdir() + + if full: + self.logger.debug("Adding buildroot (full): %s" % path) + else: + path = os.path.join(path, 'builddir') + self.logger.debug("Adding buildroot: %s" % path) + if not os.path.exists(path): + raise koji.GenericError("Buildroot directory is missing: %s" % path) + + tar_path = os.path.join(self.workdir, 'broot-%s.tar.gz' % buildrootID) + self.logger.debug("Creating buildroot archive %s", tar_path) + f = tarfile.open(tar_path, "w:gz") + f.add(path, filter=omit_paths) f.close() - self.logger.debug("Uploading %s to hub." % tar_path) + + self.logger.debug("Uploading %s to hub", tar_path) self.uploadFile(tar_path, volume=config['volume']) os.unlink(tar_path) - self.logger.debug("Finished saving buildroots for task %d" % taskID) + self.logger.debug("Finished saving buildroot %s", buildrootID) diff --git a/plugins/hub/save_failed_tree.py b/plugins/hub/save_failed_tree.py index 46ee865b..3a981284 100644 --- a/plugins/hub/save_failed_tree.py +++ b/plugins/hub/save_failed_tree.py @@ -15,7 +15,7 @@ allowed_methods = None @export -def saveFailedTree(taskID, full=False, **opts): +def saveFailedTree(buildrootID, full=False, **opts): """Create saveFailedTree task If arguments are invalid, error message is returned. Otherwise task id of @@ -23,7 +23,7 @@ def saveFailedTree(taskID, full=False, **opts): global config, allowed_methods # let it raise errors - taskID = int(taskID) + buildrootID = int(buildrootID) full = bool(full) # read configuration only once @@ -34,6 +34,8 @@ def saveFailedTree(taskID, full=False, **opts): if len(allowed_methods) == 1 and allowed_methods[0] == '*': allowed_methods = '*' + brinfo = kojihub.get_buildroot(buildrootID, strict=True) + taskID = brinfo['task_id'] task_info = kojihub.Task(taskID).getInfo() if task_info['state'] != koji.TASK_STATES['FAILED']: raise koji.PreBuildError("Task %s has not failed. Only failed tasks can upload their buildroots." % taskID) @@ -45,8 +47,8 @@ def saveFailedTree(taskID, full=False, **opts): elif not kojihub.get_host(task_info['host_id'])['enabled']: raise koji.PreBuildError("Host is disabled.") - args = koji.encode_args(taskID, full, **opts) + args = koji.encode_args(buildrootID, full, **opts) taskopts = { - 'assign': task_info['host_id'], + 'assign': brinfo['host_id'], } return kojihub.make_task('saveFailedTree', args, **taskopts)