Compare commits
No commits in common. "d4c1987b22ef3ca22d86576c80c9f0560e5e0889" and "1bdae04cc4f8d5409d1bbd1fc56f17e5a48220a3" have entirely different histories.
d4c1987b22
...
1bdae04cc4
@ -1,202 +0,0 @@
|
|||||||
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
|
|
||||||
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
From 2c3dcc5bb5de4d3f83902bb8cb7f0fe1fa9a55b9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: wang-guangge <wangguangge@huawei.com>
|
|
||||||
Date: Tue, 19 Dec 2023 21:03:48 +0800
|
|
||||||
Subject: [PATCH] support restore default boot kernel if kabi check failed
|
|
||||||
|
|
||||||
---
|
|
||||||
hotpatch/hotupgrade.py | 19 ++++++++-----
|
|
||||||
hotpatch/upgrade_en.py | 61 ++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
2 files changed, 73 insertions(+), 7 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/hotpatch/hotupgrade.py b/hotpatch/hotupgrade.py
|
|
||||||
index 37497cf..4e1ea96 100644
|
|
||||||
--- a/hotpatch/hotupgrade.py
|
|
||||||
+++ b/hotpatch/hotupgrade.py
|
|
||||||
@@ -43,6 +43,7 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
is_need_accept_kernel_hp = False
|
|
||||||
is_kernel_coldpatch_installed = False
|
|
||||||
kernel_coldpatch = ''
|
|
||||||
+ previous_boot_kernel = None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def set_argparser(parser):
|
|
||||||
@@ -80,6 +81,9 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
commands._checkEnabledRepo(self.base)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
+ self.upgrade_en = UpgradeEnhanceCommand(self.cli)
|
|
||||||
+ self.previous_boot_kernel = self.upgrade_en.get_default_boot_kernel()
|
|
||||||
+
|
|
||||||
if self.opts.pkg_specs:
|
|
||||||
self.hp_list = self.opts.pkg_specs
|
|
||||||
elif self.opts.cves or self.opts.advisory:
|
|
||||||
@@ -181,20 +185,21 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
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)
|
|
||||||
- upgrade_en.remove_rpm(str(self.kernel_coldpatch))
|
|
||||||
+ self.upgrade_en.rebuild_rpm_db()
|
|
||||||
+ self.upgrade_en.remove_rpm(str(self.kernel_coldpatch))
|
|
||||||
+ self.upgrade_en.restore_default_boot_kernel(self.previous_boot_kernel)
|
|
||||||
self.is_need_accept_kernel_hp = False
|
|
||||||
# process kabi check
|
|
||||||
- elif not upgrade_en.kabi_check(str(self.kernel_coldpatch)) and not self.opts.force:
|
|
||||||
+ elif not self.upgrade_en.kabi_check(str(self.kernel_coldpatch)) and not self.opts.force:
|
|
||||||
logger.info(_('Gonna remove %s due to Kabi check failed.'), self.kernel_coldpatch)
|
|
||||||
# rebuild rpm database for processing kernel rpm remove operation
|
|
||||||
- upgrade_en.rebuild_rpm_db()
|
|
||||||
- upgrade_en.remove_rpm(str(self.kernel_coldpatch))
|
|
||||||
+ self.upgrade_en.rebuild_rpm_db()
|
|
||||||
+ self.upgrade_en.remove_rpm(str(self.kernel_coldpatch))
|
|
||||||
+ self.upgrade_en.restore_default_boot_kernel(self.previous_boot_kernel)
|
|
||||||
self.is_need_accept_kernel_hp = True
|
|
||||||
|
|
||||||
if target_remove_hp:
|
|
||||||
@@ -203,7 +208,7 @@ class HotupgradeCommand(dnf.cli.Command):
|
|
||||||
# it indicates that the hotupgrade task failed
|
|
||||||
is_task_success &= False
|
|
||||||
for hotpatch in target_remove_hp:
|
|
||||||
- upgrade_en.remove_rpm(hotpatch)
|
|
||||||
+ self.upgrade_en.remove_rpm(hotpatch)
|
|
||||||
return is_task_success
|
|
||||||
|
|
||||||
def _apply_hp(self, hp_full_name):
|
|
||||||
diff --git a/hotpatch/upgrade_en.py b/hotpatch/upgrade_en.py
|
|
||||||
index 94ba4da..0bd78cc 100644
|
|
||||||
--- a/hotpatch/upgrade_en.py
|
|
||||||
+++ b/hotpatch/upgrade_en.py
|
|
||||||
@@ -12,6 +12,7 @@
|
|
||||||
# ******************************************************************************/
|
|
||||||
import gzip
|
|
||||||
import subprocess
|
|
||||||
+from typing import Optional
|
|
||||||
|
|
||||||
import dnf
|
|
||||||
from dnf.cli import commands
|
|
||||||
@@ -36,6 +37,7 @@ def cmd_output(cmd):
|
|
||||||
@dnf.plugin.register_command
|
|
||||||
class UpgradeEnhanceCommand(dnf.cli.Command):
|
|
||||||
SYMVERS_FILE = "/boot/symvers-%s.gz"
|
|
||||||
+ previous_boot_kernel = None
|
|
||||||
|
|
||||||
aliases = ['upgrade-en']
|
|
||||||
summary = _(
|
|
||||||
@@ -80,8 +82,65 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
|
|
||||||
self.skipped_grp_specs = None
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
+ # if kernel kabi check failed, need change back to the default boot kernel version
|
|
||||||
+ self.previous_boot_kernel = self.get_default_boot_kernel()
|
|
||||||
self.upgrade()
|
|
||||||
|
|
||||||
+ @staticmethod
|
|
||||||
+ def get_default_boot_kernel() -> Optional[str]:
|
|
||||||
+ """
|
|
||||||
+ Get default boot kernel version.
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ str: default boot kernel
|
|
||||||
+ """
|
|
||||||
+ cmd = ["grubby", "--default-kernel"]
|
|
||||||
+ # 'grubby --default-kernel' shows boot default kernel version in the system
|
|
||||||
+ # e.g.
|
|
||||||
+ # [root@openEuler ~]# grubby --default-kernel
|
|
||||||
+ # /boot/vmlinuz-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
+ output, return_code = cmd_output(cmd)
|
|
||||||
+ default_boot_kernel = output.split('\n')[0]
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ return None
|
|
||||||
+ return default_boot_kernel
|
|
||||||
+
|
|
||||||
+ @staticmethod
|
|
||||||
+ def restore_default_boot_kernel(target_boot_kernel: str):
|
|
||||||
+ """
|
|
||||||
+ Restore default boot kernel version.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ target_boot_kernel(str): target boot kernel
|
|
||||||
+ """
|
|
||||||
+ # 'grubby --set-default=/boot/vmlinuz-4.19.90-2112.8.0.0131.oe1.x86_64' can set default boot kernel version
|
|
||||||
+ # to kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
+ if not target_boot_kernel:
|
|
||||||
+ print("Get default boot kernel before upgrade failed.")
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ cmd = ["grubby", "--set-default=%s" % target_boot_kernel]
|
|
||||||
+ try:
|
|
||||||
+ # e.g. 4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
+ target_boot_kernel_vere = target_boot_kernel.split('-', 1)[1]
|
|
||||||
+ target_boot_kernel_nevra = "kernel-%s" % target_boot_kernel_vere
|
|
||||||
+ except IndexError as e:
|
|
||||||
+ print(
|
|
||||||
+ "Parse target boot kernel failed. Please check if target boot kernel path is correct: %s."
|
|
||||||
+ % target_boot_kernel,
|
|
||||||
+ "\nRestore the default boot kernel failed. Please manually check the default boot kernel to prevent unexpected kernel switching after reboot.",
|
|
||||||
+ )
|
|
||||||
+ return
|
|
||||||
+
|
|
||||||
+ output, return_code = cmd_output(cmd)
|
|
||||||
+ if return_code != SUCCEED:
|
|
||||||
+ print(
|
|
||||||
+ "Restore the default boot kernel failed: %s. Please manually check the default boot kernel to prevent unexpected kernel switching after reboot."
|
|
||||||
+ % target_boot_kernel_nevra
|
|
||||||
+ )
|
|
||||||
+ return
|
|
||||||
+ print("Restore the default boot kernel succeed: %s." % target_boot_kernel_nevra)
|
|
||||||
+
|
|
||||||
def run_transaction(self):
|
|
||||||
"""
|
|
||||||
Process kabi check for kernel rpm package installed this time. If the kernel rpm pakcgae fails kabi check,
|
|
||||||
@@ -100,6 +159,8 @@ class UpgradeEnhanceCommand(dnf.cli.Command):
|
|
||||||
# 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)
|
|
||||||
+ # change back to the default boot kernel version before upgrade
|
|
||||||
+ self.restore_default_boot_kernel(self.previous_boot_kernel)
|
|
||||||
exit(1)
|
|
||||||
|
|
||||||
def remove_rpm(self, pkg: str):
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,152 +0,0 @@
|
|||||||
From 88f2784a4673edb9ff0a185ea43beccb5108ece0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: wang-guangge <wangguangge@huawei.com>
|
|
||||||
Date: Fri, 22 Dec 2023 18:44:27 +0800
|
|
||||||
Subject: [PATCH] improve rollback_manage.py
|
|
||||||
|
|
||||||
---
|
|
||||||
ceres/manages/rollback_manage.py | 73 ++++++++++++++++++++++++++------
|
|
||||||
1 file changed, 61 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ceres/manages/rollback_manage.py b/ceres/manages/rollback_manage.py
|
|
||||||
index 0f30d29..160a74c 100644
|
|
||||||
--- a/ceres/manages/rollback_manage.py
|
|
||||||
+++ b/ceres/manages/rollback_manage.py
|
|
||||||
@@ -237,19 +237,67 @@ class RollbackManage:
|
|
||||||
log.append(result_log)
|
|
||||||
if result_code != TaskExecuteRes.SUCCEED:
|
|
||||||
return TaskExecuteRes.FAIL, os.linesep.join(log)
|
|
||||||
+
|
|
||||||
+ result_code, result_log = self._remove_kernel_rpm(installed_rpm)
|
|
||||||
+ if result_log:
|
|
||||||
+ log.append(result_log)
|
|
||||||
+ if result_code != TaskExecuteRes.SUCCEED:
|
|
||||||
+ return TaskExecuteRes.FAIL, os.linesep.join(log)
|
|
||||||
|
|
||||||
result_code, result_log = self._change_boot_kernel_version(target_rpm)
|
|
||||||
if result_log:
|
|
||||||
log.append(result_log)
|
|
||||||
if result_code != TaskExecuteRes.SUCCEED:
|
|
||||||
return TaskExecuteRes.FAIL, os.linesep.join(log)
|
|
||||||
-
|
|
||||||
+
|
|
||||||
return TaskExecuteRes.SUCCEED, os.linesep.join(log)
|
|
||||||
-
|
|
||||||
+
|
|
||||||
+ def _remove_kernel_rpm(self, installed_rpm: str) -> Tuple[str, str]:
|
|
||||||
+ """
|
|
||||||
+ Remove the kernel rpm if the installed kernel rpm is not in use.
|
|
||||||
+
|
|
||||||
+ Args:
|
|
||||||
+ installed_rpm(str): the installed kernel in executed fix task
|
|
||||||
+
|
|
||||||
+ Returns:
|
|
||||||
+ Tuple[str, str]: a tuple containing two elements (remove result, log)
|
|
||||||
+ """
|
|
||||||
+ code, stdout, stderr = execute_shell_command(f"rpm -qa | grep {installed_rpm}")
|
|
||||||
+ # 'rpm -qa' shows installed rpm
|
|
||||||
+ # e.g.
|
|
||||||
+ # [root@openEuler ~]# rpm -qa | grep kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
+ # kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
+ if code != CommandExitCode.SUCCEED or installed_rpm not in stdout:
|
|
||||||
+ tmp_log = f"The {installed_rpm} is not installed. Please check the input parameter."
|
|
||||||
+ LOGGER.error(tmp_log)
|
|
||||||
+ return TaskExecuteRes.FAIL, tmp_log
|
|
||||||
+
|
|
||||||
+ code, current_evra, stderr = execute_shell_command(f"uname -r")
|
|
||||||
+ # 'uname -r' show the kernel version-release.arch of the current system
|
|
||||||
+ # e.g.
|
|
||||||
+ # [root@openEuler ~]# uname -r
|
|
||||||
+ # 5.10.0-136.12.0.86.oe2203sp1.x86_64
|
|
||||||
+ if code != CommandExitCode.SUCCEED:
|
|
||||||
+ LOGGER.error(stderr)
|
|
||||||
+ return TaskExecuteRes.FAIL, current_evra + stderr
|
|
||||||
+
|
|
||||||
+ # version-release.arch
|
|
||||||
+ installed_evra = installed_rpm.split("-", 1)[1]
|
|
||||||
+
|
|
||||||
+ if installed_evra == current_evra:
|
|
||||||
+ return TaskExecuteRes.SUCCEED, f"Preserve the {installed_rpm} due to it is in use."
|
|
||||||
+
|
|
||||||
+ code, stdout, stderr = execute_shell_command(f"dnf remove {installed_rpm} -y")
|
|
||||||
+ if code != CommandExitCode.SUCCEED:
|
|
||||||
+ LOGGER.error(stderr)
|
|
||||||
+ return TaskExecuteRes.FAIL, stdout + stderr
|
|
||||||
+
|
|
||||||
+ return TaskExecuteRes.SUCCEED, stdout
|
|
||||||
+
|
|
||||||
def _check_boot_kernel_version(self, installed_rpm: str) -> Tuple[str, str]:
|
|
||||||
"""
|
|
||||||
Check if the boot kernel version is consistent with the installed kernel version. If not, it indicates
|
|
||||||
- that the executed fix task has been tampered.
|
|
||||||
+ that the environment after executed fix task has been tampered.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
installed_rpm(str): the installed rpm in executed fix task
|
|
||||||
@@ -270,8 +318,8 @@ class RollbackManage:
|
|
||||||
evra = installed_rpm.split("-", 1)[1]
|
|
||||||
if evra not in stdout:
|
|
||||||
tmp_log = (
|
|
||||||
- "The grubby default kernel version is not consistent with installed kernel version. "
|
|
||||||
- "The executed fix task has been tampered."
|
|
||||||
+ f"The default boot kernel version is not consistent with {installed_rpm}. "
|
|
||||||
+ "The environment after executed fix task has been tampered."
|
|
||||||
)
|
|
||||||
LOGGER.error(tmp_log)
|
|
||||||
return TaskExecuteRes.FAIL, tmp_log
|
|
||||||
@@ -281,7 +329,7 @@ class RollbackManage:
|
|
||||||
def _check_current_kernel_version(self, installed_rpm: str, target_rpm: str) -> Tuple[str, str]:
|
|
||||||
"""
|
|
||||||
Check if the current kernel version is consistent with the installed kernel version or target kernel
|
|
||||||
- version. If not, it indicates that the executed fix task has been tampered.
|
|
||||||
+ version. If not, it indicates that the environment after executed fix task has been tampered.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
installed_rpm(str): the installed rpm in executed fix task
|
|
||||||
@@ -304,8 +352,8 @@ class RollbackManage:
|
|
||||||
|
|
||||||
if installed_evra != current_evra and target_evra != current_evra:
|
|
||||||
tmp_log = (
|
|
||||||
- "The current kernel version is not consistent with installed kernel version or target kernel version. "
|
|
||||||
- "The executed fix task has been tampered."
|
|
||||||
+ f"The current kernel version is neither {installed_rpm} nor {target_rpm}. "
|
|
||||||
+ "The environment after executed fix task has been tampered."
|
|
||||||
)
|
|
||||||
LOGGER.error(tmp_log)
|
|
||||||
return TaskExecuteRes.FAIL, tmp_log
|
|
||||||
@@ -314,7 +362,8 @@ class RollbackManage:
|
|
||||||
|
|
||||||
def _check_if_target_rpm_installed(self, target_rpm: str) -> Tuple[str, str]:
|
|
||||||
"""
|
|
||||||
- Check if the target kernel is installed. If not, it indicates that the executed fix task has been tampered.
|
|
||||||
+ Check if the target kernel is installed. If not, it indicates that the environment after executed fix
|
|
||||||
+ task has been tampered.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
target_rpm(str): the target rpm for rollback task
|
|
||||||
@@ -328,7 +377,7 @@ class RollbackManage:
|
|
||||||
# [root@openEuler ~]# rpm -qa | grep kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
# kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
if code != CommandExitCode.SUCCEED or target_rpm not in stdout:
|
|
||||||
- tmp_log = "The target kernel of rollback task is not installed. The executed fix task has been tampered."
|
|
||||||
+ tmp_log = "The target kernel of rollback task is not installed. The environment after executed fix task has been tampered."
|
|
||||||
LOGGER.error(tmp_log)
|
|
||||||
return TaskExecuteRes.FAIL, tmp_log
|
|
||||||
|
|
||||||
@@ -336,7 +385,7 @@ class RollbackManage:
|
|
||||||
|
|
||||||
def _change_boot_kernel_version(self, target_rpm: str) -> Tuple[str, str]:
|
|
||||||
"""
|
|
||||||
- Change the grubby default kernel version to target kernel version.
|
|
||||||
+ Change the default boot kernel version to target kernel version.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
target_rpm(str): the target rpm for rollback task
|
|
||||||
@@ -358,4 +407,4 @@ class RollbackManage:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return TaskExecuteRes.FAIL, stdout + stderr
|
|
||||||
|
|
||||||
- return TaskExecuteRes.SUCCEED, f"Change boot kernel version to {target_rpm} successfully."
|
|
||||||
+ return TaskExecuteRes.SUCCEED, f"Change default boot kernel version to {target_rpm} successfully."
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,486 +0,0 @@
|
|||||||
From d5c2db0af6d62a85c35c6cfe3e7af55edddf3b91 Mon Sep 17 00:00:00 2001
|
|
||||||
From: rabbitali <wenxin32@foxmail.com>
|
|
||||||
Date: Sun, 4 Feb 2024 00:39:26 +0800
|
|
||||||
Subject: [PATCH 1/1] fix cve-2021-33633
|
|
||||||
|
|
||||||
---
|
|
||||||
ceres/function/check.py | 4 +--
|
|
||||||
ceres/function/util.py | 11 ++++----
|
|
||||||
ceres/manages/collect_manage.py | 18 ++++++-------
|
|
||||||
ceres/manages/list_file_manage.py | 2 +-
|
|
||||||
ceres/manages/plugin_manage.py | 8 +++---
|
|
||||||
ceres/manages/resource_manage.py | 4 +--
|
|
||||||
ceres/manages/rollback_manage.py | 16 +++++------
|
|
||||||
ceres/manages/vulnerability_manage.py | 38 +++++++++++++--------------
|
|
||||||
8 files changed, 50 insertions(+), 51 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ceres/function/check.py b/ceres/function/check.py
|
|
||||||
index 20978f5..18b9561 100644
|
|
||||||
--- a/ceres/function/check.py
|
|
||||||
+++ b/ceres/function/check.py
|
|
||||||
@@ -61,14 +61,14 @@ class PreCheck(object):
|
|
||||||
"""
|
|
||||||
# Example of command execution result::
|
|
||||||
# /boot/vmlinuz-5.10.0-60.18.0.50.oe2203.x86_64
|
|
||||||
- code, boot_kernel_version, stderr = execute_shell_command("grubby --default-kernel")
|
|
||||||
+ code, boot_kernel_version, stderr = execute_shell_command(["grubby --default-kernel"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return False, "Query boot kernel info failed!"
|
|
||||||
|
|
||||||
# Example of command execution result::
|
|
||||||
# 5.10.0-60.18.0.50.oe2203.x86_64
|
|
||||||
- code, current_kernel_version, stderr = execute_shell_command("uname -r")
|
|
||||||
+ code, current_kernel_version, stderr = execute_shell_command(["uname -r"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return False, "Query current kernel info failed!"
|
|
||||||
diff --git a/ceres/function/util.py b/ceres/function/util.py
|
|
||||||
index 433db09..1d3d9e3 100644
|
|
||||||
--- a/ceres/function/util.py
|
|
||||||
+++ b/ceres/function/util.py
|
|
||||||
@@ -15,7 +15,7 @@ import json
|
|
||||||
import os
|
|
||||||
import shlex
|
|
||||||
import subprocess
|
|
||||||
-from typing import Any, Tuple, NoReturn
|
|
||||||
+from typing import Any, Tuple, NoReturn, Sequence
|
|
||||||
|
|
||||||
from libconf import load, ConfigParseError, AttrDict
|
|
||||||
from jsonschema import validate, ValidationError
|
|
||||||
@@ -63,12 +63,12 @@ def validate_data(data: Any, schema: dict) -> bool:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
-def execute_shell_command(command: str, **kwargs) -> Tuple[int, str, str]:
|
|
||||||
+def execute_shell_command(commands: Sequence[str], **kwargs) -> Tuple[int, str, str]:
|
|
||||||
"""
|
|
||||||
execute shell commands
|
|
||||||
|
|
||||||
Args:
|
|
||||||
- command(str): shell command which needs to execute
|
|
||||||
+ command(Sequence[str]): Multiple shell commands that need to be executed continuously
|
|
||||||
**kwargs: keyword arguments, it is used to create Popen object.supported options: env, cwd, bufsize, group and
|
|
||||||
so on. you can see more options information in annotation of Popen obejct.
|
|
||||||
|
|
||||||
@@ -77,11 +77,10 @@ def execute_shell_command(command: str, **kwargs) -> Tuple[int, str, str]:
|
|
||||||
a tuple containing three elements (return code, standard output, standard error).
|
|
||||||
|
|
||||||
Example usage:
|
|
||||||
- >>> return_code, stdout, stderr = execute_shell_command("ls -al|wc -l", **{"env": {"LANG": "en_US.utf-8"}})
|
|
||||||
+ >>> return_code, stdout, stderr = execute_shell_command(["ls -al", "wc -l"], **{"env": {"LANG": "en_US.utf-8"}})
|
|
||||||
>>> print(return_code, stdout, stderr)
|
|
||||||
0, 42, ""
|
|
||||||
"""
|
|
||||||
- commands = command.split('|')
|
|
||||||
process = None
|
|
||||||
stdout_data = ""
|
|
||||||
stderr_data = ""
|
|
||||||
@@ -153,7 +152,7 @@ def plugin_status_judge(plugin_name: str) -> str:
|
|
||||||
if service_name is None:
|
|
||||||
LOGGER.warning(f"Fail to get service name about {plugin_name}")
|
|
||||||
return ""
|
|
||||||
- return_code, stdout, _ = execute_shell_command(f"systemctl status {service_name}|grep Active")
|
|
||||||
+ return_code, stdout, _ = execute_shell_command([f"systemctl status {service_name}", "grep Active"])
|
|
||||||
|
|
||||||
if return_code == CommandExitCode.SUCCEED:
|
|
||||||
return stdout
|
|
||||||
diff --git a/ceres/manages/collect_manage.py b/ceres/manages/collect_manage.py
|
|
||||||
index e702120..b2ba350 100644
|
|
||||||
--- a/ceres/manages/collect_manage.py
|
|
||||||
+++ b/ceres/manages/collect_manage.py
|
|
||||||
@@ -104,7 +104,7 @@ class Collect:
|
|
||||||
Returns:
|
|
||||||
str: e.g openEuler 21.09
|
|
||||||
"""
|
|
||||||
- _, stdout, _ = execute_shell_command("cat /etc/os-release")
|
|
||||||
+ _, stdout, _ = execute_shell_command(["cat /etc/os-release"])
|
|
||||||
res = re.search('(?=PRETTY_NAME=).+', stdout)
|
|
||||||
|
|
||||||
if res:
|
|
||||||
@@ -140,7 +140,7 @@ class Collect:
|
|
||||||
Returns:
|
|
||||||
str
|
|
||||||
"""
|
|
||||||
- _, stdout, _ = execute_shell_command("dmidecode -t bios")
|
|
||||||
+ _, stdout, _ = execute_shell_command(["dmidecode -t bios"])
|
|
||||||
|
|
||||||
res = re.search('(?=Version:).+', stdout)
|
|
||||||
if res:
|
|
||||||
@@ -156,7 +156,7 @@ class Collect:
|
|
||||||
Returns:
|
|
||||||
str
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command("uname -r")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["uname -r"])
|
|
||||||
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.warning('Failed to get current kernel version, please check uname command and try again')
|
|
||||||
@@ -181,7 +181,7 @@ class Collect:
|
|
||||||
"l3_cache": string
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
- _, stdout, _ = execute_shell_command("lscpu", **{"env": {"LANG": "en_US.utf-8"}})
|
|
||||||
+ _, stdout, _ = execute_shell_command(["lscpu"], **{"env": {"LANG": "en_US.utf-8"}})
|
|
||||||
|
|
||||||
info_list = re.findall('.+:.+', stdout)
|
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ class Collect:
|
|
||||||
Returns:
|
|
||||||
str: memory size
|
|
||||||
"""
|
|
||||||
- _, stdout, _ = execute_shell_command("lsmem")
|
|
||||||
+ _, stdout, _ = execute_shell_command(["lsmem"])
|
|
||||||
|
|
||||||
res = re.search("(?=Total online memory:).+", stdout)
|
|
||||||
if res:
|
|
||||||
@@ -245,7 +245,7 @@ class Collect:
|
|
||||||
"""
|
|
||||||
res = {'size': self.__get_total_online_memory() or None, "total": None, "info": []}
|
|
||||||
|
|
||||||
- code, memory_data, _ = execute_shell_command("dmidecode -t memory")
|
|
||||||
+ code, memory_data, _ = execute_shell_command(["dmidecode -t memory"])
|
|
||||||
|
|
||||||
# dmidecode -t memory
|
|
||||||
# e.g
|
|
||||||
@@ -306,7 +306,7 @@ class Collect:
|
|
||||||
}
|
|
||||||
]
|
|
||||||
"""
|
|
||||||
- code, stdout, _ = execute_shell_command("lshw -xml -c disk")
|
|
||||||
+ code, stdout, _ = execute_shell_command(["lshw -xml -c disk"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stdout)
|
|
||||||
return []
|
|
||||||
@@ -384,7 +384,7 @@ class Collect:
|
|
||||||
Returns:
|
|
||||||
uuid(str)
|
|
||||||
"""
|
|
||||||
- code, stdout, _ = execute_shell_command("dmidecode|grep UUID")
|
|
||||||
+ code, stdout, _ = execute_shell_command(["dmidecode", "grep UUID"])
|
|
||||||
if code == CommandExitCode.SUCCEED:
|
|
||||||
return stdout.replace("-", "").split(':')[1].strip()
|
|
||||||
return ""
|
|
||||||
@@ -420,7 +420,7 @@ class Collect:
|
|
||||||
}]
|
|
||||||
"""
|
|
||||||
|
|
||||||
- code, source_name_info, _ = execute_shell_command("rpm -qi kernel|grep .src.rpm")
|
|
||||||
+ code, source_name_info, _ = execute_shell_command(["rpm -qi kernel", "grep .src.rpm"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("Failed to query installed packages.")
|
|
||||||
return []
|
|
||||||
diff --git a/ceres/manages/list_file_manage.py b/ceres/manages/list_file_manage.py
|
|
||||||
index 3d7fd21..dab55e6 100644
|
|
||||||
--- a/ceres/manages/list_file_manage.py
|
|
||||||
+++ b/ceres/manages/list_file_manage.py
|
|
||||||
@@ -40,7 +40,7 @@ class ListFileManage:
|
|
||||||
"""
|
|
||||||
file_list_res = []
|
|
||||||
try:
|
|
||||||
- command = "ls -l " + directory_path + " | awk '{print $9}'"
|
|
||||||
+ command = [f"ls -l {directory_path}", "awk '{print $9}'"]
|
|
||||||
_, stdout, _ = execute_shell_command(command)
|
|
||||||
file_list = stdout.split("\n")
|
|
||||||
for file in file_list:
|
|
||||||
diff --git a/ceres/manages/plugin_manage.py b/ceres/manages/plugin_manage.py
|
|
||||||
index ed7b2ab..fb06220 100644
|
|
||||||
--- a/ceres/manages/plugin_manage.py
|
|
||||||
+++ b/ceres/manages/plugin_manage.py
|
|
||||||
@@ -52,7 +52,7 @@ class Plugin:
|
|
||||||
if "running" in plugin_status:
|
|
||||||
return SUCCESS
|
|
||||||
|
|
||||||
- code, _, _ = execute_shell_command(f"systemctl start {self.rpm_name}")
|
|
||||||
+ code, _, _ = execute_shell_command([f"systemctl start {self.rpm_name}"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
return FAIL
|
|
||||||
return SUCCESS
|
|
||||||
@@ -68,7 +68,7 @@ class Plugin:
|
|
||||||
if "inactive" in plugin_status:
|
|
||||||
return SUCCESS
|
|
||||||
|
|
||||||
- code, _, _ = execute_shell_command(f"systemctl stop {self.rpm_name}")
|
|
||||||
+ code, _, _ = execute_shell_command([f"systemctl stop {self.rpm_name}"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
return FAIL
|
|
||||||
return SUCCESS
|
|
||||||
@@ -100,7 +100,7 @@ class Plugin:
|
|
||||||
str: dead or running
|
|
||||||
|
|
||||||
"""
|
|
||||||
- code, stdout, _ = execute_shell_command(f"systemctl status {self.rpm_name}|grep Active")
|
|
||||||
+ code, stdout, _ = execute_shell_command([f"systemctl status {self.rpm_name}", "grep Active"])
|
|
||||||
if code == CommandExitCode.SUCCEED:
|
|
||||||
return re.search(r':.+\(', stdout).group()[1:-1].strip()
|
|
||||||
LOGGER.error(f'Failed to get service {self.rpm_name} status!')
|
|
||||||
@@ -114,7 +114,7 @@ class Plugin:
|
|
||||||
Returns:
|
|
||||||
The str type of main process id
|
|
||||||
"""
|
|
||||||
- code, main_pid_info, _ = execute_shell_command(f"systemctl status {rpm_name}|grep Main")
|
|
||||||
+ code, main_pid_info, _ = execute_shell_command([f"systemctl status {rpm_name}", "grep Main"])
|
|
||||||
if code == CommandExitCode.SUCCEED:
|
|
||||||
return re.search("[0-9]+[0-9]", main_pid_info).group()
|
|
||||||
LOGGER.error(f"Failed to get {rpm_name} pid")
|
|
||||||
diff --git a/ceres/manages/resource_manage.py b/ceres/manages/resource_manage.py
|
|
||||||
index 5766744..e9c6256 100644
|
|
||||||
--- a/ceres/manages/resource_manage.py
|
|
||||||
+++ b/ceres/manages/resource_manage.py
|
|
||||||
@@ -32,7 +32,7 @@ class Resource:
|
|
||||||
Returns:
|
|
||||||
str:The memory value which has used
|
|
||||||
"""
|
|
||||||
- code, stdout, _ = execute_shell_command(f"cat /proc/{pid}/status|grep VmRSS")
|
|
||||||
+ code, stdout, _ = execute_shell_command([f"cat /proc/{pid}/status", "grep VmRSS"])
|
|
||||||
if code == CommandExitCode.SUCCEED:
|
|
||||||
return stdout.split(":")[1].strip()
|
|
||||||
LOGGER.error(f'Failed to get memory info of process {pid}!')
|
|
||||||
@@ -80,7 +80,7 @@ class Resource:
|
|
||||||
Returns:
|
|
||||||
str: cpu usage
|
|
||||||
"""
|
|
||||||
- code, stdout, _ = execute_shell_command(f"ps -aux|grep -w {rpm_name}|grep {pid}|awk {{print$3}}")
|
|
||||||
+ code, stdout, _ = execute_shell_command(["ps -aux", f"grep -w {rpm_name}", f"grep {pid}", f"awk {{print$3}}"])
|
|
||||||
if code == CommandExitCode.SUCCEED:
|
|
||||||
return f'{stdout.strip()}%'
|
|
||||||
LOGGER.error(f'Failed to get plugin cpu info about {rpm_name}.')
|
|
||||||
diff --git a/ceres/manages/rollback_manage.py b/ceres/manages/rollback_manage.py
|
|
||||||
index 160a74c..51ef6d6 100644
|
|
||||||
--- a/ceres/manages/rollback_manage.py
|
|
||||||
+++ b/ceres/manages/rollback_manage.py
|
|
||||||
@@ -162,7 +162,7 @@ class RollbackManage:
|
|
||||||
Returns:
|
|
||||||
Tuple[str, str]: a tuple containing two elements (rollback result, log)
|
|
||||||
"""
|
|
||||||
- cmd = f"dnf history rollback {dnf_event_start} -y"
|
|
||||||
+ cmd = [f"dnf history rollback {dnf_event_start} -y"]
|
|
||||||
# 'dnf history rollback transaction-id' command can revert all dnf transactions performed after transaction-id
|
|
||||||
code, stdout, stderr = execute_shell_command(cmd)
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
@@ -262,7 +262,7 @@ class RollbackManage:
|
|
||||||
Returns:
|
|
||||||
Tuple[str, str]: a tuple containing two elements (remove result, log)
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"rpm -qa | grep {installed_rpm}")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["rpm -qa", f"grep {installed_rpm}"])
|
|
||||||
# 'rpm -qa' shows installed rpm
|
|
||||||
# e.g.
|
|
||||||
# [root@openEuler ~]# rpm -qa | grep kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
@@ -272,7 +272,7 @@ class RollbackManage:
|
|
||||||
LOGGER.error(tmp_log)
|
|
||||||
return TaskExecuteRes.FAIL, tmp_log
|
|
||||||
|
|
||||||
- code, current_evra, stderr = execute_shell_command(f"uname -r")
|
|
||||||
+ code, current_evra, stderr = execute_shell_command([f"uname -r"])
|
|
||||||
# 'uname -r' show the kernel version-release.arch of the current system
|
|
||||||
# e.g.
|
|
||||||
# [root@openEuler ~]# uname -r
|
|
||||||
@@ -287,7 +287,7 @@ class RollbackManage:
|
|
||||||
if installed_evra == current_evra:
|
|
||||||
return TaskExecuteRes.SUCCEED, f"Preserve the {installed_rpm} due to it is in use."
|
|
||||||
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"dnf remove {installed_rpm} -y")
|
|
||||||
+ code, stdout, stderr = execute_shell_command([f"dnf remove {installed_rpm} -y"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return TaskExecuteRes.FAIL, stdout + stderr
|
|
||||||
@@ -305,7 +305,7 @@ class RollbackManage:
|
|
||||||
Returns:
|
|
||||||
Tuple[str, str]: a tuple containing two elements (check result, log)
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"grubby --default-kernel")
|
|
||||||
+ code, stdout, stderr = execute_shell_command([f"grubby --default-kernel"])
|
|
||||||
# 'grubby --default-kernel' shows boot default kernel version in the system
|
|
||||||
# e.g.
|
|
||||||
# [root@openEuler ~]# grubby --default-kernel
|
|
||||||
@@ -338,7 +338,7 @@ class RollbackManage:
|
|
||||||
Returns:
|
|
||||||
Tuple[str, str]: a tuple containing two elements (check result, log)
|
|
||||||
"""
|
|
||||||
- code, current_evra, stderr = execute_shell_command(f"uname -r")
|
|
||||||
+ code, current_evra, stderr = execute_shell_command(["uname -r"])
|
|
||||||
# 'uname -r' show the kernel version-release.arch of the current system
|
|
||||||
# e.g.
|
|
||||||
# [root@openEuler ~]# uname -r
|
|
||||||
@@ -371,7 +371,7 @@ class RollbackManage:
|
|
||||||
Returns:
|
|
||||||
Tuple[str, str]: a tuple containing two elements (check result, log)
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"rpm -qa | grep {target_rpm}")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["rpm -qa", f"grep {target_rpm}"])
|
|
||||||
# 'rpm -qa' shows installed rpm
|
|
||||||
# e.g.
|
|
||||||
# [root@openEuler ~]# rpm -qa | grep kernel-4.19.90-2112.8.0.0131.oe1.x86_64
|
|
||||||
@@ -402,7 +402,7 @@ class RollbackManage:
|
|
||||||
return TaskExecuteRes.FAIL, tmp_log
|
|
||||||
|
|
||||||
# 'grubby --set-default=/boot/vmlinuz-xxx' changes the default boot entry
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"grubby --set-default={boot_file}")
|
|
||||||
+ code, stdout, stderr = execute_shell_command([f"grubby --set-default={boot_file}"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return TaskExecuteRes.FAIL, stdout + stderr
|
|
||||||
diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py
|
|
||||||
index 314e054..9017b17 100644
|
|
||||||
--- a/ceres/manages/vulnerability_manage.py
|
|
||||||
+++ b/ceres/manages/vulnerability_manage.py
|
|
||||||
@@ -87,7 +87,7 @@ class VulnerabilityManage:
|
|
||||||
Returns:
|
|
||||||
bool
|
|
||||||
"""
|
|
||||||
- code, _, stderr = execute_shell_command(f"dnf repoinfo --repo {repo_id}")
|
|
||||||
+ code, _, stderr = execute_shell_command([f"dnf repoinfo --repo {repo_id}"])
|
|
||||||
if code == CommandExitCode.SUCCEED:
|
|
||||||
return True
|
|
||||||
LOGGER.warning(f"Failed to query repo information with repo id {repo_id}.")
|
|
||||||
@@ -181,9 +181,7 @@ class VulnerabilityManage:
|
|
||||||
# powertop:powertop-2.9-12.oe1.x86_64
|
|
||||||
# libusbx:libusbx-1.0.23-1.oe1.x86_64
|
|
||||||
code, stdout, _ = execute_shell_command(
|
|
||||||
- """
|
|
||||||
- rpm -qa --queryformat '%{NAME}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | grep kernel
|
|
||||||
- """
|
|
||||||
+ ["rpm -qa --queryformat '%{NAME}:%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n'", "grep kernel"]
|
|
||||||
)
|
|
||||||
if code != CommandExitCode.SUCCEED or not stdout:
|
|
||||||
LOGGER.error("query installed packages info failed!")
|
|
||||||
@@ -222,7 +220,7 @@ class VulnerabilityManage:
|
|
||||||
# CVE-2021-45469 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64
|
|
||||||
# CVE-2021-44733 Important/Sec. kernel-4.19.90-2201.1.0.0132.oe1.x86_64
|
|
||||||
unfixed_cves = []
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf updateinfo list cves | grep kernel")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves", "grep kernel"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("query unfixed cve info failed by dnf!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -287,7 +285,7 @@ class VulnerabilityManage:
|
|
||||||
# CVE-2021-42574 Important/Sec. binutils-2.34-19.oe1.x86_64 -
|
|
||||||
# CVE-2023-1513 Important/Sec. kernel-4.19.90-2304.1.0.0196.oe1.x86_64 patch-kernel-4.19.90-2112...
|
|
||||||
cve_info_list = []
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves | grep kernel")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves", "grep kernel"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("query unfixed cve info failed by dnf!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -354,7 +352,7 @@ class VulnerabilityManage:
|
|
||||||
return fixed_cves
|
|
||||||
current_kernel_rpm_name = f"kernel-{current_kernel_version}"
|
|
||||||
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf updateinfo list cves --installed |grep kernel")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves --installed", "grep kernel"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("query fixed cve info failed!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -400,7 +398,7 @@ class VulnerabilityManage:
|
|
||||||
return []
|
|
||||||
current_kernel_rpm_name = f"kernel-{current_kernel_version}"
|
|
||||||
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves --installed | grep kernel")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves --installed", "grep kernel"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("query unfixed cve info failed by dnf!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -468,7 +466,7 @@ class VulnerabilityManage:
|
|
||||||
# CVE-2023-1111 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED
|
|
||||||
# CVE-2023-1112 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED
|
|
||||||
result = {}
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf hotpatch --list cves")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf hotpatch --list cves"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("query applied hotpatch info failed!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -634,7 +632,7 @@ class VulnerabilityManage:
|
|
||||||
Tuple[str, str]
|
|
||||||
a tuple containing two elements (upgrade result, package upgrade log).
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"dnf upgrade-en {rpm} -y")
|
|
||||||
+ code, stdout, stderr = execute_shell_command([f"dnf upgrade-en {rpm} -y"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return TaskExecuteRes.FAIL, stdout + stderr
|
|
||||||
@@ -673,7 +671,7 @@ class VulnerabilityManage:
|
|
||||||
final_fix_result, package_update_info = TaskExecuteRes.SUCCEED, []
|
|
||||||
|
|
||||||
for rpm in rpms:
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"dnf hotupgrade {rpm} -y")
|
|
||||||
+ code, stdout, stderr = execute_shell_command([f"dnf hotupgrade {rpm} -y"])
|
|
||||||
tmp = {
|
|
||||||
"available_rpm": rpm,
|
|
||||||
"result": TaskExecuteRes.SUCCEED,
|
|
||||||
@@ -711,7 +709,7 @@ class VulnerabilityManage:
|
|
||||||
"kernel-5.10.0-60.91.0.116.oe2203.x86_64": ["CVE-2023-2006"]
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf updateinfo list cves")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf updateinfo list cves"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("Failed to query update info by dnf!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -737,7 +735,7 @@ class VulnerabilityManage:
|
|
||||||
Example:
|
|
||||||
"Succeed", {"kernel": {"CVE-2023-XXXX","CVE-2022-XXXX"}}
|
|
||||||
"""
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves --installed")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(["dnf hot-updateinfo list cves --installed"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error("Failed to query fixed cves by hotpatch!")
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
@@ -808,7 +806,7 @@ class VulnerabilityManage:
|
|
||||||
return package_set
|
|
||||||
|
|
||||||
# The exit code of the command is 1 when input parameters contains assumeno
|
|
||||||
- _, stdout, _ = execute_shell_command(f"dnf upgrade-en {package} --assumeno")
|
|
||||||
+ _, stdout, _ = execute_shell_command([f"dnf upgrade-en {package} --assumeno"])
|
|
||||||
|
|
||||||
installed_rpm_info = re.findall(r"(Upgrading|Installing):(.*?)Transaction Summary", stdout, re.S)
|
|
||||||
if not installed_rpm_info:
|
|
||||||
@@ -841,7 +839,7 @@ class VulnerabilityManage:
|
|
||||||
return False
|
|
||||||
|
|
||||||
LOGGER.info("The Linux boot kernel is about to be changed")
|
|
||||||
- code, _, stderr = execute_shell_command(f"grubby --set-default={boot_kernel_path}")
|
|
||||||
+ code, _, stderr = execute_shell_command([f"grubby --set-default={boot_kernel_path}"])
|
|
||||||
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.info("The Linux boot kernel change failed")
|
|
||||||
@@ -863,7 +861,9 @@ class VulnerabilityManage:
|
|
||||||
# ---------------------------------------------------------------------
|
|
||||||
# 3 | rm aops-ceres | 2023-11-30 09:57 | Removed | 1
|
|
||||||
# 2 | install gcc | 2023-11-30 09:57 | Install | 1
|
|
||||||
- code, stdout, stderr = execute_shell_command("dnf history | grep -E '^\s*[0-9]+'|head -1|awk '{print $1}'")
|
|
||||||
+ code, stdout, stderr = execute_shell_command(
|
|
||||||
+ ["dnf history", "grep -E '^\s*[0-9]+'", "head -1", "awk '{print $1}'"]
|
|
||||||
+ )
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(stderr)
|
|
||||||
return None
|
|
||||||
@@ -898,7 +898,7 @@ class VulnerabilityManage:
|
|
||||||
# Last metadata expiration check: 3:25:24 ago on Wed 13 Sep 2023 08:16:17 AM CST.
|
|
||||||
# Gonna accept this hot patch: kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1
|
|
||||||
# accept hot patch 'kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1' failed, remain original status
|
|
||||||
- code, stdout, stderr = execute_shell_command(f"dnf hotpatch --{operation} {wait_to_remove_patch}")
|
|
||||||
+ code, stdout, stderr = execute_shell_command([f"dnf hotpatch --{operation} {wait_to_remove_patch}"])
|
|
||||||
if code != CommandExitCode.SUCCEED or 'failed' in stdout:
|
|
||||||
LOGGER.error(f"hotpatch {hotpatch} set status failed!")
|
|
||||||
return False, stdout + stderr
|
|
||||||
@@ -982,7 +982,7 @@ class VulnerabilityManage:
|
|
||||||
"CVE-XXXX-XXX": {"patch 1", "patch 2"}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
- code, stdout, _ = execute_shell_command(f"dnf hot-updateinfo list cves --installed|grep patch")
|
|
||||||
+ code, stdout, _ = execute_shell_command([f"dnf hot-updateinfo list cves --installed", "grep patch"])
|
|
||||||
if code != CommandExitCode.SUCCEED:
|
|
||||||
LOGGER.error(f"Failed to query the hotpatch list.")
|
|
||||||
return None
|
|
||||||
@@ -1016,6 +1016,6 @@ class VulnerabilityManage:
|
|
||||||
Args:
|
|
||||||
hotpatch: hotpatch package which needs to remove
|
|
||||||
"""
|
|
||||||
- cmd = f"dnf remove {hotpatch} -y"
|
|
||||||
+ cmd = [f"dnf remove {hotpatch} -y"]
|
|
||||||
_, stdout, stderr = execute_shell_command(cmd)
|
|
||||||
return True, f"Command:{cmd}\n\n{stdout}\n{stderr}\n"
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,58 +0,0 @@
|
|||||||
From 19b611645b9be2e72c81cab5cb456f9a943d3caa Mon Sep 17 00:00:00 2001
|
|
||||||
From: rabbitali <wenxin32@foxmail.com>
|
|
||||||
Date: Wed, 7 Feb 2024 12:23:28 +0800
|
|
||||||
Subject: [PATCH 1/1] override list file method
|
|
||||||
|
|
||||||
---
|
|
||||||
ceres/manages/list_file_manage.py | 26 +++++++++++---------------
|
|
||||||
1 file changed, 11 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/ceres/manages/list_file_manage.py b/ceres/manages/list_file_manage.py
|
|
||||||
index dab55e6..081a714 100644
|
|
||||||
--- a/ceres/manages/list_file_manage.py
|
|
||||||
+++ b/ceres/manages/list_file_manage.py
|
|
||||||
@@ -14,14 +14,9 @@
|
|
||||||
# Description: default
|
|
||||||
# Date: 2023/6/14 16:31
|
|
||||||
import os
|
|
||||||
-import subprocess
|
|
||||||
|
|
||||||
from ceres.function.log import LOGGER
|
|
||||||
-from ceres.function.status import (
|
|
||||||
- UNKNOWN_ERROR,
|
|
||||||
- SUCCESS
|
|
||||||
-)
|
|
||||||
-from ceres.function.util import execute_shell_command
|
|
||||||
+from ceres.function.status import FILE_NOT_FOUND, UNKNOWN_ERROR, SUCCESS, PARAM_ERROR
|
|
||||||
|
|
||||||
|
|
||||||
class ListFileManage:
|
|
||||||
@@ -39,15 +34,16 @@ class ListFileManage:
|
|
||||||
str: status code
|
|
||||||
"""
|
|
||||||
file_list_res = []
|
|
||||||
+
|
|
||||||
+ if not os.path.exists(directory_path):
|
|
||||||
+ return FILE_NOT_FOUND, {"resp": file_list_res}
|
|
||||||
+
|
|
||||||
+ if os.path.isfile(directory_path):
|
|
||||||
+ return PARAM_ERROR, {"resp": file_list_res}
|
|
||||||
+
|
|
||||||
try:
|
|
||||||
- command = [f"ls -l {directory_path}", "awk '{print $9}'"]
|
|
||||||
- _, stdout, _ = execute_shell_command(command)
|
|
||||||
- file_list = stdout.split("\n")
|
|
||||||
- for file in file_list:
|
|
||||||
- if file:
|
|
||||||
- file_path_res = os.path.join(directory_path, file)
|
|
||||||
- file_list_res.append(file_path_res)
|
|
||||||
+ file_list_res = [os.path.join(directory_path, file) for file in os.listdir(directory_path)]
|
|
||||||
return SUCCESS, {"resp": file_list_res}
|
|
||||||
- except Exception as e:
|
|
||||||
- LOGGER.error("list the pam.d file failed, with msg{}".format(e))
|
|
||||||
+ except OSError as e:
|
|
||||||
+ LOGGER.error(f"Failed to read the file list under the path with message {e}")
|
|
||||||
return UNKNOWN_ERROR, {"resp": list()}
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
From f6cc88528868c646292f7b4d238e848b70d9246a Mon Sep 17 00:00:00 2001
|
|
||||||
From: rabbitali <wenxin32@foxmail.com>
|
|
||||||
Date: Wed, 5 Jun 2024 19:30:03 +0800
|
|
||||||
Subject: [PATCH 1/1] update register template file
|
|
||||||
|
|
||||||
---
|
|
||||||
conf/register_example.json | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/conf/register_example.json b/conf/register_example.json
|
|
||||||
index 4fcd642..60bcbc4 100644
|
|
||||||
--- a/conf/register_example.json
|
|
||||||
+++ b/conf/register_example.json
|
|
||||||
@@ -7,5 +7,6 @@
|
|
||||||
"host_group_name": "aops",
|
|
||||||
"management": false,
|
|
||||||
"ssh_port":22,
|
|
||||||
- "access_token": "token-string"
|
|
||||||
+ "access_token": "token-string",
|
|
||||||
+ "ssh_pkey":""
|
|
||||||
}
|
|
||||||
\ No newline at end of file
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
Name: aops-ceres
|
Name: aops-ceres
|
||||||
Version: v1.4.1
|
Version: v1.4.1
|
||||||
Release: 7
|
Release: 1
|
||||||
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,12 +13,6 @@ 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
|
|
||||||
Patch0002: 0002-support-restore-grubby-if-kabi-check-failed.patch
|
|
||||||
Patch0003: 0003-remove-installed-rpm-if-unreboot-and-improve-log-for-rollback.patch
|
|
||||||
Patch0004: 0004-fix-cve-2021-33633.patch
|
|
||||||
Patch0005: 0005-override-list-file-method.patch
|
|
||||||
Patch0006: 0006-update-register-template-file.patch
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -92,24 +86,6 @@ 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
|
||||||
* Wed Jun 05 2024 wenxin<wenxin32@foxmail.com> - v1.4.1-7
|
|
||||||
- update register template file
|
|
||||||
|
|
||||||
* Wed Feb 07 2024 wenxin<wenxin32@foxmail.com> - v1.4.1-6
|
|
||||||
- override list file method
|
|
||||||
|
|
||||||
* Sun Feb 04 2024 wenxin<wenxin32@foxmail.com> - v1.4.1-5
|
|
||||||
- fix cve-2021-33633
|
|
||||||
|
|
||||||
* Fri Dec 22 2023 wangguangge<wangguangge@huawei.com> - v1.4.1-4
|
|
||||||
- support remove installed rpm if unreboot and improve log info for rollback operation
|
|
||||||
|
|
||||||
* Wed Dec 20 2023 wangguangge<wangguangge@huawei.com> - v1.4.1-3
|
|
||||||
- support restore default grubby boot kernel if kernel kabi check failed
|
|
||||||
|
|
||||||
* 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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user