From c387ba5f185fddd18d40b56588ce70546c75a4ad Mon Sep 17 00:00:00 2001 From: Ghanshyam Mann Date: Tue, 13 Oct 2020 18:20:38 -0500 Subject: [PATCH] Implement distributed leadership in tools and schema MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have resolution merged for distributed leadership[1] and there are few projects want to adopt this model in Wallaby cycle, first one is oslo[2]. This commit add the support of new model in governance tooling, doc and, schema. Basically making changes to fill the distributed leadership liaisons and displaing those in projects rst. Below are the changes done: - Removed 'PTL' field to be mandatory instead making either 'PTL' or 'leadership_type: distributed' field as mandatory. - To avoid confustion with existing liasion field, changed TC liaison field name from 'liaisons' to sub field named 'tc_members' - Extended the existing liaison field for distributed leadersip liaisons. It will looks like below: liaisons: tc_members: - zaneb - ttx release: - name: Hervé Beraud irc: hberaud email: hberaud@redhat.com - name: Daniel Bengtsson irc: damani email: dbengt@redhat.com tact-sig: - name: Hervé Beraud irc: hberaud email: hberaud@redhat.com security: - name: Daniel Bengtsson irc: damani email: dbengt@redhat.com and on site: TC Members Liaisons ricolin, belmoreira Release Liaisons Hervé Beraud (hberaud) , Daniel Bengtsson (damani) [1] https://governance.openstack.org/tc/resolutions/20200803-distributed-project-leadership.html [2] https://review.opendev.org/#/c/757906 Change-Id: If96915a16a8746aed6f0cb844c53ad61a300c234 --- doc/source/_exts/tc_liaisons.py | 3 +- doc/source/_exts/teams.py | 51 +++- openstack_governance/projects_schema.yaml | 63 ++++- openstack_governance/tests/test_governance.py | 20 +- reference/projects.yaml | 246 +++++++++++------- tools/assign_liaisons.py | 10 +- 6 files changed, 279 insertions(+), 114 deletions(-) diff --git a/doc/source/_exts/tc_liaisons.py b/doc/source/_exts/tc_liaisons.py index 2b86a3155..a2d32060a 100644 --- a/doc/source/_exts/tc_liaisons.py +++ b/doc/source/_exts/tc_liaisons.py @@ -71,8 +71,9 @@ class TCLiaisonsTable(tables.Table): data_iter = projects.load_project_file(filename) liaisons = {} for project_name, project in data_iter.items(): + proj_liaisons = project.get('liaisons', {}) - for liaison in project.get('liaisons', []): + for liaison in proj_liaisons.get('tc_members', []): try: liaisons[liaison].extend([project_name]) except KeyError: diff --git a/doc/source/_exts/teams.py b/doc/source/_exts/teams.py index 9a8652013..2eaf0be1b 100644 --- a/doc/source/_exts/teams.py +++ b/doc/source/_exts/teams.py @@ -43,7 +43,11 @@ def _team_to_rst(name, info): yield '' yield ':Home Page: ' + info.get('url', '') ptl = info.get('ptl', {'name': '', 'irc': '', 'email': ''}) - yield ':PTL: %(name)s (``%(irc)s``) <%(email)s>' % ptl + leadership_type = info.get('leadership_type') + if leadership_type: + yield ':Leadership Type: ' + leadership_type + else: + yield ':PTL: %(name)s (``%(irc)s``) <%(email)s>' % ptl irc_channel = info.get('irc-channel') if irc_channel: yield ':IRC Channel: `#%s <%s%s>`__' % ( @@ -53,7 +57,50 @@ def _team_to_rst(name, info): yield ':Service: ' + service liaisons = info.get('liaisons') if liaisons: - yield ':TC Liaisons: ' + ", ".join(liaisons) + contact_format = {'name': '', 'irc': '', 'email': ''} + tc_members = liaisons.get('tc_members') + if tc_members: + yield ':TC Members Liaisons: ' + ", ".join(tc_members) + release = liaisons.get('release', contact_format) + if release != contact_format: + yield ':Release Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % rl + for rl in release) + tact_sig = liaisons.get('tact-sig', contact_format) + if tact_sig != contact_format: + yield ':TACT SIG Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % tl + for tl in tact_sig) + security = liaisons.get('security', contact_format) + if security != contact_format: + yield ':Security Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % sl + for sl in security) + events = liaisons.get('events', contact_format) + if events != contact_format: + yield ':Events Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % el + for el in events) + project_update_onboarding = liaisons.get('project_update_onboarding', contact_format) + if project_update_onboarding != contact_format: + yield ':Project Update Onboarding Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % pl + for pl in project_update_onboarding) + meeting_facilitator = liaisons.get('meeting_facilitator', contact_format) + if meeting_facilitator != contact_format: + yield ':Meeting Facilitator Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % ml + for ml in meeting_facilitator) + bug_deputy = liaisons.get('bug_deputy', contact_format) + if bug_deputy != contact_format: + yield ':Bug Deputy Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % bl + for bl in bug_deputy) + rfe_coordinator = liaisons.get('rfe_coordinator', contact_format) + if rfe_coordinator != contact_format: + yield ':RFE Coordinator Liaisons: ' + ', '.join( + '%(name)s (``%(irc)s``) <%(email)s>' % rcl + for rcl in rfe_coordinator) yield '' mission = info.get('mission', '').rstrip() if mission: diff --git a/openstack_governance/projects_schema.yaml b/openstack_governance/projects_schema.yaml index 386b1e88e..510f98dc7 100644 --- a/openstack_governance/projects_schema.yaml +++ b/openstack_governance/projects_schema.yaml @@ -3,15 +3,41 @@ $schema: "http://json-schema.org/schema#" $id: "https://opendev.org/openstack/releases/src/branch/master/README.rst" +contact_schema: &contact_schema + type: "array" + items: + type: "object" + required: + - name + - email + additionalProperties: false + properties: + name: + type: "string" + irc: + type: "string" + email: + type: "string" + format: "email" + minItems: 1 + uniqueItems: true + additionalProperties: # Do not allow any properties not defined here. This lets us catch # typos. additionalProperties: false - required: - - ptl - - deliverables - - url - - mission + oneOf: + - required: + - ptl + - deliverables + - url + - mission + - required: + - leadership_type + - liaisons + - deliverables + - url + - mission properties: ptl: type: "object" @@ -27,6 +53,10 @@ additionalProperties: email: type: "string" format: "email" + leadership_type: + type: "string" + enum: + - distributed appointed: type: "array" items: @@ -38,10 +68,25 @@ additionalProperties: url: type: "string" liaisons: - type: "array" - uniqueItems: true - items: - type: "string" + type: "object" + properties: + tc_members: + type: "array" + items: + type: "string" + uniqueItems: true + # TODO(gmann): Make release, tact-sig, + # and, security liaison as required for + # distributed leadership type. + release: *contact_schema + tact-sig: *contact_schema + security: *contact_schema + events: *contact_schema + project_update_onboarding: *contact_schema + meeting_facilitator: *contact_schema + bug_deputy: *contact_schema + rfp_coordinator: *contact_schema + additionalProperties: false mission: type: "string" deliverables: diff --git a/openstack_governance/tests/test_governance.py b/openstack_governance/tests/test_governance.py index 0d68172f5..01cee5d1e 100644 --- a/openstack_governance/tests/test_governance.py +++ b/openstack_governance/tests/test_governance.py @@ -32,8 +32,24 @@ Release Management: their own releases. url: https://wiki.openstack.org/wiki/Release_Management liaisons: - - zaneb - - ttx + tc_members: + - zaneb + - ttx + release: + - name: Hervé Beraud + irc: hberaud + email: hberaud@redhat.com + tact-sig: + - name: Hervé Beraud + irc: hberaud + email: hberaud@redhat.com + - name: Daniel Bengtsson + irc: damani + email: dbengt@redhat.com + security: + - name: Daniel Bengtsson + irc: damani + email: dbengt@redhat.com tags: - team:diverse-affiliation deliverables: diff --git a/reference/projects.yaml b/reference/projects.yaml index 70b2ea0f4..1a25ba07c 100644 --- a/reference/projects.yaml +++ b/reference/projects.yaml @@ -24,8 +24,9 @@ adjutant: repos: - openstack/python-adjutantclient liaisons: - - knikolla - - mnaser + tc_members: + - knikolla + - mnaser barbican: ptl: name: Douglas Mendizábal @@ -74,8 +75,9 @@ barbican: tags: - vulnerability:managed liaisons: - - knikolla - - cloudnull + tc_members: + - knikolla + - cloudnull blazar: ptl: name: Pierre Riteau @@ -110,8 +112,9 @@ blazar: repos: - openstack/python-blazarclient liaisons: - - mugsie - - belmoreira + tc_members: + - mugsie + - belmoreira cinder: ptl: name: Brian Rosmaita @@ -164,8 +167,9 @@ cinder: - vulnerability:managed - stable:follows-policy liaisons: - - cloudnull - - mugsie + tc_members: + - cloudnull + - mugsie cloudkitty: ptl: name: APPOINTMENT NEEDED @@ -199,8 +203,9 @@ cloudkitty: repos: - openstack/cloudkitty-tempest-plugin liaisons: - - evrardjp - - knikolla + tc_members: + - evrardjp + - knikolla cyborg: ptl: name: Yumeng Bao @@ -229,8 +234,9 @@ cyborg: repos: - openstack/cyborg-tempest-plugin liaisons: - - njohnston - - cloudnull + tc_members: + - njohnston + - cloudnull designate: ptl: name: Michael Johnson @@ -272,8 +278,9 @@ designate: tags: - stable:follows-policy liaisons: - - evrardjp - - jungleboyj + tc_members: + - evrardjp + - jungleboyj ec2-api: ptl: name: Andrey Pavlov @@ -292,8 +299,9 @@ ec2-api: repos: - openstack/ec2api-tempest-plugin liaisons: - - jungleboyj - - mnaser + tc_members: + - jungleboyj + - mnaser freezer: ptl: name: cai hui @@ -328,8 +336,9 @@ freezer: repos: - openstack/python-freezerclient liaisons: - - ricolin - - jungleboyj + tc_members: + - ricolin + - jungleboyj glance: ptl: name: Abhishek Kekane @@ -370,8 +379,9 @@ glance: - vulnerability:managed - stable:follows-policy liaisons: - - mnaser - - njohnston + tc_members: + - mnaser + - njohnston heat: ptl: name: Rico Lin @@ -429,7 +439,8 @@ heat: tosca-parser: repos: - openstack/tosca-parser - liaisons: [ricolin, jungleboyj] + liaisons: + tc_members: [ricolin, jungleboyj] horizon: ptl: name: Ivan Kolodyazhny @@ -549,8 +560,9 @@ horizon: repos: - openstack/xstatic-spin liaisons: - - mnaser - - mugsie + tc_members: + - mnaser + - mugsie ironic: ptl: name: Julia Kreger @@ -656,8 +668,9 @@ ironic: email: jay@jvf.cc expires-in: July 2019 liaisons: - - mnaser - - knikolla + tc_members: + - mnaser + - knikolla karbor: ptl: name: APPOINTMENT NEEDED @@ -680,8 +693,9 @@ karbor: repos: - openstack/python-karborclient liaisons: - - mugsie - - belmoreira + tc_members: + - mugsie + - belmoreira keystone: ptl: name: Kristi Nikolla @@ -737,8 +751,9 @@ keystone: repos: - openstack/ldappool liaisons: - - mnaser - - knikolla + tc_members: + - mnaser + - knikolla kolla: ptl: name: Mark Goddard @@ -768,8 +783,9 @@ kolla: - openstack/kayobe-config - openstack/kayobe-config-dev liaisons: - - evrardjp - - mugsie + tc_members: + - evrardjp + - mugsie kuryr: ptl: name: Maysa de Macedo Souza @@ -797,8 +813,9 @@ kuryr: repos: - openstack/kuryr-tempest-plugin liaisons: - - belmoreira - - njohnston + tc_members: + - belmoreira + - njohnston magnum: ptl: name: Spyros Trigazis @@ -827,7 +844,8 @@ magnum: python-magnumclient: repos: - openstack/python-magnumclient - liaisons: [ricolin, belmoreira] + liaisons: + tc_members: [ricolin, belmoreira] manila: ptl: name: Goutham Pacha Ravi @@ -870,7 +888,8 @@ manila: python-manilaclient: repos: - openstack/python-manilaclient - liaisons: [gmann, cloudnull] + liaisons: + tc_members: [gmann, cloudnull] masakari: ptl: name: Radosław Piliszek @@ -902,8 +921,9 @@ masakari: repos: - openstack/masakari-dashboard liaisons: - - evrardjp - - cloudnull + tc_members: + - evrardjp + - cloudnull mistral: ptl: name: Renat Akhmerov @@ -940,7 +960,8 @@ mistral: mistral-extra: repos: - openstack/mistral-extra - liaisons: [ricolin, jungleboyj] + liaisons: + tc_members: [ricolin, jungleboyj] monasca: ptl: name: Martin Chacon Piza @@ -1012,8 +1033,9 @@ monasca: repos: - openstack/monasca-kibana-plugin liaisons: - - ricolin - - belmoreira + tc_members: + - ricolin + - belmoreira murano: ptl: name: Rong Zhu @@ -1065,8 +1087,9 @@ murano: repos: - openstack/murano-tempest-plugin liaisons: - - cloudnull - - njohnston + tc_members: + - cloudnull + - njohnston neutron: ptl: name: Sławek Kapłoński @@ -1164,7 +1187,8 @@ neutron: os-ken: repos: - openstack/os-ken - liaisons: [njohnston, mnaser] + liaisons: + tc_members: [njohnston, mnaser] nova: ptl: name: Balazs Gibizer @@ -1204,7 +1228,8 @@ nova: os-vif: repos: - openstack/os-vif - liaisons: [gmann, cloudnull] + liaisons: + tc_members: [gmann, cloudnull] octavia: ptl: name: APPOINTMENT NEEDED @@ -1259,8 +1284,9 @@ octavia: tags: - stable:follows-policy liaisons: - - cloudnull - - mugsie + tc_members: + - cloudnull + - mugsie OpenStack Charms: ptl: name: APPOINTMENT NEEDED @@ -1786,8 +1812,9 @@ OpenStack Charms: repos: - openstack/charm-watcher-dashboard liaisons: - - evrardjp - - gmann + tc_members: + - evrardjp + - gmann openstack-chef: ptl: name: Lance Albertson @@ -1881,8 +1908,9 @@ openstack-chef: repos: - openstack/openstack-chef-specs liaisons: - - njohnston - - ricolin + tc_members: + - njohnston + - ricolin OpenStack-Helm: ptl: name: Gage Hugo @@ -1926,8 +1954,9 @@ OpenStack-Helm: repos: - openstack/loci liaisons: - - evrardjp - - njohnston + tc_members: + - evrardjp + - njohnston OpenStackAnsible: ptl: name: Dmitriy Rabotyagov @@ -2020,8 +2049,9 @@ OpenStackAnsible: repos: - openstack/openstack-ansible-specs liaisons: - - evrardjp - - knikolla + tc_members: + - evrardjp + - knikolla OpenStackSDK: ptl: name: Artem Goncharov @@ -2075,7 +2105,8 @@ OpenStackSDK: - openstack/shade tags: - assert:follows-standard-deprecation - liaisons: [diablo_rojo, cloudnull] + liaisons: + tc_members: [diablo_rojo, cloudnull] oslo: ptl: name: APPOINTMENT NEEDED @@ -2292,7 +2323,8 @@ oslo: repos: - openstack/whereto - liaisons: [ricolin, belmoreira] + liaisons: + tc_members: [ricolin, belmoreira] placement: ptl: name: APPOINTMENT NEEDED @@ -2324,8 +2356,9 @@ placement: repos: - openstack/os-resource-classes liaisons: - - gmann - - njohnston + tc_members: + - gmann + - njohnston Puppet OpenStack: ptl: name: Shengping Zhong @@ -2483,8 +2516,9 @@ Puppet OpenStack: - openstack/puppet-zaqar liaisons: - - evrardjp - - ricolin + tc_members: + - evrardjp + - ricolin qinling: ptl: name: APPOINTMENT NEEDED @@ -2508,8 +2542,9 @@ qinling: - openstack/qinling-dashboard liaisons: - - mugsie - - jungleboyj + tc_members: + - mugsie + - jungleboyj Quality Assurance: ptl: name: Masayuki Igawa @@ -2612,7 +2647,8 @@ Quality Assurance: release-management: none repos: - openstack/whitebox-tempest-plugin - liaisons: [gmann, jungleboyj] + liaisons: + tc_members: [gmann, jungleboyj] rally: ptl: name: Andrey Kurilin @@ -2640,8 +2676,9 @@ rally: - openstack/performance-docs liaisons: - - knikolla - - diablo_rojo + tc_members: + - knikolla + - diablo_rojo Release Management: ptl: name: Hervé Beraud @@ -2670,8 +2707,9 @@ Release Management: repos: - openstack/specs-cookiecutter liaisons: - - diablo_rojo - - evrardjp + tc_members: + - diablo_rojo + - evrardjp requirements: ptl: name: Matthew Thode @@ -2689,8 +2727,9 @@ requirements: repos: - openstack/requirements liaisons: - - diablo_rojo - - belmoreira + tc_members: + - diablo_rojo + - belmoreira sahara: ptl: name: Jeremy Freudberg @@ -2792,8 +2831,9 @@ sahara: - openstack/sahara-specs liaisons: - - gmann - - njohnston + tc_members: + - gmann + - njohnston searchlight: ptl: name: APPOINTMENT NEEDED @@ -2825,8 +2865,9 @@ searchlight: - openstack/searchlight-ui liaisons: - - mugsie - - belmoreira + tc_members: + - mugsie + - belmoreira senlin: ptl: name: APPOINTMENT NEEDED @@ -2852,7 +2893,8 @@ senlin: repos: - openstack/senlin-tempest-plugin - liaisons: [ricolin, mnaser] + liaisons: + tc_members: [ricolin, mnaser] solum: ptl: name: Rong Zhu @@ -2884,8 +2926,9 @@ solum: - openstack/solum-tempest-plugin liaisons: - - jungleboyj - - belmoreira + tc_members: + - jungleboyj + - belmoreira storlets: ptl: name: Takashi Kajinami @@ -2904,8 +2947,9 @@ storlets: - openstack/storlets liaisons: - - jungleboyj - - knikolla + tc_members: + - jungleboyj + - knikolla swift: ptl: name: Tim Burke @@ -2949,8 +2993,9 @@ swift: - openstack/swift-bench liaisons: - - cloudnull - - diablo_rojo + tc_members: + - cloudnull + - diablo_rojo tacker: ptl: name: Yasufumi Ogawa @@ -2980,7 +3025,8 @@ tacker: repos: - openstack/tacker-specs - liaisons: [gmann, knikolla] + liaisons: + tc_members: [gmann, knikolla] Telemetry: ptl: name: Rong Zhu @@ -3031,8 +3077,9 @@ Telemetry: - openstack/telemetry-tempest-plugin liaisons: - - cloudnull - - gmann + tc_members: + - cloudnull + - gmann tripleo: ptl: @@ -3169,8 +3216,9 @@ tripleo: - openstack/tripleo-ha-utils liaisons: - - diablo_rojo - - jungleboyj + tc_members: + - diablo_rojo + - jungleboyj trove: ptl: name: Lingxian Kong @@ -3212,8 +3260,9 @@ trove: - openstack/trove-tempest-plugin liaisons: - - gmann - - diablo_rojo + tc_members: + - gmann + - diablo_rojo vitrage: ptl: name: Eyal Bar-Ilan @@ -3263,8 +3312,9 @@ vitrage: - openstack/xstatic-moment-timezone liaisons: - - belmoreira - - mugsie + tc_members: + - belmoreira + - mugsie watcher: ptl: name: canwei li @@ -3297,8 +3347,9 @@ watcher: - openstack/watcher-dashboard liaisons: - - mugsie - - mnaser + tc_members: + - mugsie + - mnaser winstackers: ptl: name: Lucian Petrut @@ -3329,8 +3380,9 @@ winstackers: - openstack/compute-hyperv liaisons: - - mnaser - - jungleboyj + tc_members: + - mnaser + - jungleboyj zaqar: ptl: name: wang hao @@ -3368,7 +3420,8 @@ zaqar: repos: - openstack/zaqar-ui - liaisons: [njohnston, evrardjp] + liaisons: + tc_members: [njohnston, evrardjp] zun: ptl: name: Feng Shengqin @@ -3394,5 +3447,6 @@ zun: repos: - openstack/zun-ui liaisons: - - mugsie - - diablo_rojo + tc_members: + - mugsie + - diablo_rojo diff --git a/tools/assign_liaisons.py b/tools/assign_liaisons.py index 1405921b8..e8e9c00d4 100644 --- a/tools/assign_liaisons.py +++ b/tools/assign_liaisons.py @@ -61,7 +61,8 @@ def main(): if not args.replace_all: for _, team in project_data.items(): - for member in team.get('liaisons', []): + proj_liaisons = team.get('liaisons', {}) + for member in proj_liaisons.get('tc_members', []): member_counts.update({member: 1}) choices = [] @@ -71,9 +72,10 @@ def main(): # person to a team twice. for name, team in project_data.items(): - liaisons = team.get('liaisons', []) + proj_liaisons = team.get('liaisons', {}) + liaisons = proj_liaisons.get('tc_members', []) if args.remove_all: - team['liaisons'] = [] + team['liaisons']['tc_members'] = [] continue if args.replace_all: liaisons = [] @@ -84,7 +86,7 @@ def main(): choices.insert(0, next_choice) next_choice = choices.pop() liaisons.append(next_choice) - team['liaisons'] = liaisons + team['liaisons']['tc_members'] = liaisons projects.write_project_file(project_data, args.projects_file)