!146 [sync] PR-144: improve task execution status code and hotupgrade logic of reinstalling active/accept hotpatch

From: @openeuler-sync-bot 
Reviewed-by: @zhu-yuncheng 
Signed-off-by: @zhu-yuncheng
This commit is contained in:
openeuler-ci-bot 2023-12-22 03:59:38 +00:00 committed by Gitee
commit 47ed6cb37c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 207 additions and 2 deletions

View File

@ -0,0 +1,202 @@
From 2229dade5b178fa2f6a3b572f110eb4fe6677935 Mon Sep 17 00:00:00 2001
From: wang-guangge <wangguangge@huawei.com>
Date: Mon, 18 Dec 2023 21:59:46 +0800
Subject: [PATCH] improve task execution status code and hotupgrade logic of
reinstalling active/accept hotpatch
---
hotpatch/hotupgrade.py | 69 +++++++++++++++++++++++++++++++-----------
hotpatch/upgrade_en.py | 6 ++--
2 files changed, 54 insertions(+), 21 deletions(-)
diff --git a/hotpatch/hotupgrade.py b/hotpatch/hotupgrade.py
index 5dfee0d..37497cf 100644
--- a/hotpatch/hotupgrade.py
+++ b/hotpatch/hotupgrade.py
@@ -13,6 +13,7 @@
from __future__ import print_function
from time import sleep
+from typing import Tuple
import dnf.base
import dnf.exceptions
@@ -28,6 +29,8 @@ from .upgrade_en import UpgradeEnhanceCommand
from .version import Versions
EMPTY_TAG = "-"
+SUCCEED = 0
+FAIL = 255
@dnf.plugin.register_command
@@ -94,9 +97,14 @@ class HotupgradeCommand(dnf.cli.Command):
logger.info(_('No hot patches marked for install.'))
return
- applied_old_patches = self._get_applied_old_patch(list(available_hp_dict.values()))
- if applied_old_patches:
- self._remove_hot_patches(applied_old_patches)
+ uneffectived_old_patches, effectived_old_patches = self._get_applied_old_patch(list(available_hp_dict.values()))
+ # remove effectived hp from self.hp_list and available_hp_dict
+ effectived_hp_list = [key for key, value in available_hp_dict.items() if value in effectived_old_patches]
+ self.hp_list = [hp for hp in self.hp_list if hp not in effectived_hp_list]
+ available_hp_dict = {key: value for key, value in available_hp_dict.items() if value not in effectived_hp_list}
+
+ if uneffectived_old_patches:
+ self._remove_hot_patches(uneffectived_old_patches)
else:
self.syscare.save()
success = self._install_rpm_pkg(list(available_hp_dict.keys()))
@@ -143,14 +151,24 @@ class HotupgradeCommand(dnf.cli.Command):
if str(ts_item.pkg) == self.kernel_coldpatch:
self.is_kernel_coldpatch_installed = True
- self.keep_hp_operation_atomic(is_all_kernel_hp_actived, target_remove_hp)
+ is_task_success = True
+ is_task_success &= self.keep_hp_operation_atomic(is_all_kernel_hp_actived, target_remove_hp)
if self.is_need_accept_kernel_hp and acceptable_hp:
+ is_accept_success = True
logger.info(_('No available kernel cold patch for takeover, gonna accept available kernel hot patch.'))
for hp in acceptable_hp:
- self._accept_kernel_hp(hp)
+ pkg_info = self._parse_hp_name(hp)
+ if pkg_info['target_name'] != "kernel":
+ continue
+ is_accept_success &= False if self._accept_hp(hp) != SUCCEED else True
+ # if need accept operation but failed, it indicates hotupgrade task failed
+ is_task_success &= is_accept_success
+
+ if not is_task_success:
+ exit(1)
- def keep_hp_operation_atomic(self, is_all_kernel_hp_actived, target_remove_hp):
+ def keep_hp_operation_atomic(self, is_all_kernel_hp_actived, target_remove_hp) -> bool:
"""
Keep hotpatch related operation atomic. Once one kernel hotpatch is not successfully activated or
kabi check fails, uninstall the kernel coldpatch. And unsuccessfully activated hotpatch package
@@ -159,9 +177,13 @@ class HotupgradeCommand(dnf.cli.Command):
Args:
is_all_kernel_hp_actived(bool): are all kernel related hotpatches activated
target_remove_hp(list): target remove hotpatch list
+
+ Returns:
+ bool: if hotupgrade task success
"""
upgrade_en = UpgradeEnhanceCommand(self.cli)
+ is_task_success = True
if self.is_kernel_coldpatch_installed:
if not is_all_kernel_hp_actived:
logger.info(_('Gonna remove %s due to some kernel hotpatch activation failed.'), self.kernel_coldpatch)
@@ -177,8 +199,12 @@ class HotupgradeCommand(dnf.cli.Command):
if target_remove_hp:
logger.info(_('Gonna remove unsuccessfully activated hotpatch rpm.'))
+ # when processing remove operation, do not achieve the expected result of activating hotpatch rpm,
+ # it indicates that the hotupgrade task failed
+ is_task_success &= False
for hotpatch in target_remove_hp:
upgrade_en.remove_rpm(hotpatch)
+ return is_task_success
def _apply_hp(self, hp_full_name):
pkg_info = self._parse_hp_name(hp_full_name)
@@ -264,7 +290,7 @@ class HotupgradeCommand(dnf.cli.Command):
return hp_map
@staticmethod
- def _get_applied_old_patch(available_hp_list: list) -> list:
+ def _get_applied_old_patch(available_hp_list: list) -> Tuple[list, list]:
"""
get targets' applied accumulative hot patches.
User can install and apply multiple sgl (single) hot patches because the rpm name is different,
@@ -273,9 +299,11 @@ class HotupgradeCommand(dnf.cli.Command):
available_hp_list: e.g. ['redis-1.0-1/ACC-1-1', 'redis-1.0-1/SGL_CVE_2022_1-1-1']
Returns:
- list: applied hot patches. e.g. ['redis-1.0-1/ACC-1-1']
+ Tuple[str, str]: a tuple containing two elements (uneffectived hot patches, effectived hot patches).
+ e.g. (['redis-1.0-1/ACC-1-1'], ['redis-1.0-1/SGL_CVE_2022_3047-1-1'])
"""
- hotpatch_set = set()
+ uneffectived_hotpatch_set = set()
+ effectived_hotpatch_set = set()
hps_info = Syscare.list()
for hp_info in hps_info:
# hp_info[Name] is the middle column of syscare list. format: {target_rpm_name}/{hp_name}/{binary_file}
@@ -297,9 +325,12 @@ class HotupgradeCommand(dnf.cli.Command):
hp_info["Status"],
binary_file,
)
- if hotpatch not in hotpatch_set:
- hotpatch_set.add(hotpatch)
- return list(hotpatch_set)
+ if hp_info["Status"] in ["ACTIVED", "ACCEPTED"]:
+ effectived_hotpatch_set.add(hotpatch)
+ continue
+ if hotpatch not in uneffectived_hotpatch_set:
+ uneffectived_hotpatch_set.add(hotpatch)
+ return list(uneffectived_hotpatch_set), list(effectived_hotpatch_set)
def _remove_hot_patches(self, applied_old_patches: list) -> None:
# output = Output(self.base, dnf.conf.Conf())
@@ -548,19 +579,21 @@ class HotupgradeCommand(dnf.cli.Command):
parsed_nevra = parsed_nevras[0]
return parsed_nevra.name, "%s-%s" % (parsed_nevra.version, parsed_nevra.release)
- def _accept_kernel_hp(self, hp_full_name: str):
+ def _accept_hp(self, hp_full_name: str) -> int:
"""
- accept kernel hot patch
+ accept hot patch
Args:
str: hp_full_name: full name of hot patch. e.g. patch-kernel-5.10.0-1-ACC-1-1.x86_64
+
+ Returns:
+ int: status
"""
pkg_info = self._parse_hp_name(hp_full_name)
- if pkg_info['target_name'] != "kernel":
- return
hp_subname = self._get_hp_subname_for_syscare(pkg_info)
output, status = self.syscare.accept(hp_subname)
if status:
- logger.info(_('Accept kernel hot patch failed: %s.'), hp_subname)
+ logger.info(_('Accept hot patch failed: %s.'), hp_subname)
else:
- logger.info(_('Accept kernel hot patch succeed: %s.'), hp_subname)
+ logger.info(_('Accept hot patch succeed: %s.'), hp_subname)
+ return status
diff --git a/hotpatch/upgrade_en.py b/hotpatch/upgrade_en.py
index 3053179..94ba4da 100644
--- a/hotpatch/upgrade_en.py
+++ b/hotpatch/upgrade_en.py
@@ -97,7 +97,10 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
print('Gonna remove %s due to kabi check failed.' % kernel_pkg)
# rebuild rpm database for processing kernel rpm remove operation
self.rebuild_rpm_db()
+ # when processing remove operation, do not achieve the expected result of installing related rpm,
+ # it indicates that the upgrade task failed
self.remove_rpm(kernel_pkg)
+ exit(1)
def remove_rpm(self, pkg: str):
"""
@@ -113,11 +116,8 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
if return_code != SUCCEED:
print('Remove package failed: %s.' % pkg)
print(output)
- exit(1)
else:
print('Remove package succeed: %s.' % pkg)
- # do not achieve the expected result of installing related rpm
- exit(1)
def rebuild_rpm_db(self):
"""
--
2.27.0

View File

@ -2,7 +2,7 @@
Name: aops-ceres Name: aops-ceres
Version: v1.4.1 Version: v1.4.1
Release: 1 Release: 2
Summary: An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on. Summary: An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on.
License: MulanPSL2 License: MulanPSL2
URL: https://gitee.com/openeuler/%{name} URL: https://gitee.com/openeuler/%{name}
@ -13,7 +13,7 @@ Requires: python3-requests python3-jsonschema python3-libconf
Requires: python3-concurrent-log-handler dmidecode dnf-hotpatch-plugin >= v1.3.4 Requires: python3-concurrent-log-handler dmidecode dnf-hotpatch-plugin >= v1.3.4
Provides: aops-ceres Provides: aops-ceres
Conflicts: aops-agent Conflicts: aops-agent
Patch0001: 0001-improve-status-judgement-and-hotupgrade-logic.patch
%description %description
An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on. An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on.
@ -86,6 +86,9 @@ install -b -m500 ./extra-tools/da-tool/script/da-tool.sh ${RPM_BUILD_ROOT}
%attr(0500, root, root) %{_bindir}/da-tool-analysis %attr(0500, root, root) %{_bindir}/da-tool-analysis
%changelog %changelog
* Mon Dec 18 2023 wangguangge<wangguangge@huawei.com> - v1.4.1-2
- improve task execution status code and hotupgrade logic of reinstalling active/accept hotpatch
* Mon Dec 18 2023 wangguangge<wangguangge@huawei.com> - v1.4.1-1 * Mon Dec 18 2023 wangguangge<wangguangge@huawei.com> - v1.4.1-1
- update to v1.4.1 - update to v1.4.1
- update cve fix logic - update cve fix logic