From 888a30f79f46432db60cf4140b0451a714a72578 Mon Sep 17 00:00:00 2001 From: zhuofeng Date: Mon, 3 Jun 2024 10:25:24 +0800 Subject: [PATCH 1/2] add plugin rasdaemon to syssentry --- sysSentry-1.0.2/config/tasks/rasdaemon.mod | 8 ++ .../src/python/syssentry/cron_process.py | 30 ++++++- .../src/python/syssentry/global_values.py | 84 +++++++++++++++++++ .../src/python/syssentry/load_mods.py | 22 +++++ .../src/python/syssentry/syssentry.py | 8 ++ 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 sysSentry-1.0.2/config/tasks/rasdaemon.mod diff --git a/sysSentry-1.0.2/config/tasks/rasdaemon.mod b/sysSentry-1.0.2/config/tasks/rasdaemon.mod new file mode 100644 index 0000000..ed6f3c6 --- /dev/null +++ b/sysSentry-1.0.2/config/tasks/rasdaemon.mod @@ -0,0 +1,8 @@ +[common] +enabled=yes +task_start=/usr/sbin/rasdaemon -f +task_stop=kill $pid +type=oneshot +onstart=yes +env_file=/etc/sysconfig/rasdaemon +conflict=up \ No newline at end of file diff --git a/sysSentry-1.0.2/src/python/syssentry/cron_process.py b/sysSentry-1.0.2/src/python/syssentry/cron_process.py index 88e4cc6..50780b3 100644 --- a/sysSentry-1.0.2/src/python/syssentry/cron_process.py +++ b/sysSentry-1.0.2/src/python/syssentry/cron_process.py @@ -21,7 +21,7 @@ import subprocess from .utils import get_current_time_string from .result import ResultLevel, RESULT_LEVEL_ERR_MSG_DICT from .global_values import InspectTask -from .task_map import TasksMap, PERIOD_TYPE +from .task_map import TasksMap, PERIOD_TYPE, ONESHOT_TYPE from .mod_status import set_runtime_status, WAITING_STATUS, RUNNING_STATUS, \ FAILED_STATUS, EXITED_STATUS @@ -33,10 +33,13 @@ class PeriodTask(InspectTask): self.interval = int(interval) self.last_exec_timestamp = 0 self.runtime_status = WAITING_STATUS + self.onstart = True def stop(self): self.period_enabled = False cmd_list = self.task_stop.split() + if cmd_list[-1] == "$pid": + cmd_list[-1] = str(self.pid) try: subprocess.Popen(cmd_list, stdout=subprocess.PIPE, close_fds=True) except OSError: @@ -58,6 +61,13 @@ class PeriodTask(InspectTask): self.period_enabled = True self.upgrade_period_timestamp() + if self.conflict != 'up': + ret = self.check_conflict() + if not ret: + return False, "check conflict failed" + if self.env_file: + self.load_env_file() + cmd_list = self.task_start.split() try: logfile = open(self.log_file, 'a') @@ -105,6 +115,20 @@ class PeriodTask(InspectTask): self.last_exec_timestamp = cur_timestamp logging.debug("period current timestamp %d", self.last_exec_timestamp) + def onstart_handle(self): + if not self.load_enabled: + return False + if not self.period_enabled: + logging.debug("period not enabled") + return False + if not self.onstart: + return False + + res, _ = self.start() + if res: + set_runtime_status(self.name, RUNNING_STATUS) + self.upgrade_period_timestamp() + def period_tasks_handle(): """period tasks handler""" @@ -118,6 +142,10 @@ def period_tasks_handle(): logging.debug("period not enabled") continue + if not task.onstart: + logging.debug("period onstart not enabled, task: %s", task.name) + continue + if task.runtime_status == WAITING_STATUS and \ task.check_period_timestamp(): logging.info("period task exec! name: %s", task.name) diff --git a/sysSentry-1.0.2/src/python/syssentry/global_values.py b/sysSentry-1.0.2/src/python/syssentry/global_values.py index dbff46e..483d544 100644 --- a/sysSentry-1.0.2/src/python/syssentry/global_values.py +++ b/sysSentry-1.0.2/src/python/syssentry/global_values.py @@ -20,6 +20,7 @@ import os from .result import ResultLevel, RESULT_LEVEL_ERR_MSG_DICT from .utils import get_current_time_string +from .mod_status import set_runtime_status, RUNNING_STATUS SENTRY_RUN_DIR = "/var/run/sysSentry" CTL_SOCKET_PATH = "/var/run/sysSentry/control.sock" @@ -69,6 +70,12 @@ class InspectTask: "error_msg": "", "details": {} } + # pull task + self.onstart = False + # ccnfig env_file + self.env_file = "" + # start mode + self.conflict = "up" def start(self): """ @@ -83,6 +90,14 @@ class InspectTask: if not self.period_enabled: self.period_enabled = True if self.runtime_status in ("EXITED", "FAILED"): + + if self.conflict != 'up': + ret = self.check_conflict() + if not ret: + return False, "check conflict failed" + if self.env_file: + self.load_env_file() + cmd_list = self.task_start.split() try: logfile = open(self.log_file, 'a') @@ -117,6 +132,8 @@ class InspectTask: self.period_enabled = False if self.runtime_status == "RUNNING": cmd_list = self.task_stop.split() + if cmd_list[-1] == "$pid": + cmd_list[-1] = str(self.pid) try: subprocess.Popen(cmd_list, stdout=subprocess.PIPE, close_fds=True) except OSError: @@ -130,3 +147,70 @@ class InspectTask: def get_result(self): """get result""" return self.result_info + + def onstart_handle(self): + if not self.load_enabled: + return False + if not self.onstart: + return False + res, _ = self.start() + if not res: + return False + set_runtime_status(self.name, RUNNING_STATUS) + + def check_conflict(self): + logging.debug("load_env_file detail, task_name: %s, conflict: %s, env_file: %s", + self.name, self.conflict, self.env_file) + pid_list = [] + check_cmd = ["ps", "aux"] + try: + result = subprocess.run(check_cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except subprocess.CalledProcessError as e: + raise Exception(f"failed with return code {e.returncode}") + + output_lines = result.stdout.decode("utf-8").splitlines() + for line in output_lines: + if self.task_start not in line: + continue + pid = int(line.split()[1]) + pid_list.append(pid) + logging.debug("current pid_list = %s", pid_list) + + if self.conflict == "kill" and pid_list: + for pid in pid_list: + subprocess.run(["kill", str(pid)], shell=False) + logging.debug("the program is killed, pid=%d", pid) + elif self.conflict == "down" and pid_list: + logging.warning("the conflict field is set to down, so program = [%s] is exited!", self.name) + return False + return True + + def load_env_file(self): + if not os.path.exists(self.env_file): + logging.warning("env_file: %s is not exist, use default environ", self.env_file) + return + + if not os.access(self.env_file, os.R_OK): + logging.warning("env_file: %s is not be read, use default environ", self.env_file) + return + + # read config + environ_conf = {} + with open(self.env_file, 'r') as file: + for line in file: + line = line.strip() + if not line or line.startswith("#") or "=" not in line: + continue + key, value = line.split("=", 1) + value = value.strip('"') + if not key or not value: + logging.error("env_file = %s format is error, use default environ", self.env_file) + return + environ_conf[key] = value + + # set environ + for key, value in environ_conf.items(): + logging.debug("environ key=%s, value=%s", key, value) + os.environ[key] = value + + logging.debug("the subprocess=[%s] begin to run", self.name) diff --git a/sysSentry-1.0.2/src/python/syssentry/load_mods.py b/sysSentry-1.0.2/src/python/syssentry/load_mods.py index 6bf3862..48d7e66 100644 --- a/sysSentry-1.0.2/src/python/syssentry/load_mods.py +++ b/sysSentry-1.0.2/src/python/syssentry/load_mods.py @@ -38,11 +38,15 @@ CONF_PERIOD_INTERVAL = 'interval' CONF_HEARTBEAT_INTERVAL = 'heartbeat_interval' CONF_HEARTBEAT_ACTION = 'heartbeat_action' CONF_TASK_RESTART = 'task_restart' +CONF_ONSTART = 'onstart' +CONF_ENV_FILE = 'env_file' +CONF_CONFLICT = 'conflict' MOD_FILE_SUFFIX = '.mod' MOD_SUFFIX_LEN = 4 ENABLED_FLAGS_SET = ("yes", "no") +ONSTART_FLAGS_SET = ("yes", "no") def mod_name_verify(mod_name): @@ -190,6 +194,21 @@ def parse_mod_conf(mod_name, mod_conf): task.heartbeat_interval = heartbeat_interval task.load_enabled = is_enabled + if CONF_ONSTART in mod_conf.options(CONF_TASK): + is_onstart = (mod_conf.get(CONF_TASK, CONF_ONSTART) == 'yes') + if task_type == PERIOD_CONF: + is_onstart = (mod_conf.get(CONF_TASK, CONF_ONSTART) != 'no') + logging.debug("the task ready to start") + task.onstart = is_onstart + + if CONF_ENV_FILE in mod_conf.options(CONF_TASK): + env_file_dir = mod_conf.get(CONF_TASK, CONF_ENV_FILE) + task.env_file = env_file_dir + + if CONF_CONFLICT in mod_conf.options(CONF_TASK): + conflict = mod_conf.get(CONF_TASK, CONF_CONFLICT) + task.conflict = conflict + return task @@ -287,6 +306,9 @@ def reload_mod_by_name(mod_name): task.task_stop = new_task.task_stop task.load_enabled = new_task.load_enabled task.heartbeat_interval = new_task.heartbeat_interval + task.onstart = new_task.onstart + task.env_file = new_task.env_file + task.conflict = new_task.conflict if task.type == PERIOD_TYPE: task.interval = new_task.interval set_task_status(mod_name, "LOADED") diff --git a/sysSentry-1.0.2/src/python/syssentry/syssentry.py b/sysSentry-1.0.2/src/python/syssentry/syssentry.py index 40b5619..de9dcad 100644 --- a/sysSentry-1.0.2/src/python/syssentry/syssentry.py +++ b/sysSentry-1.0.2/src/python/syssentry/syssentry.py @@ -375,6 +375,14 @@ def main_loop(): epoll_fd.register(heartbeat_fd.fileno(), select.EPOLLIN) logging.debug("start main loop") + # onstart_tasks_handle() + for task_type in TasksMap.tasks_dict: + for task_name in TasksMap.tasks_dict.get(task_type): + task = TasksMap.tasks_dict.get(task_type).get(task_name) + if not task: + continue + task.onstart_handle() + while True: try: events_list = epoll_fd.poll(SERVER_EPOLL_TIMEOUT) -- Gitee From a51cddf78b3bf14c81bc61e31419fbdfde88dc6b Mon Sep 17 00:00:00 2001 From: zhuofeng Date: Fri, 30 Aug 2024 19:03:14 +0800 Subject: [PATCH 2/2] Add Deleted Code --- sysSentry-1.0.2/src/python/syssentry/syssentry.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sysSentry-1.0.2/src/python/syssentry/syssentry.py b/sysSentry-1.0.2/src/python/syssentry/syssentry.py index 32b81e3..3d5cb8d 100644 --- a/sysSentry-1.0.2/src/python/syssentry/syssentry.py +++ b/sysSentry-1.0.2/src/python/syssentry/syssentry.py @@ -462,6 +462,14 @@ def main_loop(): epoll_fd.register(cpu_alarm_fd.fileno(), select.EPOLLIN) logging.debug("start main loop") + # onstart_tasks_handle() + for task_type in TasksMap.tasks_dict: + for task_name in TasksMap.tasks_dict.get(task_type): + task = TasksMap.tasks_dict.get(task_type).get(task_name) + if not task: + continue + task.onstart_handle() + while True: try: events_list = epoll_fd.poll(SERVER_EPOLL_TIMEOUT) -- Gitee