From 9484044f79830245c0deddb0ab09018819627aa0 Mon Sep 17 00:00:00 2001 From: Marios Andreou Date: Tue, 16 Nov 2021 18:11:59 +0200 Subject: [PATCH] Add CentOS Stream 9 support for tripleo-repos This patch adds support for CentOS Stream 9 in tripleo-repos operation. Co-Authored-By: Douglas Viroel Change-Id: I0aa9c3c4feec9065c1d823e2bb783f4286304ddb --- plugins/module_utils/tripleo_repos/main.py | 102 ++++++++++++++------- tests/unit/tripleo_repos/test_main.py | 58 +++++++++++- 2 files changed, 127 insertions(+), 33 deletions(-) diff --git a/plugins/module_utils/tripleo_repos/main.py b/plugins/module_utils/tripleo_repos/main.py index 45da371..3c1b305 100755 --- a/plugins/module_utils/tripleo_repos/main.py +++ b/plugins/module_utils/tripleo_repos/main.py @@ -40,9 +40,11 @@ DEFAULT_RDO_MIRROR = 'https://trunk.rdoproject.org' # RHEL is only provided to licensed cloud providers via RHUI DEFAULT_MIRROR_MAP = { 'fedora': 'https://mirrors.fedoraproject.org', - 'centos': 'http://mirror.centos.org', - 'ubi': 'http://mirror.centos.org', - 'rhel': 'https://trunk.rdoproject.org', + 'centos7': 'http://mirror.centos.org', + 'centos8': 'http://mirror.centos.org', + 'centos9': 'http://mirror.stream.centos.org', + 'ubi8': 'http://mirror.centos.org', + 'rhel8': 'https://trunk.rdoproject.org', } CEPH_REPO_TEMPLATE = ''' [tripleo-centos-ceph-%(ceph_release)s] @@ -62,7 +64,7 @@ enabled=1 HIGHAVAILABILITY_REPO_TEMPLATE = ''' [tripleo-centos-highavailability] name=tripleo-centos-highavailability -baseurl=%(mirror)s/centos/%(stream)s/HighAvailability/$basearch/os/ +baseurl=%(mirror)s/%(legacy_url)s%(stream)s/HighAvailability/$basearch/os/ gpgcheck=0 enabled=1 ''' @@ -70,23 +72,23 @@ enabled=1 POWERTOOLS_REPO_TEMPLATE = ''' [tripleo-centos-powertools] name=tripleo-centos-powertools -baseurl=%(mirror)s/centos/%(stream)s/PowerTools/$basearch/os/ +baseurl=%(mirror)s/%(legacy_url)s%(stream)s/%(pt_name)s/$basearch/os/ gpgcheck=0 enabled=1 ''' # ubi-8 only APPSTREAM_REPO_TEMPLATE = ''' -[AppStream] -name=CentOS-$releasever - AppStream -baseurl=%(mirror)s/centos/$releasever/AppStream/$basearch/os/ +[tripleo-centos-appstream] +name=tripleo-centos-appstream +baseurl=%(mirror)s/%(legacy_url)s%(stream)s/AppStream/$basearch/os/ gpgcheck=0 enabled=1 %(extra)s ''' BASE_REPO_TEMPLATE = ''' -[BaseOS] -name=CentOS-$releasever - Base -baseurl=%(mirror)s/centos/$releasever/BaseOS/$basearch/os/ +[tripleo-centos-baseos] +name=tripleo-centos-baseos +baseurl=%(mirror)s/%(legacy_url)s%(stream)s/BaseOS/$basearch/os/ gpgcheck=0 enabled=1 ''' @@ -96,10 +98,13 @@ enabled=1 SUPPORTED_DISTROS = [ ('centos', '7'), ('centos', '8'), + ('centos', '9'), ('fedora', ''), ('rhel', '8'), ('ubi', '8') # a subcase of the rhel distro ] +DISTRO_CHOICES = ["".join(distro_pair) + for distro_pair in SUPPORTED_DISTROS] class InvalidArguments(Exception): @@ -159,11 +164,6 @@ def _parse_args(distro_id, distro_major_version_id): distro = "{0}{1}".format(distro_id, distro_major_version_id) - # Calculating arguments default from constants - default_mirror = DEFAULT_MIRROR_MAP.get(distro_id, None) - distro_choices = ["".join(distro_pair) - for distro_pair in SUPPORTED_DISTROS] - parser = argparse.ArgumentParser( description='Download and install repos necessary for TripleO. Note ' 'that some of these repos require yum-plugin-priorities, ' @@ -184,7 +184,7 @@ def _parse_args(distro_id, distro_major_version_id): 'from the appropriate location.') parser.add_argument('-d', '--distro', default=distro, - choices=distro_choices, + choices=DISTRO_CHOICES, nargs='?', help='Target distro with default detected at runtime. ' ) @@ -196,7 +196,6 @@ def _parse_args(distro_id, distro_major_version_id): default=DEFAULT_OUTPUT_PATH, help='Directory in which to save the selected repos.') parser.add_argument('--mirror', - default=default_mirror, help='Server from which to install base OS packages. ' 'Default value is based on distro param.') parser.add_argument('--rdo-mirror', @@ -215,6 +214,15 @@ def _parse_args(distro_id, distro_major_version_id): args = parser.parse_args() if args.no_stream: args.stream = False + + # Default mirror for args.distro (which defaults to 'distro') + default_mirror = DEFAULT_MIRROR_MAP.get(args.distro, None) + if default_mirror is None and 'fedora' in args.distro: + # We don't have different mirrors for specific fedora releases + default_mirror = DEFAULT_MIRROR_MAP.get('fedora', None) + + if args.mirror is None: + args.mirror = default_mirror args.old_mirror = default_mirror return args @@ -256,7 +264,7 @@ def _validate_distro_repos(args): if 'fedora' in args.distro: valid_repos = ['current', 'current-tripleo', 'ceph', 'deps', 'tripleo-ci-testing'] - elif args.distro in ['centos7', 'centos8', 'rhel8', 'ubi8']: + elif args.distro in DISTRO_CHOICES: valid_repos = ['ceph', 'current', 'current-tripleo', 'current-tripleo-dev', 'deps', 'tripleo-ci-testing', 'opstools', 'current-tripleo-rdo'] @@ -496,6 +504,7 @@ def _install_repos(args, base_path): distro = args.distro # CentOS-8 AppStream is required for UBI-8 + legacy_url = 'centos/' if distro == 'ubi8': if not os.path.exists("/etc/distro.repos.d"): print('WARNING: For UBI it is recommended to create ' @@ -513,24 +522,53 @@ def _install_repos(args, base_path): extra = '' if args.branch in ['train', 'ussuri', 'victoria']: extra = 'exclude=edk2-ovmf-20200602gitca407c7246bf-5*' + content = APPSTREAM_REPO_TEMPLATE % {'mirror': args.mirror, - 'extra': extra} + 'extra': extra, + 'legacy_url': legacy_url, + 'stream': '8'} _write_repo(content, distro_path) - content = BASE_REPO_TEMPLATE % {'mirror': args.mirror} + content = BASE_REPO_TEMPLATE % {'mirror': args.mirror, + 'legacy_url': legacy_url, + 'stream': '8'} _write_repo(content, distro_path) distro = 'centos8' # switch it to continue as centos8 distro - # HA, Powertools are required for CentOS-8 - if distro == 'centos8': - stream = '8' - if args.stream and not args.no_stream: - stream = stream + '-stream' - content = HIGHAVAILABILITY_REPO_TEMPLATE % {'mirror': args.mirror, - 'stream': stream} - _write_repo(content, args.output_path) - content = POWERTOOLS_REPO_TEMPLATE % {'mirror': args.mirror, - 'stream': stream} - _write_repo(content, args.output_path) + if 'centos' in distro: + stream = str(distro[-1]) + # HA, Powertools are required for CentOS-8 + if int(stream) >= 8: + if args.stream and not args.no_stream: + stream = stream + '-stream' + + pt_name = 'PowerTools' + if '9' in stream: + legacy_url = '' + pt_name = 'CRB' + + content = HIGHAVAILABILITY_REPO_TEMPLATE % { + 'mirror': args.mirror, + 'stream': stream, + 'legacy_url': legacy_url} + _write_repo(content, args.output_path) + + content = POWERTOOLS_REPO_TEMPLATE % {'mirror': args.mirror, + 'stream': stream, + 'legacy_url': legacy_url, + 'pt_name': pt_name} + _write_repo(content, args.output_path) + + if '9' in stream: + content = APPSTREAM_REPO_TEMPLATE % {'mirror': args.mirror, + 'extra': '', + 'legacy_url': legacy_url, + 'stream': stream} + _write_repo(content, args.output_path) + + content = BASE_REPO_TEMPLATE % {'mirror': args.mirror, + 'legacy_url': legacy_url, + 'stream': stream} + _write_repo(content, args.output_path) def _run_pkg_clean(distro): diff --git a/tests/unit/tripleo_repos/test_main.py b/tests/unit/tripleo_repos/test_main.py index 206677a..ae7ea4e 100644 --- a/tests/unit/tripleo_repos/test_main.py +++ b/tests/unit/tripleo_repos/test_main.py @@ -154,6 +154,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['current'] args.branch = 'master' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean]\nMr. Fusion' main._install_repos(args, 'roads/') self.assertEqual([mock.call('roads/current/delorean.repo', args), @@ -173,6 +174,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['current'] args.branch = 'mitaka' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean]\nMr. Fusion' main._install_repos(args, 'roads/') self.assertEqual([mock.call('roads/current/delorean.repo', args), @@ -192,6 +194,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['deps'] args.branch = 'master' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean-deps]\nMr. Fusion' main._install_repos(args, 'roads/') mock_get.assert_called_once_with('roads/delorean-deps.repo', args) @@ -205,6 +208,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['current-tripleo'] args.branch = 'master' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean]\nMr. Fusion' main._install_repos(args, 'roads/') self.assertEqual([mock.call('roads/current-tripleo/delorean.repo', @@ -224,6 +228,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['current-tripleo-dev'] args.branch = 'master' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean]\nMr. Fusion' main._install_repos(args, 'roads/') mock_get.assert_any_call('roads/delorean-deps.repo', args) @@ -247,6 +252,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['tripleo-ci-testing'] args.branch = 'master' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean]\nMr. Fusion' main._install_repos(args, 'roads/') self.assertEqual([mock.call('roads/tripleo-ci-testing/delorean.repo', @@ -266,6 +272,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['current-tripleo-rdo'] args.branch = 'master' args.output_path = 'test' + args.distro = 'fake' mock_get.return_value = '[delorean]\nMr. Fusion' main._install_repos(args, 'roads/') self.assertEqual([mock.call('roads/current-tripleo-rdo/delorean.repo', @@ -304,6 +311,7 @@ class TestTripleORepos(testtools.TestCase): args.repos = ['ceph'] args.branch = branch args.output_path = 'test' + args.distro = 'fake' mock_repo = '[centos-ceph-luminous]\nMr. Fusion' mock_create_ceph.return_value = mock_repo main._install_repos(args, 'roads/') @@ -317,6 +325,7 @@ class TestTripleORepos(testtools.TestCase): args.branch = 'master' args.output_path = 'test' args.mirror = 'http://foo' + args.distro = 'fake' main._install_repos(args, 'roads/') expected_repo = ('\n[tripleo-centos-opstools]\n' 'name=tripleo-centos-opstools\n' @@ -335,7 +344,7 @@ class TestTripleORepos(testtools.TestCase): args.output_path = 'test' args.old_mirror = 'http://mirror.centos.org' args.mirror = 'http://foo' - args.distro = 'centos' + args.distro = 'centos7' args.rdo_mirror = 'http://bar' # Abbreviated repos to verify the regex works fake_repo = ''' @@ -441,6 +450,53 @@ enabled=1 ], mock_write.mock_calls) + @mock.patch('tripleo_repos.main._get_repo') + @mock.patch('tripleo_repos.main._write_repo') + def test_install_repos_centos9_stream(self, mock_write, mock_get): + args = mock.Mock() + args.repos = ['current'] + args.branch = 'master' + args.output_path = 'test' + args.distro = 'centos9' + args.stream = True + args.no_stream = False + args.mirror = 'mirror' + mock_get.return_value = '[delorean]\nMr. Fusion' + main._install_repos(args, 'roads/') + self.assertEqual([mock.call('roads/current/delorean.repo', args), + mock.call('roads/delorean-deps.repo', args), + ], + mock_get.mock_calls) + self.assertEqual([mock.call('[delorean]\nMr. Fusion', 'test', + name='delorean'), + mock.call('[delorean]\nMr. Fusion', 'test'), + mock.call(( + '\n[tripleo-centos-highavailability]\n' + 'name=tripleo-centos-highavailability\n' + 'baseurl=mirror/9-stream/HighAvailability' + '/$basearch/os/\ngpgcheck=0\nenabled=1\n'), + 'test'), + mock.call(( + '\n[tripleo-centos-powertools]\n' + 'name=tripleo-centos-powertools\n' + 'baseurl=mirror/9-stream/CRB' + '/$basearch/os/\ngpgcheck=0\nenabled=1\n'), + 'test'), + mock.call(( + '\n[tripleo-centos-appstream]\n' + 'name=tripleo-centos-appstream\n' + 'baseurl=mirror/9-stream/AppStream' + '/$basearch/os/\ngpgcheck=0\nenabled=1\n\n'), + 'test'), + mock.call(( + '\n[tripleo-centos-baseos]\n' + 'name=tripleo-centos-baseos\n' + 'baseurl=mirror/9-stream/BaseOS' + '/$basearch/os/\ngpgcheck=0\nenabled=1\n'), + 'test') + ], + mock_write.mock_calls) + @mock.patch('tripleo_repos.main._get_repo') @mock.patch('tripleo_repos.main._write_repo') def test_install_repos_centos8_no_stream(self, mock_write, mock_get):