From fbef7827d586831b26ef6dcc9b3445157d3a2d4e Mon Sep 17 00:00:00 2001 From: Jeremy Stanley Date: Wed, 28 Oct 2020 18:28:56 +0000 Subject: [PATCH] Use PTL election results for governance updates A hotfix to strip non-elected PTL candidates from the candidate list when performing governance updates, so that elections with a runoff poll will get included. This could almost certainly be improved to just use the results file instead of the candidates tree, but I didn't attempt that here. Change-Id: Ia5c477d10787792c80831e2886840a9997e8d1ff --- openstack_election/cmds/update_governance.py | 12 ++++++++++++ openstack_election/utils.py | 8 ++++++++ 2 files changed, 20 insertions(+) diff --git a/openstack_election/cmds/update_governance.py b/openstack_election/cmds/update_governance.py index dcc10c05..4b345185 100644 --- a/openstack_election/cmds/update_governance.py +++ b/openstack_election/cmds/update_governance.py @@ -54,6 +54,7 @@ def load_projects(projects_fname): def update_projects(projects_fname, candidates_list, projects): + results = utils.get_ptl_results() project_count = 0 with open(projects_fname, 'w') as fh: skip = 0 @@ -78,6 +79,17 @@ def update_projects(projects_fname, candidates_list, projects): }] print('TC to appoint PTL for %s' % (p)) nr_candidates = len(candidates) + # Remove non-elected candidates if the election is closed + # TODO(fungi): rework this entire function to just use the + # election results file if we have one and not iterate over + # the candidates tree + if nr_candidates > 1: + for c1 in results['candidates'].get(p, []): + if not c1['elected']: + for c2 in list(candidates): + if c1['email'] == c2['email']: + candidates.remove(c2) + nr_candidates = len(candidates) # Only update the PTL if there is a single candidate if nr_candidates == 1: # Replace empty IRC nick strings with something useful diff --git a/openstack_election/utils.py b/openstack_election/utils.py index ba02827f..6ca56370 100644 --- a/openstack_election/utils.py +++ b/openstack_election/utils.py @@ -368,3 +368,11 @@ def build_candidates_list(election=conf['release']): 'projects': list(projects), 'leaderless': list(leaderless), 'candidates': candidates_lists} + + +def get_ptl_results(election=conf['release']): + try: + resultfd = open('doc/source/results/%s/ptl.yaml' % election) + except FileNotFoundError: + return {'candidates': {}} + return yaml.safe_load(resultfd)