diff --git a/analysis/plugin/configurator/__init__.py b/analysis/plugin/configurator/__init__.py index 31aa2cdd3961a704fc88ed15be1326557f63bab4..c01d7cc41d8d20ee76748349a45508a554fffbbb 100755 --- a/analysis/plugin/configurator/__init__.py +++ b/analysis/plugin/configurator/__init__.py @@ -19,6 +19,7 @@ __all__ = [ "affinity", "bios", "bootloader", + "file_config", "kernel_config", "script", "sysctl", diff --git a/analysis/plugin/configurator/affinity/irq.py b/analysis/plugin/configurator/affinity/irq.py index 1a32de361b0418b40e3013441679f337f8742a77..3ed2433a67b64fe43607de42788f68ca6d5c11ff 100755 --- a/analysis/plugin/configurator/affinity/irq.py +++ b/analysis/plugin/configurator/affinity/irq.py @@ -93,6 +93,7 @@ class IrqAffinity(Configurator): @staticmethod def check(config1, config2): + """replace comma""" config1 = config1.replace(",", "") config2 = config2.replace(",", "") return int(config1, base=16) == int(config2, base=16) diff --git a/analysis/plugin/configurator/bios/bios.py b/analysis/plugin/configurator/bios/bios.py index 723d65af7695289af1f52bf7e723fc5bb50b1b51..ae1fa7a9898b283141b89938ceef4171360c8a43 100755 --- a/analysis/plugin/configurator/bios/bios.py +++ b/analysis/plugin/configurator/bios/bios.py @@ -34,7 +34,7 @@ class Bios(Configurator): def _set(self, key, value): raise NeedConfigWarning( - "Please change the BIOS configuration {key} to {val}.".format( + "please change the BIOS configuration {key} to {val}".format( key=key, val=value)) def _get(self, key, _): diff --git a/analysis/plugin/configurator/common.py b/analysis/plugin/configurator/common.py index 9159a6d8617032bb1b224694f72bfd834906a025..0b5765e5738bdb77a630e69463917364be7472ef 100755 --- a/analysis/plugin/configurator/common.py +++ b/analysis/plugin/configurator/common.py @@ -90,6 +90,12 @@ class Configurator: cfg = self._getcfg(config) try: ret = self._set(cfg[0], cfg[1]) + except Warning as warn: + if self._user == "UT": + raise warn + LOGGER.warning("%s.%s: %s", self.__class__.__name__, + inspect.stack()[0][3], str(warn)) + return warn except Exception as err: if self._user == "UT": raise err @@ -188,6 +194,12 @@ class Configurator: ret = self._get(key, value) if ret is not None: ret = ret.replace('\n', ' ').strip() + except Warning as warn: + if self._user == "UT": + raise warn + LOGGER.warning("%s.%s: %s", self.__class__.__name__, + inspect.stack()[0][3], str(warn)) + return warn except Exception as err: if self._user == "UT": raise err diff --git a/analysis/plugin/configurator/file_config/__init__.py b/analysis/plugin/configurator/file_config/__init__.py new file mode 100755 index 0000000000000000000000000000000000000000..48aeb30f5ef8f813f02dcecb52506da3c740e1a0 --- /dev/null +++ b/analysis/plugin/configurator/file_config/__init__.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# Copyright (c) 2020 Huawei Technologies Co., Ltd. +# A-Tune is licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v2 for more details. +# Create: 2020-06-18 + +""" +Init file. +""" + +__all__ = ["fconfig"] + +from . import * diff --git a/analysis/plugin/configurator/file_config/fconfig.py b/analysis/plugin/configurator/file_config/fconfig.py new file mode 100755 index 0000000000000000000000000000000000000000..b2d96c32fdfa1a7e5d1c26d55c2b2ee660bb4e4f --- /dev/null +++ b/analysis/plugin/configurator/file_config/fconfig.py @@ -0,0 +1,91 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +# Copyright (c) 2020 Huawei Technologies Co., Ltd. +# A-Tune is licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v2 for more details. +# Create: 2020-06-18 + +""" +The sub class of the Configurator, used to change the file config. +""" +import inspect +import logging +import os +import random +import re +import shutil + +from analysis.plugin.public import GetConfigError, NeedConfigWarning +from ..common import Configurator + +LOGGER = logging.getLogger(__name__) + + +class FileConfig(Configurator): + """To change the file config""" + _module = "FILE_CONFIG" + _submod = "FILE_CONFIG" + _cfg_files = ["/etc/profile"] + _separator_char = "-" + + def __init__(self, user=None): + Configurator.__init__(self, user) + + def _set(self, key, value): + try: + if self.get(key, value) == value: + return 0 + except LookupError as err: + LOGGER.debug("%s.%s: %s", self.__class__.__name__, inspect.stack()[0][3], str(err)) + + with open(key, 'a') as file: + file.write(value + "\n") + + if key in self._cfg_files: + raise NeedConfigWarning( + "please exec source {file} to make the configuration take effect".format(file=key)) + return 0 + + def _get(self, key, value): + if not os.path.exists(key): + raise GetConfigError("Fail to find file {}".format(key)) + + config_key = value.split("=")[0] if value.find("=") != -1 else value + pattern = re.compile("^" + config_key + ".*", re.ASCII | re.DOTALL) + search_obj = [] + with open(key, 'r') as file: + for line in file: + result = pattern.search(line) + if result is not None: + search_obj.append(result.group(0).strip()) + + if len(search_obj) == 0: + raise LookupError("Fail to find {} entry in {}".format(config_key, key)) + + return search_obj[-1] + + def _backup(self, config, rollback_info): + cfg = self._getcfg(config) + name = cfg[0].replace("/", self._separator_char) + bak_file = "{path}/{file}{sep}{ver}".format(path=rollback_info, file=name, + sep=self._separator_char, + ver=random.random()) + shutil.copy(cfg[0], bak_file) + return "CPI_ROLLBACK_INFO = {}".format(bak_file) + + def _resume(self, key, value): + if key != "CPI_ROLLBACK_INFO": + raise ValueError("unsupported resume type: {}".format(key)) + left_index = value.rfind("/") + right_index = value.rfind(self._separator_char) + if left_index == -1 or right_index == -1: + return + cfg_file = value[left_index + 1:right_index].replace(self._separator_char, "/") + LOGGER.info("resume cfg file is %s", cfg_file) + shutil.copy(value, cfg_file) diff --git a/analysis/plugin/configurator/kernel_config/kconfig.py b/analysis/plugin/configurator/kernel_config/kconfig.py index 50e2ae19911617ec7402eb713a82d64351e8fec0..43a48b51c2d7ad7df2ff69dfb0da31175303c721 100755 --- a/analysis/plugin/configurator/kernel_config/kconfig.py +++ b/analysis/plugin/configurator/kernel_config/kconfig.py @@ -15,7 +15,6 @@ The sub class of the Configurator, used to change the kernel config. """ import gzip -import inspect import os import logging import subprocess @@ -46,7 +45,7 @@ class KernelConfig(Configurator): if self.get(key) == value: return 0 raise NeedConfigWarning( - "Please change the kernel configuration {key} to {val}.".format( + "please change the kernel configuration {key} to {val}".format( key=key, val=value)) def _get(self, key, _): @@ -61,9 +60,7 @@ class KernelConfig(Configurator): pattern = re.compile("^" + key + "=(.+)", re.ASCII | re.MULTILINE) search_obj = pattern.findall(cfgs) if len(search_obj) != 1: - err = LookupError("not find one " + key) - LOGGER.error("%s.%s: %s", self.__class__.__name__, - inspect.stack()[0][3], str(err)) + err = Warning("not find one " + key) raise err return search_obj[0] diff --git a/analysis/plugin/configurator/script/script.py b/analysis/plugin/configurator/script/script.py index f7ded0a5cfce15810a9d866cd1e9fe672cf54472..a24ebdf3f0ea454ba4f912509447ec939b144a58 100755 --- a/analysis/plugin/configurator/script/script.py +++ b/analysis/plugin/configurator/script/script.py @@ -100,6 +100,7 @@ class Script(Configurator): @staticmethod def check(_, __): + """check""" return True def _backup(self, config, rollback_info): diff --git a/analysis/plugin/configurator/sysctl/sysctl.py b/analysis/plugin/configurator/sysctl/sysctl.py index 65a20e38b87e371bf386da74c204dfcd7378f2a9..e3d81ed8ef22226fbb192a6c17d9aa1f8bc6c17f 100755 --- a/analysis/plugin/configurator/sysctl/sysctl.py +++ b/analysis/plugin/configurator/sysctl/sysctl.py @@ -44,6 +44,7 @@ class Sysctl(Configurator): @staticmethod def check(config1, config2): + """substring""" config1 = re.sub(r"\s{1,}", " ", config1) config2 = re.sub(r"\s{1,}", " ", config2) return config1 == config2 diff --git a/analysis/plugin/configurator/sysfs/sysfs.py b/analysis/plugin/configurator/sysfs/sysfs.py index 7d0552388743f9cc104b26f3aaf0901c276f0f82..6f15b95280f52ee32c36c459a269784d36ad561f 100755 --- a/analysis/plugin/configurator/sysfs/sysfs.py +++ b/analysis/plugin/configurator/sysfs/sysfs.py @@ -48,4 +48,5 @@ class Sysfs(Configurator): @staticmethod def check(_, __): + """check""" return True diff --git a/analysis/plugin/configurator/systemctl/systemctl.py b/analysis/plugin/configurator/systemctl/systemctl.py index e268e7ba98b3848afa115e471071add1b577e6de..8aed0be986313a8767cc2e5c824f1662d8eb3e90 100755 --- a/analysis/plugin/configurator/systemctl/systemctl.py +++ b/analysis/plugin/configurator/systemctl/systemctl.py @@ -53,6 +53,7 @@ class Systemctl(Configurator): @staticmethod def check(_, __): + """check""" return True def _backup(self, config, _): diff --git a/analysis/plugin/monitor/storage/iostat.py b/analysis/plugin/monitor/storage/iostat.py index 16e8cc614ee144e41f639f6d58fab65e0e3090b1..70a77c626a0dc6bc6f033288d81b102097aa1e6a 100755 --- a/analysis/plugin/monitor/storage/iostat.py +++ b/analysis/plugin/monitor/storage/iostat.py @@ -95,6 +95,7 @@ class IoStat(Monitor): keys = [] dev = "sd.*?" ret = "" + resplitobj = re.compile(r'\s*\n') device_data = {} opts, _ = getopt.getopt(para.split(), None, ['device=', 'fields=']) @@ -106,17 +107,15 @@ class IoStat(Monitor): keys.append(val) continue + rows_contents = resplitobj.split(info) dev = "Device|" + dev - pattern = re.compile( - "^(" + - dev + - r")\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)" - r"\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)" - r"\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)" - r"\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)\ {1,}(\S*)", - re.ASCII | re.MULTILINE) - search_obj = pattern.findall(info) - if len(search_obj) < 2: + search_obj = [] + pattern = re.compile("^(" + dev + r").+", re.ASCII) + for row in rows_contents: + if pattern.match(row): + search_obj.append([data for data in row.split()]) + + if len(search_obj) < 3: err = LookupError("Fail to find data for {}".format(dev)) LOGGER.error("%s.%s: %s", self.__class__.__name__, inspect.stack()[0][3], str(err)) diff --git a/analysis/plugin/monitor/system/interrupts.py b/analysis/plugin/monitor/system/interrupts.py index f9a60bdf08a6c00d7334b7e8a3fd740df3083a4a..b82eb973f9429cf5bce4ba43712598da98e6a1db 100644 --- a/analysis/plugin/monitor/system/interrupts.py +++ b/analysis/plugin/monitor/system/interrupts.py @@ -59,6 +59,6 @@ class SysInterrupts(Monitor): nic = val break - pattern = re.compile(r"^(\d*):{}$".format(nic.strip()), re.MULTILINE) + pattern = re.compile(r"^(\d*):{}".format(nic.strip()), re.MULTILINE) interrupts = pattern.findall(info) return " ".join(interrupts).strip() diff --git a/analysis/resources/profile.py b/analysis/resources/profile.py index f73c17be296978c5429def9b10086b3b3f4dc0d3..8098a38fb4220cb1b5951c32fff4aaa55a9cc3ab 100755 --- a/analysis/resources/profile.py +++ b/analysis/resources/profile.py @@ -79,7 +79,7 @@ class Profile(Resource): result["status"] = "FAILED" result["value"] = str(real_value) else: - if not real_value: + if real_value is None: result["status"] = "FAILED" result["value"] = "UNKNOWN" else: