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.
Files changed (198) hide show
  1. inpanel/__init__.py +29 -0
  2. inpanel/acme.py +289 -0
  3. inpanel/aliyuncs.py +269 -0
  4. inpanel/app.py +514 -0
  5. inpanel/apt.py +223 -0
  6. inpanel/base.py +200 -0
  7. inpanel/config.py +139 -0
  8. inpanel/data/config.ini +29 -0
  9. inpanel/data/history +5 -0
  10. inpanel/data/runlogs.ini +12 -0
  11. inpanel/data/update_info.ini +4 -0
  12. inpanel/dnf.py +225 -0
  13. inpanel/lib/__init__.py +9 -0
  14. inpanel/lib/async_process.py +98 -0
  15. inpanel/lib/filelock.py +82 -0
  16. inpanel/lib/magic.py +233 -0
  17. inpanel/lib/pxssh.py +310 -0
  18. inpanel/lib/pyDes.py +867 -0
  19. inpanel/mod/__init__.py +0 -0
  20. inpanel/mod/apt.py +316 -0
  21. inpanel/mod/certificate.py +268 -0
  22. inpanel/mod/config.py +372 -0
  23. inpanel/mod/cron.py +315 -0
  24. inpanel/mod/disk.py +322 -0
  25. inpanel/mod/dnf.py +239 -0
  26. inpanel/mod/file.py +722 -0
  27. inpanel/mod/firewall.py +199 -0
  28. inpanel/mod/firewall_base.py +137 -0
  29. inpanel/mod/firewall_firewalld.py +170 -0
  30. inpanel/mod/firewall_iptables.py +176 -0
  31. inpanel/mod/firewall_macos.py +213 -0
  32. inpanel/mod/firewall_ufw.py +128 -0
  33. inpanel/mod/ftp.py +231 -0
  34. inpanel/mod/httpd.py +1205 -0
  35. inpanel/mod/lighttpd.py +26 -0
  36. inpanel/mod/login.py +98 -0
  37. inpanel/mod/mysql.py +577 -0
  38. inpanel/mod/named.py +26 -0
  39. inpanel/mod/nginx.py +2327 -0
  40. inpanel/mod/package.py +33 -0
  41. inpanel/mod/package_apt.py +62 -0
  42. inpanel/mod/package_base.py +77 -0
  43. inpanel/mod/package_dnf.py +62 -0
  44. inpanel/mod/package_map.py +366 -0
  45. inpanel/mod/package_yum.py +64 -0
  46. inpanel/mod/php.py +289 -0
  47. inpanel/mod/process.py +291 -0
  48. inpanel/mod/proftpd.py +26 -0
  49. inpanel/mod/pureftpd.py +26 -0
  50. inpanel/mod/query.py +108 -0
  51. inpanel/mod/server.py +1319 -0
  52. inpanel/mod/service.py +262 -0
  53. inpanel/mod/setting.py +228 -0
  54. inpanel/mod/shell.py +78 -0
  55. inpanel/mod/ssh.py +280 -0
  56. inpanel/mod/system.py +220 -0
  57. inpanel/mod/task.py +1337 -0
  58. inpanel/mod/ufw.py +14 -0
  59. inpanel/mod/user.py +306 -0
  60. inpanel/mod/vsftpd.py +67 -0
  61. inpanel/mod/yum.py +243 -0
  62. inpanel/plugins/__init__.py +10 -0
  63. inpanel/plugins/__pycache__/__init__.cpython-313.pyc +0 -0
  64. inpanel/plugins/acme/static/index.html +10 -0
  65. inpanel/plugins/acme/static/index.js +13 -0
  66. inpanel/plugins/shadowsocks-libev/__pycache__/info.cpython-313.pyc +0 -0
  67. inpanel/plugins/shadowsocks-libev/info.py +73 -0
  68. inpanel/plugins/shadowsocks-libev/static/index.html +70 -0
  69. inpanel/plugins/shadowsocks-libev/static/index.js +18 -0
  70. inpanel/public/css/global.css +138 -0
  71. inpanel/public/favicon.ico +0 -0
  72. inpanel/public/images/alipay.jpg +0 -0
  73. inpanel/public/images/loading.gif +0 -0
  74. inpanel/public/images/weixin.jpg +0 -0
  75. inpanel/public/index.html +94 -0
  76. inpanel/public/js/controllers/controllers.js +566 -0
  77. inpanel/public/js/controllers/database.js +590 -0
  78. inpanel/public/js/controllers/ecs.js +624 -0
  79. inpanel/public/js/controllers/file.js +940 -0
  80. inpanel/public/js/controllers/plugins.js +105 -0
  81. inpanel/public/js/controllers/service.js +1460 -0
  82. inpanel/public/js/controllers/site.js +1241 -0
  83. inpanel/public/js/controllers/utils.js +2319 -0
  84. inpanel/public/js/core.js +221 -0
  85. inpanel/public/js/directives.js +784 -0
  86. inpanel/public/js/filters.js +395 -0
  87. inpanel/public/js/services.js +257 -0
  88. inpanel/public/lib/angular/1.0.2/angular-resource.min.js +10 -0
  89. inpanel/public/lib/angular/1.0.2/angular.min.js +158 -0
  90. inpanel/public/lib/bootstrap/css/bootstrap-theme.css +587 -0
  91. inpanel/public/lib/bootstrap/css/bootstrap-theme.css.map +1 -0
  92. inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css +6 -0
  93. inpanel/public/lib/bootstrap/css/bootstrap-theme.min.css.map +1 -0
  94. inpanel/public/lib/bootstrap/css/bootstrap.css +6757 -0
  95. inpanel/public/lib/bootstrap/css/bootstrap.css.map +1 -0
  96. inpanel/public/lib/bootstrap/css/bootstrap.min.css +6 -0
  97. inpanel/public/lib/bootstrap/css/bootstrap.min.css.map +1 -0
  98. inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.eot +0 -0
  99. inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.svg +288 -0
  100. inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf +0 -0
  101. inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff +0 -0
  102. inpanel/public/lib/bootstrap/fonts/glyphicons-halflings-regular.woff2 +0 -0
  103. inpanel/public/lib/bootstrap/img/glyphicons-halflings-white.png +0 -0
  104. inpanel/public/lib/bootstrap/img/glyphicons-halflings.png +0 -0
  105. inpanel/public/lib/bootstrap/js/bootstrap.js +2377 -0
  106. inpanel/public/lib/bootstrap/js/bootstrap.min.js +7 -0
  107. inpanel/public/lib/bootstrap/js/npm.js +13 -0
  108. inpanel/public/lib/codemirror/codemirror-compressed.js +1 -0
  109. inpanel/public/lib/codemirror/codemirror.css +173 -0
  110. inpanel/public/lib/jquery/jquery-1.12.4.min.js +5 -0
  111. inpanel/public/lib/md5/md5.js +379 -0
  112. inpanel/public/lib/md5/md5.min.js +1 -0
  113. inpanel/public/partials/database/index.html +172 -0
  114. inpanel/public/partials/database/mysql/dbedit.html +462 -0
  115. inpanel/public/partials/database/mysql/dbnew.html +348 -0
  116. inpanel/public/partials/database/mysql/useredit.html +310 -0
  117. inpanel/public/partials/database/mysql/usernew.html +97 -0
  118. inpanel/public/partials/directives/message.html +20 -0
  119. inpanel/public/partials/directives/navbar.html +25 -0
  120. inpanel/public/partials/directives/selector.html +57 -0
  121. inpanel/public/partials/directives/srvbase.html +72 -0
  122. inpanel/public/partials/directives/srvext.html +34 -0
  123. inpanel/public/partials/directives/srvfile.html +23 -0
  124. inpanel/public/partials/directives/srvinstall.html +34 -0
  125. inpanel/public/partials/directives/srvlog.html +23 -0
  126. inpanel/public/partials/directives/srvminiop.html +28 -0
  127. inpanel/public/partials/directives/srvuninstall.html +38 -0
  128. inpanel/public/partials/directives/srvupdate.html +30 -0
  129. inpanel/public/partials/ecs/account.html +156 -0
  130. inpanel/public/partials/ecs/ecs.html +198 -0
  131. inpanel/public/partials/ecs/index.html +40 -0
  132. inpanel/public/partials/ecs/setings.html +459 -0
  133. inpanel/public/partials/file/file.html +501 -0
  134. inpanel/public/partials/file/trash.html +95 -0
  135. inpanel/public/partials/ftp.html +36 -0
  136. inpanel/public/partials/log.html +83 -0
  137. inpanel/public/partials/login.html +79 -0
  138. inpanel/public/partials/logout.html +22 -0
  139. inpanel/public/partials/main.html +534 -0
  140. inpanel/public/partials/plugins/index.html +55 -0
  141. inpanel/public/partials/plugins/plugins.html +13 -0
  142. inpanel/public/partials/secure.html +13 -0
  143. inpanel/public/partials/service/apache.html +147 -0
  144. inpanel/public/partials/service/cron.html +71 -0
  145. inpanel/public/partials/service/index.html +293 -0
  146. inpanel/public/partials/service/iptables.html +40 -0
  147. inpanel/public/partials/service/lighttpd.html +63 -0
  148. inpanel/public/partials/service/mariadb.html +113 -0
  149. inpanel/public/partials/service/memcache.html +36 -0
  150. inpanel/public/partials/service/minio.html +44 -0
  151. inpanel/public/partials/service/mongodb.html +44 -0
  152. inpanel/public/partials/service/mysql.html +113 -0
  153. inpanel/public/partials/service/named.html +61 -0
  154. inpanel/public/partials/service/nginx.html +296 -0
  155. inpanel/public/partials/service/ntp.html +40 -0
  156. inpanel/public/partials/service/php.html +250 -0
  157. inpanel/public/partials/service/proftpd.html +59 -0
  158. inpanel/public/partials/service/pureftpd.html +59 -0
  159. inpanel/public/partials/service/redis.html +40 -0
  160. inpanel/public/partials/service/samba.html +58 -0
  161. inpanel/public/partials/service/sendmail.html +40 -0
  162. inpanel/public/partials/service/ssh.html +186 -0
  163. inpanel/public/partials/service/tomcat.html +65 -0
  164. inpanel/public/partials/service/vsftpd.html +195 -0
  165. inpanel/public/partials/setting.html +299 -0
  166. inpanel/public/partials/site/apache/site.html +277 -0
  167. inpanel/public/partials/site/index.html +344 -0
  168. inpanel/public/partials/site/nginx/site.html +558 -0
  169. inpanel/public/partials/sorry.html +19 -0
  170. inpanel/public/partials/storage/autofm.html +103 -0
  171. inpanel/public/partials/storage/backup.html +42 -0
  172. inpanel/public/partials/storage/index.html +360 -0
  173. inpanel/public/partials/storage/migrate.html +93 -0
  174. inpanel/public/partials/storage/movedata.html +98 -0
  175. inpanel/public/partials/storage/remote.html +77 -0
  176. inpanel/public/partials/utils/cron.html +486 -0
  177. inpanel/public/partials/utils/firewall.html +266 -0
  178. inpanel/public/partials/utils/index.html +193 -0
  179. inpanel/public/partials/utils/network.html +118 -0
  180. inpanel/public/partials/utils/process.html +239 -0
  181. inpanel/public/partials/utils/repository.html +373 -0
  182. inpanel/public/partials/utils/shell.html +28 -0
  183. inpanel/public/partials/utils/ssl.html +319 -0
  184. inpanel/public/partials/utils/time.html +109 -0
  185. inpanel/public/partials/utils/user.html +359 -0
  186. inpanel/public/robots.txt +2 -0
  187. inpanel/remote.py +109 -0
  188. inpanel/templates/file/preview.html +34 -0
  189. inpanel/templates/index.html +93 -0
  190. inpanel/utils.py +282 -0
  191. inpanel/web.py +1811 -0
  192. inpanel/yum.py +756 -0
  193. inpanel-1.2.1.dist-info/METADATA +399 -0
  194. inpanel-1.2.1.dist-info/RECORD +198 -0
  195. inpanel-1.2.1.dist-info/WHEEL +5 -0
  196. inpanel-1.2.1.dist-info/entry_points.txt +2 -0
  197. inpanel-1.2.1.dist-info/licenses/LICENSE +30 -0
  198. 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()
@@ -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()