Server IP : 184.154.167.98 / Your IP : 13.58.199.20 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 7.2.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/web-monitoring-tool/ |
Upload File : |
#!/opt/cloudlinux/venv/bin/python3 -bb # coding=utf-8 # # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2020 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENCE.TXT # import getopt import os import random import sys from sentry import init_wmt_sentry_client, setup_logger __ALL__ = ["add_cron", "erase_cron", "remove_cron", "add_cron_task"] WMT_CRONS = ['wmt-clickhouse-reporter', 'wmt-email-reporter'] def usage(): print('') print('Use following syntax to manage WMT cron jobs install utility:') print(sys.argv[0] + " [OPTIONS]") print('Options:') print(" -i | --install : install wmt cron jobs") print(" -d | --delete : delete wmt cron jobs") print(" -u | --update : update wmt cron jobs") def add_cron(file_name, minute, hour, day, month, day_of_week, user, command, check_command=True): """ Add new cron task into crontab schedule if this task or command wasn't already existed in the cron-file. :param str file_name: Name of cron-file in /etc/cron.d :param minute: Integer or char 'r' if to set random minute :param hour: Integer or char 'r' if to set random hour :param int, str day: Day number :param int, str month: Month number :param int, str day_of_week: Day of week number :param str user: Under what user do run command :param str command: What command do run :param bool check_command: If it is False, check that whole cron-task line already exists in crontab, check that command string exists instead. Default is True, check a command string. """ if minute == 'r': minute = int(round(random.uniform(0, 59))) # pylint: disable=round-builtin if hour == 'r': hour = int(round(random.uniform(0, 23))) # pylint: disable=round-builtin try: cron_task = format_cron_task(minute, hour, day, month, day_of_week, user, command) add_cron_task(file_name, cron_task, check_command) except TypeError: sys.stderr.write("Can not add task with wrong syntax") def add_cron_task(file_name, task, check_command=False): """ Add new cron task in cron format if this task or command in this task wasn't already existed in the cron-file. :param str file_name: Name of cron-file in /etc/cron.d :param str task: Cron task in format "min hour day mon d_of_w user command" :param bool check_command: If it is False, check that whole cron-task line already exists in crontab, check that command string exists instead. Default is False, check a whole cron-task string. """ cron_file_path = os.path.join('/etc/cron.d/', file_name) try: content = '' if os.path.exists(cron_file_path): with open(cron_file_path) as f: content = f.readlines() if not is_in_cron(task, content, check_command): with open(cron_file_path, 'a') as f: f.write("%s\n" % task) except (IOError, OSError): return False return True def remove_cron(file_name): """ Remove cron-file from fs :param str file_name: Name of cron-file in /etc/cron.d """ try: os.remove( os.path.join('/etc/cron.d/', file_name) ) except (OSError, IOError): pass def erase_cron(file_name): """ Make cron-file empty :param str file_name: Name of cron-file in /etc/cron.d """ f = None try: f = open( os.path.join("/etc/cron.d/", file_name), "w" ) except (IOError, OSError) as err: sys.stderr.write("Can not erase crontab file %s because %s\n" % ( file_name, str(err))) else: f.close() def format_cron_task(minute, hour, day, month, day_of_week, user, command): """ Build cron-task string in the cron format :param minute: Integer or char 'r' if to set random minute :param hour: Integer or char 'r' if to set random hour :param int day: Day number :param int month: Month number :param int day_of_week: Day of week number :param str user: Under what user do run command :param str command: What command do run :return: Cron-task in the cron format :rtype: str """ arguments = (minute, hour, day, month, day_of_week, user, command) for arg in arguments: if arg is None: raise TypeError("Wrong schedule for cron task") return "%2s %2s %2s %2s %2s %10s %s" % arguments def parse_cron_task(task): """ Split cron task string into cron task parts :param str task: Cron-task string in the cron format :return: List of cron-task parts :rtype: list of str """ return task.split(None, 6) def get_task_in_cron(crontab, get_parsed=False): """ Returns iterator through crontab tasks :param iterable crontab: Iterator with crontab tasks' strings :param bool get_parsed: If it is True, return crontab task as list of task's parts return crontab task as a string instead :return: Crontab task :rtype: str :rtype: list of str """ for cron_t in (s.strip() for s in crontab): try: if get_parsed: t = parse_cron_task(cron_t) else: t = format_cron_task(*parse_cron_task(cron_t)) except TypeError: sys.stderr.write("Wrong crontab task syntax: %s\n" % cron_t) else: yield t def is_task_in_cron(task, cron_content): """ Find first occurence of task in cron-file if it has :param str task: Cron-task in cront format to compare with :param list cron_content: list of cron contents lines :return: True if such a task is already existed in cron-file, False instead :rtype: bool """ for t in get_task_in_cron(cron_content): if t == task: return True return False def is_command_in_cron(task, cron_content): """ :param str task: Task with command to looking for :param list cron_content: list of cron content lines :return: True if such a command is already existed in cron-file, False instead :rtype: bool Find first occurence of command in cron-file if it has """ command = parse_cron_task(task)[-1] for t in get_task_in_cron(cron_content, get_parsed=True): if t[-1] == command: return True return False def is_in_cron(task, cron_content, check_command=False): """ Find first occurence of command or task in cron-file if it has :param str task: Task or command to looking for :param list cron_content: content of cron file :param bool check_command: If it is True, check command occurence, check task occurence instead :return: True if such a command or task is already existed in cron-file, False instead :rtype: bool """ if check_command: return is_command_in_cron(task, cron_content) return is_task_in_cron(task, cron_content) def is_valid_cron_task(t): """ Straight-forward approach to cron minute/hour validation (our crons always have digits on minute/hour positions) Better to clone croniter package for advanced validation """ if not t[0].isdigit() or int(t[0]) >= 60: return False if not t[1].isdigit() or int(t[1]) >= 24: return False return True def get_cron_list(): return WMT_CRONS def get_cron_params(cron_name): """ Get crontab entries for WMT cron jobs """ wmt_bin = '/usr/share/web-monitoring-tool/wmtbin' wmt_api = os.path.join(wmt_bin, 'wmt-api') logfile = '/var/log/cl_wmt.log' if cron_name == 'wmt-clickhouse-reporter': send_to_clickhouse = f'{wmt_api} --send-clickhouse' return [ 'r', 'r', '*', '*', '*', 'root', f'/usr/bin/flock -n /var/run/wmt_clickhouse_report.cronlock {send_to_clickhouse} &>> {logfile}' ] elif cron_name == 'wmt-email-reporter': report_to_mail_cmd = f'{wmt_api} --send-email' return [ '0', '0', '*', '*', '*', 'root', f'/usr/bin/flock -n /var/run/wmt_email_report.cronlock {report_to_mail_cmd} &>> {logfile}' ] elif cron_name == 'wmt-file-rotator': rotate_wmt_files = '-name "wmt-db-*.sqlite" -delete -or -name "wmt_report*.json" -delete' linux_find = f'/usr/bin/find /var/lve/wmt/ -maxdepth 1 -mtime +7 {rotate_wmt_files}' return [ '0', '0', '*', '*', '*', 'root', '/usr/bin/flock -n /var/run/wmt_file_rotator.cronlock ' + linux_find ] else: raise ValueError('Invalid cron name: %s', cron_name) def install_crons(): for cron_name in get_cron_list(): add_cron(cron_name, *get_cron_params(cron_name)) def delete_crons(): for cron_name in get_cron_list(): remove_cron(cron_name) def update_crons(): for cron_name in get_cron_list(): cron_file_path = os.path.join('/etc/cron.d/', cron_name) if not os.path.exists(cron_file_path): continue # always update cron file with actual tasks remove_cron(cron_name) add_cron(cron_name, *get_cron_params(cron_name)) if __name__ == "__main__": logger = setup_logger('cron_control') init_wmt_sentry_client() try: opts, args = getopt.getopt( sys.argv[1:], "hidu", ["help", "postupcp", "install", "delete", "update"] ) except getopt.GetoptError as err: # print help information and exit: print(str(err)) # will print something like "option -a not recognized" usage() sys.exit(2) try: for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() elif o in ("-i", "--install"): install_crons() elif o in ("-d", "--delete"): delete_crons() elif o in ("-u", "--update"): update_crons() else: usage() sys.exit(2) except Exception as e: logger.exception(e)