import os import time from hashlib import md5 from typing import Optional from .util import service_reload, check_server_config, write_file, read_file # 支持读取配置文件 # 保存并重启配置文件 # 历史文件记录 class ConfigMgr: _vhost_path = "/www/server/panel/vhost" def __init__(self, site_name: str, config_prefix: str = ""): self.site_name = site_name self.config_prefix = config_prefix def _read_config(self, web_server: str) -> Optional[str]: config_file = "{}/{}/{}{}.conf".format(self._vhost_path, web_server, self.config_prefix, self.site_name) res = read_file(config_file) if isinstance(res, str): return res return None def nginx_config(self) -> Optional[str]: return self._read_config("nginx") def apache_config(self) -> Optional[str]: return self._read_config("apache") def save_config(self, conf_data: str, web_server: str): config_file = "{}/{}/{}{}.conf".format(self._vhost_path, web_server, self.config_prefix, self.site_name) old_config = self._read_config(web_server) write_file(config_file, conf_data) errmsg = check_server_config() if errmsg: write_file(config_file, old_config) return errmsg self._save_history(web_server) service_reload() def save_nginx_config(self, conf_data: str) -> Optional[str]: return self.save_config(conf_data, "nginx") def save_apache_config(self, conf_data: str) -> Optional[str]: return self.save_config(conf_data, "apache") def history_list(self): his_path = '/www/backup/file_history' nginx_config_file = "{}/nginx/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ng_save_path = "{}{}".format(his_path, nginx_config_file) apache_config_file = "{}/apache/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ap_save_path = "{}{}".format(his_path, apache_config_file) return { "nginx": [] if not os.path.isdir(ng_save_path) else sorted(os.listdir(ng_save_path), reverse=True), "apache": [] if not os.path.isdir(ap_save_path) else sorted(os.listdir(ap_save_path), reverse=True) } def history_conf(self, history_id: str) -> Optional[str]: his_path = '/www/backup/file_history' nginx_config_file = "{}/nginx/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ng_save_path = "{}{}".format(his_path, nginx_config_file) if os.path.isdir(ng_save_path): for i in os.listdir(ng_save_path): if i == history_id: return read_file(os.path.join(ng_save_path, i)) apache_config_file = "{}/apache/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ap_save_path = "{}{}".format(his_path, apache_config_file) if os.path.isdir(ap_save_path): for i in os.listdir(ap_save_path): if i == history_id: return read_file(os.path.join(ap_save_path, i)) return None def remove_history_file(self, history_id: str) -> None: his_path = '/www/backup/file_history' nginx_config_file = "{}/nginx/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ng_save_path = "{}{}".format(his_path, nginx_config_file) if os.path.isdir(ng_save_path): for i in os.listdir(ng_save_path): if i == history_id: os.remove(os.path.join(ng_save_path, i)) apache_config_file = "{}/apache/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ap_save_path = "{}{}".format(his_path, apache_config_file) if os.path.isdir(ap_save_path): for i in os.listdir(ap_save_path): if i == history_id: os.remove(os.path.join(ng_save_path, i)) def clear_history_file(self) -> None: """ 清空所有的历史文件 """ his_path = '/www/backup/file_history' nginx_config_file = "{}/nginx/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ng_save_path = "{}{}".format(his_path, nginx_config_file) if os.path.isdir(ng_save_path): for i in os.listdir(ng_save_path): os.remove(os.path.join(ng_save_path, i)) apache_config_file = "{}/apache/{}{}.conf".format(self._vhost_path, self.config_prefix, self.site_name) ap_save_path = "{}{}".format(his_path, apache_config_file) if os.path.isdir(ap_save_path): for i in os.listdir(ap_save_path): os.remove(os.path.join(ng_save_path, i)) @staticmethod def _file_md5(filename): if not os.path.isfile(filename): return False md5_obj = md5() with open(filename, mode="rb") as f: while True: b = f.read(8096) if not b: break md5_obj.update(b) return md5_obj.hexdigest() def _save_history(self, web_server: str): if os.path.exists('/www/server/panel/data/not_file_history.pl'): return True his_path = '/www/backup/file_history' filename = "{}/{}/{}{}.conf".format(self._vhost_path, web_server, self.config_prefix, self.site_name) save_path = "{}{}".format(his_path, filename) if not os.path.isdir(save_path): os.makedirs(save_path, 384) his_list = sorted(os.listdir(save_path), reverse=True) # 倒序排列已有的历史文件 try: num = int(read_file('data/history_num.pl')) except (ValueError, TypeError): num = 100 is_write = True if len(his_list) > 0: new_file_md5 = self._file_md5(filename) last_file_md5 = self._file_md5(os.path.join(save_path, his_list[0])) is_write = new_file_md5 != last_file_md5 if is_write: new_name = str(int(time.time())) write_file(os.path.join(save_path, new_name), read_file(filename, 'rb'), "wb") his_list.insert(0, new_name) # 删除多余的副本 for i in his_list[num:]: rm_file = save_path + '/' + i if os.path.exists(rm_file): os.remove(rm_file)