InPanel 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- inpanel/__init__.py +29 -0
- inpanel/acme.py +289 -0
- inpanel/aliyuncs.py +269 -0
- inpanel/app.py +514 -0
- inpanel/apt.py +223 -0
- inpanel/base.py +200 -0
- inpanel/config.py +139 -0
- inpanel/data/config.ini +29 -0
- inpanel/data/history +5 -0
- inpanel/data/runlogs.ini +12 -0
- inpanel/data/update_info.ini +4 -0
- inpanel/dnf.py +225 -0
- inpanel/lib/__init__.py +9 -0
- inpanel/lib/async_process.py +98 -0
- inpanel/lib/filelock.py +82 -0
- inpanel/lib/magic.py +233 -0
- inpanel/lib/pxssh.py +310 -0
- inpanel/lib/pyDes.py +867 -0
- inpanel/mod/__init__.py +0 -0
- inpanel/mod/apt.py +316 -0
- inpanel/mod/certificate.py +268 -0
- inpanel/mod/config.py +372 -0
- inpanel/mod/cron.py +315 -0
- inpanel/mod/disk.py +322 -0
- inpanel/mod/dnf.py +239 -0
- inpanel/mod/file.py +722 -0
- inpanel/mod/firewall.py +199 -0
- inpanel/mod/firewall_base.py +137 -0
- inpanel/mod/firewall_firewalld.py +170 -0
- inpanel/mod/firewall_iptables.py +176 -0
- inpanel/mod/firewall_macos.py +213 -0
- inpanel/mod/firewall_ufw.py +128 -0
- inpanel/mod/ftp.py +231 -0
- inpanel/mod/httpd.py +1205 -0
- inpanel/mod/lighttpd.py +26 -0
- inpanel/mod/login.py +98 -0
- inpanel/mod/mysql.py +577 -0
- inpanel/mod/named.py +26 -0
- inpanel/mod/nginx.py +2327 -0
- inpanel/mod/package.py +33 -0
- inpanel/mod/package_apt.py +62 -0
- inpanel/mod/package_base.py +77 -0
- inpanel/mod/package_dnf.py +62 -0
- inpanel/mod/package_map.py +366 -0
- inpanel/mod/package_yum.py +64 -0
- inpanel/mod/php.py +289 -0
- inpanel/mod/process.py +291 -0
- inpanel/mod/proftpd.py +26 -0
- inpanel/mod/pureftpd.py +26 -0
- inpanel/mod/query.py +108 -0
- inpanel/mod/server.py +1319 -0
- inpanel/mod/service.py +262 -0
- inpanel/mod/setting.py +228 -0
- inpanel/mod/shell.py +78 -0
- inpanel/mod/ssh.py +280 -0
- inpanel/mod/system.py +220 -0
- inpanel/mod/task.py +1337 -0
- inpanel/mod/ufw.py +14 -0
- inpanel/mod/user.py +306 -0
- inpanel/mod/vsftpd.py +67 -0
- inpanel/mod/yum.py +243 -0
- inpanel/plugins/__init__.py +10 -0
- inpanel/plugins/__pycache__/__init__.cpython-313.pyc +0 -0
- inpanel/plugins/acme/static/index.html +10 -0
- inpanel/plugins/acme/static/index.js +13 -0
- inpanel/plugins/shadowsocks-libev/__pycache__/info.cpython-313.pyc +0 -0
- inpanel/plugins/shadowsocks-libev/info.py +73 -0
- inpanel/plugins/shadowsocks-libev/static/index.html +70 -0
- inpanel/plugins/shadowsocks-libev/static/index.js +18 -0
- inpanel/public/css/global.css +138 -0
- inpanel/public/favicon.ico +0 -0
- inpanel/public/images/alipay.jpg +0 -0
- inpanel/public/images/loading.gif +0 -0
- inpanel/public/images/weixin.jpg +0 -0
- inpanel/public/index.html +94 -0
- inpanel/public/js/controllers/controllers.js +566 -0
- inpanel/public/js/controllers/database.js +590 -0
- inpanel/public/js/controllers/ecs.js +624 -0
- inpanel/public/js/controllers/file.js +940 -0
- inpanel/public/js/controllers/plugins.js +105 -0
- inpanel/public/js/controllers/service.js +1460 -0
- inpanel/public/js/controllers/site.js +1241 -0
- inpanel/public/js/controllers/utils.js +2319 -0
- inpanel/public/js/core.js +221 -0
- inpanel/public/js/directives.js +784 -0
- inpanel/public/js/filters.js +395 -0
- inpanel/public/js/services.js +257 -0
- inpanel/public/lib/angular/1.0.2/angular-resource.min.js +10 -0
- inpanel/public/lib/angular/1.0.2/angular.min.js +158 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.css +587 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.css.map +1 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css +6 -0
- inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css.map +1 -0
- inpanel/public/lib/bootstrap/css/bootstrap.css +6757 -0
- inpanel/public/lib/bootstrap/css/bootstrap.css.map +1 -0
- inpanel/public/lib/bootstrap/css/bootstrap.min.css +6 -0
- inpanel/public/lib/bootstrap/css/bootstrap.min.css.map +1 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
- inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
- inpanel/public/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
- inpanel/public/lib/bootstrap/img/glyphicons-halflings.png +0 -0
- inpanel/public/lib/bootstrap/js/bootstrap.js +2377 -0
- inpanel/public/lib/bootstrap/js/bootstrap.min.js +7 -0
- inpanel/public/lib/bootstrap/js/npm.js +13 -0
- inpanel/public/lib/codemirror/codemirror-compressed.js +1 -0
- inpanel/public/lib/codemirror/codemirror.css +173 -0
- inpanel/public/lib/jquery/jquery-1.12.4.min.js +5 -0
- inpanel/public/lib/md5/md5.js +379 -0
- inpanel/public/lib/md5/md5.min.js +1 -0
- inpanel/public/partials/database/index.html +172 -0
- inpanel/public/partials/database/mysql/dbedit.html +462 -0
- inpanel/public/partials/database/mysql/dbnew.html +348 -0
- inpanel/public/partials/database/mysql/useredit.html +310 -0
- inpanel/public/partials/database/mysql/usernew.html +97 -0
- inpanel/public/partials/directives/message.html +20 -0
- inpanel/public/partials/directives/navbar.html +25 -0
- inpanel/public/partials/directives/selector.html +57 -0
- inpanel/public/partials/directives/srvbase.html +72 -0
- inpanel/public/partials/directives/srvext.html +34 -0
- inpanel/public/partials/directives/srvfile.html +23 -0
- inpanel/public/partials/directives/srvinstall.html +34 -0
- inpanel/public/partials/directives/srvlog.html +23 -0
- inpanel/public/partials/directives/srvminiop.html +28 -0
- inpanel/public/partials/directives/srvuninstall.html +38 -0
- inpanel/public/partials/directives/srvupdate.html +30 -0
- inpanel/public/partials/ecs/account.html +156 -0
- inpanel/public/partials/ecs/ecs.html +198 -0
- inpanel/public/partials/ecs/index.html +40 -0
- inpanel/public/partials/ecs/setings.html +459 -0
- inpanel/public/partials/file/file.html +501 -0
- inpanel/public/partials/file/trash.html +95 -0
- inpanel/public/partials/ftp.html +36 -0
- inpanel/public/partials/log.html +83 -0
- inpanel/public/partials/login.html +79 -0
- inpanel/public/partials/logout.html +22 -0
- inpanel/public/partials/main.html +534 -0
- inpanel/public/partials/plugins/index.html +55 -0
- inpanel/public/partials/plugins/plugins.html +13 -0
- inpanel/public/partials/secure.html +13 -0
- inpanel/public/partials/service/apache.html +147 -0
- inpanel/public/partials/service/cron.html +71 -0
- inpanel/public/partials/service/index.html +293 -0
- inpanel/public/partials/service/iptables.html +40 -0
- inpanel/public/partials/service/lighttpd.html +63 -0
- inpanel/public/partials/service/mariadb.html +113 -0
- inpanel/public/partials/service/memcache.html +36 -0
- inpanel/public/partials/service/minio.html +44 -0
- inpanel/public/partials/service/mongodb.html +44 -0
- inpanel/public/partials/service/mysql.html +113 -0
- inpanel/public/partials/service/named.html +61 -0
- inpanel/public/partials/service/nginx.html +296 -0
- inpanel/public/partials/service/ntp.html +40 -0
- inpanel/public/partials/service/php.html +250 -0
- inpanel/public/partials/service/proftpd.html +59 -0
- inpanel/public/partials/service/pureftpd.html +59 -0
- inpanel/public/partials/service/redis.html +40 -0
- inpanel/public/partials/service/samba.html +58 -0
- inpanel/public/partials/service/sendmail.html +40 -0
- inpanel/public/partials/service/ssh.html +186 -0
- inpanel/public/partials/service/tomcat.html +65 -0
- inpanel/public/partials/service/vsftpd.html +195 -0
- inpanel/public/partials/setting.html +299 -0
- inpanel/public/partials/site/apache/site.html +277 -0
- inpanel/public/partials/site/index.html +344 -0
- inpanel/public/partials/site/nginx/site.html +558 -0
- inpanel/public/partials/sorry.html +19 -0
- inpanel/public/partials/storage/autofm.html +103 -0
- inpanel/public/partials/storage/backup.html +42 -0
- inpanel/public/partials/storage/index.html +360 -0
- inpanel/public/partials/storage/migrate.html +93 -0
- inpanel/public/partials/storage/movedata.html +98 -0
- inpanel/public/partials/storage/remote.html +77 -0
- inpanel/public/partials/utils/cron.html +486 -0
- inpanel/public/partials/utils/firewall.html +266 -0
- inpanel/public/partials/utils/index.html +193 -0
- inpanel/public/partials/utils/network.html +118 -0
- inpanel/public/partials/utils/process.html +239 -0
- inpanel/public/partials/utils/repository.html +373 -0
- inpanel/public/partials/utils/shell.html +28 -0
- inpanel/public/partials/utils/ssl.html +319 -0
- inpanel/public/partials/utils/time.html +109 -0
- inpanel/public/partials/utils/user.html +359 -0
- inpanel/public/robots.txt +2 -0
- inpanel/remote.py +109 -0
- inpanel/templates/file/preview.html +34 -0
- inpanel/templates/index.html +93 -0
- inpanel/utils.py +282 -0
- inpanel/web.py +1811 -0
- inpanel/yum.py +756 -0
- inpanel-1.2.1.dist-info/METADATA +399 -0
- inpanel-1.2.1.dist-info/RECORD +198 -0
- inpanel-1.2.1.dist-info/WHEEL +5 -0
- inpanel-1.2.1.dist-info/entry_points.txt +2 -0
- inpanel-1.2.1.dist-info/licenses/LICENSE +30 -0
- inpanel-1.2.1.dist-info/top_level.txt +1 -0
inpanel/mod/php.py
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# InPanel is distributed under the terms of the (new) BSD License.
|
|
7
|
+
# The full license can be found in 'LICENSE'.
|
|
8
|
+
|
|
9
|
+
'''Package for PHP operations.'''
|
|
10
|
+
|
|
11
|
+
import os
|
|
12
|
+
import subprocess
|
|
13
|
+
from glob import glob
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from shlex import split
|
|
16
|
+
|
|
17
|
+
from ..base import config_path
|
|
18
|
+
from .config import Config
|
|
19
|
+
|
|
20
|
+
# load php module config
|
|
21
|
+
php_config = Config(str(Path(config_path) / 'module/php.ini'))
|
|
22
|
+
# print('php_config', php_config.get_config())
|
|
23
|
+
base_config = php_config.get('base', 'config')
|
|
24
|
+
base_php_fpm = php_config.get('base', 'php-fpm')
|
|
25
|
+
|
|
26
|
+
if Path(base_config).exists():
|
|
27
|
+
PHPCFG = base_config
|
|
28
|
+
else:
|
|
29
|
+
PHPCFG = '/etc/php.ini'
|
|
30
|
+
|
|
31
|
+
if Path(base_php_fpm).exists():
|
|
32
|
+
PHPFPMCFG = base_php_fpm
|
|
33
|
+
else:
|
|
34
|
+
PHPFPMCFG = '/etc/php-fpm.conf'
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def phpinfo():
|
|
38
|
+
"""Add or remove service to autostart list.
|
|
39
|
+
"""
|
|
40
|
+
cmd = 'php-cgi -i'
|
|
41
|
+
p = subprocess.Popen(split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
|
|
42
|
+
info = p.stdout.read().decode('utf8')
|
|
43
|
+
p.stderr.read()
|
|
44
|
+
p.wait()
|
|
45
|
+
|
|
46
|
+
# Remove headers like
|
|
47
|
+
# X-Powered-By: PHP/5.3.16
|
|
48
|
+
# Content-type: text/html
|
|
49
|
+
info = info[info.find('<!DOCTYPE'):]
|
|
50
|
+
return info
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def loadconfig(initype='php', inifile=None, detail=False):
|
|
54
|
+
"""Read the php.ini or php-fpm.ini.
|
|
55
|
+
|
|
56
|
+
initype can be 'php' or 'php-fpm'.
|
|
57
|
+
"""
|
|
58
|
+
if not inifile:
|
|
59
|
+
inifile = initype == 'php' and PHPCFG or PHPFPMCFG
|
|
60
|
+
|
|
61
|
+
settings = {}
|
|
62
|
+
with open(inifile, encoding='utf-8') as f:
|
|
63
|
+
for line_i, line in enumerate(f):
|
|
64
|
+
line = line.strip()
|
|
65
|
+
if not line or line == ';' or line.startswith('; ') or line.startswith(';;'):
|
|
66
|
+
continue
|
|
67
|
+
|
|
68
|
+
# detect if it is a section
|
|
69
|
+
if line.startswith('['):
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
# detect if it's commented
|
|
73
|
+
if line.startswith(';'):
|
|
74
|
+
line = line.strip(';')
|
|
75
|
+
commented = True
|
|
76
|
+
if not detail:
|
|
77
|
+
continue
|
|
78
|
+
else:
|
|
79
|
+
commented = False
|
|
80
|
+
|
|
81
|
+
fs = line.split('=', 1)
|
|
82
|
+
if len(fs) != 2:
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
item = fs[0].strip()
|
|
86
|
+
value = fs[1].strip()
|
|
87
|
+
if item == 'include':
|
|
88
|
+
for incfile in sorted(glob(value)):
|
|
89
|
+
settings.update(loadconfig(initype, incfile, detail))
|
|
90
|
+
else:
|
|
91
|
+
if item in settings:
|
|
92
|
+
if detail:
|
|
93
|
+
count = settings[item]['count']+1
|
|
94
|
+
if not commented:
|
|
95
|
+
settings[item] = detail and {
|
|
96
|
+
'file': inifile,
|
|
97
|
+
'line': line_i,
|
|
98
|
+
'value': value,
|
|
99
|
+
'commented': commented,
|
|
100
|
+
} or value
|
|
101
|
+
else:
|
|
102
|
+
count = 1
|
|
103
|
+
settings[item] = detail and {
|
|
104
|
+
'file': inifile,
|
|
105
|
+
'line': line_i,
|
|
106
|
+
'value': fs[1].strip(),
|
|
107
|
+
'commented': commented,
|
|
108
|
+
} or value
|
|
109
|
+
if detail:
|
|
110
|
+
settings[item]['count'] = count
|
|
111
|
+
|
|
112
|
+
return settings
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def ini_get(item, detail=False, config=None, initype='php'):
|
|
116
|
+
"""Get value of an ini item.
|
|
117
|
+
"""
|
|
118
|
+
if not config:
|
|
119
|
+
config = loadconfig(initype=initype, detail=detail)
|
|
120
|
+
if item in config:
|
|
121
|
+
return config[item]
|
|
122
|
+
else:
|
|
123
|
+
return None
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def ini_set(item, value, commented=False, config=None, initype='php'):
|
|
127
|
+
"""Set value of an ini item.
|
|
128
|
+
"""
|
|
129
|
+
inifile = initype == 'php' and PHPCFG or PHPFPMCFG
|
|
130
|
+
v = ini_get(item, detail=True, config=config, initype=initype)
|
|
131
|
+
|
|
132
|
+
if v:
|
|
133
|
+
# detect if value change
|
|
134
|
+
if v['commented'] == commented and v['value'] == value:
|
|
135
|
+
return True
|
|
136
|
+
|
|
137
|
+
# empty value should be commented
|
|
138
|
+
if value == '':
|
|
139
|
+
commented = True
|
|
140
|
+
|
|
141
|
+
# replace item in line
|
|
142
|
+
lines = []
|
|
143
|
+
with open(v['file'], encoding='utf-8') as f:
|
|
144
|
+
for line_i, line in enumerate(f):
|
|
145
|
+
if line_i == v['line']:
|
|
146
|
+
if not v['commented']:
|
|
147
|
+
if commented:
|
|
148
|
+
if v['count'] > 1:
|
|
149
|
+
# delete this line, just ignore it
|
|
150
|
+
pass
|
|
151
|
+
else:
|
|
152
|
+
# comment this line
|
|
153
|
+
lines.append(';%s = %s\n' % (item, value))
|
|
154
|
+
else:
|
|
155
|
+
lines.append('%s = %s\n' % (item, value))
|
|
156
|
+
else:
|
|
157
|
+
if commented:
|
|
158
|
+
# do not allow change comment value
|
|
159
|
+
lines.append(line)
|
|
160
|
+
pass
|
|
161
|
+
else:
|
|
162
|
+
# append a new line after comment line
|
|
163
|
+
lines.append(line)
|
|
164
|
+
lines.append('%s = %s\n' % (item, value))
|
|
165
|
+
else:
|
|
166
|
+
lines.append(line)
|
|
167
|
+
with open(v['file'], 'w', encoding='utf-8') as f:
|
|
168
|
+
f.write(''.join(lines))
|
|
169
|
+
else:
|
|
170
|
+
# append to the end of file
|
|
171
|
+
with open(inifile, 'a', encoding='utf-8') as f:
|
|
172
|
+
f.write('\n%s%s = %s\n' % (commented and ';' or '', item, value))
|
|
173
|
+
|
|
174
|
+
return True
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def web_handler(context):
|
|
178
|
+
action = context.get_argument('action', '')
|
|
179
|
+
|
|
180
|
+
if action == 'getphpsettings':
|
|
181
|
+
settings = loadconfig('php')
|
|
182
|
+
context.write({'code': 0, 'msg': '', 'data': settings})
|
|
183
|
+
|
|
184
|
+
elif action == 'getfpmsettings':
|
|
185
|
+
settings = loadconfig('php-fpm')
|
|
186
|
+
context.write({'code': 0, 'msg': '', 'data': settings})
|
|
187
|
+
|
|
188
|
+
elif action == 'updatephpsettings':
|
|
189
|
+
short_open_tag = context.get_argument('short_open_tag', '')
|
|
190
|
+
expose_php = context.get_argument('expose_php', '')
|
|
191
|
+
max_execution_time = context.get_argument('max_execution_time', '')
|
|
192
|
+
memory_limit = context.get_argument('memory_limit', '')
|
|
193
|
+
display_errors = context.get_argument('display_errors', '')
|
|
194
|
+
post_max_size = context.get_argument('post_max_size', '')
|
|
195
|
+
upload_max_filesize = context.get_argument('upload_max_filesize', '')
|
|
196
|
+
date_timezone = context.get_argument('date.timezone', '')
|
|
197
|
+
|
|
198
|
+
short_open_tag = short_open_tag.lower() == 'on' and 'On' or 'Off'
|
|
199
|
+
expose_php = expose_php.lower() == 'on' and 'On' or 'Off'
|
|
200
|
+
display_errors = display_errors.lower() == 'on' and 'On' or 'Off'
|
|
201
|
+
|
|
202
|
+
if not max_execution_time == '' and not max_execution_time.isdigit():
|
|
203
|
+
context.write({'code': -1, 'msg': 'max_execution_time 必须为数字!'})
|
|
204
|
+
return
|
|
205
|
+
if not memory_limit == '' and not memory_limit.isdigit():
|
|
206
|
+
context.write({'code': -1, 'msg': 'memory_limit 必须为数字!'})
|
|
207
|
+
return
|
|
208
|
+
if not post_max_size == '' and not post_max_size.isdigit():
|
|
209
|
+
context.write({'code': -1, 'msg': 'post_max_size 必须为数字!'})
|
|
210
|
+
return
|
|
211
|
+
if not upload_max_filesize == '' and not upload_max_filesize.isdigit():
|
|
212
|
+
context.write({'code': -1, 'msg': 'upload_max_filesize 必须为数字!'})
|
|
213
|
+
return
|
|
214
|
+
|
|
215
|
+
memory_limit = '%sM' % memory_limit
|
|
216
|
+
post_max_size = '%sM' % post_max_size
|
|
217
|
+
upload_max_filesize = '%sM' % upload_max_filesize
|
|
218
|
+
|
|
219
|
+
ini_set('short_open_tag', short_open_tag, initype='php')
|
|
220
|
+
ini_set('expose_php', expose_php, initype='php')
|
|
221
|
+
ini_set('max_execution_time', max_execution_time, initype='php')
|
|
222
|
+
ini_set('memory_limit', memory_limit, initype='php')
|
|
223
|
+
ini_set('display_errors', display_errors, initype='php')
|
|
224
|
+
ini_set('post_max_size', post_max_size, initype='php')
|
|
225
|
+
ini_set('upload_max_filesize', upload_max_filesize, initype='php')
|
|
226
|
+
ini_set('date.timezone', date_timezone, initype='php')
|
|
227
|
+
|
|
228
|
+
context.write({'code': 0, 'msg': 'PHP设置保存成功!'})
|
|
229
|
+
|
|
230
|
+
elif action == 'updatefpmsettings':
|
|
231
|
+
listen = context.get_argument('listen', '')
|
|
232
|
+
pm = context.get_argument('pm', '')
|
|
233
|
+
pm_max_children = context.get_argument('pm.max_children', '')
|
|
234
|
+
pm_start_servers = context.get_argument('pm.start_servers', '')
|
|
235
|
+
pm_min_spare_servers = context.get_argument('pm.min_spare_servers', '')
|
|
236
|
+
pm_max_spare_servers = context.get_argument('pm.max_spare_servers', '')
|
|
237
|
+
pm_max_requests = context.get_argument('pm.max_requests', '')
|
|
238
|
+
request_terminate_timeout = context.get_argument('request_terminate_timeout', '')
|
|
239
|
+
request_slowlog_timeout = context.get_argument('request_slowlog_timeout', '')
|
|
240
|
+
|
|
241
|
+
pm = pm.lower() == 'on' and 'dynamic' or 'static'
|
|
242
|
+
if not pm_max_children == '' and not pm_max_children.isdigit():
|
|
243
|
+
context.write({'code': -1, 'msg': 'pm.max_children 必须为数字!'})
|
|
244
|
+
return
|
|
245
|
+
if not pm_start_servers == '' and not pm_start_servers.isdigit():
|
|
246
|
+
context.write({'code': -1, 'msg': 'pm.start_servers 必须为数字!'})
|
|
247
|
+
return
|
|
248
|
+
if not pm_min_spare_servers == '' and not pm_min_spare_servers.isdigit():
|
|
249
|
+
context.write({'code': -1, 'msg': 'pm.min_spare_servers 必须为数字!'})
|
|
250
|
+
return
|
|
251
|
+
if not pm_max_spare_servers == '' and not pm_max_spare_servers.isdigit():
|
|
252
|
+
context.write({'code': -1, 'msg': 'pm.max_spare_servers 必须为数字!'})
|
|
253
|
+
return
|
|
254
|
+
if not pm_max_requests == '' and not pm_max_requests.isdigit():
|
|
255
|
+
context.write({'code': -1, 'msg': 'pm.max_requests 必须为数字!'})
|
|
256
|
+
return
|
|
257
|
+
if not request_terminate_timeout == '' and not request_terminate_timeout.isdigit():
|
|
258
|
+
context.write({'code': -1, 'msg': 'request_terminate_timeout 必须为数字!'})
|
|
259
|
+
return
|
|
260
|
+
if not request_slowlog_timeout == '' and not request_slowlog_timeout.isdigit():
|
|
261
|
+
context.write({'code': -1, 'msg': 'request_slowlog_timeout 必须为数字!'})
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
ini_set('listen', listen, initype='php-fpm')
|
|
265
|
+
ini_set('pm', pm, initype='php-fpm')
|
|
266
|
+
ini_set('pm.max_children', pm_max_children, initype='php-fpm')
|
|
267
|
+
ini_set('pm.start_servers', pm_start_servers, initype='php-fpm')
|
|
268
|
+
ini_set('pm.min_spare_servers', pm_min_spare_servers, initype='php-fpm')
|
|
269
|
+
ini_set('pm.max_spare_servers', pm_max_spare_servers, initype='php-fpm')
|
|
270
|
+
ini_set('pm.max_requests', pm_max_requests, initype='php-fpm')
|
|
271
|
+
ini_set('request_terminate_timeout', request_terminate_timeout, initype='php-fpm')
|
|
272
|
+
ini_set('request_slowlog_timeout', request_slowlog_timeout, initype='php-fpm')
|
|
273
|
+
|
|
274
|
+
context.write({'code': 0, 'msg': 'PHP FastCGI 设置保存成功!'})
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
if __name__ == '__main__':
|
|
278
|
+
import pprint
|
|
279
|
+
pp = pprint.PrettyPrinter(indent=4)
|
|
280
|
+
|
|
281
|
+
# pp.pprint(loadconfig())
|
|
282
|
+
#print ini_get('short_open_tag', detail=True)
|
|
283
|
+
#print ini_set('short_open_tag', 'On', commented=False)
|
|
284
|
+
#print ini_get('date.timezone', detail=True)
|
|
285
|
+
#print ini_set('date.timezone', '', commented=False)
|
|
286
|
+
|
|
287
|
+
# pp.pprint(loadconfig('php-fpm'))
|
|
288
|
+
#print ini_get('pm', detail=False, initype='php-fpm')
|
|
289
|
+
#print ini_set('pm', 'static', initype='php-fpm')
|
inpanel/mod/process.py
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# InPanel is distributed under the terms of the New BSD License.
|
|
7
|
+
# The full license can be found in 'LICENSE'.
|
|
8
|
+
'''Module for process Management.'''
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from subprocess import getstatusoutput
|
|
12
|
+
|
|
13
|
+
import psutil
|
|
14
|
+
|
|
15
|
+
from ..base import kernel_name
|
|
16
|
+
from ..web import RequestHandler
|
|
17
|
+
|
|
18
|
+
# from utils import b2h
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class WebRequestProcess(RequestHandler):
|
|
22
|
+
'''Handler for load process list.'''
|
|
23
|
+
|
|
24
|
+
def get(self, sec, pid=None):
|
|
25
|
+
self.authed()
|
|
26
|
+
|
|
27
|
+
if sec == 'list':
|
|
28
|
+
self.write({'code': 0, 'data': get_list()})
|
|
29
|
+
elif sec == 'info':
|
|
30
|
+
self.write({'code': 0, 'data': get_info(pid)})
|
|
31
|
+
elif sec == 'status':
|
|
32
|
+
res = get_status(pid)
|
|
33
|
+
if res:
|
|
34
|
+
self.write({'code': 0, 'data': res})
|
|
35
|
+
else:
|
|
36
|
+
self.write({'code': -1, 'msg': '获取进程状态信息失败!'})
|
|
37
|
+
elif sec == 'file':
|
|
38
|
+
self.write({'code': 0, 'data': get_file(pid)})
|
|
39
|
+
elif sec == 'memory':
|
|
40
|
+
self.write({'code': 0, 'data': get_memory(pid)})
|
|
41
|
+
elif sec == 'network':
|
|
42
|
+
self.write({'code': 0, 'data': get_network(pid)})
|
|
43
|
+
else:
|
|
44
|
+
self.write({'code': -1, 'msg': '操作非法!'})
|
|
45
|
+
|
|
46
|
+
def post(self, sec, pids):
|
|
47
|
+
self.authed()
|
|
48
|
+
|
|
49
|
+
if self.config.get('runtime', 'mode') == 'demo':
|
|
50
|
+
self.write({'code': -1, 'msg': '演示模式不允许操作进程!'})
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
if sec == 'kill':
|
|
54
|
+
if kill_pid(pids):
|
|
55
|
+
self.write({'code': 0, 'msg': '进程终止成功!'})
|
|
56
|
+
else:
|
|
57
|
+
self.write({'code': -1, 'msg': '进程终止失败!'})
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def get_list():
|
|
61
|
+
'''get process list'''
|
|
62
|
+
res = []
|
|
63
|
+
pids = psutil.pids()
|
|
64
|
+
# print('pids', pids)
|
|
65
|
+
for pid in pids:
|
|
66
|
+
item = get_base(pid)
|
|
67
|
+
if item is not None:
|
|
68
|
+
res.append(item)
|
|
69
|
+
return res
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def get_name(pid):
|
|
73
|
+
'''get name by pid'''
|
|
74
|
+
if not pid:
|
|
75
|
+
return None
|
|
76
|
+
p = psutil.Process(int(pid))
|
|
77
|
+
return p.name()
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def kill_process(name=None):
|
|
81
|
+
'''kill process by name'''
|
|
82
|
+
if name is None:
|
|
83
|
+
return None
|
|
84
|
+
pids = get_pids(name)
|
|
85
|
+
# print('pid', pids)
|
|
86
|
+
if pids:
|
|
87
|
+
return kill_pid(pids)
|
|
88
|
+
else:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def kill_pid(pid):
|
|
93
|
+
'''kill process by pids'''
|
|
94
|
+
if not pid:
|
|
95
|
+
return None
|
|
96
|
+
# print('kill_pid', pid)
|
|
97
|
+
p = psutil.Process(int(pid))
|
|
98
|
+
try:
|
|
99
|
+
p.kill()
|
|
100
|
+
return True
|
|
101
|
+
except:
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
def get_pids(name):
|
|
105
|
+
'''get pids of a process'''
|
|
106
|
+
if not name:
|
|
107
|
+
return None
|
|
108
|
+
res = []
|
|
109
|
+
# /bin/ps auxww | grep php | grep -v grep | awk '{print $2}'
|
|
110
|
+
if kernel_name in ('Linux', 'Darwin'):
|
|
111
|
+
cmd = "/bin/ps auxww | grep %s | grep -v grep | awk '{print $2}'" % name
|
|
112
|
+
status, result = getstatusoutput(cmd)
|
|
113
|
+
if status == 0 and result:
|
|
114
|
+
res = ' '.join(result.split()).split(' ') # list
|
|
115
|
+
return res
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def get_cmdline(pid):
|
|
119
|
+
'''parse cmdline'''
|
|
120
|
+
if not pid:
|
|
121
|
+
return None
|
|
122
|
+
if kernel_name == 'Linux':
|
|
123
|
+
p = '/proc/%s/cmdline' % pid
|
|
124
|
+
if not Path(p).exists():
|
|
125
|
+
return None
|
|
126
|
+
with open(p, 'r', encoding='utf-8') as f:
|
|
127
|
+
line = f.readline()
|
|
128
|
+
return line.strip()
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def get_base(pid=None):
|
|
132
|
+
'''get base info'''
|
|
133
|
+
if pid is None:
|
|
134
|
+
return {}
|
|
135
|
+
p = psutil.Process(int(pid))
|
|
136
|
+
memory = p.memory_info()
|
|
137
|
+
return {
|
|
138
|
+
'name': p.name(), # 进程名
|
|
139
|
+
'status': p.status(), # 进程状态
|
|
140
|
+
'pid': pid,
|
|
141
|
+
'ppid': p.ppid(),
|
|
142
|
+
'rss': str(memory[0]), # rss 是常驻集大小,它是进程使用的实际物理内存
|
|
143
|
+
'vms': str(memory[1]) # vms 是虚拟内存大小,它是进程正在使用的虚拟内存
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def get_file(pid=None):
|
|
148
|
+
'''get files opened by process'''
|
|
149
|
+
if pid is None:
|
|
150
|
+
return []
|
|
151
|
+
p = psutil.Process(int(pid))
|
|
152
|
+
return p.open_files()
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def save_pid_file(pidfile, pid):
|
|
156
|
+
'''create/save pid file'''
|
|
157
|
+
pidfile_path = Path(pidfile)
|
|
158
|
+
if not pidfile_path.parent.exists():
|
|
159
|
+
pidfile_path.parent.mkdir(parents=True, exist_ok=True)
|
|
160
|
+
with open(pidfile, 'w+', encoding='utf-8') as f:
|
|
161
|
+
f.write(str(pid))
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def remove_pid_file(pidfile):
|
|
165
|
+
'''remove pid file'''
|
|
166
|
+
pidfile_path = Path(pidfile)
|
|
167
|
+
if pidfile_path.exists():
|
|
168
|
+
pidfile_path.unlink()
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def get_status(pid=None):
|
|
172
|
+
'''parse status'''
|
|
173
|
+
if pid is None:
|
|
174
|
+
return None
|
|
175
|
+
p = psutil.Process(int(pid))
|
|
176
|
+
return p.status()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def get_io(pid):
|
|
180
|
+
'''parse io'''
|
|
181
|
+
if not pid:
|
|
182
|
+
return None
|
|
183
|
+
res = {}
|
|
184
|
+
if kernel_name == 'Linux':
|
|
185
|
+
p = '/proc/%s/io' % pid
|
|
186
|
+
if not Path(p).exists():
|
|
187
|
+
return None
|
|
188
|
+
with open(p, 'r', encoding='utf-8') as f:
|
|
189
|
+
line = f.readline()
|
|
190
|
+
while line:
|
|
191
|
+
out = line.strip()
|
|
192
|
+
res[out.split()[0].split(':')[0].lower()] = out.split()[1]
|
|
193
|
+
line = f.readline()
|
|
194
|
+
return res
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def get_memory(pid=None):
|
|
198
|
+
'''get memory'''
|
|
199
|
+
if pid is None:
|
|
200
|
+
return {}
|
|
201
|
+
p = psutil.Process(int(pid))
|
|
202
|
+
return p.memory_info()
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def get_info(pid=None):
|
|
206
|
+
'''get info'''
|
|
207
|
+
if pid is None:
|
|
208
|
+
return {}
|
|
209
|
+
p = psutil.Process(int(pid))
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
'pid': pid,
|
|
213
|
+
'name': p.name(), # 进程名
|
|
214
|
+
'ppid': p.ppid(), # 父进程ID
|
|
215
|
+
'cmdline': p.cmdline(), # 启动的命令行
|
|
216
|
+
'exe': p.exe(), # 进程exe路径
|
|
217
|
+
'cwd': p.cwd(), # 进程的工作目录绝对路径
|
|
218
|
+
'status': p.status(), # 进程状态
|
|
219
|
+
'create_time': p.create_time(), # 进程创建时间秒
|
|
220
|
+
'uids': p.uids(), # 进程uid信息
|
|
221
|
+
'gids': p.gids(), # 进程gids信息
|
|
222
|
+
'username': p.username(), # 进程用户名
|
|
223
|
+
'cpu_percent': p.cpu_percent(), # CPU利用率
|
|
224
|
+
'cpu_times': p.cpu_times(), # 进程的cpu时间信息,包括user,system两个cpu信息
|
|
225
|
+
'memory_info': p.memory_info(), # 进程内存rss,vms信息 [utils.b2h(i) for i in p.memory_info()]
|
|
226
|
+
'memory_percent': p.memory_percent(),
|
|
227
|
+
'terminal': p.terminal(), # 进程终端
|
|
228
|
+
'num_threads': p.num_threads(), # 进程开启的线程数
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def get_network(pid=None):
|
|
233
|
+
'''parse network'''
|
|
234
|
+
if pid is None:
|
|
235
|
+
return None
|
|
236
|
+
res = []
|
|
237
|
+
p = psutil.Process(int(pid))
|
|
238
|
+
net = p.connections()
|
|
239
|
+
# print('net', net)
|
|
240
|
+
for n in net:
|
|
241
|
+
res.append({
|
|
242
|
+
'local': {
|
|
243
|
+
'ip': n[3][0],
|
|
244
|
+
'port': n[3][1]
|
|
245
|
+
} if n[3] else None,
|
|
246
|
+
'remote': {
|
|
247
|
+
'ip': n[4][0],
|
|
248
|
+
'port': n[4][1]
|
|
249
|
+
} if n[4] else None,
|
|
250
|
+
'status': n[5]
|
|
251
|
+
})
|
|
252
|
+
# print('res', res)
|
|
253
|
+
return res
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
if __name__ == '__main__':
|
|
257
|
+
pass
|
|
258
|
+
# pids = get_list()
|
|
259
|
+
# print(pids)
|
|
260
|
+
# print('kill_process', kill_process('sshd'))
|
|
261
|
+
# print('kill_pid00', kill_pids(11587))
|
|
262
|
+
# print(get_pids('php'))
|
|
263
|
+
# print(get_list())
|
|
264
|
+
# print(get_info(144))
|
|
265
|
+
# print(get_network(144))
|
|
266
|
+
# print('psutil.process_iter()', psutil.process_iter())
|
|
267
|
+
# pid = 78269
|
|
268
|
+
# p = psutil.Process(pid)
|
|
269
|
+
# # p = psutil.process_iter()
|
|
270
|
+
# # p = psutil.pids()
|
|
271
|
+
# memory = p.memory_info()
|
|
272
|
+
# # print('memory', memory)
|
|
273
|
+
# res = {
|
|
274
|
+
# 'name': p.name(), # 进程名
|
|
275
|
+
# 'status': p.status(), # 进程状态
|
|
276
|
+
# 'uid': p.uids(), # 进程状态
|
|
277
|
+
# 'tgid': p.gids(), # 进程的gid信息
|
|
278
|
+
# 'create_time': p.create_time(), # 进程创建时间
|
|
279
|
+
# 'pid': pid,
|
|
280
|
+
# 'ppid': p.ppid(),
|
|
281
|
+
# # 'fdsize': '',
|
|
282
|
+
# # 'vmpeak': memory[0],
|
|
283
|
+
# 'vmsize': memory[0],
|
|
284
|
+
# 'vmrss': memory[1]
|
|
285
|
+
# }
|
|
286
|
+
# # print('res', res)
|
|
287
|
+
# # for p in pi:
|
|
288
|
+
# # try:
|
|
289
|
+
# # print('p', p)
|
|
290
|
+
# # except psutil.Error:
|
|
291
|
+
# # pass
|
inpanel/mod/proftpd.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# InPanel is distributed under the terms of the New BSD License.
|
|
7
|
+
# The full license can be found in 'LICENSE'.
|
|
8
|
+
|
|
9
|
+
"""Module for ProFTPD configuration management."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def web_handler(self):
|
|
13
|
+
action = self.get_argument('action', '')
|
|
14
|
+
if action == 'getsettings':
|
|
15
|
+
self.write({'code': 0, 'msg': 'ProFTPD 配置信息获取成功!', 'data': get_config()})
|
|
16
|
+
elif action == 'savesettings':
|
|
17
|
+
self.write({'code': 0, 'msg': 'ProFTPD 服务配置保存成功!', 'data': set_config(self)})
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_config():
|
|
22
|
+
return dict()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def set_config(self):
|
|
26
|
+
return dict()
|
inpanel/mod/pureftpd.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# Copyright (c) 2017-2026 Jackson Dou
|
|
4
|
+
# All rights reserved.
|
|
5
|
+
#
|
|
6
|
+
# InPanel is distributed under the terms of the New BSD License.
|
|
7
|
+
# The full license can be found in 'LICENSE'.
|
|
8
|
+
|
|
9
|
+
"""Module for Pure-FTPd configuration management."""
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def web_handler(self):
|
|
13
|
+
action = self.get_argument('action', '')
|
|
14
|
+
if action == 'getsettings':
|
|
15
|
+
self.write({'code': 0, 'msg': 'Pure-FTPd 配置信息获取成功!', 'data': get_config()})
|
|
16
|
+
elif action == 'savesettings':
|
|
17
|
+
self.write({'code': 0, 'msg': 'Pure-FTPd 服务配置保存成功!', 'data': set_config(self)})
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_config():
|
|
22
|
+
return dict()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def set_config(self):
|
|
26
|
+
return dict()
|