Merge ~chad.smith/cloud-init:bug/1781229-centos6-copr-get-linux-distro into cloud-init:master

Proposed by Chad Smith
Status: Merged
Approved by: Scott Moser
Approved revision: dffbb57447888a54977c91920bdc513052c9e6b2
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~chad.smith/cloud-init:bug/1781229-centos6-copr-get-linux-distro
Merge into: cloud-init:master
Diff against target: 107 lines (+55/-3)
2 files modified
cloudinit/tests/test_util.py (+27/-2)
cloudinit/util.py (+28/-1)
Reviewer Review Type Date Requested Status
Scott Moser Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+349380@code.launchpad.net

Commit message

get_linux_distro: add support for centos6 and rawhide flavors of redhat

An empty /etc/os-release exists on some redhat images, most notably
the COPR build images of centos6 and rawhide. On platforms missing
/etc/os-release or having an empty /etc/os-release file, use
_parse_redhat_release on rhel-based images to obtain distribution and
release codename information.

LP: #1781229

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :

FAILED: Continuous integration, rev:96b18320782f2e2f75781f5dbd0a89fa3d912a35
https://jenkins.ubuntu.com/server/job/cloud-init-ci/157/
Executed test runs:
    SUCCESS: Checkout
    FAILED: Unit & Style Tests

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/157/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Chad Smith (chad.smith) wrote :

test run of this branch on copr: https://copr.fedorainfracloud.org/coprs/blackboxsw/cloud-init/build/776423/

kicked this off with the following:

1. git clone <thisbranch>
2. ./tools/run-container --source-package centos/7
3.in copr UI builds tab click "New Build" button
https://copr.fedorainfracloud.org/coprs/blackboxsw/cloud-init/builds/

4. click Upload tab and choose your src.rpm file that was built in step 2

dffbb57... by Chad Smith

pycodestyle fixes

Revision history for this message
Server Team CI bot (server-team-bot) wrote :

PASSED: Continuous integration, rev:dffbb57447888a54977c91920bdc513052c9e6b2
https://jenkins.ubuntu.com/server/job/cloud-init-ci/158/
Executed test runs:
    SUCCESS: Checkout
    SUCCESS: Unit & Style Tests
    SUCCESS: Ubuntu LTS: Build
    SUCCESS: Ubuntu LTS: Integration
    SUCCESS: MAAS Compatability Testing
    IN_PROGRESS: Declarative: Post Actions

Click here to trigger a rebuild:
https://jenkins.ubuntu.com/server/job/cloud-init-ci/158/rebuild

review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

I launched a RHEL instance on ibm softlayer in order to see what it had in /etc/redhat-release.

# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.5 (Maipo)

I'll get redhat 6 version tomorrow.

for the record, the util.get_linux_distro() did work, as it used /etc/os-release.

# cat /etc/os-release
NAME="Red Hat Enterprise Linux Server"
VERSION="7.5 (Maipo)"
ID="rhel"
ID_LIKE="fedora"
VARIANT="Server"
VARIANT_ID="server"
VERSION_ID="7.5"
PRETTY_NAME="Red Hat"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:redhat:enterprise_linux:7.5:GA:server"
HOME_URL="https://www.redhat.com/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"

REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 7"
REDHAT_BUGZILLA_PRODUCT_VERSION=7.5
REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux"
REDHAT_SUPPORT_PRODUCT_VERSION="7.5"

Revision history for this message
Scott Moser (smoser) wrote :

Launched a redhat 6 image there, and got
# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.10 (Santiago)

# cat /etc/os-release
cat: /etc/os-release: No such file or directory

Revision history for this message
Scott Moser (smoser) wrote :

I'm going to hit 'accept', and let this land and then i'll try to adjust to support redhat-release actually having 'Red Hat' values rather than centos.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/tests/test_util.py b/cloudinit/tests/test_util.py
2index 6a31e50..387d894 100644
3--- a/cloudinit/tests/test_util.py
4+++ b/cloudinit/tests/test_util.py
5@@ -57,6 +57,9 @@ OS_RELEASE_CENTOS = dedent("""\
6 REDHAT_SUPPORT_PRODUCT_VERSION="7"
7 """)
8
9+REDHAT_RELEASE_CENTOS_6 = "CentOS release 6.10 (Final)"
10+REDHAT_RELEASE_CENTOS_7 = "CentOS Linux release 7.5.1804 (Core)"
11+
12 OS_RELEASE_DEBIAN = dedent("""\
13 PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
14 NAME="Debian GNU/Linux"
15@@ -337,6 +340,12 @@ class TestGetLinuxDistro(CiTestCase):
16 if path == '/etc/os-release':
17 return 1
18
19+ @classmethod
20+ def redhat_release_exists(self, path):
21+ """Side effect function """
22+ if path == '/etc/redhat-release':
23+ return 1
24+
25 @mock.patch('cloudinit.util.load_file')
26 def test_get_linux_distro_quoted_name(self, m_os_release, m_path_exists):
27 """Verify we get the correct name if the os-release file has
28@@ -356,8 +365,24 @@ class TestGetLinuxDistro(CiTestCase):
29 self.assertEqual(('ubuntu', '16.04', 'xenial'), dist)
30
31 @mock.patch('cloudinit.util.load_file')
32- def test_get_linux_centos(self, m_os_release, m_path_exists):
33- """Verify we get the correct name and release name on CentOS."""
34+ def test_get_linux_centos6(self, m_os_release, m_path_exists):
35+ """Verify we get the correct name and release name on CentOS 6."""
36+ m_os_release.return_value = REDHAT_RELEASE_CENTOS_6
37+ m_path_exists.side_effect = TestGetLinuxDistro.redhat_release_exists
38+ dist = util.get_linux_distro()
39+ self.assertEqual(('centos', '6.10', 'Final'), dist)
40+
41+ @mock.patch('cloudinit.util.load_file')
42+ def test_get_linux_centos7_redhat_release(self, m_os_release, m_exists):
43+ """Verify the correct release info on CentOS 7 without os-release."""
44+ m_os_release.return_value = REDHAT_RELEASE_CENTOS_7
45+ m_exists.side_effect = TestGetLinuxDistro.redhat_release_exists
46+ dist = util.get_linux_distro()
47+ self.assertEqual(('centos', '7.5.1804', 'Core'), dist)
48+
49+ @mock.patch('cloudinit.util.load_file')
50+ def test_get_linux_copr_centos(self, m_os_release, m_path_exists):
51+ """Verify we get the correct name and release name on COPR CentOS."""
52 m_os_release.return_value = OS_RELEASE_CENTOS
53 m_path_exists.side_effect = TestGetLinuxDistro.os_release_exists
54 dist = util.get_linux_distro()
55diff --git a/cloudinit/util.py b/cloudinit/util.py
56index d0b0e90..8604db5 100644
57--- a/cloudinit/util.py
58+++ b/cloudinit/util.py
59@@ -576,12 +576,39 @@ def get_cfg_option_int(yobj, key, default=0):
60 return int(get_cfg_option_str(yobj, key, default=default))
61
62
63+def _parse_redhat_release(release_file=None):
64+ """Return a dictionary of distro info fields from /etc/redhat-release.
65+
66+ Dict keys will align with /etc/os-release keys:
67+ ID, VERSION_ID, VERSION_CODENAME
68+ """
69+
70+ if not release_file:
71+ release_file = '/etc/redhat-release'
72+ if not os.path.exists(release_file):
73+ return {}
74+ redhat_release = load_file(release_file)
75+ redhat_regex = (
76+ r'(?P<name>\S+) (Linux )?release (?P<version>[\d\.]+) '
77+ r'\((?P<codename>[^)]+)\)')
78+ match = re.match(redhat_regex, redhat_release)
79+ if match:
80+ group = match.groupdict()
81+ return {'ID': group['name'].lower(), 'VERSION_ID': group['version'],
82+ 'VERSION_CODENAME': group['codename']}
83+ return {}
84+
85+
86 def get_linux_distro():
87 distro_name = ''
88 distro_version = ''
89 flavor = ''
90+ os_release = {}
91 if os.path.exists('/etc/os-release'):
92 os_release = load_shell_content(load_file('/etc/os-release'))
93+ if not os_release:
94+ os_release = _parse_redhat_release()
95+ if os_release:
96 distro_name = os_release.get('ID', '')
97 distro_version = os_release.get('VERSION_ID', '')
98 if 'sles' in distro_name or 'suse' in distro_name:
99@@ -594,7 +621,7 @@ def get_linux_distro():
100 flavor = os_release.get('VERSION_CODENAME', '')
101 if not flavor:
102 match = re.match(r'[^ ]+ \((?P<codename>[^)]+)\)',
103- os_release.get('VERSION'))
104+ os_release.get('VERSION', ''))
105 if match:
106 flavor = match.groupdict()['codename']
107 else:

Subscribers

People subscribed via source and target branches