File size: 6,975 Bytes
08c964e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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):
                try:
                    os.unlink(os.path.join(ng_save_path, i))
                except IsADirectoryError:
                    try:
                        os.rmdir(os.path.join(ng_save_path, i))
                    except Exception:
                        pass
                except:
                    pass

        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):
                try:
                    os.unlink(os.path.join(ap_save_path, i))
                except IsADirectoryError:
                    try:
                        os.rmdir(os.path.join(ap_save_path, i))
                    except Exception:
                        pass
                except:
                    pass

    @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)