diff --git a/docs/shared_combiners_catalog/rhel_for_edge.rst b/docs/shared_combiners_catalog/rhel_for_edge.rst new file mode 100644 index 0000000000..891f6fdc44 --- /dev/null +++ b/docs/shared_combiners_catalog/rhel_for_edge.rst @@ -0,0 +1,3 @@ +.. automodule:: insights.combiners.rhel_for_edge + :members: + :show-inheritance: diff --git a/insights/combiners/rhel_for_edge.py b/insights/combiners/rhel_for_edge.py new file mode 100644 index 0000000000..641d10936d --- /dev/null +++ b/insights/combiners/rhel_for_edge.py @@ -0,0 +1,67 @@ +""" +Combiner for edge computing systems +=================================== +This combiner uses the following parsers to determine if the system is an edge computing systems. + +* :py:class:`insights.parsers.installed_rpms.InstalledRpms` +* :py:class:`insights.parsers.cmdline.CmdLine` +* :py:class:`insights.parsers.systemd.unitfiles.ListUnits` +* :py:class:`insights.parsers.redhat_release.RedhatRelease` +""" +from insights.core.plugins import combiner +from insights.parsers.cmdline import CmdLine +from insights.parsers.installed_rpms import InstalledRpms +from insights.parsers.systemd.unitfiles import ListUnits +from insights.parsers.redhat_release import RedhatRelease + + +@combiner(InstalledRpms, CmdLine, ListUnits, RedhatRelease) +class RhelForEdge(object): + """ + Combiner for checking if the system is an edge computing systems. + Edge computing system packages are managed via rpm-ostree. + Red Hat CoreOS is also managed via rpm-ostree, use the string "Red Hat Enterprise Linux release" + from "/etc/redhat-release" to determine if it is an edge computing system as it is + "Red Hat Enterprise Linux CoreOS release" on RedHat CoreOs. + + .. note:: + RHEL for EDGE is available and supported since RHEL 8.3. + + When an edge computing system created from online console edge image is configured to use + automated management, the output of "rhc status" is the following:: + + Connection status for test.localhost: + - Connected to Red Hat Subscription Management + - The Red Hat connector daemon is active + + If a system can upload insights archive, it must be connected to Red Hat Subscription Management, + rhcd service running means an edge computing system is configured to use automated management. + + Attributes: + is_edge (bool): True when it is an edge computing system + is_automated (bool): True when the the edge computing system is configured to use automated management + + .. note:: + It is also able to run rhcd service on the edge systems created from cockpit edge image, + "is_automated" is only for front-end resolution surface, it is used when customers determine that + the image is from online console. + + Examples: + >>> type(rhel_for_edge_obj) + + >>> rhel_for_edge_obj.is_edge + True + >>> rhel_for_edge_obj.is_automated + True + """ + + def __init__(self, rpms, cmdline, units, redhatrelease): + self.is_edge = False + self.is_automated = False + + if ('rpm-ostree' in rpms and 'yum' not in rpms) and \ + ('ostree' in cmdline) and \ + ("red hat enterprise linux release" in redhatrelease.raw.lower()): + self.is_edge = True + if units.is_running("rhcd.service"): + self.is_automated = True diff --git a/insights/tests/combiners/test_rhel_for_edge.py b/insights/tests/combiners/test_rhel_for_edge.py new file mode 100644 index 0000000000..d3a25f2fd5 --- /dev/null +++ b/insights/tests/combiners/test_rhel_for_edge.py @@ -0,0 +1,110 @@ +from insights.parsers.installed_rpms import InstalledRpms +from insights.parsers.cmdline import CmdLine +from insights.parsers.systemd.unitfiles import ListUnits +from insights.parsers.redhat_release import RedhatRelease +from insights.combiners.rhel_for_edge import RhelForEdge +from insights.combiners import rhel_for_edge +from insights.tests import context_wrap +import doctest + +CONTENT_REDHAT_RELEASE_RHEL = """ +Red Hat Enterprise Linux release 8.4 (Ootpa) +""".strip() + +CONTENT_REDHAT_RELEASE_COREOS = """ +Red Hat Enterprise Linux CoreOS release 4.12 +""".strip() + +CMDLINE_RHEL = """ +BOOT_IMAGE=/vmlinuz-4.18.0-80.el8.x86_64 root=/dev/mapper/rootvg-rootlv ro crashkernel=184M rd.lvm.lv=rootvg/rootlv biosdevname=0 printk.time=1 numa=off audit=1 transparent_hugepage=always LANG=en_US.UTF-8 +""".strip() + +CMDLINE_EDGE = """ +BOOT_IMAGE=(hd0,msdos1)/ostree/rhel-323453435435234234232534534/vmlinuz-4.18.0-348.20.1.el8_5.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap ostree=/ostree/boot.1/rhel/08987978979/0 rhgb quiet LANG=en_US.UTF-8 +""".strip() + +CONTENT_SYSTEMCTL_LIST_UNITS_NO_AUTOMATED = """ +postgresql.service loaded active running PostgreSQL database server +""".strip() + +CONTENT_SYSTEMCTL_LIST_UNITS_AUTOMATED = """ +postgresql.service loaded active running PostgreSQL database server +rhcd.service loaded active running Red Hat connector daemon +""".strip() + +CONTENT_INSTALLED_RPMS_RHEL = """ +kernel-4.18.0-305.19.1.el8_4.x86_64 +""".strip() + +CONTENT_INSTALLED_RPMS_EDGE = """ +kernel-4.18.0-305.19.1.el8_4.x86_64 +rpm-ostree-2021.5-2.el8.x86_64 +""".strip() + + +def test_rhel_for_edge_true_1(): + install_rpms = InstalledRpms(context_wrap(CONTENT_INSTALLED_RPMS_EDGE)) + cmdline = CmdLine(context_wrap(CMDLINE_EDGE)) + list_units = ListUnits(context_wrap(CONTENT_SYSTEMCTL_LIST_UNITS_NO_AUTOMATED)) + redhat_release = RedhatRelease(context_wrap(CONTENT_REDHAT_RELEASE_RHEL)) + + result = RhelForEdge(install_rpms, cmdline, list_units, redhat_release) + assert result.is_edge is True + assert result.is_automated is False + + +def test_rhel_for_edge_true_2(): + install_rpms = InstalledRpms(context_wrap(CONTENT_INSTALLED_RPMS_EDGE)) + cmdline = CmdLine(context_wrap(CMDLINE_EDGE)) + list_units = ListUnits(context_wrap(CONTENT_SYSTEMCTL_LIST_UNITS_AUTOMATED)) + redhat_release = RedhatRelease(context_wrap(CONTENT_REDHAT_RELEASE_RHEL)) + + result = RhelForEdge(install_rpms, cmdline, list_units, redhat_release) + assert result.is_edge is True + assert result.is_automated is True + + +def test_rhel_for_edge_false_1(): + install_rpms = InstalledRpms(context_wrap(CONTENT_INSTALLED_RPMS_RHEL)) + cmdline = CmdLine(context_wrap(CMDLINE_EDGE)) + list_units = ListUnits(context_wrap(CONTENT_SYSTEMCTL_LIST_UNITS_AUTOMATED)) + redhat_release = RedhatRelease(context_wrap(CONTENT_REDHAT_RELEASE_RHEL)) + + result = RhelForEdge(install_rpms, cmdline, list_units, redhat_release) + assert result.is_edge is False + assert result.is_automated is False + + +def test_rhel_for_edge_false_2(): + install_rpms = InstalledRpms(context_wrap(CONTENT_INSTALLED_RPMS_EDGE)) + cmdline = CmdLine(context_wrap(CMDLINE_RHEL)) + list_units = ListUnits(context_wrap(CONTENT_SYSTEMCTL_LIST_UNITS_AUTOMATED)) + redhat_release = RedhatRelease(context_wrap(CONTENT_REDHAT_RELEASE_RHEL)) + + result = RhelForEdge(install_rpms, cmdline, list_units, redhat_release) + assert result.is_edge is False + assert result.is_automated is False + + +def test_rhel_for_edge_false_3(): + install_rpms = InstalledRpms(context_wrap(CONTENT_INSTALLED_RPMS_EDGE)) + cmdline = CmdLine(context_wrap(CMDLINE_EDGE)) + list_units = ListUnits(context_wrap(CONTENT_SYSTEMCTL_LIST_UNITS_AUTOMATED)) + redhat_release = RedhatRelease(context_wrap(CONTENT_REDHAT_RELEASE_COREOS)) + + result = RhelForEdge(install_rpms, cmdline, list_units, redhat_release) + assert result.is_edge is False + assert result.is_automated is False + + +def test_doc_examples(): + install_rpms = InstalledRpms(context_wrap(CONTENT_INSTALLED_RPMS_EDGE)) + cmdline = CmdLine(context_wrap(CMDLINE_EDGE)) + list_units = ListUnits(context_wrap(CONTENT_SYSTEMCTL_LIST_UNITS_AUTOMATED)) + redhat_release = RedhatRelease(context_wrap(CONTENT_REDHAT_RELEASE_RHEL)) + + env = { + 'rhel_for_edge_obj': RhelForEdge(install_rpms, cmdline, list_units, redhat_release) + } + failed, total = doctest.testmod(rhel_for_edge, globs=env) + assert failed == 0