-
Notifications
You must be signed in to change notification settings - Fork 68
Refactor osdetect for rhel family OSes #464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,46 +1,17 @@ | ||
| # Copyright 2020 Cloudbase Solutions Srl | ||
| # All Rights Reserved. | ||
|
|
||
| import re | ||
|
|
||
| from coriolis import constants | ||
| from coriolis.osmorphing.osdetect import base | ||
| from oslo_log import log as logging | ||
| from coriolis.osmorphing.osdetect import common | ||
|
|
||
|
|
||
| LOG = logging.getLogger(__name__) | ||
| CENTOS_DISTRO_IDENTIFIER = "CentOS" | ||
| CENTOS_STREAM_DISTRO_IDENTIFIER = "CentOS Stream" | ||
| ALMA_IDENTIFIER = "AlmaLinux" | ||
| CENTOS_DISTRO_IDENTIFIER = common.CENTOS_DISTRO_IDENTIFIER | ||
| CENTOS_STREAM_DISTRO_IDENTIFIER = common.CENTOS_STREAM_DISTRO_IDENTIFIER | ||
|
|
||
|
|
||
| class CentOSOSDetectTools(base.BaseLinuxOSDetectTools): | ||
|
|
||
| def detect_os(self): | ||
| info = {} | ||
| redhat_release_path = "etc/redhat-release" | ||
| if self._test_path(redhat_release_path): | ||
| release_info = self._read_file( | ||
| redhat_release_path).decode().splitlines() | ||
| if release_info: | ||
| m = re.match(r"^(.*) release ([0-9]+(\.[0-9]+)*)( \(.*\))?.*$", | ||
| release_info[0].strip()) | ||
| if m: | ||
| distro, version, _, _ = m.groups() | ||
| if (CENTOS_DISTRO_IDENTIFIER not in distro and | ||
| ALMA_IDENTIFIER not in distro): | ||
| LOG.debug( | ||
| "Distro does not appear to be a CentOS or Alma: " | ||
| f"{distro}") | ||
| return {} | ||
|
|
||
| distribution_name = CENTOS_DISTRO_IDENTIFIER | ||
| if CENTOS_STREAM_DISTRO_IDENTIFIER in distro: | ||
| distribution_name = CENTOS_STREAM_DISTRO_IDENTIFIER | ||
| info = { | ||
| "os_type": constants.OS_TYPE_LINUX, | ||
| "distribution_name": distribution_name, | ||
| "release_version": version, | ||
| "friendly_release_name": "%s Version %s" % ( | ||
| distribution_name, version)} | ||
| return info | ||
| return common.detect_os_from_os_release( | ||
| self._get_os_release(), | ||
| match_ids={"centos", "almalinux"}) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| # Copyright 2026 Cloudbase Solutions Srl | ||
| # All Rights Reserved. | ||
|
|
||
| """Shared /etc/os-release parsing for RHEL-family osdetect tools.""" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd rename the module to "redhat_common.py" |
||
|
|
||
| from coriolis import constants | ||
|
|
||
| ROCKY_LINUX_DISTRO_IDENTIFIER = "Rocky Linux" | ||
| CENTOS_DISTRO_IDENTIFIER = "CentOS" | ||
| CENTOS_STREAM_DISTRO_IDENTIFIER = "CentOS Stream" | ||
| RED_HAT_DISTRO_IDENTIFIER = "Red Hat Enterprise Linux" | ||
| ORACLE_DISTRO_IDENTIFIER = "Oracle Linux" | ||
|
|
||
| OS_RELEASE_ID_MAP = { | ||
| "rocky": ROCKY_LINUX_DISTRO_IDENTIFIER, | ||
| "centos": CENTOS_DISTRO_IDENTIFIER, | ||
| "almalinux": CENTOS_DISTRO_IDENTIFIER, | ||
| "rhel": RED_HAT_DISTRO_IDENTIFIER, | ||
| "ol": ORACLE_DISTRO_IDENTIFIER, | ||
| } | ||
|
|
||
|
|
||
| def detect_os_from_os_release(os_release, *, match_ids): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use type hints and document the "os_release" parameter, stating that it's a dict populated by /etc/os-release values. |
||
| """Detect a RHEL-family distro from /etc/os-release. | ||
|
|
||
| Each osdetect module passes the ``ID`` value(s) it handles, e.g. | ||
| ``match_ids={"rocky"}`` or ``match_ids={"centos", "almalinux"}``. | ||
| """ | ||
| if not os_release: | ||
| return {} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the very least, we should log a warning if we haven't received the os_release dict. |
||
|
|
||
| os_id = (os_release.get("ID") or "").lower() | ||
| if os_id not in match_ids: | ||
| return {} | ||
|
|
||
| default_name = OS_RELEASE_ID_MAP.get(os_id) | ||
| if not default_name: | ||
| return {} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Warning? The id matches but we don't have a default distribution name for that given identifier. |
||
|
|
||
| version = os_release.get("VERSION_ID") | ||
| if not version: | ||
| return {} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, the OS id matches but it doesn't include a version. Let's log a warning. |
||
|
|
||
| name = os_release.get("NAME") or default_name | ||
| if os_id == "centos" and "Stream" in name: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need this special check for centos stream? I tried out a docker image and got Speaking of which, won't there always be a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Stream was added starting with CentOS 8, regarding the NAME entry, I agree on using
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My point is that the default will probably never be used, making |
||
| distribution_name = CENTOS_STREAM_DISTRO_IDENTIFIER | ||
| else: | ||
| distribution_name = default_name | ||
|
|
||
| return { | ||
| "os_type": constants.OS_TYPE_LINUX, | ||
| "distribution_name": distribution_name, | ||
| "release_version": version, | ||
| "friendly_release_name": "%s Version %s" % ( | ||
| distribution_name, version)} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,16 @@ | ||
| # Copyright 2020 Cloudbase Solutions Srl | ||
| # All Rights Reserved. | ||
|
|
||
| import re | ||
|
|
||
| from coriolis import constants | ||
| from coriolis.osmorphing.osdetect import base | ||
| from coriolis.osmorphing.osdetect import common | ||
|
|
||
|
|
||
| ORACLE_DISTRO_IDENTIFIER = "Oracle Linux" | ||
| ORACLE_DISTRO_IDENTIFIER = common.ORACLE_DISTRO_IDENTIFIER | ||
|
|
||
|
|
||
| class OracleOSDetectTools(base.BaseLinuxOSDetectTools): | ||
|
|
||
| def detect_os(self): | ||
| info = {} | ||
| oracle_release_path = "etc/oracle-release" | ||
| if self._test_path(oracle_release_path): | ||
| release_info = self._read_file( | ||
| oracle_release_path).decode().splitlines() | ||
| if release_info: | ||
| m = re.match(r"^(.*) release ([0-9].*)$", | ||
| release_info[0].strip()) | ||
| if m: | ||
| distro, version = m.groups() | ||
| info = { | ||
| "os_type": constants.OS_TYPE_LINUX, | ||
| "distribution_name": ORACLE_DISTRO_IDENTIFIER, | ||
| "release_version": version, | ||
| "friendly_release_name": "%s Version %s" % ( | ||
| distro, version)} | ||
| return info | ||
| return common.detect_os_from_os_release( | ||
| self._get_os_release(), | ||
| match_ids={"ol"}) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,40 +1,16 @@ | ||
| # Copyright 2020 Cloudbase Solutions Srl | ||
| # All Rights Reserved. | ||
|
|
||
| import re | ||
|
|
||
| from oslo_log import log as logging | ||
|
|
||
| from coriolis import constants | ||
| from coriolis.osmorphing.osdetect import base | ||
| from coriolis.osmorphing.osdetect import common | ||
|
|
||
|
|
||
| LOG = logging.getLogger(__name__) | ||
| RED_HAT_DISTRO_IDENTIFIER = "Red Hat Enterprise Linux" | ||
| RED_HAT_DISTRO_IDENTIFIER = common.RED_HAT_DISTRO_IDENTIFIER | ||
|
|
||
|
|
||
| class RedHatOSDetectTools(base.BaseLinuxOSDetectTools): | ||
|
|
||
| def detect_os(self): | ||
| info = {} | ||
| redhat_release_path = "etc/redhat-release" | ||
| if self._test_path(redhat_release_path): | ||
| release_info = self._read_file( | ||
| redhat_release_path).decode().splitlines() | ||
| if release_info: | ||
| m = re.match(r"^(.*) release ([0-9].*) \((.*)\).*$", | ||
| release_info[0].strip()) | ||
| if m: | ||
| distro, version, _ = m.groups() | ||
| if RED_HAT_DISTRO_IDENTIFIER not in distro: | ||
| LOG.debug( | ||
| "Distro does not appear to be a RHEL: %s", distro) | ||
| return {} | ||
|
|
||
| info = { | ||
| "os_type": constants.OS_TYPE_LINUX, | ||
| "distribution_name": RED_HAT_DISTRO_IDENTIFIER, | ||
| "release_version": version, | ||
| "friendly_release_name": "%s Version %s" % ( | ||
| RED_HAT_DISTRO_IDENTIFIER, version)} | ||
| return info | ||
| return common.detect_os_from_os_release( | ||
| self._get_os_release(), | ||
| match_ids={"rhel"}) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,40 +1,16 @@ | ||
| # Copyright 2023 Cloudbase Solutions Srl | ||
| # All Rights Reserved. | ||
|
|
||
| import re | ||
|
|
||
| from coriolis import constants | ||
| from coriolis.osmorphing.osdetect import base | ||
| from oslo_log import log as logging | ||
| from coriolis.osmorphing.osdetect import common | ||
|
|
||
|
|
||
| LOG = logging.getLogger(__name__) | ||
| ROCKY_LINUX_DISTRO_IDENTIFIER = "Rocky Linux" | ||
| ROCKY_LINUX_DISTRO_IDENTIFIER = common.ROCKY_LINUX_DISTRO_IDENTIFIER | ||
|
|
||
|
|
||
| class RockyLinuxOSDetectTools(base.BaseLinuxOSDetectTools): | ||
|
|
||
| def detect_os(self): | ||
| info = {} | ||
| redhat_release_path = "etc/redhat-release" | ||
| if self._test_path(redhat_release_path): | ||
| release_info = self._read_file( | ||
| redhat_release_path).decode().splitlines() | ||
| if release_info: | ||
| m = re.match(r"^(.*) release ([0-9]+(\.[0-9]+)*)( \(.*\))?.*$", | ||
| release_info[0].strip()) | ||
| if m: | ||
| distro, version, _, _ = m.groups() | ||
| if ROCKY_LINUX_DISTRO_IDENTIFIER not in distro: | ||
| LOG.debug( | ||
| "Distro does not appear to be a Rocky Linux: %s", | ||
| distro) | ||
| return {} | ||
|
|
||
| info = { | ||
| "os_type": constants.OS_TYPE_LINUX, | ||
| "distribution_name": ROCKY_LINUX_DISTRO_IDENTIFIER, | ||
| "release_version": version, | ||
| "friendly_release_name": "%s Version %s" % ( | ||
| ROCKY_LINUX_DISTRO_IDENTIFIER, version)} | ||
| return info | ||
| return common.detect_os_from_os_release( | ||
| self._get_os_release(), | ||
| match_ids={"rocky"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RHEL 6 and derivate OS-es do not have the /etc/os-release file. Are we going to drop RHEL 6 support? If so, the PR description must clearly state it. We can also remove RHEL 6 specific os-morphing code.