From 08ffdba1a692c342539d0d7826e3483691faaf91 Mon Sep 17 00:00:00 2001 From: wang-guangge Date: Fri, 2 Jun 2023 14:12:23 +0800 Subject: [PATCH] add 0002-increase-the-usage-scenarious-of-dnf-hotpatch-plugin.patch and update aops-apollo.spec --- ...ge-scenarious-of-dnf-hotpatch-plugin.patch | 385 ++++++++++++++++++ aops-apollo.spec | 6 +- 2 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 0002-increase-the-usage-scenarious-of-dnf-hotpatch-plugin.patch diff --git a/0002-increase-the-usage-scenarious-of-dnf-hotpatch-plugin.patch b/0002-increase-the-usage-scenarious-of-dnf-hotpatch-plugin.patch new file mode 100644 index 0000000..73f81c4 --- /dev/null +++ b/0002-increase-the-usage-scenarious-of-dnf-hotpatch-plugin.patch @@ -0,0 +1,385 @@ +From faeec6eff1e80be893916d16fb6bd3cd8f0246c9 Mon Sep 17 00:00:00 2001 +From: wang-guangge +Date: Wed, 31 May 2023 18:06:22 +0800 +Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B7=A1=E6=A3=80=E5=91=BD?= + =?UTF-8?q?=E4=BB=A4=E9=80=82=E9=85=8D=E5=9C=BA=E6=99=AF=EF=BC=8C=E4=BF=AE?= + =?UTF-8?q?=E6=94=B9hotpatch=5Fupdateinfo.py=E6=9F=A5=E6=89=BE=E7=83=AD?= + =?UTF-8?q?=E8=A1=A5=E4=B8=81=E4=BF=A1=E6=81=AF=E6=96=B9=E5=BC=8F?= +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +--- + hotpatch/baseclass.py | 14 ++-- + hotpatch/hot-updateinfo.py | 118 +++++++++----------------------- + hotpatch/hotpatch.py | 13 ++-- + hotpatch/hotpatch_updateinfo.py | 58 ++++++++++------ + 4 files changed, 83 insertions(+), 120 deletions(-) + +diff --git a/hotpatch/baseclass.py b/hotpatch/baseclass.py +index d88ef40..2542a03 100644 +--- a/hotpatch/baseclass.py ++++ b/hotpatch/baseclass.py +@@ -115,7 +115,7 @@ class Hotpatch(object): + + + class Cve(object): +- __slots__ = ['_cve_id', '_hotpatch'] ++ __slots__ = ['_cve_id', '_hotpatches'] + + def __init__(self, + id, +@@ -124,15 +124,14 @@ class Cve(object): + id: str + """ + self._cve_id = id +- self._hotpatch = None ++ self._hotpatches = [] + + @property +- def hotpatch(self): +- return self._hotpatch ++ def hotpatches(self): ++ return self._hotpatches + +- @hotpatch.setter +- def hotpatch(self, hotpatch: Hotpatch): +- self._hotpatch = hotpatch ++ def add_hotpatch(self, hotpatch: Hotpatch): ++ self._hotpatches.append(hotpatch) + + @property + def cve_id(self): +@@ -206,3 +205,4 @@ class Advisory(object): + + def add_hotpatch(self, hotpatch: Hotpatch): + self._hotpatches.append(hotpatch) ++ +diff --git a/hotpatch/hot-updateinfo.py b/hotpatch/hot-updateinfo.py +index 779337b..d1e6d58 100644 +--- a/hotpatch/hot-updateinfo.py ++++ b/hotpatch/hot-updateinfo.py +@@ -4,46 +4,6 @@ from dnf.cli.commands.updateinfo import UpdateInfoCommand + import hawkey + from .hotpatch_updateinfo import HotpatchUpdateInfo + +- +-class Versions: +- """ +- Version number processing +- """ +- +- separator = (".", "-") +- _connector = "&" +- +- def _order(self, version, separator=None): +- """ +- Version of the cutting +- Args: +- version: version +- separator: separator +- +- Returns: +- +- """ +- if not separator: +- separator = self._connector +- return tuple([int(v) for v in version.split(separator) if v.isdigit()]) +- +- def lgt(self, version, compare_version): +- """ +- Returns true if the size of the compared version is greater +- than that of the compared version, or false otherwise +- +- """ +- for separator in self.separator: +- version = self._connector.join( +- [v for v in version.split(separator)]) +- compare_version = self._connector.join( +- [v for v in compare_version.split(separator)] +- ) +- version = self._order(version) +- compare_version = self._order(compare_version) +- return version >= compare_version +- +- + @dnf.plugin.register_command + class HotUpdateinfoCommand(dnf.cli.Command): + aliases = ['hot-updateinfo'] +@@ -118,26 +78,13 @@ class HotUpdateinfoCommand(dnf.cli.Command): + + return mapping_nevra_cve + +- def _filter_and_format_list_output(self, echo_lines: list, fixed_cve_id: set, fixed_coldpatches: set): ++ def _filter_and_format_list_output(self, echo_lines: list, fixed_cve_id: set): + """ + Only show specified cve information that have not been fixed, and format output + """ +- def is_patch_fixed(coldpatch, fixed_coldpatches): +- """ +- Check whether the coldpatch is fixed +- """ +- for fixed_coldpatch in fixed_coldpatches: +- pkg_name, pkg_evr, _ = coldpatch +- fixed_pkg_name, fixed_pkg_evr, _ = fixed_coldpatch +- if pkg_name != fixed_pkg_name: +- continue +- if version.lgt(fixed_pkg_evr, pkg_evr): +- return True +- return False + + idw = tiw = ciw = 0 + format_lines = set() +- version = Versions() + for echo_line in echo_lines: + cve_id, adv_type, coldpatch, hotpatch = echo_line[0], echo_line[1], echo_line[2], echo_line[3] + if self.filter_cves is not None and cve_id not in self.filter_cves: +@@ -145,11 +92,8 @@ class HotUpdateinfoCommand(dnf.cli.Command): + if cve_id in fixed_cve_id: + continue + if not isinstance(coldpatch, str): +- if is_patch_fixed(coldpatch, fixed_coldpatches): +- continue +- else: +- pkg_name, pkg_evr, pkg_arch = coldpatch +- coldpatch = '%s-%s.%s' % (pkg_name, pkg_evr, pkg_arch) ++ pkg_name, pkg_evr, pkg_arch = coldpatch ++ coldpatch = '%s-%s.%s' % (pkg_name, pkg_evr, pkg_arch) + + idw = max(idw, len(cve_id)) + tiw = max(tiw, len(adv_type)) +@@ -178,41 +122,43 @@ class HotUpdateinfoCommand(dnf.cli.Command): + mapping_nevra_cve = self.get_mapping_nevra_cve() + echo_lines = [] + fixed_cve_id = set() +- fixed_coldpatches = set() + iterated_cve_id = set() + for ((nevra), aupdated), id2type in sorted(mapping_nevra_cve.items(), key=lambda x: x[0]): + pkg_name, pkg_evr, pkg_arch = nevra + for cve_id, atypesev in id2type.items(): + iterated_cve_id.add(cve_id) +- label = type2label(self.updateinfo, *atypesev) +- echo_line = [cve_id, label, nevra, '-'] +- echo_lines.append(echo_line) +- if cve_id not in self.hp_hawkey.hotpatch_cves: ++ label = type2label(self.updateinfo, *atypesev) ++ if cve_id not in self.hp_hawkey.hotpatch_cves or not self.hp_hawkey.hotpatch_cves[cve_id].hotpatches: ++ echo_line = [cve_id, label, nevra, '-'] ++ echo_lines.append(echo_line) + continue +- hotpatch = self.hp_hawkey.hotpatch_cves[cve_id].hotpatch +- if hotpatch is None or hotpatch.src_pkg_nevre[0] != pkg_name: +- continue +- if hotpatch.state == self.hp_hawkey.INSTALLED: +- # record the fixed cves +- for cve_id in hotpatch.cves: +- fixed_cve_id.add(cve_id) +- # record the fixed coldpatch to filter the cves of the corresponding coldpatch with the lower version +- fixed_coldpatches.add((nevra)) +- echo_lines.pop() +- elif hotpatch.state == self.hp_hawkey.INSTALLABLE: +- echo_lines[-1][3] = hotpatch.nevra ++ ++ for hotpatch in self.hp_hawkey.hotpatch_cves[cve_id].hotpatches: ++ echo_line = [cve_id, label, nevra, '-'] ++ echo_lines.append(echo_line) ++ if hotpatch.src_pkg_nevre[0] != pkg_name: ++ continue ++ if hotpatch.state == self.hp_hawkey.INSTALLED: ++ # record the fixed cves ++ for cve_id in hotpatch.cves: ++ fixed_cve_id.add(cve_id) ++ echo_lines.pop() ++ elif hotpatch.state == self.hp_hawkey.INSTALLABLE: ++ echo_lines[-1][3] = hotpatch.nevra ++ + + hp_cve_list = list(set(self.hp_hawkey.hotpatch_cves.keys()).difference(iterated_cve_id)) + for cve_id in hp_cve_list: +- hotpatch = self.hp_hawkey.hotpatch_cves[cve_id].hotpatch +- if hotpatch is None: +- continue +- echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', '-'] +- if hotpatch.state == self.hp_hawkey.INSTALLED: +- continue +- elif hotpatch.state == self.hp_hawkey.INSTALLABLE: +- echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', hotpatch.nevra] +- echo_lines.append(echo_line) ++ for hotpatch in self.hp_hawkey.hotpatch_cves[cve_id].hotpatches: ++ echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', '-'] ++ if hotpatch.state == self.hp_hawkey.INSTALLED: ++ # record the fixed cves ++ fixed_cve_id.add(cve_id) ++ continue ++ elif hotpatch.state == self.hp_hawkey.INSTALLABLE: ++ echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', hotpatch.nevra] ++ echo_lines.append(echo_line) + + self._filter_and_format_list_output( +- echo_lines, fixed_cve_id, fixed_coldpatches) ++ echo_lines, fixed_cve_id) ++ +diff --git a/hotpatch/hotpatch.py b/hotpatch/hotpatch.py +index 0704a08..ccef636 100644 +--- a/hotpatch/hotpatch.py ++++ b/hotpatch/hotpatch.py +@@ -102,12 +102,12 @@ class HotpatchCommand(dnf.cli.Command): + hotpatch_cves = self.hp_hawkey.hotpatch_cves + echo_lines = [] + for cve_id in hotpatch_cves.keys(): +- hotpatch = hotpatch_cves[cve_id].hotpatch +- status = self.hp_hawkey._get_hotpatch_status_in_syscare(hotpatch) +- if status == '': +- continue +- echo_line = [cve_id, hotpatch.syscare_name, status] +- echo_lines.append(echo_line) ++ for hotpatch in hotpatch_cves[cve_id].hotpatches: ++ status = self.hp_hawkey._get_hotpatch_status_in_syscare(hotpatch) ++ if status == '': ++ continue ++ echo_line = [cve_id, hotpatch.syscare_name, status] ++ echo_lines.append(echo_line) + + self._filter_and_format_list_output(echo_lines) + +@@ -133,3 +133,4 @@ class HotpatchCommand(dnf.cli.Command): + else: + logger.info(_("%s hot patch '%s' succeed"), operate, self.base.output.term.bold(target_patch)) + ++ +diff --git a/hotpatch/hotpatch_updateinfo.py b/hotpatch/hotpatch_updateinfo.py +index 6689553..399e05c 100644 +--- a/hotpatch/hotpatch_updateinfo.py ++++ b/hotpatch/hotpatch_updateinfo.py +@@ -67,7 +67,7 @@ class HotpatchUpdateInfo(object): + """ + Initialize hotpatch information from repos + """ +- # get xxx-hotpatch.xml.gz file paths by traversing the system_cachedir(/var/cache/dnf) ++ # get xxx-updateinfo.xml.gz file paths by traversing the system_cachedir(/var/cache/dnf) + system_cachedir = self.cli.base.conf.system_cachedir + all_repos = self.cli.base.repos + map_repo_updateinfoxml = {} +@@ -80,9 +80,9 @@ class HotpatchUpdateInfo(object): + continue + + for xml_file in os.listdir(repodata_path): +- # the hotpatch relevant updateinfo is recorded in xxx-hotpatch.xml.gz +- if "hotpatch" in xml_file: +- repo_name = file.split("-")[0] ++ # the hotpatch relevant updateinfo is recorded in xxx-updateinfo.xml.gz ++ if "updateinfo" in xml_file: ++ repo_name = file.rsplit("-")[0] + cache_updateinfo_xml_path = os.path.join( + repodata_path, xml_file) + map_repo_updateinfoxml[repo_name] = cache_updateinfo_xml_path +@@ -99,7 +99,7 @@ class HotpatchUpdateInfo(object): + Parse the pkglist information, filter the hotpatches with different arches + """ + hotpatches = [] +- hot_patch_collection = pkglist.find('collection') ++ hot_patch_collection = pkglist.find('hot_patch_collection') + arches = self.base.sack.list_arches() + if not hot_patch_collection: + return hotpatches +@@ -171,14 +171,19 @@ class HotpatchUpdateInfo(object): + advisory.cves = advisory_cves + + for hotpatch_kwargs in advisory_hotpatches: ++ # parse the id string of the package to list ++ # e.g. parse the id of "CVE-2021-2023,CVE-2021-2024" to ["CVE-2021-2023", "CVE-2021-2024"] ++ hotpatch_ref_id = hotpatch_kwargs.pop('id') ++ hotpatch_ref_id = hotpatch_ref_id.split(',') ++ + hotpatch = Hotpatch(**hotpatch_kwargs) + hotpatch.advisory = advisory +- hotpatch.cves = advisory_cves.keys() ++ hotpatch.cves = hotpatch_ref_id + + advisory.add_hotpatch(hotpatch) +- +- for cve in advisory_cves.values(): +- cve.hotpatch = hotpatch ++ ++ for ref_id in hotpatch_ref_id: ++ advisory_cves[ref_id].add_hotpatch(hotpatch) + + self._hotpatch_advisories[advisory_kwargs['id']] = advisory + +@@ -213,9 +218,9 @@ class HotpatchUpdateInfo(object): + + def _parse_and_store_from_xml(self, updateinfoxml): + """ +- Parse and store hotpatch update information from xxx-hotpatch.xml.gz ++ Parse and store hotpatch update information from xxx-updateinfo.xml.gz + +- xxx-hotpatch.xml.gz e.g. ++ xxx-updateinfo.xml.gz e.g. + + + +@@ -226,19 +231,26 @@ class HotpatchUpdateInfo(object): + openEuler + + +- ++ ++ + + patch-redis-6.2.5-1-HP001.(CVE-2022-24048) + +- ++ + openEuler +- +- patch-redis-6.2.5-1-HP001-0-1.aarch64.rpm ++ ++ patch-redis-6.2.5-1-HP001-1-1.aarch64.rpm ++ ++ ++ patch-redis-6.2.5-1-HP001-1-1.x86_64.rpm ++ ++ ++ patch-redis-6.2.5-1-HP002-1-1.aarch64.rpm + +- +- patch-redis-6.2.5-1-HP001-0-1.x86_64.rpm ++ ++ patch-redis-6.2.5-1-HP002-1-1.x86_64.rpm + +- ++ + + + ... +@@ -248,6 +260,9 @@ class HotpatchUpdateInfo(object): + tree = ET.parse(content) + root = tree.getroot() + for update in root.iter('update'): ++ # check whether the hotpatch relevant package information is in each advisory ++ if not update.find('pkglist/hot_patch_collection'): ++ continue + advisory = self._parse_advisory(update) + self._store_advisory_info(advisory) + +@@ -288,9 +303,9 @@ class HotpatchUpdateInfo(object): + mapping_cve_hotpatches[cve_id] = [] + if cve_id not in self.hotpatch_cves: + continue +- hotpatch = self.hotpatch_cves[cve_id].hotpatch +- if hotpatch is not None and hotpatch.state == self.INSTALLABLE: +- mapping_cve_hotpatches[cve_id].append(hotpatch.nevra) ++ for hotpatch in self.hotpatch_cves[cve_id].hotpatches: ++ if hotpatch.state == self.INSTALLABLE: ++ mapping_cve_hotpatches[cve_id].append(hotpatch.nevra) + return mapping_cve_hotpatches + + def get_hotpatches_from_advisories(self, advisories: list[str]) -> dict(): +@@ -317,3 +332,4 @@ class HotpatchUpdateInfo(object): + mapping_advisory_hotpatches[advisory_id].append( + hotpatch.nevra) + return mapping_advisory_hotpatches ++ +-- +2.33.0 + diff --git a/aops-apollo.spec b/aops-apollo.spec index 25eb901..28d28b4 100644 --- a/aops-apollo.spec +++ b/aops-apollo.spec @@ -1,11 +1,12 @@ Name: aops-apollo Version: v1.2.1 -Release: 2 +Release: 3 Summary: Cve management service, monitor machine vulnerabilities and provide fix functions. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz Patch0001: 0001-fix-some-apis-which-has-filter-fault.patch +Patch0002: 0002-increase-the-usage-scenarious-of-dnf-hotpatch-plugin.patch BuildRequires: python3-setuptools Requires: aops-vulcanus >= v1.2.0 @@ -76,6 +77,9 @@ cp -r hotpatch %{buildroot}/%{python3_sitelib}/dnf-plugins/ %{python3_sitelib}/aops_apollo_tool/* %changelog +* Fri Jun 2 2023 wang-guangge - v1.2.1-3 +- increase the usage scenarious of dnf-hotpatch-plugin + * Wed May 31 2023 wenxin - v1.2.1-2 - fix issue that can not be filtered by CVE ID when query cve rollbak task info - fix issue that can not be filtered by cve rollback when query task list -- Gitee