def handle_save_failed_tree(options, session, args): "Create tarball with whole buildtree" 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("-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 task or buildroot ID") try: id_val = int(args[0]) except ValueError: parser.error("ID must be an integer") activate_session(session, options) 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(br_id, opts.full) except koji.GenericError as e: m = str(e) 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 %s for buildroot %s" % (task_id, br_id)) print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) if opts.nowait: return else: session.logout() return watch_tasks(session, [task_id], quiet=opts.quiet, poll_interval=options.poll_interval, topurl=options.topurl)
def handle_replicate_tasks(options, session, args): """[admin] Replicate tasks""" (parser, opts, task_ids) = parse_options(options, args) if options.debug: logger.setLevel(logging.DEBUG) else: logger.setLevel(logging.INFO) task_ids = check_options(parser, opts, task_ids) activate_session(session, options) channel_override = getattr(opts, 'channel_override', None) if channel_override: opts.channels_override = session.getChannel(channel_override, strict=True)['id'] if not task_ids: tasks = get_tasks(session, parser, opts) else: tasks = task_ids b_queue = queue.Queue() for task in tasks: b_queue.put(task) threads = [] for i in range(4): subsession = session.subsession() thread = threading.Thread(name='replicator %i' % i, target=replicate_handler, args=(subsession, b_queue, opts)) thread.setDaemon(True) thread.start() threads.append(thread) for t in threads: t.join()
def handle_list_sidetags(options, session, args): "List sidetags" usage = _("%(prog)s list-sidetags [options]") usage += _( "\n(Specify the --help global option for a list of other help options)" ) parser = ArgumentParser(usage=usage) parser.add_argument("--basetag", action="store", help=_("Filter on basetag")) parser.add_argument("--user", action="store", help=_("Filter on user")) parser.add_argument("--mine", action="store_true", help=_("Filter on user")) opts = parser.parse_args(args) if opts.mine and opts.user: parser.error(_("Specify only one from --user --mine")) if opts.mine: activate_session(session, options) user = session.getLoggedInUser()["name"] else: user = opts.user for tag in session.listSideTags(basetag=opts.basetag, user=user): print(tag["name"])
def test_activate_session_pw(self): session = mock.MagicMock() session.logged_in = True options = {'authtype': 'password', 'debug': False, 'cert': ''} activate_session(session, options) session.login.assert_called_once_with() session.ssl_login.assert_not_called() session.krb_login.assert_not_called()
def ensure_logged_in(self): """ Log in if we are not already logged in """ if not self.session.logged_in: self.session.opts['noauth'] = False # Log in ("activate") this session: # Note: this can raise SystemExit if there is a problem, eg with # Kerberos: activate_session(self.session, self.session.opts)
def test_activate_session_pw_implicit(self): session = mock.MagicMock() session.logged_in = True options = {'authtype': None, 'debug': False, 'cert': '', 'user': '******'} activate_session(session, options) session.login.assert_called_once_with() session.ssl_login.assert_not_called() session.krb_login.assert_not_called()
def test_activate_session_krb(self): session = mock.MagicMock() session.logged_in = True options = {'authtype': 'kerberos', 'debug': False, 'cert': '', 'keytab': None, 'principal': None} activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() session.krb_login.assert_called_once_with(proxyuser=None)
def test_activate_session_no_method(self): session = mock.MagicMock() session.logged_in = False options = {'authtype': None, 'debug': False, 'cert': ''} activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() session.gssapi_login.assert_called_once() self.error.assert_called_once()
def handle_osbuild_image(options, session, argv): "[build] Build images via osbuild" args = parse_args(argv) name, version, arch, target = args.name, args.version, args.arch, args.target distro, image_types = args.distro, args.image_type if not image_types: image_types = ["qcow2"] opts = {} if args.release: opts["release"] = args.release if args.repo: opts["repo"] = ",".join(args.repo) # Do some early checks to be able to give quick feedback check_target(session, target) if not options.quiet: print("name:", name) print("version:", version) print("distro:", distro) print("arches:", ", ".join(arch)) print("target:", target) print("image types ", str(image_types)) pprint(opts) kl.activate_session(session, options) task_id = session.osbuildImage(name, version, distro, image_types, target, arch, opts=opts) if not options.quiet: print("Created task: %s" % task_id) print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) # pylint: disable=protected-access if (args.wait is None and kl._running_in_bg()) or args.wait is False: # either running in the background or must not wait by user's # request. All done. return None session.logout() res = kl.watch_tasks(session, [task_id], quiet=options.quiet) if res == 0: result = session.getTaskResult(task_id) print(result) return res
def test_activate_session_krb_implicit(self): session = mock.MagicMock() session.logged_in = True options = {'authtype': None, 'debug': False, 'cert': '', 'keytab': None, 'principal': None} self.has_krb_creds.return_value = True activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() session.krb_login.assert_called_once_with(proxyuser=None)
def test_activate_session_no_method(self): session = mock.MagicMock() session.logged_in = False options = {'authtype': None, 'debug': False, 'cert': ''} self.has_krb_creds.return_value = False activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() session.krb_login.assert_not_called() self.error.assert_called_once()
def test_activate_session_noauth(self): session = mock.MagicMock() session.logged_in = False options = {'authtype': 'noauth', 'debug': False} activate_session(session, options) options = {'authtype': None, 'noauth': True, 'debug': False} activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() session.krb_login.assert_not_called()
def handle_build(options, session, args, flatpak=False, sourcebuild=False): if sourcebuild: build_opts, args, opts, parser = parse_source_arguments(options, args) else: build_opts, args, opts, parser = parse_arguments( options, args, flatpak) activate_session(session, options) target = args[0] build_target = session.getBuildTarget(target) if not build_target: parser.error(_("Unknown build target: %s" % target)) dest_tag = session.getTag(build_target['dest_tag']) if not dest_tag: parser.error( _("Unknown destination tag: %s" % build_target['dest_tag_name'])) if dest_tag['locked'] and not build_opts.scratch: parser.error(_("Destination tag %s is locked" % dest_tag['name'])) priority = None if build_opts.background: # relative to koji.PRIO_DEFAULT priority = 5 if sourcebuild: task_id = session.buildSourceContainer( target, opts, priority=priority, channel=build_opts.channel_override) else: source = args[1] task_id = session.buildContainer(source, target, opts, priority=priority, channel=build_opts.channel_override) if not build_opts.quiet: print("Created task: %s" % task_id) print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) if build_opts.wait or (build_opts.wait is None and not _running_in_bg()): session.logout() rv = watch_tasks(session, [task_id], quiet=build_opts.quiet) # Task completed and a result should be available. if rv == 0: result = session.getTaskResult(task_id) print_task_result(task_id, result, options.weburl) return rv else: return
def handle_add_sidetag(options, session, args): "Create sidetag" usage = _("%(prog)s add-sidetag [options] <basetag>") usage += _( "\n(Specify the --help global option for a list of other help options)" ) parser = ArgumentParser(usage=usage) parser.add_argument("basetag", help="name of basetag") parser.add_argument( "-q", "--quiet", action="store_true", help=_("Do not print tag name"), default=options.quiet, ) parser.add_argument("-w", "--wait", action="store_true", help=_("Wait until repo is ready.")) parser.add_argument("--debuginfo", action="store_true", help=_("Buildroot repo will contain debuginfos")) parser.add_argument("--suffix", action="store", help=_("Suffix from hub-supported ones")) opts = parser.parse_args(args) activate_session(session, options) kwargs = {"debuginfo": opts.debuginfo} if opts.suffix: kwargs['suffix'] = opts.suffix try: tag = session.createSideTag(opts.basetag, **kwargs) except koji.ActionNotAllowed: parser.error(_("Policy violation")) except koji.ParameterError as ex: if 'suffix' in str(ex): parser.error( _("Hub is older and doesn't support --suffix, please run it without it" )) else: raise if not opts.quiet: print(tag["name"]) if opts.wait: args = ["--target", tag["name"]] if opts.quiet: args.append("--quiet") anon_handle_wait_repo(options, session, args)
def handle_build(options, session, args, flatpak): build_opts, args, opts, parser = parse_arguments(options, args, flatpak) activate_session(session, options) target = args[0] if target.lower() == "none" and build_opts.repo_id: target = None build_opts.skip_tag = True else: build_target = session.getBuildTarget(target) if not build_target: parser.error(_("Unknown build target: %s" % target)) dest_tag = session.getTag(build_target['dest_tag']) if not dest_tag: parser.error( _("Unknown destination tag: %s" % build_target['dest_tag_name'])) if dest_tag['locked'] and not build_opts.scratch: parser.error(_("Destination tag %s is locked" % dest_tag['name'])) source = args[1] priority = None if build_opts.background: # relative to koji.PRIO_DEFAULT priority = 5 if '://' not in source: parser.error( _("scm URL does not look like an URL to a source repository")) if '#' not in source: parser.error( _("scm URL must be of the form <url_to_repository>#<revision>)")) task_id = session.buildContainer(source, target, opts, priority=priority, channel=build_opts.channel_override) if not build_opts.quiet: print("Created task: %s" % task_id) print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) if build_opts.wait or (build_opts.wait is None and not _running_in_bg()): session.logout() rv = watch_tasks(session, [task_id], quiet=build_opts.quiet) # Task completed and a result should be available. if rv == 0: result = session.getTaskResult(task_id) print_task_result(task_id, result, options.weburl) return rv else: return
def test_activate_session_ssl(self): session = mock.MagicMock() session.logged_in = True certfile = '%s/CERT' % self.tempdir options = {'authtype': 'ssl', 'debug': False, 'cert': certfile, 'serverca': 'SERVERCA'} activate_session(session, options) session.ssl_login.assert_called_once_with(certfile, None, 'SERVERCA', proxyuser=None) session.login.assert_not_called() session.krb_login.assert_not_called()
def ensure_logged_in(session): """ Authenticate this Koji session (if necessary). :param session: a koji.ClientSession :returns: None """ if not session.logged_in: session.opts['noauth'] = False # Log in ("activate") this session: # Note: this can raise SystemExit if there is a problem, eg with # Kerberos: activate_session(session, session.opts)
def handle_edit_sidetag(options, session, args): "Edit sidetag" usage = _("%(prog)s edit-sidetag [options]") usage += _( "\n(Specify the --help global option for a list of other help options)" ) parser = ArgumentParser(usage=usage) parser.add_argument("sidetag", help="name of sidetag") parser.add_argument("--debuginfo", action="store_true", default=None, help=_("Generate debuginfo repository")) parser.add_argument("--no-debuginfo", action="store_false", dest="debuginfo") parser.add_argument("--rpm-macro", action="append", default=[], metavar="key=value", dest="rpm_macros", help=_("Set tag-specific rpm macros")) parser.add_argument("--remove-rpm-macro", action="append", default=[], metavar="key", dest="remove_rpm_macros", help=_("Remove rpm macros")) opts = parser.parse_args(args) if opts.debuginfo is None and not opts.rpm_macros and not opts.remove_rpm_macros: parser.error("At least one option needs to be specified") activate_session(session, options) kwargs = {} if opts.debuginfo is not None: kwargs['debuginfo'] = opts.debuginfo if opts.rpm_macros: rpm_macros = {} for xopt in opts.rpm_macros: key, value = xopt.split('=', 1) value = arg_filter(value) rpm_macros[key] = value kwargs['rpm_macros'] = rpm_macros if opts.remove_rpm_macros: kwargs['remove_rpm_macros'] = opts.remove_rpm_macros session.editSideTag(opts.sidetag, **kwargs)
def handle_remove_sidetag(options, session, args): "Remove sidetag" usage = "%(prog)s remove-sidetag [options] <sidetag> ..." usage += "\n(Specify the --help global option for a list of other help options)" parser = ArgumentParser(usage=usage) parser.add_argument("sidetags", help="name of sidetag", nargs="+") opts = parser.parse_args(args) activate_session(session, options) session.multicall = True for sidetag in opts.sidetags: session.removeSideTag(sidetag) session.multiCall(strict=True)
def get_session(profile): """ Return an authenticated Koji session """ # Return a cached session, if available. mykoji = koji.get_profile_module(profile) opts = mykoji.grab_session_options(mykoji.config) session = mykoji.ClientSession(mykoji.config.server, opts) # Log in ("activate") this sesssion: # Note: this can raise SystemExit if there is a problem, eg with Kerberos: activate_session(session, mykoji.config) assert session.logged_in userinfo = session.getLoggedInUser() username = userinfo['name'] log.info('authenticated to %s as %s' % (mykoji.config.server, username)) return session
def test_activate_session_krb_keytab(self): session = mock.MagicMock() session.logged_in = True options = { 'authtype': 'kerberos', 'debug': False, 'cert': '', 'keytab': 'KEYTAB', 'principal': 'PRINCIPAL' } activate_session(session, options) session.login.assert_not_called() session.ssl_login.assert_not_called() session.gssapi_login.assert_called_once_with(principal='PRINCIPAL', keytab='KEYTAB', proxyuser=None)
def handle_build(options, session, args, flatpak): build_opts, args, opts, parser = parse_arguments(options, args, flatpak) activate_session(session, options) target = args[0] if target.lower() == "none" and build_opts.repo_id: target = None build_opts.skip_tag = True else: build_target = session.getBuildTarget(target) if not build_target: parser.error(_("Unknown build target: %s" % target)) dest_tag = session.getTag(build_target['dest_tag']) if not dest_tag: parser.error(_("Unknown destination tag: %s" % build_target['dest_tag_name'])) if dest_tag['locked'] and not build_opts.scratch: parser.error(_("Destination tag %s is locked" % dest_tag['name'])) source = args[1] priority = None if build_opts.background: # relative to koji.PRIO_DEFAULT priority = 5 if '://' not in source: parser.error(_("scm URL does not look like an URL to a source repository")) if '#' not in source: parser.error(_("scm URL must be of the form <url_to_repository>#<revision>)")) task_id = session.buildContainer(source, target, opts, priority=priority, channel=build_opts.channel_override) if not build_opts.quiet: print "Created task:", task_id print "Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id) if build_opts.wait or (build_opts.wait is None and not _running_in_bg()): session.logout() rv = clikoji.watch_tasks(session, [task_id], quiet=build_opts.quiet) # Task completed and a result should be available. if rv == 0: result = session.getTaskResult(task_id) print_task_result(task_id, result, options.weburl) return rv else: return
def get_koji_session(): # Return an unauthenticated koji session try: conf = koji.read_config(PROFILE) except koji.ConfigurationError as e: if 'no configuration for profile name' in str(e): print('You are missing the brewkoji RPM. Please install it.') print('It is available in the RCMTOOLS composes.') print('http://download.devel.redhat.com/rel-eng/RCMTOOLS/') raise hub = conf['server'] opts = {'krbservice': conf['krbservice']} session = koji.ClientSession(hub, opts) # KojiOptions = namedtuple('Options', ['authtype', 'debug']) # options = KojiOptions(authtype='') # Can I simply pass in the conf dict like this? activate_session(session, conf) return session
def activate(self) -> None: """ Activate our session. This is triggered after validate, before pre_handle and handle The session and goptions attributes will have been set just prior. """ if self.session: return activate_session(self.session, self.goptions)
def handle_add_sidetag(options, session, args): "Create sidetag" usage = _("%(prog)s add-sidetag [options] <basetag>") usage += _( "\n(Specify the --help global option for a list of other help options)" ) parser = ArgumentParser(usage=usage) parser.add_argument("basetag", help="name of basetag") parser.add_argument( "-q", "--quiet", action="store_true", help=_("Do not print tag name"), default=options.quiet, ) parser.add_argument("-w", "--wait", action="store_true", help=_("Wait until repo is ready.")) parser.add_argument("--debuginfo", action="store_true", help=_("Buildroot repo will contain debuginfos")) opts = parser.parse_args(args) activate_session(session, options) try: tag = session.createSideTag(opts.basetag, debuginfo=opts.debuginfo) except koji.ActionNotAllowed: parser.error(_("Policy violation")) if not opts.quiet: print(tag["name"]) if opts.wait: args = ["--target", tag["name"]] if opts.quiet: args.append("--quiet") anon_handle_wait_repo(options, session, args)
def handle_runroot(options, session, args): "[admin] Run a command in a buildroot" usage = _("usage: %prog runroot [options] <tag> <arch> <command>") usage += _( "\n(Specify the --help global option for a list of other help options)" ) parser = OptionParser(usage=usage) parser.disable_interspersed_args() parser.add_option("-p", "--package", action="append", default=[], help=_("make sure this package is in the chroot")) parser.add_option("-m", "--mount", action="append", default=[], help=_("mount this directory read-write in the chroot")) parser.add_option("--skip-setarch", action="store_true", default=False, help=_("bypass normal setarch in the chroot")) parser.add_option("-w", "--weight", type='int', help=_("set task weight")) parser.add_option("--channel-override", help=_("use a non-standard channel")) parser.add_option("--task-id", action="store_true", default=False, help=_("Print the ID of the runroot task")) parser.add_option( "--use-shell", action="store_true", default=False, help=_("Run command through a shell, otherwise uses exec")) parser.add_option( "--new-chroot", action="store_true", default=False, help=_( "Run command with the --new-chroot (systemd-nspawn) option to mock" )) parser.add_option("--repo-id", type="int", help=_("ID of the repo to use")) parser.add_option("--nowait", action="store_false", dest="wait", default=True, help=_("Do not wait on task")) parser.add_option("--watch", action="store_true", help=_("Watch task instead of printing runroot.log")) parser.add_option("--quiet", action="store_true", default=options.quiet, help=_("Do not print the task information")) (opts, args) = parser.parse_args(args) if len(args) < 3: parser.error(_("Incorrect number of arguments")) assert False # pragma: no cover activate_session(session, options) tag = args[0] arch = args[1] if opts.use_shell: # everything must be correctly quoted command = ' '.join(args[2:]) else: command = args[2:] try: kwargs = { 'channel': opts.channel_override, 'packages': opts.package, 'mounts': opts.mount, 'repo_id': opts.repo_id, 'skip_setarch': opts.skip_setarch, 'weight': opts.weight } # Only pass this kwarg if it is true - this prevents confusing older # builders with a different function signature if opts.new_chroot: kwargs['new_chroot'] = True task_id = session.runroot(tag, arch, command, **kwargs) except koji.GenericError as e: if 'Invalid method' in str(e): print("* The runroot plugin appears to not be installed on the" " koji hub. Please contact the administrator.") raise if opts.task_id: print(task_id) if not opts.wait: return if opts.watch: session.logout() return watch_tasks(session, [task_id], quiet=opts.quiet, poll_interval=options.poll_interval) try: while True: # wait for the task to finish if session.taskFinished(task_id): break time.sleep(options.poll_interval) except KeyboardInterrupt: # this is probably the right thing to do here print("User interrupt: canceling runroot task") session.cancelTask(task_id) raise output = list_task_output_all_volumes(session, task_id) if 'runroot.log' in output: for volume in output['runroot.log']: log = session.downloadTaskOutput(task_id, 'runroot.log', volume=volume) sys.stdout.write(log) info = session.getTaskInfo(task_id) if info is None: sys.exit(1) state = koji.TASK_STATES[info['state']] if state in ('FAILED', 'CANCELED'): sys.exit(1)
def handle_build(options, session, args, flatpak): "Build a container" if flatpak: usage = _("usage: %prog flatpak-build [options] target <scm url>") else: usage = _("usage: %prog container-build [options] target <scm url or " "archive path>") usage += _("\n(Specify the --help global option for a list of other help " "options)") parser = OptionParser(usage=usage) if flatpak: parser.add_option("-m", "--module", metavar="NAME:STREAM[:VERSION]", help="module to build against") parser.add_option("--scratch", action="store_true", help=_("Perform a scratch build")) parser.add_option("--wait", action="store_true", help=_("Wait on the build, even if running in the " "background")) parser.add_option("--nowait", action="store_false", dest="wait", help=_("Don't wait on build")) parser.add_option("--quiet", action="store_true", help=_("Do not print the task information"), default=options.quiet) if not flatpak: parser.add_option("--noprogress", action="store_true", help=_("Do not display progress of the upload")) parser.add_option("--background", action="store_true", help=_("Run the build at a lower priority")) parser.add_option("--epoch", help=_("Specify container epoch. Requires koji admin " "permission.")) parser.add_option("--repo-url", dest='yum_repourls', metavar="REPO_URL", action='append', help=_("URL of yum repo file. May be used multiple " "times.")) parser.add_option("--git-branch", metavar="GIT_BRANCH", help=_("Git branch")) parser.add_option("--channel-override", help=_("Use a non-standard channel [default: %default]"), default=DEFAULT_CHANNEL) if not flatpak: parser.add_option("--release", help=_("Set release label")) (build_opts, args) = parser.parse_args(args) if len(args) != 2: parser.error( _("Exactly two arguments (a build target and a SCM URL " "or archive file) are required")) assert False # Koji API has changed - activate_session requires two arguments # _running_in_bg has been moved to koji_cli.lib try: from koji_cli.lib import _running_in_bg, activate_session except ImportError: # Create wrappers for backwards compatibility. _running_in_bg = clikoji._running_in_bg def activate_session(session, options): try: clikoji.activate_session(session) except TypeError: clikoji.activate_session(session, options) activate_session(session, options) target = args[0] if target.lower() == "none" and build_opts.repo_id: target = None build_opts.skip_tag = True else: build_target = session.getBuildTarget(target) if not build_target: parser.error(_("Unknown build target: %s" % target)) dest_tag = session.getTag(build_target['dest_tag']) if not dest_tag: parser.error( _("Unknown destination tag: %s" % build_target['dest_tag_name'])) if dest_tag['locked'] and not build_opts.scratch: parser.error(_("Destination tag %s is locked" % dest_tag['name'])) source = args[1] opts = {} if flatpak: if not build_opts.module: parser.error(_("module must be specified")) if not build_opts.git_branch: parser.error(_("git-branch must be specified")) opts['flatpak'] = True opts['module'] = build_opts.module for key in ('scratch', 'epoch', 'yum_repourls', 'git_branch'): val = getattr(build_opts, key) if val is not None: opts[key] = val priority = None if build_opts.background: # relative to koji.PRIO_DEFAULT priority = 5 # try to check that source is an archive if '://' not in source: if flatpak: parser.error( _("scm URL does not look like an URL to a source repository")) # treat source as an archive and upload it if not build_opts.quiet: print "Uploading archive: %s" % source serverdir = clikoji._unique_path('cli-build') if _running_in_bg() or build_opts.noprogress or build_opts.quiet: callback = None else: callback = clikoji._progress_callback session.uploadWrapper(source, serverdir, callback=callback) print source = "%s/%s" % (serverdir, os.path.basename(source)) task_id = session.buildContainer(source, target, opts, priority=priority, channel=build_opts.channel_override) if not build_opts.quiet: print "Created task:", task_id print "Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id) if build_opts.wait or (build_opts.wait is None and not _running_in_bg()): session.logout() rv = clikoji.watch_tasks(session, [task_id], quiet=build_opts.quiet) # Task completed and a result should be available. if rv == 0: result = session.getTaskResult(task_id) print_task_result(task_id, result, options.weburl) return rv else: return
def handle_runroot(options, session, args): "[admin] Run a command in a buildroot" usage = _("usage: %prog runroot [options] <tag> <arch> <command>") usage += _("\n(Specify the --help global option for a list of other help options)") parser = OptionParser(usage=usage) parser.disable_interspersed_args() parser.add_option("-p", "--package", action="append", default=[], help=_("make sure this package is in the chroot")) parser.add_option("-m", "--mount", action="append", default=[], help=_("mount this directory read-write in the chroot")) parser.add_option("--skip-setarch", action="store_true", default=False, help=_("bypass normal setarch in the chroot")) parser.add_option("-w", "--weight", type='int', help=_("set task weight")) parser.add_option("--channel-override", help=_("use a non-standard channel")) parser.add_option("--task-id", action="store_true", default=False, help=_("Print the ID of the runroot task")) parser.add_option("--use-shell", action="store_true", default=False, help=_("Run command through a shell, otherwise uses exec")) parser.add_option("--new-chroot", action="store_true", default=None, help=_("Run command with the --new-chroot (systemd-nspawn) option to mock")) parser.add_option("--old-chroot", action="store_false", default=None, dest='new_chroot', help=_("Run command with the --old-chroot (systemd-nspawn) option to mock")) parser.add_option("--repo-id", type="int", help=_("ID of the repo to use")) parser.add_option("--nowait", action="store_false", dest="wait", default=True, help=_("Do not wait on task")) parser.add_option("--watch", action="store_true", help=_("Watch task instead of printing runroot.log")) parser.add_option("--quiet", action="store_true", default=options.quiet, help=_("Do not print the task information")) (opts, args) = parser.parse_args(args) if len(args) < 3: parser.error(_("Incorrect number of arguments")) assert False # pragma: no cover activate_session(session, options) tag = args[0] arch = args[1] if opts.use_shell: # everything must be correctly quoted command = ' '.join(args[2:]) else: command = args[2:] try: kwargs = { 'channel': opts.channel_override, 'packages': opts.package, 'mounts': opts.mount, 'repo_id': opts.repo_id, 'skip_setarch': opts.skip_setarch, 'weight': opts.weight } # Only pass this kwarg if it is true - this prevents confusing older # builders with a different function signature if opts.new_chroot is not None: kwargs['new_chroot'] = opts.new_chroot task_id = session.runroot(tag, arch, command, **kwargs) except koji.GenericError as e: if 'Invalid method' in str(e): print("* The runroot plugin appears to not be installed on the" " koji hub. Please contact the administrator.") raise if opts.task_id: print(task_id) if not opts.wait: return if opts.watch: session.logout() return watch_tasks(session, [task_id], quiet=opts.quiet, poll_interval=options.poll_interval) try: while True: # wait for the task to finish if session.taskFinished(task_id): break time.sleep(options.poll_interval) except KeyboardInterrupt: # this is probably the right thing to do here print("User interrupt: canceling runroot task") session.cancelTask(task_id) raise sys.stdout.flush() if not opts.quiet: output = list_task_output_all_volumes(session, task_id) if 'runroot.log' in output: for volume in output['runroot.log']: log = session.downloadTaskOutput(task_id, 'runroot.log', volume=volume) # runroot output, while normally text, can be *anything*, so # treat it as binary bytes_to_stdout(log) info = session.getTaskInfo(task_id) if info is None: sys.exit(1) state = koji.TASK_STATES[info['state']] if state in ('FAILED', 'CANCELED'): sys.exit(1)
def handle_kiwi_build(goptions, session, args): "[build] Run a command in a buildroot" usage = "usage: %prog kiwi-build [options] <target> <description_scm> <description_path>" usage += "\n(Specify the --help global option for a list of other help options)" parser = OptionParser(usage=usage) parser.add_option("--scratch", action="store_true", default=False, help="Perform a scratch build") parser.add_option( "--repo", action="append", help="Specify a repo that will override the repo used to install " "RPMs in the image. May be used multiple times. The " "build tag repo associated with the target is the default.") parser.add_option("--noprogress", action="store_true", help="Do not display progress of the upload") parser.add_option("--kiwi-profile", action="store", default=None, help="Select profile from description file") parser.add_option("--can-fail", action="store", dest="optional_arches", metavar="ARCH1,ARCH2,...", default="", help="List of archs which are not blocking for build " "(separated by commas.") parser.add_option("--arch", action="append", dest="arches", default=[], help="Limit arches to this subset") parser.add_option("--nowait", action="store_false", dest="wait", default=True) parser.add_option( "--wait", action="store_true", help="Wait on the image creation, even if running in the background") (options, args) = parser.parse_args(args) if len(args) != 3: parser.error("Incorrect number of arguments") assert False # pragma: no cover target, scm, path = args activate_session(session, goptions) kwargs = { 'scratch': options.scratch, 'optional_arches': [ canonArch(arch) for arch in options.optional_arches.split(',') if arch ], 'profile': options.kiwi_profile, } arches = [] if options.arches: arches = [canonArch(arch) for arch in options.arches] task_id = session.kiwiBuild(target=target, arches=arches, desc_url=scm, desc_path=path, **kwargs) if not goptions.quiet: print("Created task: %d" % task_id) print("Task info: %s/taskinfo?taskID=%s" % (goptions.weburl, task_id)) if options.wait or (options.wait is None and not _running_in_bg()): session.logout() return watch_tasks(session, [task_id], quiet=goptions.quiet, poll_interval=goptions.poll_interval, topurl=goptions.topurl)
def handle_save_failed_tree(options, session, args): "Create tarball with whole buildtree" 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("-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 task or buildroot ID")) try: id_val = int(args[0]) except ValueError: parser.error(_("ID must be an integer")) activate_session(session, options) 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(br_id, opts.full) except koji.GenericError as e: m = str(e) 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 %s for buildroot %s") % (task_id, br_id)) print("Task info: %s/taskinfo?taskID=%s" % (options.weburl, task_id)) if opts.nowait: return else: session.logout() return watch_tasks(session, [task_id], quiet=opts.quiet, poll_interval=options.poll_interval)
# # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import gitlab import koji from cryptography.fernet import Fernet from koji_cli.lib import activate_session from distrobuild.lookaside import Lookaside from distrobuild.mbs import MBSClient from distrobuild.settings import settings gl = gitlab.Gitlab(f"https://{settings.gitlab_host}", private_token=settings.gitlab_api_key) koji_config = koji.read_config("koji") koji_session = koji.ClientSession(koji_config["server"], koji_config) activate_session(koji_session, koji_config) mbs_client = MBSClient(settings.mbs_url) message_cipher = Fernet(settings.message_secret) lookaside_session = Lookaside(settings.storage_addr)
def __enter__(self): activate_session(self, self.opts) return self