0c0b8e3087
Git repo moves based on cgit aliases from project-config, the OpenStack TC guidance recorded in http://lists.openstack.org/pipermail/openstack-discuss/2019-April/004920.html and the ethercalc used to collect input from other users of the system. Also the results of an extensive bikeshedding session at http://eavesdrop.openstack.org/irclogs/%23openstack-infra/%23openstack-infra.2019-04-11.log.html#t2019-04-11T14:54:09 which concluded that anything left homeless goes in a namespace called "x" since that's short, a basic alphabetic character and provides no particular connotation. The opendev-migrate script, when run, provides a shareable rendering on stdout and also writes a repos.yaml file for input into the rename_repos playbook. The opendev-patching script, when run, uses the repos.yaml file and iterates over a tree of Git repositories updating their Zuul configuration, playbooks and roles as well as .gitreview files both for the project renames and the opendev hostname changes. It also creates a rename commit in project-config so that manage-projects will be in sync with the results of the rename_repos playbook. Change-Id: Ifa9fa6896110e8a33f32dcda6325bd58846935e2 Task: #30570 Co-Authored-By: James E. Blair <jeblair@redhat.com>
129 lines
4.7 KiB
Python
129 lines
4.7 KiB
Python
#!/usr/bin/python3
|
|
|
|
# Copyright (c) 2019 OpenStack Foundation
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
|
|
import csv
|
|
import io
|
|
import json
|
|
import requests
|
|
import yaml
|
|
|
|
# this will hold our mapping of old names(paces) to new
|
|
moves = {}
|
|
|
|
# here's a list of all (non-meta)projects in gerrit
|
|
repos = [r for r in json.loads(requests.get(
|
|
'http://review.openstack.org/projects/').text[5:]).keys() if '/' in r]
|
|
|
|
# a map of the first pair of columns from the namespace request ethercalc
|
|
overrides = dict([r[:2] for r in csv.reader(io.StringIO(
|
|
requests.get('https://ethercalc.openstack.org/opendev-transition.csv').text
|
|
)) if '/' in r[1]])
|
|
|
|
# all projects which are officially governed by openstack or osf
|
|
openstack = []
|
|
o_gov = 'https://opendev.org/openstack/governance/raw/branch/master/reference/'
|
|
data = yaml.safe_load(requests.get(o_gov + 'projects.yaml').text)
|
|
for team in data.values():
|
|
for deli in team['deliverables'].values():
|
|
for repo in deli['repos']:
|
|
openstack.append(repo)
|
|
for f in ('foundation-board-repos.yaml', 'sigs-repos.yaml',
|
|
'technical-committee-repos.yaml', 'user-committee-repos.yaml'):
|
|
data = yaml.safe_load(requests.get(o_gov + f).text)
|
|
for team in data.values():
|
|
for repo in team:
|
|
openstack.append(repo['repo'])
|
|
|
|
# projects which were at one time officially governed by openstack
|
|
openstack_legacy = []
|
|
data = yaml.safe_load(requests.get(o_gov + 'legacy.yaml').text)
|
|
for team in data.values():
|
|
for deli in team['deliverables'].values():
|
|
for repo in deli['repos']:
|
|
openstack_legacy.append(repo)
|
|
|
|
# use the jeepyb config to identify whitelabeled oip git projects
|
|
airship = []
|
|
starlingx = []
|
|
zuul = []
|
|
data = yaml.safe_load(requests.get(
|
|
'https://opendev.org/openstack-infra/project-config/raw/branch/master/'
|
|
'gerrit/projects.yaml').text)
|
|
for project in data:
|
|
if 'cgit-alias' in project:
|
|
if project['cgit-alias']['site'] == 'git.airshipit.org':
|
|
airship.append(project['project'])
|
|
elif project['cgit-alias']['site'] == 'git.starlingx.io':
|
|
starlingx.append(project['project'])
|
|
elif project['cgit-alias']['site'] == 'git.zuul-ci.org':
|
|
zuul.append(project['project'])
|
|
|
|
for repo in repos:
|
|
# apply the requested namespace overrides first
|
|
if repo in overrides:
|
|
moves[repo] = overrides[repo]
|
|
|
|
# airship repos identified drop the airship- prefix and move to airship
|
|
elif repo in airship:
|
|
moves[repo] = 'airship/' + repo.split('/')[1].replace('airship-', '')
|
|
|
|
# starlingx repos drop the stx- prefix and move to starlingx
|
|
elif repo in starlingx:
|
|
moves[repo] = 'starlingx/' + repo.split('/')[1].replace('stx-', '')
|
|
|
|
# all current openstack repos move to openstack
|
|
elif repo in openstack:
|
|
moves[repo] = 'openstack/' + repo.split('/')[1]
|
|
|
|
# zuul repos move to zuul
|
|
elif repo in zuul:
|
|
moves[repo] = 'zuul/' + repo.split('/')[1]
|
|
|
|
# former openstack repositories which aren't accounted for go in openstack
|
|
elif repo in openstack_legacy:
|
|
moves[repo] = 'openstack/' + repo.split('/')[1]
|
|
|
|
# unofficial repositories move from openstack to x
|
|
elif repo.startswith('openstack/'):
|
|
moves[repo] = 'x/' + repo.split('/')[1]
|
|
|
|
# everything else is unchanged
|
|
else:
|
|
moves[repo] = repo
|
|
|
|
# we'll use this data structure for the rename_repos playbook input
|
|
output = {'repos': []}
|
|
|
|
for mapping in moves.items():
|
|
if mapping[0] != mapping[1]:
|
|
# convenient stdout feedback is for sharing with people
|
|
print('%s -> %s' % mapping)
|
|
|
|
# update the rename_repos data structure
|
|
output['repos'].append({'old': mapping[0], 'new': mapping[1]})
|
|
|
|
# https://docs.openstack.org/infra/system-config/gerrit.html#renaming-a-project
|
|
with open('repos.yaml', 'w') as outfile:
|
|
yaml.dump(output, outfile)
|
|
|
|
# We should add this to the rename playbook, but time is short
|
|
with open('zuul-rename.sh', 'w') as outfile:
|
|
keyroot = '/var/lib/zuul/keys'
|
|
for d in output['repos']:
|
|
outfile.write('mv %s/ssh/project/gerrit/%s %s/ssh/project/gerrit/%s\n' %
|
|
(keyroot, d['old'], keyroot, d['new']))
|
|
outfile.write('mv %s/secrets/project/gerrit/%s %s/secrets/project/gerrit/%s\n' %
|
|
(keyroot, d['old'], keyroot, d['new']))
|