def repair_bugs(runtime, advisory, auto, id, original_state, new_state, comment, close_placeholder, use_jira, noop, default_advisory_type, bug_tracker): changed_bug_count = 0 if default_advisory_type is not None: advisory = find_default_advisory(runtime, default_advisory_type) if auto: click.echo("Fetching Advisory(errata_id={})".format(advisory)) if use_jira: raw_bug_list = [ issue["key"] for issue in errata.get_jira_issue_from_advisory(advisory) ] else: e = elliottlib.errata.Advisory(errata_id=advisory) raw_bug_list = e.errata_bugs else: click.echo("Bypassed fetching erratum, using provided BZs") raw_bug_list = cli_opts.id_convert(id) green_print("Getting bugs for advisory") # Fetch bugs in parallel because it can be really slow doing it # one-by-one when you have hundreds of bugs pbar_header("Fetching data for {} bugs: ".format(len(raw_bug_list)), "Hold on a moment, we have to grab each one", raw_bug_list) pool = ThreadPool(cpu_count()) click.secho("[", nl=False) attached_bugs = pool.map( lambda bug: progress_func(lambda: bug_tracker.get_bug(bug), '*'), raw_bug_list) # Wait for results pool.close() pool.join() click.echo(']') green_print("Got bugs for advisory") for bug in attached_bugs: if close_placeholder and "Placeholder" in bug.summary: # if set close placeholder, ignore bug state bug_tracker.update_bug_status(bug, "CLOSED") changed_bug_count += 1 else: if bug.status in original_state: bug_tracker.update_bug_status(bug, new_state) # only add comments for non-placeholder bug if comment and not noop: bug_tracker.add_comment(bug, comment, private=False) changed_bug_count += 1 green_print("{} bugs successfully modified (or would have been)".format( changed_bug_count))
def poll_signed(runtime, minutes, advisory, default_advisory_type, noop): """Poll for the signed-status of RPM builds attached to ADVISORY. Returns rc=0 when all builds have been signed. Returns non-0 after MINUTES have passed and all builds have not been signed. This non-0 return code is the number of unsigned builds remaining. All builds must show 'signed' for this command to succeed. NOTE: The two advisory options are mutually exclusive. For testing in pipeline scripts this sub-command accepts a --noop option. When --noop is used the value of --minutes is irrelevant. This command will print out the signed state of all attached builds and then exit with rc=0 if all builds are signed and non-0 if builds are still unsigned. In the non-0 case the return code is the number of unsigned builds. Wait 15 minutes for the default 4.2 advisory to show all RPMS have been signed: $ elliott -g openshift-4.2 poll-signed --use-default-advisory rpm Wait 5 mintes for the provided 4.2 advisory to show all RPMs have been signed: $ elliott -g openshift-4.2 poll-signed -m 5 --advisory 123456 Print the signed status of all attached builds, exit immediately. Return code is the number of unsigned builds. \b $ elliott -g openshift-4.2 poll-signed --noop --use-default-advisory rpm """ if not (bool(advisory) ^ bool(default_advisory_type)): raise click.BadParameter( "Use only one of --use-default-advisory or --advisory") runtime.initialize(no_group=default_advisory_type is None) if default_advisory_type is not None: advisory = find_default_advisory(runtime, default_advisory_type) if not noop: click.echo("Polling up to {} minutes for all RPMs to be signed".format( minutes)) try: e = elliottlib.errata.Advisory(errata_id=advisory) all_builds = set([]) all_signed = False # `errata_builds` is a dict with brew tags as keys, values are # lists of builds on the advisory with that tag for k, v in e.errata_builds.items(): all_builds = all_builds.union(set(v)) green_prefix("Fetching initial states: ") click.echo("{} builds to check".format(len(all_builds))) start_time = datetime.datetime.now() while datetime.datetime.now() - start_time < datetime.timedelta( minutes=minutes): pbar_header("Getting build signatures: ", "Should be pretty quick", all_builds) pool = ThreadPool(cpu_count()) # Look up builds concurrently click.secho("[", nl=False) build_sigs = pool.map( lambda build: progress_func( lambda: elliottlib.errata.build_signed(build), '*'), all_builds) # Wait for results pool.close() pool.join() click.echo(']') if all(build_sigs): all_signed = True break elif noop: # Escape the time-loop break else: yellow_prefix("Not all builds signed: ") click.echo("re-checking") continue if not all_signed: red_prefix("Signing incomplete: ") if noop: click.echo("All builds not signed. ") else: click.echo( "All builds not signed in given window ({} minutes). ". format(minutes)) exit(1) else: green_prefix("All builds signed: ") click.echo("Enjoy!") except ErrataException as ex: raise ElliottFatalError(getattr(ex, 'message', repr(ex)))
def repair_bugs(runtime, advisory, auto, id, original_state, new_state, noop, default_advisory_type): """Move bugs attached to the advisory from one state to another state. This is useful if the bugs have changed states *after* they were attached. Similar to `find-bugs` but in reverse. `repair-bugs` begins by reading bugs from an advisory, whereas `find-bugs` reads from bugzilla. This looks at attached bugs in the provided --from state and moves them to the provided --to state. \b Background: This is intended for bugs which went to MODIFIED, were attached to advisories, set to ON_QA, and then failed testing. When this happens their state is reset back to ASSIGNED. Using --use-default-advisory without a value set for the matching key in the build-data will cause an error and elliott will exit in a non-zero state. Most likely you will only want to use the `rpm` state, but that could change in the future. Use of this option conflicts with providing an advisory with the -a/--advisory option. Move bugs on 123456 FROM the MODIFIED state back TO ON_QA state: \b $ elliott --group=openshift-4.1 repair-bugs --auto --advisory 123456 --from MODIFIED --to ON_QA As above, but using the default RPM advisory defined in ocp-build-data: \b $ elliott --group=openshift-4.1 repair-bugs --auto --use-default-advisory rpm --from MODIFIED --to ON_QA The previous examples could also be ran like this (MODIFIED and ON_QA are both defaults): \b $ elliott --group=openshift-4.1 repair-bugs --auto --use-default-advisory rpm Bug ids may be given manually instead of using --auto: \b $ elliott --group=openshift-4.1 repair-bugs --id 170899 --id 8675309 --use-default-advisory rpm """ if auto and len(id) > 0: raise click.BadParameter( "Combining the automatic and manual bug modification options is not supported" ) if not auto and len(id) == 0: # No bugs were provided raise click.BadParameter( "If not using --auto then one or more --id's must be provided") if advisory and default_advisory_type: raise click.BadParameter( "Use only one of --use-default-advisory or --advisory") if len(id) == 0 and advisory is None and default_advisory_type is None: # error, no bugs, advisory, or default selected raise click.BadParameter( "No input provided: Must use one of --id, --advisory, or --use-default-advisory" ) # Load bugzilla infomation and get a reference to the api runtime.initialize() bz_data = runtime.gitdata.load_data(key='bugzilla').data bzapi = elliottlib.bzutil.get_bzapi(bz_data) changed_bug_count = 0 attached_bugs = [] if default_advisory_type is not None: advisory = find_default_advisory(runtime, default_advisory_type) raw_bug_list = [] if auto: click.echo("Fetching Erratum(errata_id={})".format(advisory)) e = Erratum(errata_id=advisory) raw_bug_list = e.errata_bugs else: click.echo("Bypassed fetching erratum, using provided BZs") raw_bug_list = cli_opts.id_convert(id) green_print("Getting bugs for advisory") # Fetch bugs in parallel because it can be really slow doing it # one-by-one when you have hundreds of bugs pbar_header("Fetching data for {} bugs: ".format(len(raw_bug_list)), "Hold on a moment, we have to grab each one", raw_bug_list) pool = ThreadPool(cpu_count()) click.secho("[", nl=False) attached_bugs = pool.map( lambda bug: progress_func(lambda: bzapi.getbug(bug), '*'), raw_bug_list) # Wait for results pool.close() pool.join() click.echo(']') green_print("Got bugs for advisory") for bug in attached_bugs: if bug.status in original_state: changed_bug_count += 1 elliottlib.bzutil.set_state(bug, new_state, noop=noop) green_print("{} bugs successfullly modified (or would have been)".format( changed_bug_count))