mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 02:19:25 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1b3e70816 | ||
|
|
6f4479558f | ||
|
|
f817792aeb | ||
|
|
c8c0e44143 | ||
|
|
6668c2e14b | ||
|
|
721f041c65 | ||
|
|
87239f5361 | ||
|
|
b48e3cbfcc | ||
|
|
4b41c6df57 | ||
|
|
b491a6e913 | ||
|
|
42271c5562 | ||
|
|
ef63465aea | ||
|
|
98745e8134 | ||
|
|
2fb293c89c | ||
|
|
4e0db8d0a1 | ||
|
|
4b1e40b42d | ||
|
|
935bee90f7 | ||
|
|
0489a9df2c | ||
|
|
20a4154240 | ||
|
|
a8ced31d32 | ||
|
|
ac97b8f7ec | ||
|
|
a797cd3741 | ||
|
|
a616736bf1 | ||
|
|
8a90f5cb90 | ||
|
|
419d4abe8e | ||
|
|
ba555fba63 | ||
|
|
7ead8708bc | ||
|
|
bd5b066afe | ||
|
|
6d08c160e0 | ||
|
|
f24f8a3a16 | ||
|
|
707b0d4b53 | ||
|
|
d19e9cd8f4 | ||
|
|
a2d0cc6cfe | ||
|
|
356fd831fb | ||
|
|
ec4988e732 | ||
|
|
3a694b8d7d | ||
|
|
d5945fd449 | ||
|
|
10186786d9 | ||
|
|
0eb8791e84 | ||
|
|
5234b55798 | ||
|
|
4efe740504 | ||
|
|
bde0ed59ad | ||
|
|
19c855790f | ||
|
|
4a90f1b8b0 | ||
|
|
f83bdffed8 | ||
|
|
087cb4fc37 | ||
|
|
66bcd15502 | ||
|
|
29e3dedbe9 | ||
|
|
f10160c239 | ||
|
|
376d09a955 | ||
|
|
9076a3a11a | ||
|
|
57719990d5 | ||
|
|
7073d66662 | ||
|
|
1983d02107 | ||
|
|
b4acb2942f | ||
|
|
c94a662235 | ||
|
|
1d61026dd3 | ||
|
|
48a55e279e | ||
|
|
55e9313711 | ||
|
|
5ab59c3b75 | ||
|
|
9c045b8e85 | ||
|
|
65e87fec1a | ||
|
|
dc8f508ac5 | ||
|
|
ce0c2fb9ea | ||
|
|
d7e70aa701 | ||
|
|
ceacaaf7ae | ||
|
|
36ad902250 | ||
|
|
7a871d3e16 | ||
|
|
f36ba4a351 | ||
|
|
5093265a24 | ||
|
|
9c4347f692 | ||
|
|
cb882ab7a1 | ||
|
|
0d5fd1b423 | ||
|
|
e694635088 | ||
|
|
3386ae2064 | ||
|
|
bbaced5976 | ||
|
|
c0d5c5c0e6 | ||
|
|
f9f7de48ef | ||
|
|
5555eab5c0 | ||
|
|
654737cbd2 | ||
|
|
04568df3df | ||
|
|
b1e8839ace | ||
|
|
80c6f91206 | ||
|
|
315b8e0e48 | ||
|
|
ed295d5456 | ||
|
|
eb38d81674 | ||
|
|
0bc3b42819 | ||
|
|
8a640981d2 | ||
|
|
7b94a61b65 | ||
|
|
e24151f332 | ||
|
|
dc43953c05 | ||
|
|
160ff6a4a7 | ||
|
|
a218ba05d2 | ||
|
|
65cb4941af | ||
|
|
53a12e7c4b | ||
|
|
6db8a906ff | ||
|
|
fc6c86e3ce | ||
|
|
f5989c881d | ||
|
|
b4946a87ee | ||
|
|
562e153371 | ||
|
|
63ea0cc129 | ||
|
|
8eacae7c6a | ||
|
|
3e48c3871a | ||
|
|
22df4cb5b1 | ||
|
|
2d5d954586 | ||
|
|
63ce3805ee | ||
|
|
3fe4918b55 | ||
|
|
24cc733e45 | ||
|
|
1ebb9e1ff3 | ||
|
|
9769f2c190 | ||
|
|
de91e4545b | ||
|
|
8d3c87a25e | ||
|
|
660e393cf1 | ||
|
|
fa5f2d6de5 | ||
|
|
f27406d343 | ||
|
|
488577af68 | ||
|
|
0f7b462b43 | ||
|
|
998f1ceae5 | ||
|
|
2a9bec3fb8 | ||
|
|
5c301296df | ||
|
|
45b0e94132 | ||
|
|
06be751d1a | ||
|
|
f939b03a0b | ||
|
|
3339406f37 | ||
|
|
f32d07ccc9 | ||
|
|
ab8f1623bf | ||
|
|
d467d73230 | ||
|
|
4b0dd7d3fb | ||
|
|
91d243f8b1 | ||
|
|
d682882d25 | ||
|
|
0b3745c933 | ||
|
|
935c3012f9 | ||
|
|
a191548a83 | ||
|
|
9a01d61e1e | ||
|
|
7524798385 | ||
|
|
86e3796524 | ||
|
|
37d68f5ff8 | ||
|
|
647e3904d2 | ||
|
|
c5abb3eea1 | ||
|
|
65c94c64ae | ||
|
|
dbc132951b | ||
|
|
440ba49e7b | ||
|
|
6a0f78b1a0 | ||
|
|
a69ff3e373 | ||
|
|
770d37e575 | ||
|
|
e725ad90ca | ||
|
|
bf5d8f7f27 | ||
|
|
9bc72b23d6 | ||
|
|
3ac3350240 | ||
|
|
c1d04b0a16 | ||
|
|
1962cece21 | ||
|
|
0d24b8aebd | ||
|
|
de50de0a75 | ||
|
|
190fc88d4f | ||
|
|
727a7872a7 | ||
|
|
d408d56826 | ||
|
|
1cccd63edc | ||
|
|
cc50816286 | ||
|
|
04426c7a67 | ||
|
|
3979820eae | ||
|
|
3a850a31a1 | ||
|
|
6f5487b487 | ||
|
|
d09a96ec84 | ||
|
|
dcc4e14e7b | ||
|
|
e947b8db4e | ||
|
|
158a66ab62 | ||
|
|
df596fc673 | ||
|
|
707fd668d5 | ||
|
|
b96c4c00e3 | ||
|
|
bc6cf72cfe | ||
|
|
48dacb4c27 | ||
|
|
78c9abbde2 | ||
|
|
d8d772c6dc | ||
|
|
33e114ffdd | ||
|
|
552b63d329 | ||
|
|
36637260a7 | ||
|
|
53fbb5039b | ||
|
|
74152af289 | ||
|
|
5bf4401fb0 | ||
|
|
12117a3b27 | ||
|
|
d726f1bb15 | ||
|
|
a2b316b4d2 | ||
|
|
0d48e5250a | ||
|
|
d3cd606432 | ||
|
|
600435f23c | ||
|
|
b4831d64b9 | ||
|
|
6638967636 | ||
|
|
ead409a58c | ||
|
|
971da145cb | ||
|
|
055d440484 | ||
|
|
97e2d131b4 | ||
|
|
e2784d2d55 | ||
|
|
6b697ae3be | ||
|
|
207fa1d15e | ||
|
|
454e399d3d | ||
|
|
6ea8f20a9d | ||
|
|
9dc3496c27 | ||
|
|
b523b84609 | ||
|
|
e443b88ad9 | ||
|
|
480ae78579 | ||
|
|
fb31e3ca15 | ||
|
|
53fdaed5c3 | ||
|
|
37f6f2b6bc | ||
|
|
d1028bcc41 | ||
|
|
72e7800b50 | ||
|
|
bb717d2963 | ||
|
|
16787aebd0 | ||
|
|
d769822731 | ||
|
|
b6073ba8d3 | ||
|
|
8d50f75f18 | ||
|
|
8077b4cb13 | ||
|
|
7a9f1ebf5e | ||
|
|
21f5670a85 | ||
|
|
dbd0664c72 | ||
|
|
f9e53164d9 | ||
|
|
62e0321126 | ||
|
|
51b82ecbbb | ||
|
|
0229f50fef | ||
|
|
be176001ea | ||
|
|
3bea21bb94 | ||
|
|
4b3104c849 | ||
|
|
0cbb1ad02e | ||
|
|
221f114dd4 | ||
|
|
5a5c2f3e33 | ||
|
|
69de62f8c3 | ||
|
|
af7698e157 | ||
|
|
f0af84f940 | ||
|
|
4802dde50a | ||
|
|
fcbf7be2b6 | ||
|
|
f77484df84 | ||
|
|
64ccba7595 | ||
|
|
b1935372a1 | ||
|
|
03c9afed4a | ||
|
|
4e63c82e93 | ||
|
|
6fa2fde791 | ||
|
|
98353df1ee | ||
|
|
50978741aa | ||
|
|
d4431f11be | ||
|
|
3faad62dd8 | ||
|
|
6d2550e607 | ||
|
|
f835e4d6a1 | ||
|
|
e33bdc5b7d | ||
|
|
1e6fe01819 | ||
|
|
c522738df5 | ||
|
|
5a8be9de7c | ||
|
|
fd9c860d9b | ||
|
|
306a6d450f | ||
|
|
79fd1d7157 | ||
|
|
9276e811c2 | ||
|
|
d1493ca13f | ||
|
|
13c605d58a | ||
|
|
36d19f2250 | ||
|
|
8f229c99be | ||
|
|
72b16e9540 | ||
|
|
dbe2a1f0df | ||
|
|
4c3f8c095f | ||
|
|
589933dc33 | ||
|
|
de36f41182 | ||
|
|
8e1b4881c4 | ||
|
|
692872ecd6 | ||
|
|
d422a640d5 | ||
|
|
46d293613e | ||
|
|
b775625890 | ||
|
|
eb2bb595de | ||
|
|
0ddc3bf762 | ||
|
|
e45604f211 | ||
|
|
4f22d9ae70 | ||
|
|
732363ec41 | ||
|
|
bc688aa93f | ||
|
|
56ed68b888 | ||
|
|
90539a5049 | ||
|
|
df15100272 | ||
|
|
4bfec3ac06 | ||
|
|
3a80a27970 | ||
|
|
09e79aff63 | ||
|
|
41a36a6fd3 | ||
|
|
fc0974dc91 | ||
|
|
4942c92b33 | ||
|
|
e173c2e51a | ||
|
|
daddf317e2 | ||
|
|
7e919050b2 | ||
|
|
af9d050536 | ||
|
|
a9e6acd407 | ||
|
|
180e67dde9 | ||
|
|
f8451fadba | ||
|
|
558bfcb1ee | ||
|
|
6a27e69ee7 | ||
|
|
b5d28b4ef2 | ||
|
|
8f80336901 | ||
|
|
0a78dda06c | ||
|
|
b6c3020705 | ||
|
|
ed70d4faa3 | ||
|
|
46e4f55105 | ||
|
|
235f0b6d66 | ||
|
|
633066088d | ||
|
|
48f223f4f9 | ||
|
|
709a91dcec | ||
|
|
2592291b49 | ||
|
|
502893194e | ||
|
|
8976e97ea5 | ||
|
|
22cb5f3bc2 | ||
|
|
0888b89ea7 | ||
|
|
738e69562e | ||
|
|
511b62d911 | ||
|
|
d748674b49 | ||
|
|
828372f16f | ||
|
|
a349b2bc81 | ||
|
|
4f3fe2af54 | ||
|
|
4670811fd6 | ||
|
|
e1fb85859a | ||
|
|
c0fc1148eb | ||
|
|
50052e7650 | ||
|
|
8053f9b593 | ||
|
|
1a5cdca70d | ||
|
|
341690d234 | ||
|
|
d76654b853 | ||
|
|
0ef35e1474 | ||
|
|
9ea52e452a | ||
|
|
5e39e1a463 | ||
|
|
36421ae254 | ||
|
|
a34f025a36 | ||
|
|
7be4f9ea98 | ||
|
|
2dc93bf490 | ||
|
|
73fb46fcc0 | ||
|
|
f4ea1dc544 | ||
|
|
d17cc990fe | ||
|
|
8edd40393b | ||
|
|
98e653710c | ||
|
|
3eb6937778 | ||
|
|
974eaf3583 | ||
|
|
dadcc2df6d | ||
|
|
639d5413e5 | ||
|
|
1d114d9db7 | ||
|
|
dfa669a032 | ||
|
|
bf370685b3 | ||
|
|
8f9bdde0a1 | ||
|
|
dbbc32258a | ||
|
|
bf79e3028a | ||
|
|
0650858824 | ||
|
|
83f736d5b2 | ||
|
|
bafee3782a | ||
|
|
1aff003ba3 | ||
|
|
30e779686a | ||
|
|
15eccc72f3 | ||
|
|
f69691fac7 | ||
|
|
1ffcb9ca7d | ||
|
|
75514f8e5c | ||
|
|
098be84816 | ||
|
|
8752e394a3 | ||
|
|
0350f3ecbb | ||
|
|
3c855afc43 | ||
|
|
0c8ec2132f | ||
|
|
e3deac06b4 | ||
|
|
b92dbea2c8 | ||
|
|
4da6738909 | ||
|
|
1665256627 | ||
|
|
d49ebe9fa8 | ||
|
|
6dbdf26d80 | ||
|
|
114ed15c02 | ||
|
|
315eb82a89 | ||
|
|
f4ef03304d | ||
|
|
9877d04979 | ||
|
|
e6f379db9d | ||
|
|
ecad324fc6 | ||
|
|
ed13ee1645 | ||
|
|
603c436f4e | ||
|
|
d917c23fda | ||
|
|
a0c4273280 | ||
|
|
8e71d0a306 | ||
|
|
01dfb6f248 | ||
|
|
4ab1d14ffe | ||
|
|
665fe41014 | ||
|
|
ddba4f3abe | ||
|
|
1f65f80bef | ||
|
|
8dd9f707a6 | ||
|
|
14437611c8 | ||
|
|
bfe857ee59 | ||
|
|
01efa67bf1 | ||
|
|
3b3356d5c6 | ||
|
|
6dbfd385fb | ||
|
|
1e9fa587f5 | ||
|
|
fd673b76e8 | ||
|
|
d2340872c0 | ||
|
|
1c14566b6c | ||
|
|
adde0086aa | ||
|
|
b6ca99f1ef | ||
|
|
c920b46a13 | ||
|
|
338e64d295 | ||
|
|
f030f7a97d | ||
|
|
ef7da2ec96 | ||
|
|
6dec09741f | ||
|
|
6d75a65a09 | ||
|
|
8eeb55d555 | ||
|
|
f54feaa87b | ||
|
|
b828fc2188 | ||
|
|
e645be4285 | ||
|
|
05a7b8818e | ||
|
|
391b313a65 | ||
|
|
df7bff4a72 | ||
|
|
2eefd7d3fa | ||
|
|
130e4cf546 | ||
|
|
096dfa6b96 | ||
|
|
77361259c3 | ||
|
|
4aad9f90db |
+2
-2
@@ -154,6 +154,7 @@ data/notify.json
|
||||
data/api.json
|
||||
data/bind_domain.pl
|
||||
data/unauthorized_status.pl
|
||||
data/auth_secret.pl
|
||||
|
||||
plugins/vip_*
|
||||
plugins/own_*
|
||||
@@ -171,10 +172,9 @@ plugins/fastdfs
|
||||
plugins/v2ray
|
||||
plugins/frp
|
||||
plugins/file_search
|
||||
plugins/proxysql
|
||||
debug.out
|
||||
|
||||
|
||||
|
||||
|
||||
mdioks.session-journal
|
||||
*.session
|
||||
|
||||
@@ -29,20 +29,20 @@
|
||||
基本上可以使用,后续会继续优化!欢迎提供意见!
|
||||
|
||||
- 吹水组 - https://t.me/mdserver_web
|
||||
- 交流论坛 - https://bbs.midoks.me
|
||||
|
||||
- 交流论坛 - https://bbs.midoks.icu
|
||||
- discord - https://discord.gg/3zXk4mES
|
||||
```
|
||||
如果出现问题,最好私给我面板信息。不要让我猜。如果不提供,不要提出问题,自行解决。 — 座右铭
|
||||
Talk is cheap, show me the code. -- linus
|
||||
```
|
||||
|
||||
- [兼容性测试报告](/compatibility.md)
|
||||
- [常用命令说明](/cmd.md)
|
||||
- [常用命令说明](/cmd.md) [ mw default ]
|
||||
|
||||
### 主要插件介绍
|
||||
|
||||
* OpenResty - 轻量级,占有内存少,并发能力强。
|
||||
* PHP[53-82] - PHP是世界上最好的编程语言。
|
||||
* PHP[53-83] - PHP是世界上最好的编程语言。
|
||||
* MySQL - 一种关系数据库管理系统。
|
||||
* MariaDB - 是MySQL的一个重要分支。
|
||||
* MySQL[APT/YUM] - 一种关系数据库管理系统。
|
||||
@@ -78,7 +78,7 @@ phpMyAdmin[4.4.15]支持MySQL[5.5-5.7]
|
||||
phpMyAdmin[5.2.0]支持MySQL[8.0]
|
||||
|
||||
PHP[53-72]支持phpMyAdmin[4.4.15]
|
||||
PHP[72-82]支持phpMyAdmin[5.2.0]
|
||||
PHP[72-83]支持phpMyAdmin[5.2.0]
|
||||
```
|
||||
|
||||
# 郑重声明
|
||||
@@ -90,7 +90,7 @@ PHP[72-82]支持phpMyAdmin[5.2.0]
|
||||
|
||||
# 特别赞助
|
||||
|
||||
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.pw/)
|
||||
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan1.cc)
|
||||
|
||||
# AD - VPS推荐 - 🙏
|
||||
|
||||
@@ -102,26 +102,18 @@ PHP[72-82]支持phpMyAdmin[5.2.0]
|
||||
|
||||
# Docker
|
||||
|
||||
- 由[DDSRem](https://github.com/DDSRem)开发维护。
|
||||
- https://hub.docker.com/r/ddsderek/mw
|
||||
- 由[DDS-Derek](https://github.com/DDS-Derek)开发维护。
|
||||
- https://github.com/DDS-Derek/mdserver-web-Docker
|
||||
|
||||
```
|
||||
docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:443 -p 888:888 ddsderek/mw-server:latest
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.16.2
|
||||
### 版本更新 0.16.4
|
||||
|
||||
* keepalived插件改造,集成mysql高可用配置。
|
||||
* redis(主从/集群)配置识别。
|
||||
* MySQL主从同步1236错误,添加修复功能。
|
||||
* MySQL二进制日志查看。
|
||||
* 源码安装成功后删除解压包,节省体积。
|
||||
* 网站统计-增加查询条件。
|
||||
* php增加yaml扩展。
|
||||
* php扩展ioncube修复。
|
||||
* php-fpm增加【按需】配置。
|
||||
* gitea/gogs同步功能改造。
|
||||
* 二次验证。
|
||||
* OP防火墙修复。
|
||||
|
||||
### JSDelivr安装地址
|
||||
|
||||
@@ -149,7 +141,7 @@ wget --no-check-certificate -O uninstall.sh https://cdn.jsdelivr.net/gh/midoks/m
|
||||
|
||||
```
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | bash
|
||||
curl --insecure -fsSL https://code.midoks.me/midoks/mdserver-web/raw/branch/master/scripts/install.sh | bash
|
||||
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/master/scripts/install.sh | bash
|
||||
```
|
||||
|
||||
- 直接更新
|
||||
@@ -186,8 +178,8 @@ wget --no-check-certificate -O uninstall.sh https://raw.githubusercontent.com/mi
|
||||
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/debug.sh | bash
|
||||
|
||||
curl --insecure -fsSL https://code.midoks.me/midoks/mdserver-web/raw/branch/dev/scripts/install_dev.sh | bash
|
||||
curl --insecure -fsSL https://code.midoks.me/midoks/mdserver-web/raw/branch/dev/scripts/update_dev.sh | bash
|
||||
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/dev/scripts/install_dev.sh | bash
|
||||
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/dev/scripts/update_dev.sh | bash
|
||||
```
|
||||
|
||||
### 捐赠地址 USDT(TRC20)
|
||||
@@ -199,7 +191,7 @@ TVbNgrpeGBGZVm5gTLa21ADP7RpnPFhjya
|
||||
|
||||
### 微信赞助
|
||||
|
||||
[](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/weixin_zz.jpg)
|
||||
[](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/alipay_zz.jpg)
|
||||
|
||||
|
||||
### 无图不真相
|
||||
|
||||
+1
-12
@@ -33,10 +33,10 @@ from flask import redirect
|
||||
|
||||
def init():
|
||||
initDB()
|
||||
initDBSshPort()
|
||||
initUserInfo()
|
||||
initInitD()
|
||||
initInitTask()
|
||||
return True
|
||||
|
||||
|
||||
def local():
|
||||
@@ -63,17 +63,6 @@ def initDB():
|
||||
print(str(ex))
|
||||
|
||||
|
||||
def initDBSshPort():
|
||||
# SSH端口必须放开
|
||||
import firewall_api
|
||||
cmd_data = mw.execShell(
|
||||
"cat /etc/ssh/sshd_config | grep '^Port \d*' | tail -1")
|
||||
ssh_port = cmd_data[0].replace("Port ", '').strip()
|
||||
if ssh_port == '':
|
||||
ssh_port = '22'
|
||||
firewall_api.firewall_api().addAcceptPortArgs(ssh_port, 'SSH远程管理服务', 'port')
|
||||
|
||||
|
||||
def doContentReplace(src, dst):
|
||||
content = mw.readFile(src)
|
||||
content = content.replace("{$SERVER_PATH}", mw.getRunDir())
|
||||
|
||||
+121
-47
@@ -20,6 +20,7 @@ import mw
|
||||
import re
|
||||
import json
|
||||
import pwd
|
||||
import pytz
|
||||
|
||||
from flask import session
|
||||
from flask import request
|
||||
@@ -27,9 +28,26 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.16.2'
|
||||
__version = '0.16.4'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
# 统一默认配置文件
|
||||
__file = {
|
||||
'api' : 'data/api.json', # API文件
|
||||
'debug' : 'data/debug.pl', # DEBUG文件
|
||||
'close' : 'data/close.pl', # 识别关闭面板文件
|
||||
'basic_auth' : 'data/basic_auth.json', # 面板Basic验证
|
||||
'admin_path' : 'data/admin_path.pl', # 面板后缀路径设置
|
||||
'ipv6' : 'data/ipv6.pl', # ipv6识别文件
|
||||
'bind_domain' : 'data/bind_domain.pl', # 面板域名绑定
|
||||
'unauth_status' : 'data/unauthorized_status.pl', # URL路径未成功显示状态
|
||||
'auth_secret': 'data/auth_secret.pl', # 二次验证密钥
|
||||
'ssl':'data/ssl.pl', # ssl设置
|
||||
'hook_database' : 'data/hook_database.json', # 数据库钩子
|
||||
'hook_menu' : 'data/hook_menu.json', # 菜单钩子
|
||||
'hook_global_static' : 'data/hook_global_static.json', # 静态文件钩子
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@@ -178,7 +196,7 @@ class config_api:
|
||||
basic_open = request.form.get('is_open', '').strip()
|
||||
|
||||
salt = '_md_salt'
|
||||
path = 'data/basic_auth.json'
|
||||
path = self.__file['basic_auth']
|
||||
is_open = True
|
||||
|
||||
if basic_open == 'false':
|
||||
@@ -223,7 +241,7 @@ class config_api:
|
||||
backup_path = request.form.get('backup_path', '')
|
||||
|
||||
if domain != '':
|
||||
reg = "^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
|
||||
reg = "^([\\w\\-\\*]{1,100}\\.){1,4}(\\w{1,10}|\\w{1,10}\\.\\w{1,10})$"
|
||||
if not re.match(reg, domain):
|
||||
return mw.returnJson(False, '主域名格式不正确')
|
||||
|
||||
@@ -285,7 +303,7 @@ class config_api:
|
||||
return mw.returnJson(False, '安全入口地址长度不能小于6位!')
|
||||
if admin_path in admin_path_checks:
|
||||
return mw.returnJson(False, '该入口已被面板占用,请使用其它入口!')
|
||||
if not re.match("^/[\w\./-_]+$", admin_path):
|
||||
if not re.match("^/[\\w\\./-_]+$", admin_path):
|
||||
return mw.returnJson(False, '入口地址格式不正确,示例: /mw_rand')
|
||||
# else:
|
||||
# domain = mw.readFile('data/bind_domain.pl')
|
||||
@@ -299,7 +317,7 @@ class config_api:
|
||||
# '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:<a
|
||||
# style="color:red;"><br>1、绑定访问域名<br>2、绑定授权IP</a>')
|
||||
|
||||
admin_path_file = 'data/admin_path.pl'
|
||||
admin_path_file = self.__file['admin_path']
|
||||
admin_path_old = '/'
|
||||
if os.path.exists(admin_path_file):
|
||||
admin_path_old = mw.readFile(admin_path_file).strip()
|
||||
@@ -310,7 +328,7 @@ class config_api:
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
def closePanelApi(self):
|
||||
filename = 'data/close.pl'
|
||||
filename = self.__file['close']
|
||||
if os.path.exists(filename):
|
||||
os.remove(filename)
|
||||
return mw.returnJson(True, '开启成功')
|
||||
@@ -328,8 +346,8 @@ class config_api:
|
||||
return mw.returnJson(True, '开发模式开启!')
|
||||
|
||||
def setIpv6StatusApi(self):
|
||||
ipv6_file = 'data/ipv6.pl'
|
||||
if os.path.exists('data/ipv6.pl'):
|
||||
ipv6_file = self.__file['ipv6']
|
||||
if os.path.exists(ipv6_file):
|
||||
os.remove(ipv6_file)
|
||||
mw.writeLog('面板设置', '关闭面板IPv6兼容!')
|
||||
else:
|
||||
@@ -399,7 +417,7 @@ class config_api:
|
||||
# 设置面板SSL证书设置
|
||||
def setPanelHttpToHttpsApi(self):
|
||||
|
||||
bind_domain = 'data/bind_domain.pl'
|
||||
bind_domain = self.__file['bind_domain']
|
||||
if not os.path.exists(bind_domain):
|
||||
return mw.returnJson(False, '先要绑定域名!')
|
||||
|
||||
@@ -429,9 +447,9 @@ class config_api:
|
||||
else:
|
||||
conf = mw.readFile(panel_ssl)
|
||||
if conf:
|
||||
rep = "\n\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
rep = "\n\\s*#HTTP_TO_HTTPS_START(.|\n){1,300}#HTTP_TO_HTTPS_END"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeFile(panel_ssl, conf)
|
||||
|
||||
@@ -444,7 +462,7 @@ class config_api:
|
||||
|
||||
# 删除面板证书
|
||||
def delPanelSslApi(self):
|
||||
bind_domain = 'data/bind_domain.pl'
|
||||
bind_domain = self.__file['bind_domain']
|
||||
if not os.path.exists(bind_domain):
|
||||
return mw.returnJson(False, '未绑定域名!')
|
||||
|
||||
@@ -473,7 +491,7 @@ class config_api:
|
||||
def applyPanelLetSslApi(self):
|
||||
|
||||
# check domain is bind?
|
||||
bind_domain = 'data/bind_domain.pl'
|
||||
bind_domain = self.__file['bind_domain']
|
||||
if not os.path.exists(bind_domain):
|
||||
return mw.returnJson(False, '先要绑定域名!')
|
||||
|
||||
@@ -530,7 +548,7 @@ class config_api:
|
||||
panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf"
|
||||
dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf"
|
||||
|
||||
cfg_domain = 'data/bind_domain.pl'
|
||||
cfg_domain = self.__file['bind_domain']
|
||||
if domain == '':
|
||||
os.remove(cfg_domain)
|
||||
os.remove(dst_panel_path)
|
||||
@@ -559,7 +577,7 @@ class config_api:
|
||||
|
||||
# 设置面板SSL
|
||||
def setPanelSslApi(self):
|
||||
sslConf = mw.getRunDir() + '/data/ssl.pl'
|
||||
sslConf = mw.getRunDir() + '/' + self.__file['ssl']
|
||||
|
||||
panel_tpl = mw.getRunDir() + "/data/tpl/nginx_panel.conf"
|
||||
dst_panel_path = mw.getServerDir() + "/web_conf/nginx/vhost/panel.conf"
|
||||
@@ -568,35 +586,35 @@ class config_api:
|
||||
|
||||
conf = mw.readFile(dst_panel_path)
|
||||
if conf:
|
||||
rep = "\s+ssl_certificate\s+.+;\s+ssl_certificate_key\s+.+;"
|
||||
rep = "\\s+ssl_certificate\\s+.+;\\s+ssl_certificate_key\\s+.+;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_protocols\s+.+;\n"
|
||||
rep = "\\s+ssl_protocols\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_ciphers\s+.+;\n"
|
||||
rep = "\\s+ssl_ciphers\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_prefer_server_ciphers\s+.+;\n"
|
||||
rep = "\\s+ssl_prefer_server_ciphers\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_session_cache\s+.+;\n"
|
||||
rep = "\\s+ssl_session_cache\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_session_timeout\s+.+;\n"
|
||||
rep = "\\s+ssl_session_timeout\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_ecdh_curve\s+.+;\n"
|
||||
rep = "\\s+ssl_ecdh_curve\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_session_tickets\s+.+;\n"
|
||||
rep = "\\s+ssl_session_tickets\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_stapling\s+.+;\n"
|
||||
rep = "\\s+ssl_stapling\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl_stapling_verify\s+.+;\n"
|
||||
rep = "\\s+ssl_stapling_verify\\s+.+;\n"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+ssl\s+on;"
|
||||
rep = "\\s+ssl\\s+on;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+error_page\s497.+;"
|
||||
rep = "\\s+error_page\\s497.+;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+if.+server_port.+\n.+\n\s+\s*}"
|
||||
rep = "\\s+if.+server_port.+\n.+\n\\s+\\s*}"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+listen\s+443.*;"
|
||||
rep = "\\s+listen\\s+443.*;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
rep = "\s+listen\s+\[\:\:\]\:443.*;"
|
||||
rep = "\\s+listen\\s+\\[\\:\\:\\]\\:443.*;"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeFile(dst_panel_path, conf)
|
||||
|
||||
@@ -627,7 +645,7 @@ class config_api:
|
||||
|
||||
conf = conf.replace('#error_page 404/404.html;', sslStr)
|
||||
|
||||
rep = "listen\s+([0-9]+)\s*[default_server]*;"
|
||||
rep = "listen\\s+([0-9]+)\\s*[default_server]*;"
|
||||
tmp = re.findall(rep, conf)
|
||||
if not mw.inArray(tmp, '443'):
|
||||
listen = re.search(rep, conf).group()
|
||||
@@ -743,15 +761,15 @@ class config_api:
|
||||
|
||||
def setStatusCodeApi(self):
|
||||
status_code = request.form.get('status_code', '').strip()
|
||||
if re.match("^\d+$", status_code):
|
||||
if re.match("^\\d+$", status_code):
|
||||
status_code = int(status_code)
|
||||
if status_code != 0:
|
||||
if status_code < 100 or status_code > 999:
|
||||
return mw.returnJson(False, '状态码范围错误!')
|
||||
else:
|
||||
return mw.returnJson(False, '状态码范围错误!')
|
||||
|
||||
mw.writeFile('data/unauthorized_status.pl', str(status_code))
|
||||
unauthorized_status = self.__file['unauth_status']
|
||||
mw.writeFile(unauthorized_status, str(status_code))
|
||||
mw.writeLog('面板设置', '将未授权响应状态码设置为:{}'.format(status_code))
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
@@ -870,8 +888,7 @@ class config_api:
|
||||
if not 'token_crypt' in data:
|
||||
token = mw.getRandomString(32)
|
||||
data['token'] = mw.md5(token)
|
||||
data['token_crypt'] = mw.enCrypt(
|
||||
data['token'], token).decode('utf-8')
|
||||
data['token_crypt'] = mw.enCrypt(data['token'], token).decode('utf-8')
|
||||
|
||||
token = stats[data['open']] + '成功!'
|
||||
mw.writeLog('API配置', '%sAPI接口' % stats[data['open']])
|
||||
@@ -887,7 +904,7 @@ class config_api:
|
||||
return mw.returnJson(True, '保存成功!')
|
||||
|
||||
def renderUnauthorizedStatus(self, data):
|
||||
cfg_unauth_status = 'data/unauthorized_status.pl'
|
||||
cfg_unauth_status = self.__file['unauth_status']
|
||||
if os.path.exists(cfg_unauth_status):
|
||||
status_code = mw.readFile(cfg_unauth_status)
|
||||
data['status_code'] = status_code
|
||||
@@ -911,6 +928,52 @@ class config_api:
|
||||
data['status_code_msg'] = "默认-安全入口错误提示"
|
||||
return data
|
||||
|
||||
|
||||
def getTimezoneListApi(self):
|
||||
# 获取时区列表
|
||||
# pytz.all_timezones | 所有
|
||||
# pytz.common_timezones
|
||||
return pytz.all_timezones
|
||||
|
||||
def setTimezoneApi(self):
|
||||
# 设置时区列表
|
||||
timezone = request.form.get('timezone', '').strip()
|
||||
cmd = 'timedatectl set-timezone "'+timezone+'"'
|
||||
mw.execShell(cmd)
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def getAuthSecretApi(self):
|
||||
reset = request.form.get('reset', '')
|
||||
|
||||
import pyotp
|
||||
auth = self.__file['auth_secret']
|
||||
tag = 'mdserver-web'
|
||||
if os.path.exists(auth) and reset != '1':
|
||||
content = mw.readFile(auth)
|
||||
sec = mw.deDoubleCrypt(tag,content)
|
||||
else:
|
||||
sec = pyotp.random_base32()
|
||||
crypt_data = mw.enDoubleCrypt(tag, sec)
|
||||
mw.writeFile(auth, crypt_data)
|
||||
|
||||
ip = mw.getHostAddr()
|
||||
url = pyotp.totp.TOTP(sec).provisioning_uri(name=ip, issuer_name='mdserver-web')
|
||||
|
||||
rdata = {}
|
||||
rdata['secret'] = sec
|
||||
rdata['url'] = url
|
||||
return mw.returnJson(True, '设置成功!', rdata)
|
||||
|
||||
def setAuthSecretApi(self):
|
||||
auth = self.__file['auth_secret']
|
||||
if os.path.exists(auth):
|
||||
os.remove(auth)
|
||||
return mw.returnJson(True, '关闭成功!', 0)
|
||||
else:
|
||||
return mw.returnJson(True, '开启成功!', 1)
|
||||
|
||||
|
||||
def get(self):
|
||||
|
||||
data = {}
|
||||
@@ -923,31 +986,38 @@ class config_api:
|
||||
data['port'] = mw.getHostPort()
|
||||
data['ip'] = mw.getHostAddr()
|
||||
|
||||
admin_path_file = 'data/admin_path.pl'
|
||||
admin_path_file = self.__file['admin_path']
|
||||
if not os.path.exists(admin_path_file):
|
||||
data['admin_path'] = '/'
|
||||
else:
|
||||
data['admin_path'] = mw.readFile(admin_path_file)
|
||||
|
||||
ipv6_file = 'data/ipv6.pl'
|
||||
ipv6_file = self.__file['ipv6']
|
||||
if os.path.exists(ipv6_file):
|
||||
data['ipv6'] = 'checked'
|
||||
else:
|
||||
data['ipv6'] = ''
|
||||
|
||||
debug_file = 'data/debug.pl'
|
||||
debug_file = self.__file['debug']
|
||||
if os.path.exists(debug_file):
|
||||
data['debug'] = 'checked'
|
||||
else:
|
||||
data['debug'] = ''
|
||||
|
||||
ssl_file = 'data/ssl.pl'
|
||||
if os.path.exists('data/ssl.pl'):
|
||||
ssl_file = self.__file['ssl']
|
||||
if os.path.exists(ssl_file):
|
||||
data['ssl'] = 'checked'
|
||||
else:
|
||||
data['ssl'] = ''
|
||||
|
||||
basic_auth = 'data/basic_auth.json'
|
||||
|
||||
auth_secret = self.__file['auth_secret']
|
||||
if os.path.exists(auth_secret):
|
||||
data['auth_secret'] = 'checked'
|
||||
else:
|
||||
data['auth_secret'] = ''
|
||||
|
||||
basic_auth = self.__file['basic_auth']
|
||||
if os.path.exists(basic_auth):
|
||||
bac = mw.readFile(basic_auth)
|
||||
bac = json.loads(bac)
|
||||
@@ -956,7 +1026,7 @@ class config_api:
|
||||
else:
|
||||
data['basic_auth'] = ''
|
||||
|
||||
cfg_domain = 'data/bind_domain.pl'
|
||||
cfg_domain = self.__file['bind_domain']
|
||||
if os.path.exists(cfg_domain):
|
||||
domain = mw.readFile(cfg_domain)
|
||||
data['bind_domain'] = domain.strip()
|
||||
@@ -965,6 +1035,7 @@ class config_api:
|
||||
|
||||
data = self.renderUnauthorizedStatus(data)
|
||||
|
||||
#api
|
||||
api_token = self.__api_addr
|
||||
if os.path.exists(api_token):
|
||||
bac = mw.readFile(api_token)
|
||||
@@ -974,6 +1045,9 @@ class config_api:
|
||||
else:
|
||||
data['api_token'] = ''
|
||||
|
||||
#auth
|
||||
|
||||
|
||||
data['site_count'] = mw.M('sites').count()
|
||||
|
||||
data['username'] = mw.M('users').where(
|
||||
@@ -982,7 +1056,7 @@ class config_api:
|
||||
data['hook_tag'] = request.args.get('tag', '')
|
||||
|
||||
# databases hook
|
||||
database_hook_file = 'data/hook_database.json'
|
||||
database_hook_file = self.__file['hook_database']
|
||||
if os.path.exists(database_hook_file):
|
||||
df = mw.readFile(database_hook_file)
|
||||
df = json.loads(df)
|
||||
@@ -991,7 +1065,7 @@ class config_api:
|
||||
data['hook_database'] = []
|
||||
|
||||
# menu hook
|
||||
menu_hook_file = 'data/hook_menu.json'
|
||||
menu_hook_file = self.__file['hook_menu']
|
||||
if os.path.exists(menu_hook_file):
|
||||
df = mw.readFile(menu_hook_file)
|
||||
df = json.loads(df)
|
||||
@@ -1000,7 +1074,7 @@ class config_api:
|
||||
data['hook_menu'] = []
|
||||
|
||||
# global_static hook
|
||||
global_static_hook_file = 'data/hook_global_static.json'
|
||||
global_static_hook_file = self.__file['hook_global_static']
|
||||
if os.path.exists(global_static_hook_file):
|
||||
df = mw.readFile(global_static_hook_file)
|
||||
df = json.loads(df)
|
||||
|
||||
@@ -77,7 +77,9 @@ class logs_api:
|
||||
if log_name in ['dmesg'] or log_name.find('dmesg') == 0:
|
||||
return '内核缓冲区日志'
|
||||
if log_name in ['syslog'] or log_name.find('syslog') == 0:
|
||||
return '系统警告/错误日志'
|
||||
return '系统日志'
|
||||
if log_name in ['rsyncd.log']:
|
||||
return '远程同步日志'
|
||||
if log_name in ['btmp']:
|
||||
return '失败的登录记录'
|
||||
if log_name in ['utmp', 'wtmp']:
|
||||
|
||||
+25
-7
@@ -246,7 +246,7 @@ def isInstalledWeb():
|
||||
|
||||
def isIpAddr(ip):
|
||||
check_ip = re.compile(
|
||||
'^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$')
|
||||
'^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$')
|
||||
if check_ip.match(ip):
|
||||
return True
|
||||
else:
|
||||
@@ -394,6 +394,9 @@ def getPageObject(args, result='1,2,3,4,5,8'):
|
||||
if 'tojs' in args:
|
||||
info['return_js'] = args['tojs']
|
||||
|
||||
if 'args_tpl' in args:
|
||||
info['args_tpl'] = args['args_tpl']
|
||||
|
||||
return (page.GetPage(info, result), page)
|
||||
|
||||
|
||||
@@ -905,7 +908,22 @@ def aesDecrypt_Crypto(data, key, vi):
|
||||
text_decrypted = text_decrypted.decode('utf8').rstrip() # 去掉补位的右侧空格
|
||||
return text_decrypted
|
||||
|
||||
def encodeImage(imgsrc, newsrc):
|
||||
# 图片加密
|
||||
import struct
|
||||
old_fp = open(imgsrc, 'rb')
|
||||
imgFile = old_fp.read()
|
||||
old_fp.close()
|
||||
|
||||
new_fp = open(newsrc,"wb")
|
||||
for x in imgFile:
|
||||
value = x ^ 86
|
||||
value = hex(value)
|
||||
s = struct.pack('B',int(value,16))
|
||||
new_fp.write(s)
|
||||
new_fp.close()
|
||||
return True
|
||||
|
||||
def buildSoftLink(src, dst, force=False):
|
||||
'''
|
||||
建立软连接
|
||||
@@ -1158,10 +1176,10 @@ def getLocalIpBack():
|
||||
url = 'http://pv.sohu.com/cityjson?ie=utf-8'
|
||||
req = urllib.request.urlopen(url, timeout=10)
|
||||
content = req.read().decode('utf-8')
|
||||
ipaddress = re.search('\d+.\d+.\d+.\d+', content).group(0)
|
||||
ipaddress = re.search('\\d+.\\d+.\\d+.\\d+', content).group(0)
|
||||
writeFile(filename, ipaddress)
|
||||
|
||||
ipaddress = re.search('\d+.\d+.\d+.\d+', ipaddress).group(0)
|
||||
ipaddress = re.search('\\d+.\\d+.\\d+.\\d+', ipaddress).group(0)
|
||||
return ipaddress
|
||||
except Exception as ex:
|
||||
# print(ex)
|
||||
@@ -1226,7 +1244,7 @@ def checkIp(ip):
|
||||
# 检查是否为IPv4地址
|
||||
import re
|
||||
p = re.compile(
|
||||
'^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
|
||||
'^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$')
|
||||
if p.match(ip):
|
||||
return True
|
||||
else:
|
||||
@@ -1364,13 +1382,13 @@ def getCpuType():
|
||||
|
||||
# 取CPU类型
|
||||
cpuinfo = open('/proc/cpuinfo', 'r').read()
|
||||
rep = "model\s+name\s+:\s+(.+)"
|
||||
rep = "model\\s+name\\s+:\\s+(.+)"
|
||||
tmp = re.search(rep, cpuinfo, re.I)
|
||||
if tmp:
|
||||
cpuType = tmp.groups()[0]
|
||||
else:
|
||||
cpuinfo = execShell('LANG="en_US.UTF-8" && lscpu')[0]
|
||||
rep = "Model\s+name:\s+(.+)"
|
||||
rep = "Model\\s+name:\\s+(.+)"
|
||||
tmp = re.search(rep, cpuinfo, re.I)
|
||||
if tmp:
|
||||
cpuType = tmp.groups()[0]
|
||||
@@ -1754,7 +1772,7 @@ def getSSHPort():
|
||||
try:
|
||||
file = '/etc/ssh/sshd_config'
|
||||
conf = readFile(file)
|
||||
rep = "(#*)?Port\s+([0-9]+)\s*\n"
|
||||
rep = "(#*)?Port\\s+([0-9]+)\\s*\n"
|
||||
port = re.search(rep, conf).groups(0)[1]
|
||||
return int(port)
|
||||
except:
|
||||
|
||||
+14
-6
@@ -39,6 +39,7 @@ class Page():
|
||||
__RTURN_JS = False # 是否返回JS回调
|
||||
__START_NUM = None # 起始行
|
||||
__END_NUM = None # 结束行
|
||||
__ARGS_TPL = ''
|
||||
|
||||
def __init__(self):
|
||||
if False:
|
||||
@@ -51,12 +52,19 @@ class Page():
|
||||
self.__FO = tmp['FO']
|
||||
self.__LINE = tmp['LINE']
|
||||
|
||||
def getPageNum(self, num):
|
||||
return str(num) + self.__ARGS_TPL
|
||||
|
||||
def GetPage(self, pageInfo, limit='1,2,3,4,5,6,7,8'):
|
||||
# 取分页信息
|
||||
# @param pageInfo 传入分页参数字典
|
||||
# @param limit 返回系列
|
||||
self.__RTURN_JS = pageInfo['return_js']
|
||||
self.__COUNT_ROW = pageInfo['count']
|
||||
|
||||
if 'args_tpl' in pageInfo:
|
||||
self.__ARGS_TPL = pageInfo['args_tpl']
|
||||
|
||||
self.ROW = pageInfo['row']
|
||||
self.__C_PAGE = self.__GetCpage(pageInfo['p'])
|
||||
self.__START_NUM = self.__StartRow()
|
||||
@@ -111,7 +119,7 @@ class Page():
|
||||
str(self.__COUNT_PAGE) + "'>" + str(self.__END) + "</a>"
|
||||
else:
|
||||
endStr = "<a class='Pend' onclick='" + self.__RTURN_JS + \
|
||||
"(" + str(self.__COUNT_PAGE) + ")'>" + \
|
||||
"(" + self.getPageNum(self.__COUNT_PAGE) + ")'>" + \
|
||||
str(self.__END) + "</a>"
|
||||
return endStr
|
||||
|
||||
@@ -126,7 +134,7 @@ class Page():
|
||||
str(self.__C_PAGE + 1) + "'>" + str(self.__NEXT) + "</a>"
|
||||
else:
|
||||
nextStr = "<a class='Pnext' onclick='" + self.__RTURN_JS + \
|
||||
"(" + str(self.__C_PAGE + 1) + ")'>" + \
|
||||
"(" + self.getPageNum(self.__C_PAGE + 1) + ")'>" + \
|
||||
str(self.__NEXT) + "</a>"
|
||||
|
||||
return nextStr
|
||||
@@ -151,7 +159,7 @@ class Page():
|
||||
"p=" + str(page) + "'>" + str(page) + "</a>"
|
||||
else:
|
||||
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
|
||||
"(" + str(page) + ")'>" + str(page) + "</a>"
|
||||
"(" + self.getPageNum(page) + ")'>" + str(page) + "</a>"
|
||||
|
||||
# 当前页
|
||||
if self.__C_PAGE > 0:
|
||||
@@ -174,7 +182,7 @@ class Page():
|
||||
"p=" + str(page) + "'>" + str(page) + "</a>"
|
||||
else:
|
||||
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
|
||||
"(" + str(page) + ")'>" + str(page) + "</a>"
|
||||
"(" + self.getPageNum(page) + ")'>" + str(page) + "</a>"
|
||||
|
||||
return pages
|
||||
|
||||
@@ -189,7 +197,7 @@ class Page():
|
||||
str(self.__C_PAGE - 1) + "'>" + str(self.__PREV) + "</a>"
|
||||
else:
|
||||
startStr = "<a class='Ppren' onclick='" + self.__RTURN_JS + \
|
||||
"(" + str(self.__C_PAGE - 1) + ")'>" + \
|
||||
"(" + self.getPageNum(self.__C_PAGE - 1) + ")'>" + \
|
||||
str(self.__PREV) + "</a>"
|
||||
return startStr
|
||||
|
||||
@@ -204,7 +212,7 @@ class Page():
|
||||
self.__URI + "p=1'>" + str(self.__START) + "</a>"
|
||||
else:
|
||||
startStr = "<a class='Pstart' onclick='" + \
|
||||
self.__RTURN_JS + "(1)'>" + str(self.__START) + "</a>"
|
||||
self.__RTURN_JS + "("+self.getPageNum(1)+")'>" + str(self.__START) + "</a>"
|
||||
return startStr
|
||||
|
||||
def __GetCpage(self, p):
|
||||
|
||||
@@ -148,7 +148,7 @@ class plugins_api:
|
||||
def initApi(self):
|
||||
|
||||
plugin_names = {
|
||||
'openresty': '1.21.4.2',
|
||||
'openresty': '1.21.4.3',
|
||||
'php': '56',
|
||||
'swap': '1.1',
|
||||
'mysql': '5.7',
|
||||
|
||||
+30
-11
@@ -105,7 +105,7 @@ class site_api:
|
||||
|
||||
start = (int(p) - 1) * (int(limit))
|
||||
|
||||
siteM = mw.M('sites').field('id,name,path,status,ps,addtime,edate')
|
||||
siteM = siteC = mw.M('sites').field('id,name,path,status,ps,addtime,edate,type_id')
|
||||
|
||||
sql_where = ''
|
||||
if search != '':
|
||||
@@ -113,30 +113,37 @@ class site_api:
|
||||
|
||||
if type_id != '' and int(type_id) >= 0 and search != '':
|
||||
sql_where = sql_where + " and type_id=" + type_id + ""
|
||||
elif type_id != '' and int(type_id) >= 0:
|
||||
if type_id != '' and int(type_id) >= 0:
|
||||
sql_where = " type_id=" + type_id
|
||||
|
||||
if sql_where != '':
|
||||
siteM.where(sql_where)
|
||||
|
||||
_list = siteM.limit((str(start)) + ',' +
|
||||
limit).order('id desc').select()
|
||||
|
||||
_list = siteM.limit((str(start)) + ',' +limit).order('id desc').select()
|
||||
if _list != None:
|
||||
for i in range(len(_list)):
|
||||
_list[i]['backup_count'] = mw.M('backup').where(
|
||||
"pid=? AND type=?", (_list[i]['id'], 0)).count()
|
||||
_list[i]['backup_count'] = mw.M('backup').where("pid=? AND type=?", (_list[i]['id'], 0)).count()
|
||||
|
||||
_ret = {}
|
||||
_ret['data'] = _list
|
||||
|
||||
count = siteM.count()
|
||||
if sql_where != '':
|
||||
count = siteC.where(sql_where).count()
|
||||
else:
|
||||
count = siteC.count()
|
||||
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['tojs'] = 'getWeb'
|
||||
_page['p'] = p
|
||||
_page['row'] = limit
|
||||
|
||||
page_args_tpl = ''
|
||||
page_args_tpl += ','+type_id+''
|
||||
if search != '':
|
||||
page_args_tpl += ',"'+search+'"'
|
||||
_page['args_tpl'] = page_args_tpl
|
||||
|
||||
_ret['page'] = mw.getPage(_page)
|
||||
return mw.getJson(_ret)
|
||||
|
||||
@@ -973,6 +980,9 @@ class site_api:
|
||||
siteInfo = mw.M('sites').where(
|
||||
'name=?', (siteName,)).field('id,name,path').find()
|
||||
path = self.getSitePath(siteName)
|
||||
if path == '':
|
||||
return mw.returnJson(False, '【'+siteName+'】配置文件,异常!')
|
||||
|
||||
srcPath = siteInfo['path']
|
||||
|
||||
# 检测acme是否安装
|
||||
@@ -2201,7 +2211,10 @@ location ^~ {from} {\n\
|
||||
if os.path.exists(file):
|
||||
conf = mw.readFile(file)
|
||||
rep = '\s*root\s*(.+);'
|
||||
path = re.search(rep, conf).groups()[0]
|
||||
find_cnf = re.search(rep, conf)
|
||||
if not find_cnf:
|
||||
return ''
|
||||
path = find_cnf.groups()[0]
|
||||
return path
|
||||
return ''
|
||||
|
||||
@@ -2300,9 +2313,15 @@ location ^~ {from} {\n\
|
||||
def getSitePhpVersion(self, siteName):
|
||||
conf = mw.readFile(self.getHostConf(siteName))
|
||||
rep = "enable-php-(.*)\.conf"
|
||||
tmp = re.search(rep, conf).groups()
|
||||
find_php_cnf = re.search(rep, conf)
|
||||
|
||||
def_pver = '00'
|
||||
if find_php_cnf:
|
||||
tmp = find_php_cnf.groups()
|
||||
def_pver = tmp[0]
|
||||
|
||||
data = {}
|
||||
data['phpversion'] = tmp[0]
|
||||
data['phpversion'] = def_pver
|
||||
return mw.getJson(data)
|
||||
|
||||
def getIndex(self, sid):
|
||||
|
||||
@@ -299,7 +299,8 @@ class system_api:
|
||||
data_list = data.strip().split("\n")
|
||||
mac_version = ''
|
||||
for x in data_list:
|
||||
mac_version += x.split("\t")[1] + ' '
|
||||
xlist = x.split("\t")
|
||||
mac_version += xlist[len(xlist)-1] + ' '
|
||||
|
||||
arch_ver = mw.execShell("arch")
|
||||
return mac_version + " (" + arch_ver[0].strip() + ")"
|
||||
@@ -366,15 +367,15 @@ class system_api:
|
||||
mem = psutil.virtual_memory()
|
||||
if mw.getOs() == 'darwin':
|
||||
memInfo = {
|
||||
'memTotal': mem.total / 1024 / 1024
|
||||
'memTotal': mem.total,
|
||||
}
|
||||
memInfo['memRealUsed'] = memInfo['memTotal'] * (mem.percent / 100)
|
||||
else:
|
||||
memInfo = {
|
||||
'memTotal': mem.total / 1024 / 1024,
|
||||
'memFree': mem.free / 1024 / 1024,
|
||||
'memBuffers': mem.buffers / 1024 / 1024,
|
||||
'memCached': mem.cached / 1024 / 1024
|
||||
'memTotal': mem.total,
|
||||
'memFree': mem.free,
|
||||
'memBuffers': mem.buffers,
|
||||
'memCached': mem.cached
|
||||
}
|
||||
|
||||
memInfo['memRealUsed'] = memInfo['memTotal'] - \
|
||||
@@ -558,9 +559,9 @@ class system_api:
|
||||
networkInfo['upTotal'] = networkIo[0]
|
||||
networkInfo['downTotal'] = networkIo[1]
|
||||
networkInfo['up'] = round(float(
|
||||
networkIo[0] - session['up']) / 1024 / (ntime - session['otime']), 2)
|
||||
networkIo[0] - session['up']) / (ntime - session['otime']), 2)
|
||||
networkInfo['down'] = round(
|
||||
float(networkIo[1] - session['down']) / 1024 / (ntime - session['otime']), 2)
|
||||
float(networkIo[1] - session['down']) / (ntime - session['otime']), 2)
|
||||
networkInfo['downPackets'] = networkIo[3]
|
||||
networkInfo['upPackets'] = networkIo[2]
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import requests
|
||||
|
||||
class vip_api:
|
||||
|
||||
api_url = 'https://wo.midoks.me/api/wp-json/vip'
|
||||
api_url = 'https://wo.midoks.icu/api/wp-json/vip'
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
/etc/init.d/mw default | 显示登录信息
|
||||
/etc/init.d/mw db | 快捷连接数据库
|
||||
----------------------------------------
|
||||
mw open | 开启面板
|
||||
mw close | 关闭面板
|
||||
|
||||
mw debug | 开发测试
|
||||
mw venv | 进入虚拟环境
|
||||
mw venv | 进入虚拟环境
|
||||
mw mirror | 切换镜像
|
||||
mw install_app | 快捷安装常用软件
|
||||
mw update | 更新到正式
|
||||
|
||||
+18
-18
@@ -29,24 +29,24 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
|
||||
|
||||
|
||||
|
||||
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |PHP82 |
|
||||
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
|
||||
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Debian 12 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |PHP82 |PHP83 |
|
||||
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
|
||||
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Debian 12 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Executable
+25
@@ -0,0 +1,25 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('data_query');">服务</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(300);
|
||||
resetPluginWinWidth(380);
|
||||
pluginService('data_query', $('.plugin_version').attr('version'));
|
||||
</script>
|
||||
Executable
+97
@@ -0,0 +1,97 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'data_query'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[3:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def status():
|
||||
return 'start'
|
||||
|
||||
def appOp(method):
|
||||
return 'ok'
|
||||
|
||||
|
||||
|
||||
def start():
|
||||
return appOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return appOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = appOp('restart')
|
||||
return status
|
||||
|
||||
def reload():
|
||||
return appOp('reload')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"hook":[
|
||||
{
|
||||
"tag":"menu",
|
||||
"menu": {
|
||||
"title":"数据管理",
|
||||
"name":"data_query",
|
||||
"path":"static/html/index.html",
|
||||
"css_path":"static/css/data.css",
|
||||
"js_path":"static/js/app.js"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag":"global_static",
|
||||
"global_static": {
|
||||
"title":"数据管理",
|
||||
"name":"data_query",
|
||||
"css_path":"static/css/ico.css"
|
||||
}
|
||||
}
|
||||
],
|
||||
"sort": 7,
|
||||
"ps": "数据简单管理(memcached,redis,mongodb)",
|
||||
"name": "data_query",
|
||||
"title": "数据管理",
|
||||
"shell": "install.sh",
|
||||
"versions":"1.0",
|
||||
"tip": "soft",
|
||||
"checks": "server/data_query",
|
||||
"path": "server/data_query",
|
||||
"display": 1,
|
||||
"author": "midoks",
|
||||
"date": "2024-01-22",
|
||||
"type": 0,
|
||||
"pid": "2"
|
||||
}
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/data_query
|
||||
echo "${VERSION}" > $serverPath/data_query/version.pl
|
||||
|
||||
echo '安装完成'
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/data_query
|
||||
echo "卸载成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+253
@@ -0,0 +1,253 @@
|
||||
# coding:utf-8
|
||||
|
||||
# https://pypi.org/project/pymemcache/
|
||||
# https://pymemcache.readthedocs.io/en/latest/getting_started.html#using-a-client-pool
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import pymemcache
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
def inner():
|
||||
if cls not in _instance:
|
||||
_instance[cls] = cls()
|
||||
return _instance[cls]
|
||||
return inner
|
||||
|
||||
@singleton
|
||||
class nosqlMemcached():
|
||||
|
||||
__DB_PASS = None
|
||||
__DB_USER = None
|
||||
__DB_PORT = 11211
|
||||
__DB_HOST = '127.0.0.1'
|
||||
__DB_CONN = None
|
||||
__DB_ERR = None
|
||||
|
||||
__DB_LOCAL = None
|
||||
|
||||
def __init__(self):
|
||||
self.__config = self.get_options(None)
|
||||
|
||||
|
||||
def conn(self):
|
||||
|
||||
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
|
||||
mem_path = "{}/memcached".format(mw.getServerDir())
|
||||
if not os.path.exists(mem_path): return False
|
||||
|
||||
if not self.__DB_LOCAL:
|
||||
self.__DB_PORT = int(self.__config['port'])
|
||||
try:
|
||||
self.__DB_CONN = pymemcache.client.base.PooledClient((self.__DB_HOST,self.__DB_PORT), max_pool_size=4)
|
||||
return self.__DB_CONN
|
||||
except pymemcache.exceptions.MemcacheError:
|
||||
return False
|
||||
except Exception:
|
||||
self.__DB_ERR = mw.getTracebackInfo()
|
||||
return False
|
||||
|
||||
# 获取配置项
|
||||
def get_options(self, get=None):
|
||||
|
||||
result = {}
|
||||
mem_content = mw.readFile("{}/memcached/memcached.env".format(mw.getServerDir()))
|
||||
if not mem_content: return False
|
||||
|
||||
keys = ["bind", "PORT"]
|
||||
rep = 'PORT\s*=\s*(.*)'
|
||||
port_re = re.search(rep, mem_content)
|
||||
if port_re:
|
||||
result['port'] = int(port_re.groups()[0].strip())
|
||||
else:
|
||||
result['port'] = 11211
|
||||
return result
|
||||
|
||||
def set_host(self, host, port, prefix=''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_LOCAL = 1
|
||||
return self
|
||||
|
||||
|
||||
@singleton
|
||||
class nosqlMemcachedCtr():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getInstanceBySid(self, sid = 0):
|
||||
instance = nosqlMemcached()
|
||||
return instance
|
||||
|
||||
def getItems(self, args):
|
||||
sid = args['sid']
|
||||
mem_instance = self.getInstanceBySid(sid).conn()
|
||||
if mem_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = {}
|
||||
m_items = mem_instance.stats('items')
|
||||
|
||||
item_no = []
|
||||
for i in m_items:
|
||||
item_match = b'items:(\d*?):number'
|
||||
item_match_re = re.search(item_match, i)
|
||||
if item_match_re:
|
||||
v = item_match_re.groups()[0].strip()
|
||||
v_str = v.decode()
|
||||
if not v_str in item_no:
|
||||
item_no.append(v_str)
|
||||
|
||||
if len(item_no) == 0:
|
||||
item_no = [0]
|
||||
|
||||
result['items'] = item_no
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def getKeyList(self, args):
|
||||
sid = args['sid']
|
||||
mem_instance = self.getInstanceBySid(sid).conn()
|
||||
if mem_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
|
||||
p = 1
|
||||
size = 10
|
||||
if 'p' in args:
|
||||
p = args['p']
|
||||
|
||||
if 'size' in args:
|
||||
size = args['size']
|
||||
|
||||
item_id = args['item_id']
|
||||
if item_id == '0':
|
||||
return mw.returnData(False,'ok')
|
||||
|
||||
m_items = mem_instance.stats('items')
|
||||
|
||||
item_key = 'items:%s:number' % item_id
|
||||
item_key_b = item_key.encode("utf-8")
|
||||
m_items_v = m_items[item_key_b]
|
||||
|
||||
|
||||
start = (p-1)*size
|
||||
end = start+size
|
||||
if end > m_items_v:
|
||||
end = m_items_v
|
||||
|
||||
|
||||
all_key = mem_instance.stats('cachedump', str(item_id) , str(0))
|
||||
# print(all_key)
|
||||
all_key_list = []
|
||||
cur_time_t = time.time()
|
||||
for k in all_key:
|
||||
t = {}
|
||||
t['k'] = k.decode("utf-8")
|
||||
v = all_key[k].decode("utf-8")
|
||||
v = v.strip('[').strip(']').split(';')
|
||||
t['s'] = v[0]
|
||||
cur_time = v[1].strip().split(' ')[0]
|
||||
|
||||
if int(cur_time) != 0 :
|
||||
t['t'] = int(cur_time) - int(cur_time_t)
|
||||
else:
|
||||
t['t'] = 0
|
||||
all_key_list.append(t)
|
||||
|
||||
# print(len(all_key_list))
|
||||
# print(start,end)
|
||||
return_all_key = all_key_list[start:end]
|
||||
|
||||
for x in range(len(return_all_key)):
|
||||
v = mem_instance.get(return_all_key[x]['k'])
|
||||
return_all_key[x]['v'] = v.decode('utf-8')
|
||||
|
||||
result = {}
|
||||
result['list'] = return_all_key
|
||||
result['p'] = p
|
||||
|
||||
page_args = {}
|
||||
page_args['count'] = len(all_key_list)
|
||||
page_args['tojs'] = 'memcachedGetKeyList'
|
||||
page_args['p'] = p
|
||||
page_args['row'] = size
|
||||
result['page'] = mw.getPage(page_args)
|
||||
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def delVal(self, args):
|
||||
|
||||
sid = args['sid']
|
||||
mem_instance = self.getInstanceBySid(sid).conn()
|
||||
if mem_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
key = args['key']
|
||||
mem_instance.delete(key)
|
||||
return mw.returnData(True,'删除成功!')
|
||||
|
||||
def setKv(self, args):
|
||||
|
||||
sid = args['sid']
|
||||
mem_instance = self.getInstanceBySid(sid).conn()
|
||||
if mem_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
key = args['key']
|
||||
val = args['val']
|
||||
endtime = args['endtime']
|
||||
mem_instance.set(key, val, int(endtime))
|
||||
return mw.returnData(True,'设置成功!')
|
||||
|
||||
def clear(self, args):
|
||||
sid = args['sid']
|
||||
mem_instance = self.getInstanceBySid(sid).conn()
|
||||
if mem_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
mem_instance.flush_all()
|
||||
return mw.returnData(True,'清空成功!')
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
# 获取 memcached 列表
|
||||
def get_items(args):
|
||||
t = nosqlMemcachedCtr()
|
||||
return t.getItems(args)
|
||||
|
||||
def get_key_list(args):
|
||||
t = nosqlMemcachedCtr()
|
||||
return t.getKeyList(args)
|
||||
|
||||
def del_val(args):
|
||||
t = nosqlMemcachedCtr()
|
||||
return t.delVal(args)
|
||||
|
||||
def set_kv(args):
|
||||
t = nosqlMemcachedCtr()
|
||||
return t.setKv(args)
|
||||
|
||||
def clear(args):
|
||||
t = nosqlMemcachedCtr()
|
||||
return t.clear(args)
|
||||
|
||||
# 测试
|
||||
def test(args):
|
||||
sid = args['sid']
|
||||
t = nosqlMemcachedCtr()
|
||||
print(t.get_options())
|
||||
print("test")
|
||||
return 'ok'
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
|
||||
Executable
+254
@@ -0,0 +1,254 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import pymongo
|
||||
import json
|
||||
|
||||
from bson.objectid import ObjectId
|
||||
from bson.json_util import dumps
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
def inner():
|
||||
if cls not in _instance:
|
||||
_instance[cls] = cls()
|
||||
return _instance[cls]
|
||||
return inner
|
||||
|
||||
|
||||
@singleton
|
||||
class nosqlMongodb():
|
||||
|
||||
__DB_PASS = None
|
||||
__DB_USER = None
|
||||
__DB_PORT = 6379
|
||||
__DB_HOST = '127.0.0.1'
|
||||
__DB_CONN = None
|
||||
__DB_ERR = None
|
||||
|
||||
__DB_LOCAL = None
|
||||
|
||||
def __init__(self):
|
||||
self.__config = self.get_options(None)
|
||||
|
||||
|
||||
def mgdb_conn(self):
|
||||
|
||||
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
|
||||
mgdb_path = "{}/mongodb".format(mw.getServerDir())
|
||||
if not os.path.exists(mgdb_path): return False
|
||||
|
||||
if not self.__DB_LOCAL:
|
||||
self.__DB_PORT = int(self.__config['port'])
|
||||
|
||||
# print(self.__DB_HOST,self.__DB_PORT, self.__DB_PASS)
|
||||
try:
|
||||
self.__DB_CONN = pymongo.MongoClient(host=self.__DB_HOST, port=self.__DB_PORT, maxPoolSize=10)
|
||||
self.__DB_CONN.admin.command('ping')
|
||||
return self.__DB_CONN
|
||||
except pymongo.errors.ConnectionFailure:
|
||||
return False
|
||||
except Exception:
|
||||
self.__DB_ERR = mw.get_error_info()
|
||||
return False
|
||||
|
||||
# 获取配置项
|
||||
def get_options(self, get=None):
|
||||
result = {}
|
||||
mgdb_content = mw.readFile("{}/mongodb/mongodb.conf".format(mw.getServerDir()))
|
||||
if not mgdb_content: return False
|
||||
|
||||
keys = ["bind_ip", "port"]
|
||||
|
||||
result['host'] = '127.0.0.1'
|
||||
rep = 'port\s*=\s*(.*)'
|
||||
ip_re = re.search(rep, mgdb_content)
|
||||
if ip_re:
|
||||
result['port'] = int(ip_re.groups()[0].strip())
|
||||
else:
|
||||
result['port'] = 27017
|
||||
return result
|
||||
|
||||
def set_host(self, host, port, name, username, password, prefix=''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_LOCAL = 1
|
||||
return self
|
||||
|
||||
|
||||
|
||||
@singleton
|
||||
class nosqlMongodbCtr():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getInstanceBySid(self, sid = 0):
|
||||
instance = nosqlMongodb()
|
||||
return instance
|
||||
|
||||
def getDbList(self, args):
|
||||
sid = args['sid']
|
||||
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
|
||||
if mgdb_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = {}
|
||||
doc_list = mgdb_instance.list_database_names()
|
||||
rlist = []
|
||||
for x in doc_list:
|
||||
if not x in ['admin', 'config', 'local']:
|
||||
rlist.append(x)
|
||||
result['list'] = rlist
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def getCollectionsList(self, args):
|
||||
sid = args['sid']
|
||||
name = args['name']
|
||||
|
||||
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
|
||||
if mgdb_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = {}
|
||||
collections = mgdb_instance[name].list_collection_names()
|
||||
result['collections'] = collections
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def getDataList(self, args):
|
||||
sid = args['sid']
|
||||
db = args['db']
|
||||
collection = args['collection']
|
||||
p = 1
|
||||
size = 10
|
||||
if 'p' in args:
|
||||
p = args['p']
|
||||
|
||||
if 'size' in args:
|
||||
size = args['size']
|
||||
|
||||
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
|
||||
if mgdb_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
db_instance = mgdb_instance[db]
|
||||
collection_instance = db_instance[collection]
|
||||
|
||||
start_index = (p - 1) * size
|
||||
end_index = p * size
|
||||
args_where = args['where']
|
||||
|
||||
where = {}
|
||||
if 'field' in args_where:
|
||||
mg_field = args_where['field']
|
||||
|
||||
if mg_field == '_id':
|
||||
mg_value = ObjectId(args_where['value'])
|
||||
where[mg_field] = mg_value
|
||||
else:
|
||||
mg_value = args_where['value']
|
||||
where[mg_field] = re.compile(mg_value)
|
||||
|
||||
# print(where)
|
||||
result = collection_instance.find(where).skip(start_index).limit(size).sort({'_id':-1})
|
||||
count = collection_instance.count_documents(where)
|
||||
d = []
|
||||
for document in result:
|
||||
d.append(document)
|
||||
|
||||
doc_str_json = dumps(d)
|
||||
result = json.loads(doc_str_json)
|
||||
|
||||
|
||||
page_args = {}
|
||||
page_args['count'] = count
|
||||
page_args['tojs'] = 'mongodbDataList'
|
||||
page_args['p'] = p
|
||||
page_args['row'] = size
|
||||
|
||||
rdata = {}
|
||||
rdata['page'] = mw.getPage(page_args)
|
||||
rdata['list'] = result
|
||||
rdata['count'] = count
|
||||
|
||||
rdata['soso_field'] = ''
|
||||
if 'field' in args_where:
|
||||
rdata['soso_field'] = args_where['field']
|
||||
|
||||
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
def delById(self,args):
|
||||
sid = args['sid']
|
||||
db = args['db']
|
||||
collection = args['collection']
|
||||
|
||||
mgdb_instance = self.getInstanceBySid(sid).mgdb_conn()
|
||||
if mgdb_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
db_instance = mgdb_instance[db]
|
||||
collection_instance = db_instance[collection]
|
||||
|
||||
_id = args['_id']
|
||||
result = collection_instance.delete_one({"_id": ObjectId(_id)})
|
||||
|
||||
return mw.returnData(True,'文档删除【%d】个成功!' % result.deleted_count)
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
# 获取 mongodb databases 列表
|
||||
def get_db_list(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.getDbList(args)
|
||||
|
||||
# 获取 mongodb collections 列表
|
||||
def get_collections_list(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.getCollectionsList(args)
|
||||
|
||||
def get_data_list(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.getDataList(args)
|
||||
|
||||
def set_kv(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.setKv(args)
|
||||
|
||||
|
||||
def del_val(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.delVal(args)
|
||||
|
||||
def batch_del_val(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.batchDelVal(args)
|
||||
|
||||
def clear_flushdb(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.clearFlushDB(args)
|
||||
|
||||
def del_by_id(args):
|
||||
t = nosqlMongodbCtr()
|
||||
return t.delById(args)
|
||||
|
||||
# 测试
|
||||
def test(args):
|
||||
sid = args['sid']
|
||||
t = nosqlMongodbCtr()
|
||||
print(t.get_options())
|
||||
print("test")
|
||||
return 'ok'
|
||||
Executable
+347
@@ -0,0 +1,347 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import redis
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
# def getPluginName():
|
||||
# return 'data_query'
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
def inner():
|
||||
if cls not in _instance:
|
||||
_instance[cls] = cls()
|
||||
return _instance[cls]
|
||||
return inner
|
||||
|
||||
@singleton
|
||||
class nosqlRedis():
|
||||
|
||||
__DB_PASS = None
|
||||
__DB_USER = None
|
||||
__DB_PORT = 6379
|
||||
__DB_HOST = '127.0.0.1'
|
||||
__DB_CONN = None
|
||||
__DB_ERR = None
|
||||
|
||||
__DB_LOCAL = None
|
||||
|
||||
def __init__(self):
|
||||
self.__config = self.get_options(None)
|
||||
|
||||
|
||||
def redis_conn(self, db_idx=0):
|
||||
|
||||
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
|
||||
redis_path = "{}/redis".format(mw.getServerDir())
|
||||
if not os.path.exists(redis_path): return False
|
||||
|
||||
if not self.__DB_LOCAL:
|
||||
self.__DB_PASS = self.__config['requirepass']
|
||||
self.__DB_PORT = int(self.__config['port'])
|
||||
|
||||
# print(self.__DB_HOST,self.__DB_PORT, self.__DB_PASS)
|
||||
try:
|
||||
redis_pool = redis.ConnectionPool(host=self.__DB_HOST, port=self.__DB_PORT, password=self.__DB_PASS, db=db_idx, socket_timeout=3)
|
||||
self.__DB_CONN = redis.Redis(connection_pool=redis_pool)
|
||||
self.__DB_CONN.ping()
|
||||
return self.__DB_CONN
|
||||
except redis.exceptions.ConnectionError:
|
||||
return False
|
||||
except Exception:
|
||||
self.__DB_ERR = mw.getTracebackInfo()
|
||||
return False
|
||||
|
||||
# 获取配置项
|
||||
def get_options(self, get=None):
|
||||
|
||||
result = {}
|
||||
redis_conf = mw.readFile("{}/redis/redis.conf".format(mw.getServerDir()))
|
||||
if not redis_conf: return False
|
||||
|
||||
keys = ["bind", "port", "timeout", "maxclients", "databases", "requirepass", "maxmemory"]
|
||||
for k in keys:
|
||||
v = ""
|
||||
rep = "\n%s\s+(.+)" % k
|
||||
group = re.search(rep, redis_conf)
|
||||
if not group:
|
||||
if k == "maxmemory":
|
||||
v = "0"
|
||||
if k == "maxclients":
|
||||
v = "10000"
|
||||
if k == "requirepass":
|
||||
v = ""
|
||||
else:
|
||||
if k == "maxmemory":
|
||||
v = int(group.group(1).strip("mb"))
|
||||
else:
|
||||
v = group.group(1)
|
||||
result[k] = v
|
||||
return result
|
||||
|
||||
def set_host(self, host, port, name, username, password, prefix=''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_LOCAL = 1
|
||||
return self
|
||||
|
||||
|
||||
@singleton
|
||||
class nosqlRedisCtr():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getInstanceBySid(self, sid = 0):
|
||||
instance = nosqlRedis()
|
||||
return instance
|
||||
|
||||
def getList(self, args):
|
||||
|
||||
sid = args['sid']
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(0)
|
||||
if redis_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
|
||||
redis_info = redis_instance.info()
|
||||
is_cluster = redis_info.get("cluster_enabled", 0)
|
||||
if is_cluster != 0:
|
||||
return mw.returnData(False, "当前不支持连接redis集群!")
|
||||
|
||||
db_num = 16
|
||||
if sid != 0:
|
||||
db_num = 1000
|
||||
|
||||
result = []
|
||||
for x in range(0, db_num):
|
||||
data = {}
|
||||
data['id'] = x
|
||||
data['name'] = 'DB{}'.format(x)
|
||||
try:
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(x)
|
||||
data['keynum'] = redis_instance.dbsize()
|
||||
result.append(data)
|
||||
except:
|
||||
break
|
||||
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def getDbKeyList(self, args):
|
||||
p = 1
|
||||
size = 10
|
||||
|
||||
if not 'sid' in args:
|
||||
return mw.returnData(False, "缺少参数!sid")
|
||||
|
||||
if 'p' in args:
|
||||
p = args['p']
|
||||
if p < 1:
|
||||
p = 1
|
||||
if p > 10:
|
||||
p = 10
|
||||
|
||||
if 'size' in args:
|
||||
size = args['size']
|
||||
|
||||
sid = args['sid']
|
||||
idx = args['idx']
|
||||
search = '*'
|
||||
if 'search' in args and args['search'] != '':
|
||||
search = args['search']
|
||||
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
|
||||
|
||||
total = redis_instance.dbsize()
|
||||
|
||||
if search != '*':
|
||||
keylist = redis_instance.keys(search)
|
||||
total = len(keylist)
|
||||
else:
|
||||
keys = redis_instance.scan(cursor=0, match="{}".format(search), count=p*size)
|
||||
keylist = keys[1]
|
||||
|
||||
slist = keylist[(p - 1) * size:p*size]
|
||||
|
||||
items = []
|
||||
for key in slist:
|
||||
item = {}
|
||||
try:
|
||||
item['name'] = key.decode()
|
||||
except Exception as e:
|
||||
item['name'] = str(key)
|
||||
|
||||
item['endtime'] = redis_instance.ttl(key)
|
||||
item['type'] = redis_instance.type(key).decode()
|
||||
|
||||
if item['type'] == 'string':
|
||||
try:
|
||||
item['val'] = redis_instance.get(key).decode()
|
||||
except Exception as e:
|
||||
item['val'] = str(redis_instance.get(key))
|
||||
elif item['type'] == 'hash':
|
||||
if redis_instance.hlen(key) > 500:
|
||||
item['val'] = "数据量过大无法显示!共 {} 条".format(redis_instance.hlen(key))
|
||||
else:
|
||||
item['val'] = str(redis_instance.hgetall(key))
|
||||
elif item['type'] == 'list':
|
||||
if redis_instance.llen(key) > 500:
|
||||
item['val'] = "数据量过大无法显示!共 {} 条".format(redis_instance.llen(key))
|
||||
else:
|
||||
item['val'] = str(redis_instance.lrange(key, 0, -1))
|
||||
elif item['type'] == 'set':
|
||||
if redis_instance.scard(key) > 500:
|
||||
item['val'] = "数据量过大无法显示!共 {} 条".format(redis_instance.scard(key))
|
||||
else:
|
||||
item['val'] = str(redis_instance.smembers(key))
|
||||
elif item['type'] == 'zset':
|
||||
if redis_instance.zcard(key) > 500:
|
||||
item['val'] = "数据量过大无法显示!共 {} 条".format(redis_instance.zcard(key))
|
||||
else:
|
||||
item['val'] = str(redis_instance.zrange(key, 0, -1, withscores=True))
|
||||
else:
|
||||
item['val'] = ''
|
||||
|
||||
try:
|
||||
item['len'] = redis_instance.strlen(key)
|
||||
except:
|
||||
item['len'] = len(item['val'])
|
||||
items.append(item)
|
||||
|
||||
|
||||
page_args = {}
|
||||
page_args['count'] = total
|
||||
page_args['tojs'] = 'redisGetKeyList'
|
||||
page_args['p'] = p
|
||||
page_args['row'] = size
|
||||
|
||||
rdata = {}
|
||||
rdata['page'] = mw.getPage(page_args)
|
||||
rdata['data'] = items
|
||||
return mw.returnData(True,'ok',rdata)
|
||||
|
||||
def setKv(self,args):
|
||||
if not 'name' in args:
|
||||
return mw.returnData(False, "缺少参数!name")
|
||||
if not 'val' in args:
|
||||
return mw.returnData(False, "缺少参数!val")
|
||||
if not 'idx' in args:
|
||||
return mw.returnData(False, "缺少参数!idx")
|
||||
|
||||
sid = args['sid']
|
||||
idx = args['idx']
|
||||
|
||||
name = args["name"]
|
||||
val = args["val"]
|
||||
endtime = args["endtime"]
|
||||
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
|
||||
|
||||
redis_info = redis_instance.info()
|
||||
if redis_info['role'] == 'slave':
|
||||
return mw.returnData(False,'从库不能写操作!')
|
||||
|
||||
if endtime != '0':
|
||||
redis_instance.set(name, val, int(endtime))
|
||||
else:
|
||||
redis_instance.set(name, val)
|
||||
|
||||
return mw.returnData(True,'操作成功')
|
||||
|
||||
def delVal(self, args):
|
||||
sid = args['sid']
|
||||
idx = args['idx']
|
||||
name = args["name"]
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
|
||||
|
||||
redis_info = redis_instance.info()
|
||||
if redis_info['role'] == 'slave':
|
||||
return mw.returnData(False,'从库不能删除操作!')
|
||||
|
||||
redis_instance.delete(name)
|
||||
return mw.returnData(True,'操作成功')
|
||||
|
||||
def batchDelVal(self, args):
|
||||
sid = args['sid']
|
||||
idx = args['idx']
|
||||
keys = args["keys"]
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
|
||||
|
||||
redis_info = redis_instance.info()
|
||||
if redis_info['role'] == 'slave':
|
||||
return mw.returnData(False,'从库不能删除操作!')
|
||||
|
||||
for k in keys:
|
||||
redis_instance.delete(k)
|
||||
return mw.returnData(True,'操作成功')
|
||||
|
||||
def clearFlushDB(self, args):
|
||||
|
||||
sid = args['sid']
|
||||
idxs = args['idxs']
|
||||
|
||||
for idx in idxs:
|
||||
redis_instance = self.getInstanceBySid(sid).redis_conn(idx)
|
||||
|
||||
redis_info = redis_instance.info()
|
||||
if redis_info['role'] == 'slave':
|
||||
return mw.returnData(False,'从库不能清空操作!')
|
||||
|
||||
redis_instance.flushdb()
|
||||
|
||||
return mw.returnData(True,'操作成功')
|
||||
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
# 获取 redis databases 列表
|
||||
def get_list(args):
|
||||
t = nosqlRedisCtr()
|
||||
return t.getList(args)
|
||||
|
||||
# 获取 redis key 列表
|
||||
def get_dbkey_list(args):
|
||||
t = nosqlRedisCtr()
|
||||
return t.getDbKeyList(args)
|
||||
|
||||
|
||||
def set_kv(args):
|
||||
t = nosqlRedisCtr()
|
||||
return t.setKv(args)
|
||||
|
||||
|
||||
def del_val(args):
|
||||
t = nosqlRedisCtr()
|
||||
return t.delVal(args)
|
||||
|
||||
def batch_del_val(args):
|
||||
t = nosqlRedisCtr()
|
||||
return t.batchDelVal(args)
|
||||
|
||||
def clear_flushdb(args):
|
||||
t = nosqlRedisCtr()
|
||||
return t.clearFlushDB(args)
|
||||
|
||||
# 测试
|
||||
def test(args):
|
||||
sid = args['sid']
|
||||
t = nosqlRedis()
|
||||
print(t.get_options())
|
||||
print("test")
|
||||
return 'ok'
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
|
||||
Executable
+301
@@ -0,0 +1,301 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import pymongo
|
||||
import json
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
def singleton(cls):
|
||||
_instance = {}
|
||||
|
||||
def inner():
|
||||
if cls not in _instance:
|
||||
_instance[cls] = cls()
|
||||
return _instance[cls]
|
||||
return inner
|
||||
|
||||
|
||||
@singleton
|
||||
class nosqlMySQL():
|
||||
|
||||
__DB_PASS = None
|
||||
__DB_USER = None
|
||||
__DB_PORT = 3306
|
||||
__DB_HOST = '127.0.0.1'
|
||||
__DB_CONN = None
|
||||
__DB_ERR = None
|
||||
__DB_SOCKET = None
|
||||
|
||||
__DB_LOCAL = None
|
||||
|
||||
def __init__(self):
|
||||
self.__config = self.get_options(None)
|
||||
|
||||
|
||||
def conn(self):
|
||||
|
||||
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
|
||||
my_path = "{}/mysql".format(mw.getServerDir())
|
||||
if not os.path.exists(my_path): return False
|
||||
|
||||
if not self.__DB_LOCAL:
|
||||
# print(self.__config)
|
||||
self.__DB_PORT = int(self.__config['port'])
|
||||
self.__DB_USER = self.__config['username']
|
||||
self.__DB_PASS = self.__config['password']
|
||||
self.__DB_SOCKET = self.__config['socket']
|
||||
|
||||
try:
|
||||
|
||||
db = mw.getMyORM()
|
||||
db.setPort(self.__DB_PORT)
|
||||
db.setPwd(self.__DB_PASS)
|
||||
db.setUser(self.__DB_USER)
|
||||
if self.__DB_SOCKET != '':
|
||||
db.setSocket(self.__DB_SOCKET)
|
||||
|
||||
return db
|
||||
except Exception:
|
||||
self.__DB_ERR = mw.get_error_info()
|
||||
return False
|
||||
|
||||
def sqliteDb(self,dbname='databases'):
|
||||
my_root_path = mw.getServerDir() +'/mysql'
|
||||
name = 'mysql'
|
||||
conn = mw.M(dbname).dbPos(my_root_path, name)
|
||||
return conn
|
||||
|
||||
# 获取配置项
|
||||
def get_options(self, get=None):
|
||||
result = {}
|
||||
|
||||
|
||||
my_cnf_path = "{}/mysql/etc/my.cnf".format(mw.getServerDir())
|
||||
my_content = mw.readFile(my_cnf_path)
|
||||
if not my_content: return False
|
||||
|
||||
mysql_pass = self.sqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
result['password'] = mysql_pass
|
||||
result['username'] = 'root'
|
||||
keys = ["bind_ip", "port"]
|
||||
|
||||
result['host'] = '127.0.0.1'
|
||||
rep = 'port\s*=\s*(.*)'
|
||||
|
||||
port_re = re.search(rep, my_content)
|
||||
if port_re:
|
||||
result['port'] = int(port_re.groups()[0].strip())
|
||||
else:
|
||||
result['port'] = 3306
|
||||
|
||||
socket_rep = 'socket\s*=\s*(.*)'
|
||||
socket_re = re.search(socket_rep, my_content)
|
||||
if socket_re:
|
||||
result['socket'] = socket_re.groups()[0].strip()
|
||||
else:
|
||||
result['socket'] = ''
|
||||
|
||||
return result
|
||||
|
||||
def set_host(self, host, port, name, username, password, prefix=''):
|
||||
self.__DB_HOST = host
|
||||
self.__DB_PORT = int(port)
|
||||
self.__DB_NAME = name
|
||||
if self.__DB_NAME: self.__DB_NAME = str(self.__DB_NAME)
|
||||
self.__DB_USER = str(username)
|
||||
self._USER = str(username)
|
||||
self.__DB_PASS = str(password)
|
||||
self.__DB_PREFIX = prefix
|
||||
self.__DB_LOCAL = 1
|
||||
return self
|
||||
|
||||
|
||||
|
||||
@singleton
|
||||
class nosqlMySQLCtr():
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getInstanceBySid(self, sid = 0):
|
||||
instance = nosqlMySQL()
|
||||
return instance
|
||||
|
||||
def getDbList(self, args):
|
||||
sid = args['sid']
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = {}
|
||||
db_list = my_instance.query('show databases')
|
||||
rlist = []
|
||||
for x in db_list:
|
||||
if not x['Database'] in ['information_schema', 'mysql', 'performance_schema','sys']:
|
||||
rlist.append(x['Database'])
|
||||
result['list'] = rlist
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def getTableList(self, args):
|
||||
sid = args['sid']
|
||||
db = args['db']
|
||||
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
sql = "select * from information_schema.tables where table_schema = '"+db+"'"
|
||||
table_list = my_instance.query(sql)
|
||||
# print(table_list)
|
||||
|
||||
rlist = []
|
||||
for x in table_list:
|
||||
# print(x['TABLE_NAME'])
|
||||
rlist.append(x['TABLE_NAME'])
|
||||
result = {}
|
||||
result['list'] = rlist
|
||||
return mw.returnData(True,'ok', result)
|
||||
|
||||
def getDataList(self, args):
|
||||
sid = args['sid']
|
||||
db = args['db']
|
||||
table = args['table']
|
||||
p = 1
|
||||
size = 10
|
||||
if 'p' in args:
|
||||
p = args['p']
|
||||
|
||||
if 'size' in args:
|
||||
size = args['size']
|
||||
|
||||
start_index = (p - 1) * size
|
||||
|
||||
|
||||
args_where = {}
|
||||
where_sql = ''
|
||||
if 'where' in args:
|
||||
args_where = args['where']
|
||||
if 'field' in args_where:
|
||||
if args_where['field'] == 'id' or args_where['field'].find('id')>-1:
|
||||
where_sql = ' where '+args_where['field'] + " = '"+args_where['value']+"' "
|
||||
else:
|
||||
where_sql = ' where '+args_where['field'] + " like '%"+args_where['value']+"%' "
|
||||
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
my_instance.setDbName(db)
|
||||
sql = 'select count(*) as num from ' + table + where_sql
|
||||
# print(sql)
|
||||
count_result = my_instance.query(sql)
|
||||
count = count_result[0]['num']
|
||||
|
||||
|
||||
sql = 'select * from ' + table + where_sql + ' limit '+str(start_index)+',10';
|
||||
# print(sql)
|
||||
result = my_instance.query(sql)
|
||||
|
||||
for i in range(len(result)):
|
||||
for f in result[i]:
|
||||
result[i][f] = str(result[i][f])
|
||||
|
||||
# print(result)
|
||||
|
||||
page_args = {}
|
||||
page_args['count'] = count
|
||||
page_args['tojs'] = 'mysqlGetDataList'
|
||||
page_args['p'] = p
|
||||
page_args['row'] = size
|
||||
|
||||
rdata = {}
|
||||
rdata['page'] = mw.getPage(page_args)
|
||||
rdata['list'] = result
|
||||
rdata['count'] = count
|
||||
|
||||
rdata['soso_field'] = ''
|
||||
if 'field' in args_where:
|
||||
rdata['soso_field'] = args_where['field']
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
def showProcessList(self,args):
|
||||
sql = 'show processlist';
|
||||
sid = args['sid']
|
||||
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = my_instance.query(sql)
|
||||
rdata = {}
|
||||
rdata['list'] = result
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
def showStatusList(self,args):
|
||||
sql = 'show status';
|
||||
sid = args['sid']
|
||||
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = my_instance.query(sql)
|
||||
rdata = {}
|
||||
rdata['list'] = result
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
def showStatsList(self, args):
|
||||
sql = "show status like 'Com_%'";
|
||||
sid = args['sid']
|
||||
|
||||
my_instance = self.getInstanceBySid(sid).conn()
|
||||
if my_instance is False:
|
||||
return mw.returnData(False,'无法链接')
|
||||
|
||||
result = my_instance.query(sql)
|
||||
rdata = {}
|
||||
rdata['list'] = result
|
||||
return mw.returnData(True,'ok', rdata)
|
||||
|
||||
# ---------------------------------- run ----------------------------------
|
||||
# 获取 mysql 列表
|
||||
def get_db_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.getDbList(args)
|
||||
|
||||
# 获取 mysql 列表
|
||||
def get_table_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.getTableList(args)
|
||||
|
||||
def get_data_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.getDataList(args)
|
||||
|
||||
def get_proccess_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.showProcessList(args)
|
||||
|
||||
def get_status_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.showStatusList(args)
|
||||
|
||||
def get_stats_list(args):
|
||||
t = nosqlMySQLCtr()
|
||||
return t.showStatsList(args)
|
||||
|
||||
|
||||
# 测试
|
||||
def test(args):
|
||||
sid = args['sid']
|
||||
t = nosqlMySQLCtr()
|
||||
print(t.get_options())
|
||||
print("test")
|
||||
return 'ok'
|
||||
@@ -0,0 +1,48 @@
|
||||
.main-content .safe {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mask_layer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgb(255 255 255 / 60%);
|
||||
z-index: 9998;
|
||||
}
|
||||
|
||||
.mask_layer .prompt_description {
|
||||
width: 350px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin-top: -25px;
|
||||
margin-left: -175px;
|
||||
background: #fff;
|
||||
box-shadow: 1px 1px 50px rgb(0 0 0 / 30%);
|
||||
border: 1px solid #eee;
|
||||
border-radius: 2px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
#mongodb_search xm-select {
|
||||
min-height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
#mongodb_search xm-select .xm-label .xm-label-block{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
#mongodb td:last-child, th:last-child {
|
||||
width: 44px;
|
||||
position:sticky;
|
||||
right:0; /* 首行永远固定在左侧 */
|
||||
z-index:1;
|
||||
background-color:white;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
/* menu start */
|
||||
.menu .current .menu_plugin_data_query:hover {
|
||||
background-image: url("/plugins/file?name=data_query&f=ico.png");
|
||||
}
|
||||
|
||||
.menu .menu_plugin_data_query {
|
||||
background-image: url("/plugins/file?name=data_query&f=ico.png");
|
||||
}
|
||||
|
||||
/* menu end */
|
||||
@@ -0,0 +1,294 @@
|
||||
<div class="main-content" style="min-height: 389px;">
|
||||
<div class="container-fluid" style="padding-bottom: 50px;">
|
||||
<div id="cutTab" class="pos-box bgw mtb15" style="height:45px">
|
||||
<div class="tab-list">
|
||||
<div class="tabs-item active" data-name="redis">Redis</div>
|
||||
<div class="tabs-item" data-name="mongodb">Mongodb</div>
|
||||
<div class="tabs-item" data-name="memcached">Memcached</div>
|
||||
<div class="tabs-item" data-name="mysql">MySQL</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="bgw mtb15 pd15 tab-view-box firewall-tab-view safe" style="overflow: hidden;">
|
||||
|
||||
<div class="mask_layer" style="display:none;">
|
||||
<div class="prompt_description">当前未安装本地服务器,<a class="btlink install_server" href="/soft">点击安装</a></div>
|
||||
</div>
|
||||
|
||||
<!-- mysql start -->
|
||||
<!-- show w-full -->
|
||||
<div class="tab-con hide" id="mysql" style="padding: 0px;">
|
||||
|
||||
<div class="col-md-12" style="padding: 0px;overflow: hidden;">
|
||||
<div class="tootls_group tootls_top">
|
||||
<div class="pull-left">
|
||||
<div class="server_list" style="float:left;">
|
||||
<select name="sid" class="bt-input-text c5 mr5">
|
||||
<option value="0">本地服务器</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mysql_db_list" style="float:left;">
|
||||
<select name="mysql_db" class="bt-input-text c5 mr5">
|
||||
<option value="0">数据库空</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mysql_table_list" style="float:left;">
|
||||
<select name="mysql_table" class="bt-input-text c5 mr5">
|
||||
<option value="0">数据表空</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="field" style="float:left;">
|
||||
<select name="mysql_field_key" class="bt-input-text c5 mr5" style="width:80px;">
|
||||
<option value="0">无字段</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="value" style="float:left;">
|
||||
<input name="mysql_field_value" type="text" class="bt-input-text" placeholder="请输入查找内容">
|
||||
</div>
|
||||
|
||||
<button type="button" class="mysql_find btn btn-success btn-sm mr5 ml5" style="float:right;">
|
||||
<span>查找</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="position: relative;">
|
||||
<div id="mysql_table" class="mysql_table divtable mtb10">
|
||||
<table class="table table-hover">
|
||||
<thead style="position: relative;z-index: 1;">
|
||||
<tr>
|
||||
<th><span>编号</span></th>
|
||||
<th><span>操作类型</span></th>
|
||||
<th><span>详情</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mysql_list_page page">
|
||||
<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12" style="padding-left: 3px;">
|
||||
<div id="mysql_list_tab" style="padding-top:0px;">
|
||||
<div class="tab-nav">
|
||||
<span data-name="proccess" class="on">进程</span>
|
||||
<span data-name="status" class="">状态</span>
|
||||
<span data-name="stats" class="">统计</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative;">
|
||||
<div id="mysql_ot_table" class="divtable">
|
||||
<table class="table table-hover">
|
||||
<thead style="position: relative;z-index: 1;">
|
||||
<tr>
|
||||
<th><span>编号</span></th>
|
||||
<th><span>操作类型</span></th>
|
||||
<th><span>详情</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- mysql end -->
|
||||
|
||||
<!-- mongodb start -->
|
||||
<!-- show w-full -->
|
||||
<div class="tab-con hide" id="mongodb" style="padding: 0px;">
|
||||
<div class="tootls_group tootls_top">
|
||||
<div class="pull-left">
|
||||
|
||||
<div class="field" style="float:left;">
|
||||
<select name="mongodb_field_key" class="bt-input-text c5 mr5" style="width:80px;">
|
||||
<option value="0">无字段</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="value" style="float:left;">
|
||||
<input name="mongodb_field_value" type="text" class="bt-input-text" placeholder="请输入查找内容">
|
||||
</div>
|
||||
|
||||
<button type="button" class="mongodb_find btn btn-success btn-sm mr5 ml5" style="float:right;">
|
||||
<span>查找</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pull-right" style="padding-top: 5px;">
|
||||
<div class="server_list" style="float:left;">
|
||||
<select name="sid" class="bt-input-text c5 mr5">
|
||||
<option value="0">本地服务器</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="db_list" style="float:left;">
|
||||
<select name="db" class="bt-input-text c5 mr5">
|
||||
<option value="0">空</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="search" id="mongodb_search"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="position: relative;">
|
||||
|
||||
<div id="mongodb_table" class="mongodb_table divtable mtb10">
|
||||
<table class="table table-hover">
|
||||
<thead style="position: relative;z-index: 1;">
|
||||
<tr>
|
||||
<th><span>编号</span></th>
|
||||
<th><span>操作类型</span></th>
|
||||
<th><span>详情</span></th>
|
||||
<th style="text-align:right;"><span>操作</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mongodb_list_page page">
|
||||
<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- mongodb end -->
|
||||
|
||||
<!-- redis start -->
|
||||
<div class="tab-con show w-full" id="redis" style="padding: 0px;">
|
||||
<div id="redis_ctr" style="position: relative;">
|
||||
<div class="tootls_group tootls_top">
|
||||
<div class="pull-left">
|
||||
<button id="redis_add_key" type="button" class="refresh btn btn-success btn-sm mr5">
|
||||
<span>添加key</span>
|
||||
</button>
|
||||
<button id="redis_clear_all" type="button" class="clear btn btn-default btn-sm mr5" style="border-right: 1px solid #ccc;padding-right: 20px;">
|
||||
<span>清空数据库</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="redis_list_tab" style="padding-top:10px;">
|
||||
<div class="tab-nav">
|
||||
<!-- <span data-id="0" class="on">DB0(0)</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tootls_group tootls_top">
|
||||
<div class="pull-left"></div>
|
||||
<div class="pull-right" style="padding-top: 5px;">
|
||||
<div class="search">
|
||||
<input id="redis_ksearch" type="text" class="search_input" placeholder="请输入键名称">
|
||||
<span id="redis_ksearch_span" class="glyphicon glyphicon-search" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="divtable mtb10 redis_table_content">
|
||||
<table class="table table-hover">
|
||||
<thead style="position: relative;z-index: 1;">
|
||||
<tr>
|
||||
<th width="30"><input type="checkbox" onclick="checkSelect();"></th>
|
||||
<th><span>键</span></th>
|
||||
<th><span>值</span></th>
|
||||
<th><span>数据类型</span></th>
|
||||
<th><span>数据长度</span></th>
|
||||
<th><span>有效期</span></th>
|
||||
<th style="text-align:right;"><span>操作</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tootls_group tootls_bottom">
|
||||
<div class="pull-left">
|
||||
<button id="redis_batch_del" type="button" class="btn btn-sm set_batch_option bt-disabled btn-default">批量删除</button>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<div class="page redis_list_page">
|
||||
<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- redis end -->
|
||||
|
||||
<!-- memcached start -->
|
||||
<div class="tab-con hide" id="memcached" style="padding: 0px;">
|
||||
|
||||
<div id="memcached_ctr" style="position: relative;">
|
||||
<div class="tootls_group tootls_top">
|
||||
<div class="pull-left">
|
||||
<button id="memcached_add_key" type="button" class="refresh btn btn-success btn-sm mr5">
|
||||
<span>添加key</span>
|
||||
</button>
|
||||
<button id="memcached_clear_all" type="button" class="clear btn btn-default btn-sm mr5" style="border-right: 1px solid #ccc;padding-right: 20px;">
|
||||
<span>清空</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="pull-right" style="padding-top: 5px;">
|
||||
<div class="item_list" style="float:left;">
|
||||
<select name="item" class="bt-input-text c5 mr5">
|
||||
<option value="0">空</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="search">
|
||||
<input id="memcached_ksearch" type="text" class="search_input" placeholder="请输入键名称">
|
||||
<span id="memcached_ksearch_span" class="glyphicon glyphicon-search" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="divtable mtb10 memcached_table_content">
|
||||
<table class="table table-hover">
|
||||
<thead style="position: relative;z-index: 1;">
|
||||
<tr>
|
||||
<th width="30"><input type="checkbox" onclick="checkSelect();"></th>
|
||||
<th><span>键</span></th>
|
||||
<th><span>值</span></th>
|
||||
<th><span>数据长度</span></th>
|
||||
<th><span>有效期</span></th>
|
||||
<th style="text-align:right;"><span>操作</span></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tootls_group tootls_bottom">
|
||||
<div class="pull-left">
|
||||
<button id="memcached_batch_del" type="button" class="btn btn-sm set_batch_option bt-disabled btn-default">批量删除</button>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
<div class="page memcached_list_page">
|
||||
<div><span class="Pcurrent">0</span><span class="Pcount">共0条</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- memcached end -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Executable
+1281
File diff suppressed because it is too large
Load Diff
@@ -15,5 +15,5 @@
|
||||
"home": "https://docker.io",
|
||||
"doc1":"https://docker-py.readthedocs.io/",
|
||||
"type": 0,
|
||||
"pid": "2"
|
||||
"pid": "4"
|
||||
}
|
||||
@@ -38,7 +38,7 @@ Install_App()
|
||||
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
HTTP_PREFIX="https://"
|
||||
if [ ! -z "$cn" ];then
|
||||
HTTP_PREFIX="https://ghproxy.com/"
|
||||
HTTP_PREFIX="https://mirror.ghproxy.com/"
|
||||
fi
|
||||
|
||||
# FlameGraph start
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
# http://localhost/?code=M.C106_BAY.2.3e12c859-6107-0c5b-9ef4-14b3fb8269ba&state=JzHdzHXmA7x6zl7Be6cJ6uOlf9Bg69
|
||||
|
||||
|
||||
# python3 /www/mdserver-web/plugins/gdrive/index.py site bbs.midoks.me 3
|
||||
# python3 /www/mdserver-web/plugins/gdrive/index.py site bbs.midoks.icu 3
|
||||
# python3 /www/mdserver-web/plugins/gdrive/index.py database t1 3
|
||||
# python3 /www/server/mdserver-web/plugins/msonedrive/index.py path
|
||||
# /Users/midoks/Desktop/dev/python 3
|
||||
|
||||
@@ -8,6 +8,10 @@ GIT_SDIR="{$CODE_DIR}"
|
||||
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
|
||||
GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
|
||||
|
||||
if [ ! -d $GIT_USER_DIR ];then
|
||||
mkdir -p $GIT_USER_DIR
|
||||
chown -R www:www $GIT_USER_DIR
|
||||
fi
|
||||
|
||||
git config --global credential.helper store
|
||||
git config --global pull.rebase false
|
||||
@@ -34,7 +38,7 @@ if [ ! -d $WEB_PATH ];then
|
||||
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
else
|
||||
if [ -f $GIT_PROJECT_DIR/exclude.list ];then
|
||||
rsync -vauP --delete --exclude-from="$GIT_PROJECT_DIR/exclude.list" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
rsync -vauP --exclude-from="$GIT_PROJECT_DIR/exclude.list" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
else
|
||||
rsync -vauP --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
fi
|
||||
|
||||
@@ -15,7 +15,9 @@ if [ ! -d $GIT_PROJECT_DIR ];then
|
||||
fi
|
||||
|
||||
unset GIT_DIR
|
||||
git config pull.rebase false
|
||||
|
||||
git config pull.rebase true
|
||||
git config credential.helper store
|
||||
|
||||
cd $GIT_PROJECT_DIR && git pull
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ Install_App()
|
||||
|
||||
if [ "${LOCAL_ADDR}" == "cn" ];then
|
||||
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
|
||||
wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://dl.midoks.me/soft/haproxy/haproxy-${VERSION}.tar.gz
|
||||
wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://dl.midoks.icu/soft/haproxy/haproxy-${VERSION}.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<p onclick="myPerfOpt();">性能优化</p>
|
||||
<p onclick="myLogs();">日志</p>
|
||||
<p onclick="pluginLogs('mariadb',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
|
||||
<p onclick="myBinLogs();">BINLOG</p>
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
|
||||
</div>
|
||||
|
||||
+202
-33
@@ -90,6 +90,12 @@ def getDataDir():
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getLogBinName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-bin\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getPidFile():
|
||||
file = getConf()
|
||||
@@ -294,6 +300,53 @@ def binLog():
|
||||
mw.writeFile(conf, con)
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def binLogList():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['page', 'page_size', 'tojs'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
page = int(args['page'])
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
data_dir = getDataDir()
|
||||
log_bin_name = getLogBinName()
|
||||
|
||||
alist = os.listdir(data_dir)
|
||||
log_bin_l = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(log_bin_name) and not f.endswith('.index'):
|
||||
abspath = data_dir + '/' + f
|
||||
t['name'] = f
|
||||
t['size'] = os.path.getsize(abspath)
|
||||
t['time'] = mw.getDataFromInt(os.path.getctime(abspath))
|
||||
log_bin_l.append(t)
|
||||
|
||||
log_bin_l = sorted(log_bin_l, key=lambda x: x['time'], reverse=True)
|
||||
|
||||
# print(log_bin_l)
|
||||
# print(data_dir, log_bin_name)
|
||||
|
||||
count = len(log_bin_l)
|
||||
|
||||
page_start = (page - 1) * page_size
|
||||
page_end = page_start + page_size
|
||||
if page_end > count:
|
||||
page_end = count
|
||||
|
||||
data = {}
|
||||
page_args = {}
|
||||
page_args['count'] = count
|
||||
page_args['p'] = page
|
||||
page_args['row'] = page_size
|
||||
page_args['tojs'] = args['tojs']
|
||||
data['page'] = mw.getPage(page_args)
|
||||
data['data'] = log_bin_l[page_start:page_end]
|
||||
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
def cleanBinLog():
|
||||
db = pMysqlDb()
|
||||
@@ -302,21 +355,6 @@ def cleanBinLog():
|
||||
return mw.returnJson(True, '清理BINLOG成功!')
|
||||
|
||||
|
||||
def setSkipGrantTables(v):
|
||||
'''
|
||||
设置是否密码验证
|
||||
'''
|
||||
conf = getConf()
|
||||
con = mw.readFile(conf)
|
||||
if v:
|
||||
if con.find('#skip-grant-tables') != -1:
|
||||
con = con.replace('#skip-grant-tables', 'skip-grant-tables')
|
||||
else:
|
||||
con = con.replace('skip-grant-tables', '#skip-grant-tables')
|
||||
mw.writeFile(conf, con)
|
||||
return True
|
||||
|
||||
|
||||
def getErrorLog():
|
||||
args = getArgs()
|
||||
path = getDataDir()
|
||||
@@ -579,7 +617,7 @@ def setMyPort():
|
||||
restart()
|
||||
return mw.returnJson(True, '编辑成功!')
|
||||
|
||||
|
||||
# python3 plugins/mariadb/index.py run_info {}
|
||||
def runInfo(version):
|
||||
|
||||
if status(version) == 'stop':
|
||||
@@ -760,6 +798,8 @@ def rootPwd():
|
||||
'id=?', (1,)).getField('mysql_root')
|
||||
|
||||
|
||||
# python3 plugins/mariadb/index.py import_db_external {"file":"xx.sql","name":"demo1"}
|
||||
# python3 plugins/mariadb/index.py import_db_external {"file":"db_demo1_20231221_203614 2.sql","name":"demo1"}
|
||||
def importDbExternal():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
@@ -806,6 +846,9 @@ def importDbExternal():
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find(".sql") > -1 and file.find(".sql.gz") == -1:
|
||||
import_sql = import_dir + file
|
||||
|
||||
if import_sql == "":
|
||||
return mw.returnJson(False, '未找SQL文件')
|
||||
|
||||
@@ -813,12 +856,14 @@ def importDbExternal():
|
||||
sock = getSocketFile()
|
||||
|
||||
os.environ["MYSQL_PWD"] = pwd
|
||||
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p' + \
|
||||
pwd + ' ' + name + ' < ' + import_sql
|
||||
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p"' + \
|
||||
pwd + '" ' + name + ' < "' + import_sql+'"'
|
||||
|
||||
# print(mysql_cmd)
|
||||
os.system(mysql_cmd)
|
||||
os.remove(import_sql)
|
||||
|
||||
if ext != 'sql':
|
||||
os.remove(import_sql)
|
||||
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
@@ -982,7 +1027,7 @@ def syncGetDatabases():
|
||||
host = user["Host"]
|
||||
break
|
||||
|
||||
ps = mw.getMsg('INPUT_PS')
|
||||
ps = vdb_name
|
||||
if vdb_name == 'test':
|
||||
ps = mw.getMsg('DATABASE_TEST')
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
@@ -1054,12 +1099,21 @@ def setRootPwd(version=''):
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
#强制修改
|
||||
force = 0
|
||||
if 'force' in args and args['force'] == '1':
|
||||
force = 1
|
||||
|
||||
|
||||
password = args['password']
|
||||
try:
|
||||
pdb = pMysqlDb('mysql')
|
||||
result = pdb.query("show databases")
|
||||
isError = isSqlError(result)
|
||||
if isError != None:
|
||||
if force == 1:
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '【强制修改】数据库root密码修改成功(不意为成功连接数据)!')
|
||||
return isError
|
||||
|
||||
cmd = "ALTER USER 'root'@'localhost' IDENTIFIED BY '" + password + "';"
|
||||
@@ -1069,7 +1123,12 @@ def setRootPwd(version=''):
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
orm = pMysqlDb()
|
||||
orm.execute("flush privileges")
|
||||
return mw.returnJson(True, '数据库root密码修改成功!')
|
||||
|
||||
msg = ''
|
||||
if force == 1:
|
||||
msg = ',无须强制!'
|
||||
|
||||
return mw.returnJson(True, '数据库root密码修改成功!' + msg)
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '修改错误:' + str(ex))
|
||||
|
||||
@@ -1276,16 +1335,58 @@ def setDbAccess():
|
||||
psdb.where('username=?', (name,)).save('accept,rw', (access, 'rw',))
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def openSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('#skip-grant-tables','skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
def closeSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('skip-grant-tables','#skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
|
||||
def resetDbRootPwd(version):
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
pwd = mw.getRandomString(16)
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
|
||||
db_option = "-S " + serverdir + "/mysql.sock"
|
||||
cmd_pass = serverdir + '/bin/mariadb ' + db_option + ' -uroot -e'
|
||||
cmd_pass = cmd_pass + \
|
||||
"\"flush privileges;use mysql;grant all privileges on *.* to 'root'@'localhost' identified by '" + pwd + "';"
|
||||
cmd_pass = cmd_pass + "flush privileges;\""
|
||||
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
return True
|
||||
|
||||
def fixDbAccess(version):
|
||||
|
||||
pdb = pMysqlDb()
|
||||
mdb_ddir = getDataDir()
|
||||
if not os.path.exists(mdb_ddir):
|
||||
return mw.returnJson(False, '数据目录不存在,尝试重启重建!')
|
||||
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
psdb = pSqliteDb('databases')
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
# 重置密码
|
||||
appCMD(version, 'stop')
|
||||
mw.execShell("rm -rf " + getServerDir() + "/data")
|
||||
openSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
time.sleep(3)
|
||||
resetDbRootPwd(version)
|
||||
|
||||
appCMD(version, 'stop')
|
||||
closeSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
@@ -1588,6 +1689,13 @@ def setDbMasterAccess():
|
||||
psdb.where('username=?', (username,)).save('accept', (access,))
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def resetMaster(version=''):
|
||||
pdb = pMysqlDb()
|
||||
r = pdb.execute('reset master')
|
||||
isError = isSqlError(r)
|
||||
if isError != None:
|
||||
return isError
|
||||
return mw.returnJson(True, '重置成功!')
|
||||
|
||||
def getMasterDbList(version=''):
|
||||
args = getArgs()
|
||||
@@ -1899,8 +2007,7 @@ def getMasterRepSlaveUserCmd(version):
|
||||
if mode == "gtid":
|
||||
sql = "CHANGE MASTER " + connection_name + "TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
||||
clist[0]['password'] + "', " + "MASTER_LOG_FILE='" + mstatus[0]["File"] + \
|
||||
"',MASTER_USE_GTID=no,MASTER_CONNECT_RETRY=10;"
|
||||
clist[0]['password'] + "',MASTER_USE_GTID=no,MASTER_CONNECT_RETRY=10;"
|
||||
else:
|
||||
sql = "CHANGE MASTER " + connection_name + "TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
||||
@@ -2186,6 +2293,58 @@ def getSlaveList(version=''):
|
||||
data['data'] = dlist
|
||||
return mw.getJson(data)
|
||||
|
||||
def trySlaveSyncBugfix(version=''):
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动', [])
|
||||
|
||||
mode_file = getSyncModeFile()
|
||||
if not os.path.exists(mode_file):
|
||||
return mw.returnJson(False, '需要先设置同步配置')
|
||||
|
||||
mode = mw.readFile(mode_file)
|
||||
if mode != 'sync-user':
|
||||
return mw.returnJson(False, '仅支持【同步账户】模式')
|
||||
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
slave_sync_data = conn.field('ip,port,user,pass,mode,cmd').select()
|
||||
if len(slave_sync_data) < 1:
|
||||
return mw.returnJson(False, '需要先添加【同步用户】配置!')
|
||||
|
||||
# print(slave_sync_data)
|
||||
# 本地从库
|
||||
sdb = pMysqlDb()
|
||||
|
||||
gtid_purged = ''
|
||||
|
||||
for i in range(len(slave_sync_data)):
|
||||
port = slave_sync_data[i]['port']
|
||||
password = slave_sync_data[i]['pass']
|
||||
host = slave_sync_data[i]['ip']
|
||||
user = slave_sync_data[i]['user']
|
||||
|
||||
# print(port, password, host)
|
||||
|
||||
mdb = mw.getMyORM()
|
||||
mdb.setHost(host)
|
||||
mdb.setPort(port)
|
||||
mdb.setUser(user)
|
||||
mdb.setPwd(password)
|
||||
mdb.setSocket('')
|
||||
|
||||
# var_gtid = mdb.query('show VARIABLES like "%gtid_purged%"')
|
||||
var_gtid = mdb.query('select @@global.gtid_current_pos as Value')
|
||||
#print(var_gtid)
|
||||
if len(var_gtid) > 0:
|
||||
gtid_purged += var_gtid[0]['Value'] + ','
|
||||
|
||||
gtid_purged = gtid_purged.strip(',')
|
||||
sql = "set @@global.gtid_slave_pos='" + gtid_purged + "'"
|
||||
|
||||
sdb.query('stop all slaves')
|
||||
# print(sql)
|
||||
sdb.query(sql)
|
||||
sdb.query('start all slaves')
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
|
||||
def getSlaveSyncCmd(version=''):
|
||||
root = mw.getRunDir()
|
||||
@@ -2226,7 +2385,7 @@ def parseSlaveSyncCmd(cmd):
|
||||
a[kv[0]] = kv[1].replace("'", '').replace("'", '').replace(";", '')
|
||||
return a
|
||||
|
||||
|
||||
# python3 plugins/mariadb/index.py init_slave_status {}
|
||||
def initSlaveStatusSyncUser(version=''):
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
|
||||
@@ -2267,7 +2426,7 @@ def initSlaveStatusSyncUser(version=''):
|
||||
try:
|
||||
pinfo = parseSlaveSyncCmd(cmd_sql)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, base_t + '->CMD同步命令不合规范!')
|
||||
return mw.returnJson(False, base_t + '->CMD同步命令不合规范:'+str(e))
|
||||
|
||||
pdb.query(cmd_sql)
|
||||
|
||||
@@ -2452,8 +2611,7 @@ def fullSync(version=''):
|
||||
if args['begin'] == '1':
|
||||
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
|
||||
getPluginDir() + \
|
||||
'/index.py do_full_sync {"db":"' + \
|
||||
args['db'] + '","sign":"' + sign + '"} &'
|
||||
'/index.py do_full_sync {"db":"' + args['db'] + '","sign":"' + sign + '"} &'
|
||||
# print(cmd)
|
||||
mw.execShell(cmd)
|
||||
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
|
||||
@@ -2475,6 +2633,7 @@ def fullSync(version=''):
|
||||
return json.dumps({'code': 0, 'msg': '点击开始,开始同步!', 'progress': 0})
|
||||
|
||||
|
||||
# python3 plugins/mariadb/index.py do_full_sync {"db":"demo1","sign":"","beigin":"1"}
|
||||
def doFullSync(version=''):
|
||||
mode_file = getSyncModeFile()
|
||||
if not os.path.exists(mode_file):
|
||||
@@ -2512,13 +2671,16 @@ def doFullSyncUser(version=''):
|
||||
ip = data['ip']
|
||||
|
||||
bak_file = '/tmp/tmp.sql'
|
||||
if os.path.exists(bak_file):
|
||||
os.system("rm -rf " + bak_file)
|
||||
|
||||
writeDbSyncStatus({'code': 0, 'msg': '开始同步...', 'progress': 0})
|
||||
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 10})
|
||||
|
||||
if not os.path.exists(bak_file):
|
||||
dump_sql_data = getServerDir() + "/bin/mysqldump --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p" + apass + " " + sync_db + " > " + bak_file
|
||||
# https://mariadb.com/kb/zh-cn/mariadb-dump/
|
||||
dump_sql_data = getServerDir() + "/bin/mariadb-dump -f --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p'" + apass + "' " + sync_db + ">" + bak_file
|
||||
print(dump_sql_data)
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
@@ -2526,8 +2688,9 @@ def doFullSyncUser(version=''):
|
||||
if os.path.exists(bak_file):
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
my_import_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
|
||||
' ' + sync_db + ' < ' + bak_file
|
||||
my_import_cmd = getServerDir() + '/bin/mariadb -S ' + sock + " -uroot -p'" + pwd + \
|
||||
"' " + sync_db + '<' + bak_file
|
||||
print(my_import_cmd)
|
||||
mw.execShell(my_import_cmd)
|
||||
|
||||
pinfo = parseSlaveSyncCmd(data['cmd'])
|
||||
@@ -2729,6 +2892,8 @@ if __name__ == "__main__":
|
||||
print(getConf())
|
||||
elif func == 'bin_log':
|
||||
print(binLog())
|
||||
elif func == 'binlog_list':
|
||||
print(binLogList())
|
||||
elif func == 'clean_bin_log':
|
||||
print(cleanBinLog())
|
||||
elif func == 'error_log':
|
||||
@@ -2797,6 +2962,8 @@ if __name__ == "__main__":
|
||||
print(getDbrunMode(version))
|
||||
elif func == 'set_dbrun_mode':
|
||||
print(setDbrunMode(version))
|
||||
elif func == 'reset_master':
|
||||
print(resetMaster(version))
|
||||
elif func == 'get_masterdb_list':
|
||||
print(getMasterDbList(version))
|
||||
elif func == 'get_master_status':
|
||||
@@ -2821,6 +2988,8 @@ if __name__ == "__main__":
|
||||
print(getMasterRepSlaveUserCmd(version))
|
||||
elif func == 'get_slave_list':
|
||||
print(getSlaveList(version))
|
||||
elif func == 'try_slave_sync_bugfix':
|
||||
print(trySlaveSyncBugfix(version))
|
||||
elif func == 'get_slave_sync_cmd':
|
||||
print(getSlaveSyncCmd(version))
|
||||
elif func == 'get_slave_ssh_list':
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import re
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
if mw.isAppleSystem():
|
||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
info = mw.execShell(cmd)
|
||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
sys.path.append(p)
|
||||
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'mariadb'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getSPluginDir():
|
||||
return '/www/server/mdserver-web/plugins/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = getServerDir() + '/etc/my.cnf'
|
||||
return path
|
||||
|
||||
|
||||
def getDataDir():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'datadir\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getRelayLogName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'relay-log\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getLogBinName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-bin\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def binLogListLook(args):
|
||||
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
my_bin = getServerDir() + '/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata = {}
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListLookDecode(args):
|
||||
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
my_bin = getServerDir() + '/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata = {}
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListTraceRelay(args):
|
||||
rdata = {}
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
relay_name = getRelayLogName()
|
||||
data_dir = getDataDir()
|
||||
alist = os.listdir(data_dir)
|
||||
relay_list = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(relay_name) and not f.endswith('.index'):
|
||||
relay_list.append(f)
|
||||
|
||||
relay_list = sorted(relay_list, reverse=True)
|
||||
if len(relay_list) == 0:
|
||||
rdata['cmd'] = ''
|
||||
rdata['data'] = '无Relay日志'
|
||||
return rdata
|
||||
|
||||
file = relay_list[0]
|
||||
|
||||
my_bin = getServerDir() + '/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListTraceBinLog(args):
|
||||
rdata = {}
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
log_bin_name = getLogBinName()
|
||||
|
||||
alist = os.listdir(data_dir)
|
||||
log_bin_l = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(log_bin_name) and not f.endswith('.index'):
|
||||
log_bin_l.append(f)
|
||||
|
||||
if len(log_bin_l) == 0:
|
||||
rdata['cmd'] = ''
|
||||
rdata['data'] = '无BINLOG'
|
||||
return rdata
|
||||
|
||||
log_bin_l = sorted(log_bin_l, reverse=True)
|
||||
file = log_bin_l[0]
|
||||
|
||||
my_bin = getServerDir() + '/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
+269
-10
@@ -58,6 +58,62 @@ function myAsyncPost(method,args){
|
||||
return syncPost('/plugins/run', {name:'mysql', func:method, args:_args});
|
||||
}
|
||||
|
||||
function myPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'mariadb';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_mariadb';
|
||||
args['version'] = version;
|
||||
|
||||
|
||||
if (typeof(args) == 'string' && args == ''){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function myPostCallbakN(method, version, args,callback){
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'mariadb';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_mariadb';
|
||||
args['version'] = version;
|
||||
|
||||
|
||||
if (typeof(args) == 'string' && args == ''){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function runInfo(){
|
||||
myPost('run_info','',function(data){
|
||||
|
||||
@@ -83,7 +139,7 @@ function runInfo(){
|
||||
<tr><th>活动/峰值连接数</th><td>' + rdata.Threads_running + '/' + rdata.Max_used_connections + '</td><td colspan="2">若值过大,增加max_connections</td></tr>\
|
||||
<tr><th>线程缓存命中率</th><td>' + ((1 - rdata.Threads_created / rdata.Connections) * 100).toFixed(2) + '%</td><td colspan="2">若过低,增加thread_cache_size</td></tr>\
|
||||
<tr><th>索引命中率</th><td>' + ((1 - rdata.Key_reads / rdata.Key_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">若过低,增加key_buffer_size</td></tr>\
|
||||
<tr><th>Innodb索引命中率</th><td>' + ((1 - rdata.Innodb_buffer_pool_reads / rdata.Innodb_buffer_pool_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">若过低,增加innodb_buffer_pool_size</td></tr>\
|
||||
<tr><th>Innodb索引命中率</th><td>' + (rdata.Innodb_buffer_pool_read_requests / (rdata.Innodb_buffer_pool_read_requests+rdata.Innodb_buffer_pool_reads)).toFixed(2) + '%</td><td colspan="2">若过低,增加innodb_buffer_pool_size</td></tr>\
|
||||
<tr><th>查询缓存命中率</th><td>' + cache_size + '</td><td colspan="2">' + lan.soft.mysql_status_ps5 + '</td></tr>\
|
||||
<tr><th>创建临时表到磁盘</th><td>' + ((rdata.Created_tmp_disk_tables / rdata.Created_tmp_tables) * 100).toFixed(2) + '%</td><td colspan="2">若过大,尝试增加tmp_table_size</td></tr>\
|
||||
<tr><th>已打开的表</th><td>' + rdata.Open_tables + '</td><td colspan="2">若过大,增加table_cache_size</td></tr>\
|
||||
@@ -438,13 +494,24 @@ function syncToDatabase(type){
|
||||
}
|
||||
|
||||
function setRootPwd(type, pwd){
|
||||
if (type==1){
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var index = layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
title: '修改数据库密码',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
btn:["提交","关闭"],
|
||||
btn:["提交", "关闭", "复制ROOT密码", "强制修改"],
|
||||
shadeClose: true,
|
||||
content: "<form class='bt-form pd20' id='mod_pwd'>\
|
||||
<div class='line'>\
|
||||
@@ -454,16 +521,36 @@ function setRootPwd(type, pwd){
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
yes:function(index,layero){
|
||||
yes:function(layerIndex){
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
layer.close(index);
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
},
|
||||
btn3:function(){
|
||||
var password = $("#MyPassword").val();
|
||||
copyText(password);
|
||||
return false;
|
||||
},
|
||||
btn4:function(layerIndex){
|
||||
layer.confirm('强制修改,是为了在重建时使用,确定强制?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function(index, layero){
|
||||
layer.close(index);
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password,force:'1'}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1160,6 +1247,146 @@ function dbList(page, search){
|
||||
});
|
||||
}
|
||||
|
||||
function myBinRollingLogs(_name, func, _args, line){
|
||||
|
||||
var file_line = 100;
|
||||
if ( typeof(line) != 'undefined' ){
|
||||
file_line = line;
|
||||
}
|
||||
|
||||
var reqTimer = null;
|
||||
|
||||
function requestLogs(func,file,line){
|
||||
myPostCallbakN(func,'',{'file':file,"line":line}, function(rdata){
|
||||
var data = rdata.data.data;
|
||||
var cmd = rdata.data.cmd;
|
||||
if(data == '') {
|
||||
data = '当前没有日志!';
|
||||
}
|
||||
|
||||
$('#my_rolling_cmd').html(cmd);
|
||||
|
||||
$('#my_rolling_copy').click(function(){
|
||||
copyText(cmd);
|
||||
});
|
||||
|
||||
var ebody = '<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 570px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log">'+data+'</textarea>';
|
||||
$("#my_rolling_logs").html(ebody);
|
||||
var ob = document.getElementById('roll_info_log');
|
||||
ob.scrollTop = ob.scrollHeight;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: _name + '日志',
|
||||
area: ['800px','700px'],
|
||||
end: function(){
|
||||
if (reqTimer){
|
||||
clearInterval(reqTimer);
|
||||
}
|
||||
},
|
||||
content:'<div class="change-default" style="padding:0px 20px 0px;">\
|
||||
<div class="divtable mtb10">\
|
||||
<table class="table table-hover"><tr>\
|
||||
<td id="my_rolling_cmd">cmd</td>\
|
||||
<td id="my_rolling_copy" style="width:35px;"><span class="ico-copy cursor btcopy" title="复制密码"></span></td>\
|
||||
<tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="change-default" style="padding:0px 20px 0px;" id="my_rolling_logs">\
|
||||
<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 570px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log"></textarea>\
|
||||
</div>',
|
||||
success:function(){
|
||||
var fileName = _args['file'];
|
||||
requestLogs(func,fileName,file_line);
|
||||
reqTimer = setInterval(function(){
|
||||
requestLogs(func,fileName,file_line);
|
||||
},1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogsRender(page){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
_data['tojs'] = 'myBinLogsRender';
|
||||
myPost('binlog_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
var list = '';
|
||||
for(i in rdata.data){
|
||||
list += '<tr>';
|
||||
|
||||
list += '<td>' + rdata.data[i]['name'] +'</td>';
|
||||
list += '<td>' + toSize(rdata.data[i]['size'])+'</td>';
|
||||
list += '<td>' + rdata.data[i]['time'] +'</td>';
|
||||
|
||||
|
||||
list += '<td style="text-align:right">';
|
||||
list += '<a href="javascript:;" data-index="'+i+'" class="btlink look" class="btlink">查看</a> | ';
|
||||
list += '<a href="javascript:;" data-index="'+i+'" class="btlink look_decode" class="btlink">解码查看</a>';
|
||||
list += '</td></tr>';
|
||||
}
|
||||
|
||||
if (rdata.data.length ==0){
|
||||
list = '<tr><td colspan="4">无数据</td</tr>';
|
||||
}
|
||||
|
||||
$("#binlog_list tbody").html(list);
|
||||
$('#binlog_page').html(rdata.page);
|
||||
|
||||
|
||||
$('#binlog_list .look').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = rdata.data[i]['name'];
|
||||
myBinRollingLogs('查看BINLOG','binLogListLook',{'file':file },100);
|
||||
});
|
||||
|
||||
$('#binlog_list .look_decode').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = rdata.data[i]['name'];
|
||||
myBinRollingLogs('查看解码BINLOG','binLogListLookDecode',{'file':file },100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogs(){
|
||||
var con = '<div class="safe bgw">\
|
||||
<button class="btn btn-success btn-sm relay_trace" type="button" style="margin-right: 5px;">中继日志跟踪</button>\
|
||||
<button class="btn btn-default btn-sm binlog_trace" type="button" style="margin-right: 5px;">最新BINLOG日志跟踪</button>\
|
||||
<div id="binlog_list" class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
<thead><tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>大小</th>\
|
||||
<th>时间</th>\
|
||||
<th style="text-align:right;">操作</th>\
|
||||
</tr></thead>\
|
||||
<tbody></tbody></table>\
|
||||
</div>\
|
||||
<div id="binlog_page" class="dataTables_paginate paging_bootstrap page"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
$(".soft-man-con").html(con);
|
||||
myBinLogsRender(1);
|
||||
|
||||
$('.soft-man-con .relay_trace').click(function(){
|
||||
myBinRollingLogs('中继日志跟踪','binLogListTraceRelay',{'file':''},100);
|
||||
});
|
||||
|
||||
$('.soft-man-con .binlog_trace').click(function(){
|
||||
myBinRollingLogs('最新BINLOG日志跟踪','binLogListTraceBinLog',{'file':''},100);
|
||||
});
|
||||
}
|
||||
|
||||
function myLogs(){
|
||||
|
||||
@@ -1603,6 +1830,14 @@ function setDbMasterAccess(username){
|
||||
});
|
||||
}
|
||||
|
||||
function resetMaster(){
|
||||
myPost('reset_master', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
},'正在执行重置master命令[reset master]');
|
||||
}
|
||||
|
||||
function getMasterRepSlaveList(){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
@@ -2329,11 +2564,16 @@ function masterOrSlaveConf(version=''){
|
||||
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
|
||||
</tr>";
|
||||
|
||||
var btn_list = ['复制错误',"取消"];
|
||||
if (info['Last_IO_Error'].search(/1236/i)>0){
|
||||
btn_list = ['复制错误',"取消","尝试修复"];
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '同步异常信息',
|
||||
area: ['600px','300px'],
|
||||
btn:['复制错误',"取消"],
|
||||
btn:btn_list,
|
||||
content:"<form class='bt-form pd15'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div class='tablescroll'>\
|
||||
@@ -2348,10 +2588,20 @@ function masterOrSlaveConf(version=''){
|
||||
</div>\
|
||||
</form>",
|
||||
success:function(){
|
||||
// copyText(v['Error']);
|
||||
// $('.class-copy-db-err').click(function(){
|
||||
// copyText(v['Error']);
|
||||
// });
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
copyText(info['Last_IO_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Last_SQL_Error'] != ''){
|
||||
copyText(info['Last_SQL_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Slave_SQL_Running_State'] != ''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
yes:function(){
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
@@ -2368,6 +2618,14 @@ function masterOrSlaveConf(version=''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
btn3:function(){
|
||||
myPost('try_slave_sync_bugfix', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg, function(){
|
||||
masterOrSlaveConf();
|
||||
},{ icon: rdata.status ? 1 : 5 },2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2437,6 +2695,7 @@ function masterOrSlaveConf(version=''){
|
||||
<p class="conf_p">\
|
||||
<span class="f14 c6 mr20">Master[主]配置</span><span class="f14 c6 mr20"></span>\
|
||||
<button class="btn '+(!rdata.status ? 'btn-danger' : 'btn-success')+' btn-xs btn-master">'+(!rdata.status ? '未开启' : '已开启') +'</button>\
|
||||
<button class="btn btn-success btn-xs" onclick="resetMaster()">重置</button>\
|
||||
</p>\
|
||||
<hr/>\
|
||||
<!-- master list -->\
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.11.2
|
||||
MY_VER=10.11.6
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.6.12
|
||||
MY_VER=10.6.16
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.9.5
|
||||
MY_VER=10.9.8
|
||||
|
||||
Install_app()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.0.3
|
||||
MY_VER=11.0.4
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -100,7 +100,7 @@ Install_app()
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '11.0' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.1.2
|
||||
MY_VER=11.1.3
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -100,7 +100,7 @@ Install_app()
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '11.1' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.2.1
|
||||
MY_VER=11.2.2
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -100,7 +100,7 @@ Install_app()
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '11.2' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.3.0
|
||||
MY_VER=11.3.1
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -100,7 +100,7 @@ Install_app()
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '11.3' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
|
||||
@@ -5,8 +5,13 @@ bind_ip = 127.0.0.1
|
||||
port = 27017
|
||||
fork = true
|
||||
auth = false
|
||||
#smallfiles = true
|
||||
|
||||
oplogSize=100
|
||||
|
||||
# Master/slave replication is no longer supported
|
||||
#master = true
|
||||
|
||||
#replSet = test
|
||||
|
||||
pidfilepath = {$SERVER_PATH}/mongodb/mongodb.pid
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
@@ -5,19 +16,20 @@
|
||||
<p onclick="pluginInitD('mongodb');">自启动</p>
|
||||
<p onclick="pluginConfig('mongodb');">配置修改</p>
|
||||
<p onclick="mongoStatus();">负载状态</p>
|
||||
<p onclick="mongoDocStatus();">文档状态</p>
|
||||
<p onclick="mongoReplStatus();">复制状态</p>
|
||||
<p onclick="pluginLogs('mongodb','','run_log');">日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
<div class="soft-man-con" style="height:455px;overflow: auto;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
//mongodb start
|
||||
var loading = layer.msg("资源加载中...", { icon: 16, time: 0, shade: 0.3 });
|
||||
$.getScript( "/plugins/file?name=mongodb&f=js/mongodb.js", function(){
|
||||
layer.close(loading);
|
||||
pluginService('mongodb')
|
||||
resetPluginWinHeight(530);
|
||||
$.getScript('/plugins/file?name=mongodb&f=js/mongodb.js', function(){
|
||||
pluginService('mongodb');
|
||||
});
|
||||
//mongodb end
|
||||
</script>
|
||||
+136
-15
@@ -4,6 +4,9 @@ import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import datetime
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
@@ -49,6 +52,13 @@ def getInitDTpl():
|
||||
return path
|
||||
|
||||
|
||||
def getConfPort():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'port\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
@@ -68,7 +78,7 @@ def getArgs():
|
||||
|
||||
def status():
|
||||
data = mw.execShell(
|
||||
"ps -ef|grep mongod |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
|
||||
"ps -ef|grep mongod |grep -v grep | grep -v /Applications | grep -v python | grep -v mdserver-web | awk '{print $2}'")
|
||||
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
@@ -93,6 +103,11 @@ def initDreplace():
|
||||
if not os.path.exists(data_dir):
|
||||
os.mkdir(data_dir)
|
||||
|
||||
install_ok = getServerDir() + "/install.lock"
|
||||
if os.path.exists(install_ok):
|
||||
return file_bin
|
||||
mw.writeFile(install_ok, 'ok')
|
||||
|
||||
# initd replace
|
||||
content = mw.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
@@ -122,6 +137,7 @@ def mgOp(method):
|
||||
file = initDreplace()
|
||||
if mw.isAppleSystem():
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
# print(data)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
@@ -155,35 +171,134 @@ def restart():
|
||||
|
||||
def runInfo():
|
||||
import pymongo
|
||||
client = pymongo.MongoClient(host='127.0.0.1', port=27017)
|
||||
|
||||
port = getConfPort()
|
||||
client = pymongo.MongoClient(host='127.0.0.1', port=int(port))
|
||||
db = client.admin
|
||||
serverStatus = db.command('serverStatus')
|
||||
|
||||
listDbs = client.list_database_names()
|
||||
|
||||
result = {}
|
||||
result["host"] = serverStatus['host']
|
||||
result["version"] = serverStatus['version']
|
||||
result["uptime"] = serverStatus['uptime']
|
||||
result['db_path'] = getServerDir() + "/data"
|
||||
result["connections"] = serverStatus['connections']['current']
|
||||
result["collections"] = len(listDbs)
|
||||
|
||||
pf = serverStatus['opcounters']
|
||||
result['pf'] = pf
|
||||
|
||||
return mw.getJson(result)
|
||||
|
||||
|
||||
def runDocInfo():
|
||||
import pymongo
|
||||
|
||||
port = getConfPort()
|
||||
client = pymongo.MongoClient(host='127.0.0.1', port=int(port))
|
||||
db = client.admin
|
||||
serverStatus = db.command('serverStatus')
|
||||
|
||||
listDbs = client.list_database_names()
|
||||
showDbList = []
|
||||
result = {}
|
||||
for x in range(len(listDbs)):
|
||||
mongd = client[listDbs[x]]
|
||||
stats = mongd.command({"dbstats": 1})
|
||||
if 'operationTime' in stats:
|
||||
del stats['operationTime']
|
||||
|
||||
if '$clusterTime' in stats:
|
||||
del stats['$clusterTime']
|
||||
showDbList.append(stats)
|
||||
# print(showDbList)
|
||||
# print(serverStatus)
|
||||
# for key, value in serverStatus.items():
|
||||
# print(key, value)
|
||||
result = {}
|
||||
result["version"] = serverStatus['version']
|
||||
result["uptime"] = serverStatus['uptime']
|
||||
|
||||
result['db_path'] = getServerDir() + "/data"
|
||||
|
||||
result["connections"] = serverStatus['connections']['current']
|
||||
if 'catalogStats' in serverStatus:
|
||||
result["collections"] = serverStatus['catalogStats']['collections']
|
||||
|
||||
result["dbs"] = showDbList
|
||||
return mw.getJson(result)
|
||||
|
||||
|
||||
def runReplInfo():
|
||||
import pymongo
|
||||
|
||||
port = getConfPort()
|
||||
client = pymongo.MongoClient(host='127.0.0.1', port=int(port))
|
||||
db = client.admin
|
||||
serverStatus = db.command('serverStatus')
|
||||
|
||||
result = {}
|
||||
result['status'] = '无'
|
||||
result['doc_name'] = '无'
|
||||
if 'repl' in serverStatus:
|
||||
repl = serverStatus['repl']
|
||||
# print(repl)
|
||||
if 'ismaster' in repl and repl['ismaster']:
|
||||
result['status'] = '主'
|
||||
else:
|
||||
result['status'] = '从'
|
||||
|
||||
result['setName'] = repl['setName']
|
||||
result['primary'] = repl['primary']
|
||||
result['me'] = repl['me']
|
||||
|
||||
hosts = repl['hosts']
|
||||
result['hosts'] = ','.join(hosts)
|
||||
|
||||
|
||||
return mw.returnJson(True, 'OK', result)
|
||||
|
||||
def test():
|
||||
# https://pymongo.readthedocs.io/en/stable/examples/high_availability.html
|
||||
import pymongo
|
||||
from pymongo import ReadPreference
|
||||
|
||||
port = getConfPort()
|
||||
client = pymongo.MongoClient(host='127.0.0.1', port=int(port))
|
||||
db = client.admin
|
||||
|
||||
# config = {
|
||||
# '_id': 'test',
|
||||
# 'members': [
|
||||
# {'_id': 1, 'host': '127.0.0.1:27018','priority': 10 },
|
||||
# {'_id': 2, 'host': '127.0.0.1:27019','priority': 1 },
|
||||
# {'_id': 3, 'host': '127.0.0.1:27020','priority': 0 },
|
||||
# # {'_id': 2, 'host': 'localhost:27019'}
|
||||
# ]
|
||||
# }
|
||||
|
||||
# rsStatus = client.admin.command("replSetInitiate", config)
|
||||
|
||||
# 需要通过命令行操作
|
||||
# -> rs.initiate({
|
||||
# _id: 'test',
|
||||
# members: [{
|
||||
# _id: 1,
|
||||
# host: '127.0.0.1:27018',
|
||||
# priority: 2 // 这个priority不设置为1,值越高,当主库故障的时候会优先被选举成主库
|
||||
# }, {
|
||||
# _id: 2,
|
||||
# host: '127.0.0.1:27019',
|
||||
# priority: 0 //设置为0则不能成为主库
|
||||
# }, {
|
||||
# _id: 3,
|
||||
# host: '127.0.0.1:27020',
|
||||
# priority: 1
|
||||
# }]
|
||||
# });
|
||||
|
||||
# > rs.status(); // 查询状态
|
||||
# // "stateStr" : "PRIMARY", 主节点
|
||||
# // "stateStr" : "SECONDARY", 副本节点
|
||||
|
||||
# > rs.add({"_id":3, "host":"127.0.0.1:27318","priority":0,"votes":0});
|
||||
|
||||
|
||||
serverStatus = db.command('serverStatus')
|
||||
print(serverStatus)
|
||||
|
||||
# return mw.returnJson(True, 'OK', result)
|
||||
|
||||
|
||||
def initdStatus():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
@@ -266,9 +381,15 @@ if __name__ == "__main__":
|
||||
print(initdUinstall())
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
elif func == 'run_doc_info':
|
||||
print(runDocInfo())
|
||||
elif func == 'run_repl_info':
|
||||
print(runReplInfo())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'test':
|
||||
print(test())
|
||||
else:
|
||||
print('error')
|
||||
|
||||
@@ -8,18 +8,40 @@ function mongoStatus() {
|
||||
}
|
||||
|
||||
var rdata = $.parseJSON(data.data);
|
||||
hit = (parseInt(rdata.keyspace_hits) / (parseInt(rdata.keyspace_hits) + parseInt(rdata.keyspace_misses)) * 100).toFixed(2);
|
||||
var Con = '<div class="divtable">\
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<thead><th>字段</th><th>当前值</th><th>说明</th></thead>\
|
||||
<tbody>\
|
||||
<tr><th>host</th><td>' + rdata.host + '</td><td>服务器</td></tr>\
|
||||
<tr><th>version</th><td>' + rdata.version + '</td><td>版本</td></tr>\
|
||||
<tr><th>db_path</th><td>' + rdata.db_path + '</td><td>数据路径</td></tr>\
|
||||
<tr><th>uptime</th><td>' + rdata.uptime + '</td><td>已运行秒</td></tr>\
|
||||
<tr><th>connections</th><td>' + rdata.connections + '</td><td>当前链接数</td></tr>\
|
||||
<tr><th>collections</th><td>' + rdata.collections + '</td><td>文档数</td></tr>\
|
||||
<tr><th>insert</th><td>' + rdata.pf['insert'] + '</td><td>插入命令数</td></tr>\
|
||||
<tr><th>query</th><td>' + rdata.pf['query'] + '</td><td>查询命令数</td></tr>\
|
||||
<tr><th>update</th><td>' + rdata.pf['update'] + '</td><td>更新命令数</td></tr>\
|
||||
<tr><th>delete</th><td>' + rdata.pf['delete'] + '</td><td>删除命令数</td></tr>\
|
||||
<tr><th>getmore</th><td>' + rdata.pf['getmore'] + '</td><td>getmore命令数</td></tr>\
|
||||
<tr><th>command</th><td>' + rdata.pf['command'] + '</td><td>执行命令数</td></tr>\
|
||||
<tbody>\
|
||||
</table></div><hr/>';
|
||||
</table></div>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function mongoDocStatus() {
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'mongodb', func:'run_doc_info'}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
var t = '';
|
||||
for(var i=0; i<rdata.dbs.length;i++){
|
||||
@@ -35,13 +57,54 @@ function mongoStatus() {
|
||||
}
|
||||
// console.log(t);
|
||||
|
||||
Con += '<div class="divtable">\
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<thead><th>库名</th><th>大小</th><th>存储大小</th><th>数据</th><th>索引</th><th>文档数据</th><th>对象</th></thead>\
|
||||
<tbody>'+t+'<tbody>\
|
||||
</table></div>';
|
||||
// console.log(rdata.dbs);
|
||||
|
||||
$(".soft-man-con").html(Con);
|
||||
$(".soft-man-con").html(con);
|
||||
},'json');
|
||||
}
|
||||
}
|
||||
|
||||
function mongoReplStatus() {
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'mongodb', func:'run_repl_info'}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var rdata = rdata.data;
|
||||
|
||||
var tbody = '';
|
||||
if (rdata.status == '无'){
|
||||
tbody += '<tr><td colspan="3" style="text-align:center;">无数据</td></tr>';
|
||||
} else{
|
||||
tbody += '<tr><th>状态</th><td>' + rdata.status + '</td><td>主/从</td></tr>\
|
||||
<tr><th>同步文档</th><td>' + rdata.setName + '</td><td>文档名</td></tr>\
|
||||
<tr><th>hosts</th><td><span class="overflow_hide" style="width:260px;" title="'+rdata.hosts+'">' + rdata.hosts + '</span></td><td>服务器所有节点</td></tr>\
|
||||
<tr><th>primary</th><td>' + rdata.primary + '</td><td>primary</td></tr>\
|
||||
<tr><th>me</th><td>' + rdata.me + '</td><td>me</td></tr>';
|
||||
}
|
||||
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<thead><th>字段</th><th>当前值</th><th>说明</th></thead>\
|
||||
<tbody>\
|
||||
'+tbody+'\
|
||||
<tbody>\
|
||||
</table>\
|
||||
</div>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
[client]
|
||||
user = root
|
||||
#password = your_password
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
default-character-set = UTF8MB4
|
||||
|
||||
[mysqld]
|
||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
||||
|
||||
authentication_policy=mysql_native_password
|
||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
||||
user = mysql
|
||||
port = 33206
|
||||
mysqlx_port = 33260
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
server-id = {$SERVER_ID}
|
||||
sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
net_buffer_length = 4K
|
||||
read_buffer_size = 128K
|
||||
read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=1
|
||||
tmp_table_size = 8M
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
max_allowed_packet = 128M
|
||||
|
||||
#skip-external-locking
|
||||
#skip-grant-tables
|
||||
#loose-skip-innodb
|
||||
#skip-networking
|
||||
#skip-name-resolve
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
#log_queries_not_using_indexes=on
|
||||
|
||||
relay-log=mdserver
|
||||
relay-log-index=mdserver
|
||||
|
||||
#master
|
||||
#sync_binlog=1
|
||||
|
||||
#binlog-do-db
|
||||
binlog-ignore-db = test
|
||||
binlog-ignore-db = mysql
|
||||
binlog-ignore-db = information_schema
|
||||
binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log_replica_updates
|
||||
#replicate-do-db
|
||||
slave_skip_errors=1062,1396
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
master_info_repository = table
|
||||
relay_log_info_repository = table
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_buffer_pool_size = 16M
|
||||
innodb_redo_log_capacity=10485760
|
||||
innodb_log_buffer_size = 8M
|
||||
innodb_flush_log_at_trx_commit = 1
|
||||
innodb_lock_wait_timeout = 120
|
||||
innodb_max_dirty_pages_pct = 90
|
||||
innodb_read_io_threads = 1
|
||||
innodb_write_io_threads = 1
|
||||
innodb_file_per_table=1
|
||||
binlog_expire_logs_seconds=2592000
|
||||
|
||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[myisamchk]
|
||||
key_buffer_size = 20M
|
||||
sort_buffer_size = 20M
|
||||
read_buffer = 2M
|
||||
write_buffer = 2M
|
||||
|
||||
[mysqlhotcopy]
|
||||
interactive-timeout
|
||||
@@ -12,6 +12,7 @@
|
||||
<p onclick="myPerfOpt();">性能优化</p>
|
||||
<p onclick="myLogs();">日志</p>
|
||||
<p onclick="pluginLogs('mysql-apt',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
|
||||
<p onclick="myBinLogs();">BINLOG</p>
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
|
||||
</div>
|
||||
|
||||
+218
-4
@@ -114,7 +114,16 @@ def getErrorLogsFile():
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getAuthPolicy():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'authentication_policy\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if tmp:
|
||||
return tmp.groups()[0].strip()
|
||||
# caching_sha2_password
|
||||
return 'mysql_native_password'
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = mw.getServerDir()
|
||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
||||
@@ -242,6 +251,12 @@ def getDataDir():
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getLogBinName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-bin\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getPidFile():
|
||||
file = getConf()
|
||||
@@ -297,6 +312,58 @@ def setSkipGrantTables(v):
|
||||
mw.writeFile(conf, con)
|
||||
return True
|
||||
|
||||
def binLogList():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['page', 'page_size', 'tojs'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
page = int(args['page'])
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
data_dir = getDataDir()
|
||||
log_bin_name = getLogBinName()
|
||||
|
||||
alist = os.listdir(data_dir)
|
||||
log_bin_l = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(log_bin_name) and not f.endswith('.index'):
|
||||
abspath = data_dir + '/' + f
|
||||
t['name'] = f
|
||||
t['size'] = os.path.getsize(abspath)
|
||||
t['time'] = mw.getDataFromInt(os.path.getctime(abspath))
|
||||
log_bin_l.append(t)
|
||||
|
||||
log_bin_l = sorted(log_bin_l, key=lambda x: x['time'], reverse=True)
|
||||
|
||||
# print(log_bin_l)
|
||||
# print(data_dir, log_bin_name)
|
||||
|
||||
count = len(log_bin_l)
|
||||
|
||||
page_start = (page - 1) * page_size
|
||||
page_end = page_start + page_size
|
||||
if page_end > count:
|
||||
page_end = count
|
||||
|
||||
data = {}
|
||||
page_args = {}
|
||||
page_args['count'] = count
|
||||
page_args['p'] = page
|
||||
page_args['row'] = page_size
|
||||
page_args['tojs'] = args['tojs']
|
||||
data['page'] = mw.getPage(page_args)
|
||||
data['data'] = log_bin_l[page_start:page_end]
|
||||
|
||||
return mw.getJson(data)
|
||||
|
||||
def cleanBinLog():
|
||||
db = pMysqlDb()
|
||||
cleanTime = time.strftime('%Y-%m-%d %H:%i:%s', time.localtime())
|
||||
db.execute("PURGE MASTER LOGS BEFORE '" + cleanTime + "';")
|
||||
return mw.returnJson(True, '清理BINLOG成功!')
|
||||
|
||||
def getErrorLog():
|
||||
args = getArgs()
|
||||
@@ -1061,12 +1128,20 @@ def setRootPwd(version=''):
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
#强制修改
|
||||
force = 0
|
||||
if 'force' in args and args['force'] == '1':
|
||||
force = 1
|
||||
|
||||
password = args['password']
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
result = pdb.query("show databases")
|
||||
isError = isSqlError(result)
|
||||
if isError != None:
|
||||
if force == 1:
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '【强制修改】数据库root密码修改成功(不意为成功连接数据)!')
|
||||
return isError
|
||||
|
||||
if version.find('5.7') > -1 or version.find('8.0') > -1:
|
||||
@@ -1081,11 +1156,14 @@ def setRootPwd(version=''):
|
||||
"update mysql.user set Password=password('" + password + "') where User='root'")
|
||||
pdb.execute("flush privileges")
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '数据库root密码修改成功!')
|
||||
|
||||
msg = ''
|
||||
if force == 1:
|
||||
msg = ',无须强制!'
|
||||
return mw.returnJson(True, '数据库root密码修改成功!'+msg)
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '修改错误:' + str(ex))
|
||||
|
||||
|
||||
def setUserPwd(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['password', 'name'])
|
||||
@@ -1291,7 +1369,58 @@ def setDbAccess():
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def fixDbAccess(version):
|
||||
|
||||
def openSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('#skip-grant-tables','skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
def closeSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('skip-grant-tables','#skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
|
||||
def resetDbRootPwd(version):
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
pwd = mw.getRandomString(16)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
|
||||
if float(version) < 5.7:
|
||||
cmd_pass = serverdir + '/bin/usr/bin/mysql --defaults-file=' + myconf + ' -uroot -e'
|
||||
cmd_pass = cmd_pass + '"UPDATE mysql.user SET password=PASSWORD(\'' + pwd + "') WHERE user='root';"
|
||||
cmd_pass = cmd_pass + 'flush privileges;"'
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
else:
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
reset_pwd = 'flush privileges;'
|
||||
reset_pwd = reset_pwd + \
|
||||
"UPDATE mysql.user SET authentication_string='' WHERE user='root';"
|
||||
reset_pwd = reset_pwd + "flush privileges;"
|
||||
reset_pwd = reset_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED by '" + pwd + "';"
|
||||
reset_pwd = reset_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH "+auth_policy+" by '" + pwd + "';"
|
||||
reset_pwd = reset_pwd + "flush privileges;"
|
||||
|
||||
tmp_file = "/tmp/mysql_init_tmp.log"
|
||||
mw.writeFile(tmp_file, reset_pwd)
|
||||
cmd_pass = serverdir + '/bin/usr/bin/mysql --defaults-file=' + myconf + ' -uroot -proot < ' + tmp_file
|
||||
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
os.remove(tmp_file)
|
||||
return True
|
||||
|
||||
def fixDbAccess2(version):
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
data = pdb.query('show databases')
|
||||
@@ -1304,6 +1433,35 @@ def fixDbAccess(version):
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '修复失败请重试!')
|
||||
|
||||
def fixDbAccess(version):
|
||||
|
||||
pdb = pMysqlDb()
|
||||
mdb_ddir = getDataDir()
|
||||
if not os.path.exists(mdb_ddir):
|
||||
return mw.returnJson(False, '数据目录不存在,尝试重启重建!')
|
||||
|
||||
try:
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
|
||||
# 重置密码
|
||||
appCMD(version, 'stop')
|
||||
openSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
time.sleep(3)
|
||||
resetDbRootPwd(version)
|
||||
|
||||
appCMD(version, 'stop')
|
||||
closeSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '修复失败请重试!')
|
||||
|
||||
|
||||
|
||||
def setDbRw(version=''):
|
||||
@@ -2217,6 +2375,56 @@ def getSlaveList(version=''):
|
||||
data['data'] = dlist
|
||||
return mw.getJson(data)
|
||||
|
||||
def trySlaveSyncBugfix(version=''):
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动', [])
|
||||
|
||||
mode_file = getSyncModeFile()
|
||||
if not os.path.exists(mode_file):
|
||||
return mw.returnJson(False, '需要先设置同步配置')
|
||||
|
||||
mode = mw.readFile(mode_file)
|
||||
if mode != 'sync-user':
|
||||
return mw.returnJson(False, '仅支持【同步账户】模式')
|
||||
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
slave_sync_data = conn.field('ip,port,user,pass,mode,cmd').select()
|
||||
if len(slave_sync_data) < 1:
|
||||
return mw.returnJson(False, '需要先添加【同步用户】配置!')
|
||||
|
||||
# print(slave_sync_data)
|
||||
# 本地从库
|
||||
sdb = pMysqlDb()
|
||||
|
||||
gtid_purged = ''
|
||||
|
||||
for i in range(len(slave_sync_data)):
|
||||
port = slave_sync_data[i]['port']
|
||||
password = slave_sync_data[i]['pass']
|
||||
host = slave_sync_data[i]['ip']
|
||||
user = slave_sync_data[i]['user']
|
||||
|
||||
# print(port, password, host)
|
||||
|
||||
mdb = mw.getMyORM()
|
||||
mdb.setHost(host)
|
||||
mdb.setPort(port)
|
||||
mdb.setUser(user)
|
||||
mdb.setPwd(password)
|
||||
mdb.setSocket('')
|
||||
|
||||
var_gtid = mdb.query('show VARIABLES like "%gtid_purged%"')
|
||||
if len(var_gtid) > 0:
|
||||
gtid_purged += var_gtid[0]['Value'] + ','
|
||||
|
||||
gtid_purged = gtid_purged.strip(',')
|
||||
sql = "set @@global.gtid_purged='" + gtid_purged + "'"
|
||||
|
||||
sdb.query('stop slave')
|
||||
# print(sql)
|
||||
sdb.query(sql)
|
||||
sdb.query('start slave')
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
|
||||
def getSlaveSyncCmd(version=''):
|
||||
|
||||
@@ -2802,6 +3010,8 @@ if __name__ == "__main__":
|
||||
print(getConf())
|
||||
elif func == 'bin_log':
|
||||
print(binLog())
|
||||
elif func == 'binlog_list':
|
||||
print(binLogList())
|
||||
elif func == 'clean_bin_log':
|
||||
print(cleanBinLog())
|
||||
elif func == 'error_log':
|
||||
@@ -2852,6 +3062,8 @@ if __name__ == "__main__":
|
||||
print(setDbAccess())
|
||||
elif func == 'fix_db_access':
|
||||
print(fixDbAccess(version))
|
||||
elif func == 'fix_db_access2':
|
||||
print(fixDbAccess2(version))
|
||||
elif func == 'set_db_rw':
|
||||
print(setDbRw(version))
|
||||
elif func == 'set_db_ps':
|
||||
@@ -2896,6 +3108,8 @@ if __name__ == "__main__":
|
||||
print(getMasterRepSlaveUserCmd(version))
|
||||
elif func == 'get_slave_list':
|
||||
print(getSlaveList(version))
|
||||
elif func == 'try_slave_sync_bugfix':
|
||||
print(trySlaveSyncBugfix(version))
|
||||
elif func == 'get_slave_sync_cmd':
|
||||
print(getSlaveSyncCmd(version))
|
||||
elif func == 'get_slave_ssh_list':
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import re
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
if mw.isAppleSystem():
|
||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
info = mw.execShell(cmd)
|
||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
sys.path.append(p)
|
||||
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'mysql-apt'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getSPluginDir():
|
||||
return '/www/server/mdserver-web/plugins/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = getServerDir() + '/etc/my.cnf'
|
||||
return path
|
||||
|
||||
|
||||
def getDataDir():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'datadir\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getRelayLogName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'relay-log\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getLogBinName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-bin\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def binLogListLook(args):
|
||||
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata = {}
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListLookDecode(args):
|
||||
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata = {}
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListTraceRelay(args):
|
||||
rdata = {}
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
relay_name = getRelayLogName()
|
||||
data_dir = getDataDir()
|
||||
alist = os.listdir(data_dir)
|
||||
relay_list = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(relay_name) and not f.endswith('.index'):
|
||||
relay_list.append(f)
|
||||
|
||||
relay_list = sorted(relay_list, reverse=True)
|
||||
if len(relay_list) == 0:
|
||||
rdata['cmd'] = ''
|
||||
rdata['data'] = '无Relay日志'
|
||||
return rdata
|
||||
|
||||
file = relay_list[0]
|
||||
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListTraceBinLog(args):
|
||||
rdata = {}
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
log_bin_name = getLogBinName()
|
||||
|
||||
alist = os.listdir(data_dir)
|
||||
log_bin_l = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(log_bin_name) and not f.endswith('.index'):
|
||||
log_bin_l.append(f)
|
||||
|
||||
if len(log_bin_l) == 0:
|
||||
rdata['cmd'] = ''
|
||||
rdata['data'] = '无BINLOG'
|
||||
return rdata
|
||||
|
||||
log_bin_l = sorted(log_bin_l, reverse=True)
|
||||
file = log_bin_l[0]
|
||||
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
@@ -6,7 +6,7 @@
|
||||
"type":"运行环境",
|
||||
"ps":"一种关系数据库管理系统[debian,ubuntu](极速安装)",
|
||||
"todo_versions":["5.7","8.0"],
|
||||
"versions":["5.7","8.0"],
|
||||
"versions":["5.7","8.0","8.2"],
|
||||
"shell":"install.sh",
|
||||
"install_pre_inspection":true,
|
||||
"checks":"server/mysql-apt",
|
||||
|
||||
@@ -59,6 +59,62 @@ function myAsyncPost(method,args){
|
||||
return syncPost('/plugins/run', {name:'mysql-apt', func:method, args:_args});
|
||||
}
|
||||
|
||||
function myPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'mysql';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_mysql_apt';
|
||||
args['version'] = version;
|
||||
|
||||
|
||||
if (typeof(args) == 'string' && args == ''){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function myPostCallbakN(method, version, args,callback){
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'mysql';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_mysql_apt';
|
||||
args['version'] = version;
|
||||
|
||||
|
||||
if (typeof(args) == 'string' && args == ''){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function vaildPhpmyadmin(url,username,password){
|
||||
// console.log("Authorization: Basic " + btoa(username + ":" + password));
|
||||
$.ajax({
|
||||
@@ -439,7 +495,6 @@ function setRootPwd(type, pwd){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
@@ -451,7 +506,7 @@ function setRootPwd(type, pwd){
|
||||
title: '修改数据库密码',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
btn:["提交","关闭"],
|
||||
btn:["提交", "关闭", "复制ROOT密码", "强制修改"],
|
||||
shadeClose: true,
|
||||
content: "<form class='bt-form pd20' id='mod_pwd'>\
|
||||
<div class='line'>\
|
||||
@@ -461,8 +516,36 @@ function setRootPwd(type, pwd){
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
yes:function(){
|
||||
setRootPwd(1);
|
||||
yes:function(layerIndex){
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
},
|
||||
btn3:function(){
|
||||
var password = $("#MyPassword").val();
|
||||
copyText(password);
|
||||
return false;
|
||||
},
|
||||
btn4:function(layerIndex){
|
||||
layer.confirm('强制修改,是为了在重建时使用,确定强制?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function(index, layero){
|
||||
layer.close(index);
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password,force:'1'}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1162,6 +1245,146 @@ function dbList(page, search){
|
||||
});
|
||||
}
|
||||
|
||||
function myBinRollingLogs(_name, func, _args, line){
|
||||
|
||||
var file_line = 100;
|
||||
if ( typeof(line) != 'undefined' ){
|
||||
file_line = line;
|
||||
}
|
||||
|
||||
var reqTimer = null;
|
||||
|
||||
function requestLogs(func,file,line){
|
||||
myPostCallbakN(func,'',{'file':file,"line":line}, function(rdata){
|
||||
var data = rdata.data.data;
|
||||
var cmd = rdata.data.cmd;
|
||||
if(data == '') {
|
||||
data = '当前没有日志!';
|
||||
}
|
||||
|
||||
$('#my_rolling_cmd').html(cmd);
|
||||
|
||||
$('#my_rolling_copy').click(function(){
|
||||
copyText(cmd);
|
||||
});
|
||||
|
||||
var ebody = '<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 570px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log">'+data+'</textarea>';
|
||||
$("#my_rolling_logs").html(ebody);
|
||||
var ob = document.getElementById('roll_info_log');
|
||||
ob.scrollTop = ob.scrollHeight;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: _name + '日志',
|
||||
area: ['800px','700px'],
|
||||
end: function(){
|
||||
if (reqTimer){
|
||||
clearInterval(reqTimer);
|
||||
}
|
||||
},
|
||||
content:'<div class="change-default" style="padding:0px 20px 0px;">\
|
||||
<div class="divtable mtb10">\
|
||||
<table class="table table-hover"><tr>\
|
||||
<td id="my_rolling_cmd">cmd</td>\
|
||||
<td id="my_rolling_copy" style="width:35px;"><span class="ico-copy cursor btcopy" title="复制密码"></span></td>\
|
||||
<tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="change-default" style="padding:0px 20px 0px;" id="my_rolling_logs">\
|
||||
<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 570px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log"></textarea>\
|
||||
</div>',
|
||||
success:function(){
|
||||
var fileName = _args['file'];
|
||||
requestLogs(func,fileName,file_line);
|
||||
reqTimer = setInterval(function(){
|
||||
requestLogs(func,fileName,file_line);
|
||||
},1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogsRender(page){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
_data['tojs'] = 'myBinLogsRender';
|
||||
myPost('binlog_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
var list = '';
|
||||
for(i in rdata.data){
|
||||
list += '<tr>';
|
||||
|
||||
list += '<td>' + rdata.data[i]['name'] +'</td>';
|
||||
list += '<td>' + toSize(rdata.data[i]['size'])+'</td>';
|
||||
list += '<td>' + rdata.data[i]['time'] +'</td>';
|
||||
|
||||
|
||||
list += '<td style="text-align:right">';
|
||||
list += '<a href="javascript:;" data-index="'+i+'" class="btlink look" class="btlink">查看</a> | ';
|
||||
list += '<a href="javascript:;" data-index="'+i+'" class="btlink look_decode" class="btlink">解码查看</a>';
|
||||
list += '</td></tr>';
|
||||
}
|
||||
|
||||
if (rdata.data.length ==0){
|
||||
list = '<tr><td colspan="4">无数据</td</tr>';
|
||||
}
|
||||
|
||||
$("#binlog_list tbody").html(list);
|
||||
$('#binlog_page').html(rdata.page);
|
||||
|
||||
|
||||
$('#binlog_list .look').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = rdata.data[i]['name'];
|
||||
myBinRollingLogs('查看BINLOG','binLogListLook',{'file':file },100);
|
||||
});
|
||||
|
||||
$('#binlog_list .look_decode').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = rdata.data[i]['name'];
|
||||
myBinRollingLogs('查看解码BINLOG','binLogListLookDecode',{'file':file },100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogs(){
|
||||
var con = '<div class="safe bgw">\
|
||||
<button class="btn btn-success btn-sm relay_trace" type="button" style="margin-right: 5px;">中继日志跟踪</button>\
|
||||
<button class="btn btn-default btn-sm binlog_trace" type="button" style="margin-right: 5px;">最新BINLOG日志跟踪</button>\
|
||||
<div id="binlog_list" class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
<thead><tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>大小</th>\
|
||||
<th>时间</th>\
|
||||
<th style="text-align:right;">操作</th>\
|
||||
</tr></thead>\
|
||||
<tbody></tbody></table>\
|
||||
</div>\
|
||||
<div id="binlog_page" class="dataTables_paginate paging_bootstrap page"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
$(".soft-man-con").html(con);
|
||||
myBinLogsRender(1);
|
||||
|
||||
$('.soft-man-con .relay_trace').click(function(){
|
||||
myBinRollingLogs('中继日志跟踪','binLogListTraceRelay',{'file':''},100);
|
||||
});
|
||||
|
||||
$('.soft-man-con .binlog_trace').click(function(){
|
||||
myBinRollingLogs('最新BINLOG日志跟踪','binLogListTraceBinLog',{'file':''},100);
|
||||
});
|
||||
}
|
||||
|
||||
function myLogs(){
|
||||
|
||||
@@ -2345,11 +2568,15 @@ function masterOrSlaveConf(version=''){
|
||||
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
|
||||
</tr>";
|
||||
|
||||
var btn_list = ['复制错误',"取消"];
|
||||
if (info['Last_IO_Error'].search(/1236/i)>0){
|
||||
btn_list = ['复制错误',"取消","尝试修复"];
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '同步异常信息',
|
||||
area: ['600px','300px'],
|
||||
btn:['复制错误',"取消"],
|
||||
btn:btn_list,
|
||||
content:"<form class='bt-form pd15'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div class='tablescroll'>\
|
||||
@@ -2364,10 +2591,20 @@ function masterOrSlaveConf(version=''){
|
||||
</div>\
|
||||
</form>",
|
||||
success:function(){
|
||||
// copyText(v['Error']);
|
||||
// $('.class-copy-db-err').click(function(){
|
||||
// copyText(v['Error']);
|
||||
// });
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
copyText(info['Last_IO_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Last_SQL_Error'] != ''){
|
||||
copyText(info['Last_SQL_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Slave_SQL_Running_State'] != ''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
yes:function(){
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
@@ -2384,6 +2621,14 @@ function masterOrSlaveConf(version=''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
btn3:function(){
|
||||
myPost('try_slave_sync_bugfix', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg, function(){
|
||||
masterOrSlaveConf();
|
||||
},{ icon: rdata.status ? 1 : 5 },2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Executable
+140
@@ -0,0 +1,140 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# https://downloads.mysql.com/archives/community/
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
myDir=${serverPath}/source/mysql-apt
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/mysql-apt && bash install.sh install 8.0
|
||||
|
||||
# 暂时debian12没有标准版,先用11使用
|
||||
if [ "$OSNAME" == 'debian' ] && [ "$VERSION_ID" == '12' ] ;then
|
||||
echo "暂时不支持该${OSNAME}${VERSION_ID}" > $install_tmp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
ARCH="amd64"
|
||||
TMP_ARCH=`arch`
|
||||
if [ "$TMP_ARCH" == "x86_64" ];then
|
||||
ARCH="amd64"
|
||||
elif [ "$TMP_ARCH" == "aarch64" ];then
|
||||
ARCH="arm64"
|
||||
else
|
||||
ARCH="amd64"
|
||||
fi
|
||||
|
||||
if [ "$ARCH" != "amd64" ];then
|
||||
echo "暂时不支持该${ARCH}" > $install_tmp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
MYSQL_VER=8.2.0
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_${ARCH}
|
||||
|
||||
|
||||
# /lib/systemd/system/mysql.service
|
||||
# /etc/mysql/my.cnf
|
||||
|
||||
APT_INSTALL()
|
||||
{
|
||||
########
|
||||
mkdir -p $myDir
|
||||
mkdir -p $serverPath/mysql-apt/bin
|
||||
|
||||
wget --no-check-certificate -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-8.2/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
chmod +x ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
cd ${myDir} && tar vxf ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
|
||||
apt update -y
|
||||
apt install -y libnuma1 libaio1 libmecab2
|
||||
|
||||
# 安装
|
||||
dpkg -X mysql-common_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
|
||||
|
||||
dpkg -X mysql-community-client-plugins_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-community-client-core_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-community-client_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-client_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
dpkg -X mysql-community-server-core_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
dpkg -X mysql-community-server_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-server_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
# 测试时可关闭
|
||||
rm -rf $myDir
|
||||
#######
|
||||
}
|
||||
|
||||
APT_UNINSTALL()
|
||||
{
|
||||
###
|
||||
rm -rf $myDir
|
||||
# apt remove -y mysql-server
|
||||
###
|
||||
}
|
||||
|
||||
|
||||
Install_mysql()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u mysql`"
|
||||
echo "mysql shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_INSTALL
|
||||
fi
|
||||
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/mysql-apt
|
||||
echo '8.0' > $serverPath/mysql-apt/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo '8.0' > $serverPath/mysql-apt/version.pl
|
||||
echo "暂时不支持该系统" > $install_tmp
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_UNINSTALL
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/mysql-apt
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_mysql
|
||||
else
|
||||
Uninstall_mysql
|
||||
fi
|
||||
@@ -12,6 +12,7 @@
|
||||
<p onclick="myPerfOpt();">性能优化</p>
|
||||
<p onclick="myLogs();">日志</p>
|
||||
<p onclick="pluginLogs('mysql-yum',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
|
||||
<p onclick="myBinLogs();">BINLOG</p>
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
|
||||
</div>
|
||||
|
||||
+247
-16
@@ -89,6 +89,12 @@ def getDataDir():
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getLogBinName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-bin\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getPidFile():
|
||||
file = getConf()
|
||||
@@ -129,6 +135,15 @@ def getErrorLogsFile():
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getAuthPolicy():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'authentication_policy\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if tmp:
|
||||
return tmp.groups()[0].strip()
|
||||
# caching_sha2_password
|
||||
return 'mysql_native_password'
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = mw.getServerDir()
|
||||
@@ -276,6 +291,52 @@ def binLog():
|
||||
mw.writeFile(conf, con)
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def binLogList():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['page', 'page_size', 'tojs'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
page = int(args['page'])
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
data_dir = getDataDir()
|
||||
log_bin_name = getLogBinName()
|
||||
|
||||
alist = os.listdir(data_dir)
|
||||
log_bin_l = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(log_bin_name) and not f.endswith('.index'):
|
||||
abspath = data_dir + '/' + f
|
||||
t['name'] = f
|
||||
t['size'] = os.path.getsize(abspath)
|
||||
t['time'] = mw.getDataFromInt(os.path.getctime(abspath))
|
||||
log_bin_l.append(t)
|
||||
|
||||
log_bin_l = sorted(log_bin_l, key=lambda x: x['time'], reverse=True)
|
||||
|
||||
# print(log_bin_l)
|
||||
# print(data_dir, log_bin_name)
|
||||
|
||||
count = len(log_bin_l)
|
||||
|
||||
page_start = (page - 1) * page_size
|
||||
page_end = page_start + page_size
|
||||
if page_end > count:
|
||||
page_end = count
|
||||
|
||||
data = {}
|
||||
page_args = {}
|
||||
page_args['count'] = count
|
||||
page_args['p'] = page
|
||||
page_args['row'] = page_size
|
||||
page_args['tojs'] = args['tojs']
|
||||
data['page'] = mw.getPage(page_args)
|
||||
data['data'] = log_bin_l[page_start:page_end]
|
||||
|
||||
return mw.getJson(data)
|
||||
|
||||
def cleanBinLog():
|
||||
db = pMysqlDb()
|
||||
@@ -360,8 +421,28 @@ def initMysql8Data():
|
||||
return False
|
||||
return True
|
||||
|
||||
def getLib64Pos(name=''):
|
||||
cmd = "ls /usr/lib64 | grep "+name+".so | cut -d \ -f 1 | awk 'END {print}'"
|
||||
d = mw.execShell(cmd)
|
||||
return '/usr/lib64/'+d[0]
|
||||
|
||||
def makeLib64SoftLink(name=''):
|
||||
pos = getLib64Pos(name)
|
||||
dst_file = '/usr/lib64/'+name+'.so.5'
|
||||
if os.path.exists(dst_file):
|
||||
return True
|
||||
|
||||
if os.path.exists(pos):
|
||||
cmd = 'ln -s '+pos+' '+dst_file
|
||||
mw.execShell(cmd)
|
||||
return True
|
||||
|
||||
def yumLibFix():
|
||||
makeLib64SoftLink('libncurses')
|
||||
makeLib64SoftLink('libtinfo')
|
||||
|
||||
def initMysql8Pwd():
|
||||
yumLibFix()
|
||||
'''
|
||||
/usr/bin/mysql --defaults-file=/www/server/mysql-apt/etc/my.cnf -uroot -e"UPDATE mysql.user SET password=PASSWORD('BhIroUczczNVaKvw') WHERE user='root';flush privileges;"
|
||||
/usr/bin/mysql --defaults-file=/www/server/mysql-apt/etc/my.cnf -uroot -e"alter user 'root'@'localhost' identified by '123456';"
|
||||
@@ -371,6 +452,7 @@ def initMysql8Pwd():
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
pwd = mw.getRandomString(16)
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
cmd_my = serverdir + '/bin/usr/bin/mysql'
|
||||
|
||||
@@ -378,16 +460,18 @@ def initMysql8Pwd():
|
||||
cmd_pass = cmd_pass + \
|
||||
'"alter user \'root\'@\'localhost\' identified by \'' + pwd + '\';'
|
||||
cmd_pass = cmd_pass + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '" + pwd + "';"
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH "+auth_policy+" by '" + pwd + "';"
|
||||
cmd_pass = cmd_pass + 'flush privileges;"'
|
||||
# print(cmd_pass)
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
if data[1] != '':
|
||||
print(data[1])
|
||||
exit(-1)
|
||||
|
||||
# 删除空账户
|
||||
drop_empty_user = cmd_my + ' --defaults-file=' + myconf + ' -uroot -p' + \
|
||||
pwd + ' -e "use mysql;delete from user where USER=\'\'"'
|
||||
mw.execShell(drop_empty_user)
|
||||
# drop_empty_user = cmd_my + ' --defaults-file=' + myconf + ' -uroot -p' + \
|
||||
# pwd + ' -e "use mysql;delete from user where USER=\'\'"'
|
||||
# mw.execShell(drop_empty_user)
|
||||
|
||||
# 删除测试数据库
|
||||
drop_test_db = cmd_my + ' --defaults-file=' + myconf + ' -uroot -p' + \
|
||||
@@ -397,15 +481,15 @@ def initMysql8Pwd():
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
|
||||
# 删除冗余账户
|
||||
hostname = mw.execShell('hostname')[0].strip()
|
||||
if hostname != 'localhost':
|
||||
drop_hostname = cmd_my + ' --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
# hostname = mw.execShell('hostname')[0].strip()
|
||||
# if hostname != 'localhost':
|
||||
# drop_hostname = cmd_my + ' --defaults-file=' + \
|
||||
# myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
# mw.execShell(drop_hostname)
|
||||
|
||||
drop_root_hostname = cmd_my + ' --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
# drop_root_hostname = cmd_my + ' --defaults-file=' + \
|
||||
# myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
# mw.execShell(drop_root_hostname)
|
||||
return True
|
||||
|
||||
|
||||
@@ -1041,12 +1125,20 @@ def setRootPwd(version=''):
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
#强制修改
|
||||
force = 0
|
||||
if 'force' in args and args['force'] == '1':
|
||||
force = 1
|
||||
|
||||
password = args['password']
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
result = pdb.query("show databases")
|
||||
isError = isSqlError(result)
|
||||
if isError != None:
|
||||
if force == 1:
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '【强制修改】数据库root密码修改成功(不意为成功连接数据)!')
|
||||
return isError
|
||||
|
||||
if version.find('5.7') > -1 or version.find('8.0') > -1:
|
||||
@@ -1061,7 +1153,11 @@ def setRootPwd(version=''):
|
||||
"update mysql.user set Password=password('" + password + "') where User='root'")
|
||||
pdb.execute("flush privileges")
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '数据库root密码修改成功!')
|
||||
|
||||
msg = ''
|
||||
if force == 1:
|
||||
msg = ',无须强制!'
|
||||
return mw.returnJson(True, '数据库root密码修改成功!'+msg)
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '修改错误:' + str(ex))
|
||||
|
||||
@@ -1270,8 +1366,57 @@ def setDbAccess():
|
||||
psdb.where('username=?', (name,)).save('accept,rw', (access, 'rw',))
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def openSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('#skip-grant-tables','skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
def fixDbAccess(version):
|
||||
def closeSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('skip-grant-tables','#skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
|
||||
def resetDbRootPwd(version):
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
pwd = mw.getRandomString(16)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
|
||||
if float(version) < 5.7:
|
||||
cmd_pass = serverdir + '/bin/usr/bin/mysql --defaults-file=' + myconf + ' -uroot -e'
|
||||
cmd_pass = cmd_pass + '"UPDATE mysql.user SET password=PASSWORD(\'' + pwd + "') WHERE user='root';"
|
||||
cmd_pass = cmd_pass + 'flush privileges;"'
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
else:
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
reset_pwd = 'flush privileges;'
|
||||
reset_pwd = reset_pwd + \
|
||||
"UPDATE mysql.user SET authentication_string='' WHERE user='root';"
|
||||
reset_pwd = reset_pwd + "flush privileges;"
|
||||
reset_pwd = reset_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED by '" + pwd + "';"
|
||||
reset_pwd = reset_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH "+auth_policy+" by '" + pwd + "';"
|
||||
reset_pwd = reset_pwd + "flush privileges;"
|
||||
|
||||
tmp_file = "/tmp/mysql_init_tmp.log"
|
||||
mw.writeFile(tmp_file, reset_pwd)
|
||||
cmd_pass = serverdir + '/bin/usr/bin/mysql --defaults-file=' + myconf + ' -uroot -proot < ' + tmp_file
|
||||
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
os.remove(tmp_file)
|
||||
return True
|
||||
|
||||
def fixDbAccess2(version):
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
data = pdb.query('show databases')
|
||||
@@ -1285,6 +1430,34 @@ def fixDbAccess(version):
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '修复失败请重试!')
|
||||
|
||||
def fixDbAccess(version):
|
||||
|
||||
pdb = pMysqlDb()
|
||||
mdb_ddir = getDataDir()
|
||||
if not os.path.exists(mdb_ddir):
|
||||
return mw.returnJson(False, '数据目录不存在,尝试重启重建!')
|
||||
|
||||
try:
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
|
||||
# 重置密码
|
||||
appCMD(version, 'stop')
|
||||
openSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
time.sleep(3)
|
||||
resetDbRootPwd(version)
|
||||
|
||||
appCMD(version, 'stop')
|
||||
closeSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '修复失败请重试!')
|
||||
|
||||
|
||||
def setDbRw(version=''):
|
||||
args = getArgs()
|
||||
@@ -1832,12 +2005,14 @@ def addMasterRepSlaveUser(version=''):
|
||||
pdb = pMysqlDb()
|
||||
psdb = pSqliteDb('master_replication_user')
|
||||
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
if psdb.where("username=?", (username)).count() > 0:
|
||||
return mw.returnJson(False, '用户已存在!')
|
||||
|
||||
if version == "8.0":
|
||||
sql = "CREATE USER '" + username + \
|
||||
"' IDENTIFIED WITH mysql_native_password BY '" + password + "';"
|
||||
"' IDENTIFIED WITH "+auth_policy+" BY '" + password + "';"
|
||||
pdb.execute(sql)
|
||||
sql = "grant replication slave on *.* to '" + username + "'@'%';"
|
||||
result = pdb.execute(sql)
|
||||
@@ -2197,6 +2372,56 @@ def getSlaveList(version=''):
|
||||
data['data'] = dlist
|
||||
return mw.getJson(data)
|
||||
|
||||
def trySlaveSyncBugfix(version=''):
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动', [])
|
||||
|
||||
mode_file = getSyncModeFile()
|
||||
if not os.path.exists(mode_file):
|
||||
return mw.returnJson(False, '需要先设置同步配置')
|
||||
|
||||
mode = mw.readFile(mode_file)
|
||||
if mode != 'sync-user':
|
||||
return mw.returnJson(False, '仅支持【同步账户】模式')
|
||||
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
slave_sync_data = conn.field('ip,port,user,pass,mode,cmd').select()
|
||||
if len(slave_sync_data) < 1:
|
||||
return mw.returnJson(False, '需要先添加【同步用户】配置!')
|
||||
|
||||
# print(slave_sync_data)
|
||||
# 本地从库
|
||||
sdb = pMysqlDb()
|
||||
|
||||
gtid_purged = ''
|
||||
|
||||
for i in range(len(slave_sync_data)):
|
||||
port = slave_sync_data[i]['port']
|
||||
password = slave_sync_data[i]['pass']
|
||||
host = slave_sync_data[i]['ip']
|
||||
user = slave_sync_data[i]['user']
|
||||
|
||||
# print(port, password, host)
|
||||
|
||||
mdb = mw.getMyORM()
|
||||
mdb.setHost(host)
|
||||
mdb.setPort(port)
|
||||
mdb.setUser(user)
|
||||
mdb.setPwd(password)
|
||||
mdb.setSocket('')
|
||||
|
||||
var_gtid = mdb.query('show VARIABLES like "%gtid_purged%"')
|
||||
if len(var_gtid) > 0:
|
||||
gtid_purged += var_gtid[0]['Value'] + ','
|
||||
|
||||
gtid_purged = gtid_purged.strip(',')
|
||||
sql = "set @@global.gtid_purged='" + gtid_purged + "'"
|
||||
|
||||
sdb.query('stop slave')
|
||||
# print(sql)
|
||||
sdb.query(sql)
|
||||
sdb.query('start slave')
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
|
||||
def getSlaveSyncCmd(version=''):
|
||||
|
||||
@@ -2775,6 +3000,8 @@ if __name__ == "__main__":
|
||||
print(getConf())
|
||||
elif func == 'bin_log':
|
||||
print(binLog())
|
||||
elif func == 'binlog_list':
|
||||
print(binLogList())
|
||||
elif func == 'clean_bin_log':
|
||||
print(cleanBinLog())
|
||||
elif func == 'error_log':
|
||||
@@ -2825,6 +3052,8 @@ if __name__ == "__main__":
|
||||
print(setDbAccess())
|
||||
elif func == 'fix_db_access':
|
||||
print(fixDbAccess(version))
|
||||
elif func == 'fix_db_access2':
|
||||
print(fixDbAccess2(version))
|
||||
elif func == 'set_db_rw':
|
||||
print(setDbRw(version))
|
||||
elif func == 'set_db_ps':
|
||||
@@ -2869,6 +3098,8 @@ if __name__ == "__main__":
|
||||
print(getMasterRepSlaveUserCmd(version))
|
||||
elif func == 'get_slave_list':
|
||||
print(getSlaveList(version))
|
||||
elif func == 'try_slave_sync_bugfix':
|
||||
print(trySlaveSyncBugfix(version))
|
||||
elif func == 'get_slave_sync_cmd':
|
||||
print(getSlaveSyncCmd(version))
|
||||
elif func == 'get_slave_ssh_list':
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
import re
|
||||
import json
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
if mw.isAppleSystem():
|
||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
info = mw.execShell(cmd)
|
||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
sys.path.append(p)
|
||||
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'mysql-yum'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getSPluginDir():
|
||||
return '/www/server/mdserver-web/plugins/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = getServerDir() + '/etc/my.cnf'
|
||||
return path
|
||||
|
||||
|
||||
def getDataDir():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'datadir\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getRelayLogName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'relay-log\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getLogBinName():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-bin\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def binLogListLook(args):
|
||||
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata = {}
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListLookDecode(args):
|
||||
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata = {}
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListTraceRelay(args):
|
||||
rdata = {}
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
relay_name = getRelayLogName()
|
||||
data_dir = getDataDir()
|
||||
alist = os.listdir(data_dir)
|
||||
relay_list = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(relay_name) and not f.endswith('.index'):
|
||||
relay_list.append(f)
|
||||
|
||||
relay_list = sorted(relay_list, reverse=True)
|
||||
if len(relay_list) == 0:
|
||||
rdata['cmd'] = ''
|
||||
rdata['data'] = '无Relay日志'
|
||||
return rdata
|
||||
|
||||
file = relay_list[0]
|
||||
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
|
||||
|
||||
def binLogListTraceBinLog(args):
|
||||
rdata = {}
|
||||
file = args['file']
|
||||
line = args['line']
|
||||
|
||||
data_dir = getDataDir()
|
||||
log_bin_name = getLogBinName()
|
||||
|
||||
alist = os.listdir(data_dir)
|
||||
log_bin_l = []
|
||||
for x in range(len(alist)):
|
||||
f = alist[x]
|
||||
t = {}
|
||||
if f.startswith(log_bin_name) and not f.endswith('.index'):
|
||||
log_bin_l.append(f)
|
||||
|
||||
if len(log_bin_l) == 0:
|
||||
rdata['cmd'] = ''
|
||||
rdata['data'] = '无BINLOG'
|
||||
return rdata
|
||||
|
||||
log_bin_l = sorted(log_bin_l, reverse=True)
|
||||
file = log_bin_l[0]
|
||||
|
||||
my_bin = getServerDir() + '/bin/usr/bin'
|
||||
my_binlog_cmd = my_bin + '/mysqlbinlog'
|
||||
|
||||
cmd = my_binlog_cmd + ' --no-defaults --base64-output=decode-rows -vvvv ' + \
|
||||
data_dir + '/' + file + '|tail -' + str(line)
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
|
||||
rdata['cmd'] = cmd
|
||||
rdata['data'] = data[0]
|
||||
|
||||
return rdata
|
||||
@@ -59,6 +59,63 @@ function myAsyncPost(method,args){
|
||||
return syncPost('/plugins/run', {name:'mysql-yum', func:method, args:_args});
|
||||
}
|
||||
|
||||
function myPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'mysql-yum';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_mysql_yum';
|
||||
args['version'] = version;
|
||||
|
||||
|
||||
if (typeof(args) == 'string' && args == ''){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function myPostCallbakN(method, version, args,callback){
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'mysql-yum';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_mysql_yum';
|
||||
args['version'] = version;
|
||||
|
||||
|
||||
if (typeof(args) == 'string' && args == ''){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function vaildPhpmyadmin(url,username,password){
|
||||
// console.log("Authorization: Basic " + btoa(username + ":" + password));
|
||||
$.ajax({
|
||||
@@ -439,7 +496,6 @@ function setRootPwd(type, pwd){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
@@ -451,7 +507,7 @@ function setRootPwd(type, pwd){
|
||||
title: '修改数据库密码',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
btn:["提交","关闭"],
|
||||
btn:["提交", "关闭", "复制ROOT密码", "强制修改"],
|
||||
shadeClose: true,
|
||||
content: "<form class='bt-form pd20' id='mod_pwd'>\
|
||||
<div class='line'>\
|
||||
@@ -461,8 +517,36 @@ function setRootPwd(type, pwd){
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
yes:function(){
|
||||
setRootPwd(1);
|
||||
yes:function(layerIndex){
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
},
|
||||
btn3:function(){
|
||||
var password = $("#MyPassword").val();
|
||||
copyText(password);
|
||||
return false;
|
||||
},
|
||||
btn4:function(layerIndex){
|
||||
layer.confirm('强制修改,是为了在重建时使用,确定强制?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function(index, layero){
|
||||
layer.close(index);
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password,force:'1'}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1162,6 +1246,146 @@ function dbList(page, search){
|
||||
});
|
||||
}
|
||||
|
||||
function myBinRollingLogs(_name, func, _args, line){
|
||||
|
||||
var file_line = 100;
|
||||
if ( typeof(line) != 'undefined' ){
|
||||
file_line = line;
|
||||
}
|
||||
|
||||
var reqTimer = null;
|
||||
|
||||
function requestLogs(func,file,line){
|
||||
myPostCallbakN(func,'',{'file':file,"line":line}, function(rdata){
|
||||
var data = rdata.data.data;
|
||||
var cmd = rdata.data.cmd;
|
||||
if(data == '') {
|
||||
data = '当前没有日志!';
|
||||
}
|
||||
|
||||
$('#my_rolling_cmd').html(cmd);
|
||||
|
||||
$('#my_rolling_copy').click(function(){
|
||||
copyText(cmd);
|
||||
});
|
||||
|
||||
var ebody = '<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 570px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log">'+data+'</textarea>';
|
||||
$("#my_rolling_logs").html(ebody);
|
||||
var ob = document.getElementById('roll_info_log');
|
||||
ob.scrollTop = ob.scrollHeight;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: _name + '日志',
|
||||
area: ['800px','700px'],
|
||||
end: function(){
|
||||
if (reqTimer){
|
||||
clearInterval(reqTimer);
|
||||
}
|
||||
},
|
||||
content:'<div class="change-default" style="padding:0px 20px 0px;">\
|
||||
<div class="divtable mtb10">\
|
||||
<table class="table table-hover"><tr>\
|
||||
<td id="my_rolling_cmd">cmd</td>\
|
||||
<td id="my_rolling_copy" style="width:35px;"><span class="ico-copy cursor btcopy" title="复制密码"></span></td>\
|
||||
<tr>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="change-default" style="padding:0px 20px 0px;" id="my_rolling_logs">\
|
||||
<textarea readonly="readonly" style="margin: 0px;width: 100%;height: 570px;background-color: #333;color:#fff; padding:0 5px" id="roll_info_log"></textarea>\
|
||||
</div>',
|
||||
success:function(){
|
||||
var fileName = _args['file'];
|
||||
requestLogs(func,fileName,file_line);
|
||||
reqTimer = setInterval(function(){
|
||||
requestLogs(func,fileName,file_line);
|
||||
},1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogsRender(page){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
_data['tojs'] = 'myBinLogsRender';
|
||||
myPost('binlog_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
var list = '';
|
||||
for(i in rdata.data){
|
||||
list += '<tr>';
|
||||
|
||||
list += '<td>' + rdata.data[i]['name'] +'</td>';
|
||||
list += '<td>' + toSize(rdata.data[i]['size'])+'</td>';
|
||||
list += '<td>' + rdata.data[i]['time'] +'</td>';
|
||||
|
||||
|
||||
list += '<td style="text-align:right">';
|
||||
list += '<a href="javascript:;" data-index="'+i+'" class="btlink look" class="btlink">查看</a> | ';
|
||||
list += '<a href="javascript:;" data-index="'+i+'" class="btlink look_decode" class="btlink">解码查看</a>';
|
||||
list += '</td></tr>';
|
||||
}
|
||||
|
||||
if (rdata.data.length ==0){
|
||||
list = '<tr><td colspan="4">无数据</td</tr>';
|
||||
}
|
||||
|
||||
$("#binlog_list tbody").html(list);
|
||||
$('#binlog_page').html(rdata.page);
|
||||
|
||||
|
||||
$('#binlog_list .look').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = rdata.data[i]['name'];
|
||||
myBinRollingLogs('查看BINLOG','binLogListLook',{'file':file },100);
|
||||
});
|
||||
|
||||
$('#binlog_list .look_decode').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = rdata.data[i]['name'];
|
||||
myBinRollingLogs('查看解码BINLOG','binLogListLookDecode',{'file':file },100);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogs(){
|
||||
var con = '<div class="safe bgw">\
|
||||
<button class="btn btn-success btn-sm relay_trace" type="button" style="margin-right: 5px;">中继日志跟踪</button>\
|
||||
<button class="btn btn-default btn-sm binlog_trace" type="button" style="margin-right: 5px;">最新BINLOG日志跟踪</button>\
|
||||
<div id="binlog_list" class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
<thead><tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>大小</th>\
|
||||
<th>时间</th>\
|
||||
<th style="text-align:right;">操作</th>\
|
||||
</tr></thead>\
|
||||
<tbody></tbody></table>\
|
||||
</div>\
|
||||
<div id="binlog_page" class="dataTables_paginate paging_bootstrap page"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
$(".soft-man-con").html(con);
|
||||
myBinLogsRender(1);
|
||||
|
||||
$('.soft-man-con .relay_trace').click(function(){
|
||||
myBinRollingLogs('中继日志跟踪','binLogListTraceRelay',{'file':''},100);
|
||||
});
|
||||
|
||||
$('.soft-man-con .binlog_trace').click(function(){
|
||||
myBinRollingLogs('最新BINLOG日志跟踪','binLogListTraceBinLog',{'file':''},100);
|
||||
});
|
||||
}
|
||||
|
||||
function myLogs(){
|
||||
|
||||
@@ -2345,11 +2569,15 @@ function masterOrSlaveConf(version=''){
|
||||
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
|
||||
</tr>";
|
||||
|
||||
var btn_list = ['复制错误',"取消"];
|
||||
if (info['Last_IO_Error'].search(/1236/i)>0){
|
||||
btn_list = ['复制错误',"取消","尝试修复"];
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '同步异常信息',
|
||||
area: ['600px','300px'],
|
||||
btn:['复制错误',"取消"],
|
||||
btn:btn_list,
|
||||
content:"<form class='bt-form pd15'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div class='tablescroll'>\
|
||||
@@ -2364,10 +2592,20 @@ function masterOrSlaveConf(version=''){
|
||||
</div>\
|
||||
</form>",
|
||||
success:function(){
|
||||
// copyText(v['Error']);
|
||||
// $('.class-copy-db-err').click(function(){
|
||||
// copyText(v['Error']);
|
||||
// });
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
copyText(info['Last_IO_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Last_SQL_Error'] != ''){
|
||||
copyText(info['Last_SQL_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Slave_SQL_Running_State'] != ''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
yes:function(){
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
@@ -2384,6 +2622,14 @@ function masterOrSlaveConf(version=''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
btn3:function(){
|
||||
myPost('try_slave_sync_bugfix', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg, function(){
|
||||
masterOrSlaveConf();
|
||||
},{ icon: rdata.status ? 1 : 5 },2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -100,7 +100,7 @@ Install_mysql()
|
||||
rm -rf $myDir
|
||||
|
||||
echo '8.0' > $serverPath/mysql-yum/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
@@ -110,7 +110,7 @@ Uninstall_mysql()
|
||||
YUM_UNINSTALL
|
||||
fi
|
||||
rm -rf $serverPath/mysql-yum
|
||||
echo '卸载完成' > $install_tmp
|
||||
echo '卸载完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
|
||||
@@ -0,0 +1,291 @@
|
||||
# coding: utf-8
|
||||
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pymysql.cursors
|
||||
|
||||
|
||||
class ORM:
|
||||
__DB_PASS = None
|
||||
__DB_USER = 'root'
|
||||
__DB_PORT = 3306
|
||||
__DB_NAME = ''
|
||||
__DB_HOST = 'localhost'
|
||||
__DB_CONN = None
|
||||
__DB_CUR = None
|
||||
__DB_ERR = None
|
||||
__DB_CNF = '/etc/my.cnf'
|
||||
__DB_SOCKET = '/www/server/mysql/mysql.sock'
|
||||
__DB_CHARSET = "utf8"
|
||||
|
||||
# orm
|
||||
__DB_TABLE = "" # 被操作的表名称
|
||||
__OPT_WHERE = "" # where条件
|
||||
__OPT_LIMIT = "" # limit条件
|
||||
__OPT_GROUP = "" # group条件
|
||||
__OPT_ORDER = "" # order条件
|
||||
__OPT_FIELD = "*" # field条件
|
||||
__OPT_PARAM = () # where值
|
||||
|
||||
def __Conn(self):
|
||||
'''连接数据库'''
|
||||
try:
|
||||
|
||||
if os.path.exists(self.__DB_SOCKET):
|
||||
try:
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
||||
database=self.__DB_NAME,
|
||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
||||
unix_socket=self.__DB_SOCKET, cursorclass=pymysql.cursors.DictCursor)
|
||||
except Exception as e:
|
||||
self.__DB_HOST = '127.0.0.1'
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
||||
database=self.__DB_NAME,
|
||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
||||
unix_socket=self.__DB_SOCKET, cursorclass=pymysql.cursors.DictCursor)
|
||||
else:
|
||||
try:
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
||||
database=self.__DB_NAME,
|
||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
||||
cursorclass=pymysql.cursors.DictCursor)
|
||||
except Exception as e:
|
||||
self.__DB_HOST = '127.0.0.1'
|
||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
||||
database=self.__DB_NAME,
|
||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
||||
cursorclass=pymysql.cursors.DictCursor)
|
||||
|
||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
||||
return True
|
||||
except Exception as e:
|
||||
self.__DB_ERR = e
|
||||
return False
|
||||
|
||||
def setDbConf(self, conf):
|
||||
self.__DB_CNF = conf
|
||||
|
||||
def setSocket(self, sock):
|
||||
self.__DB_SOCKET = sock
|
||||
|
||||
def setCharset(self, charset):
|
||||
self.__DB_CHARSET = charset
|
||||
|
||||
def setHost(self, host):
|
||||
self.__DB_HOST = host
|
||||
|
||||
def setPort(self, port):
|
||||
self.__DB_PORT = port
|
||||
|
||||
def setUser(self, user):
|
||||
self.__DB_USER = user
|
||||
|
||||
def setPwd(self, pwd):
|
||||
self.__DB_PASS = pwd
|
||||
|
||||
def getPwd(self):
|
||||
return self.__DB_PASS
|
||||
|
||||
def setDbName(self, name):
|
||||
self.__DB_NAME = name
|
||||
|
||||
def execute(self, sql, param=()):
|
||||
# 执行SQL语句返回受影响行
|
||||
if not self.__Conn():
|
||||
return self.__DB_ERR
|
||||
try:
|
||||
result = self.__DB_CUR.execute(sql,param)
|
||||
self.__DB_CONN.commit()
|
||||
self.__Close()
|
||||
return result
|
||||
except Exception as ex:
|
||||
return ex
|
||||
|
||||
def query(self, sql, param=()):
|
||||
# 执行SQL语句返回数据集
|
||||
if not self.__Conn():
|
||||
return self.__DB_ERR
|
||||
try:
|
||||
self.__DB_CUR.execute(sql,param)
|
||||
result = self.__DB_CUR.fetchall()
|
||||
# print(result)
|
||||
# 将元组转换成列表
|
||||
# data = map(list, result)
|
||||
self.__Close()
|
||||
return result
|
||||
except Exception as ex:
|
||||
return ex
|
||||
|
||||
def __Close(self):
|
||||
# 关闭连接
|
||||
self.__DB_CUR.close()
|
||||
self.__DB_CONN.close()
|
||||
|
||||
|
||||
def checkInput(self, data):
|
||||
if not data:
|
||||
return data
|
||||
if type(data) != str:
|
||||
return data
|
||||
checkList = [
|
||||
{'d': '<', 'r': '<'},
|
||||
{'d': '>', 'r': '>'},
|
||||
{'d': '\'', 'r': '‘'},
|
||||
{'d': '"', 'r': '“'},
|
||||
{'d': '&', 'r': '&'},
|
||||
{'d': '#', 'r': '#'},
|
||||
{'d': '<', 'r': '<'}
|
||||
]
|
||||
for v in checkList:
|
||||
data = data.replace(v['d'], v['r'])
|
||||
return data
|
||||
|
||||
|
||||
def table(self, table):
|
||||
# 设置表名
|
||||
self.__DB_TABLE = table
|
||||
return self
|
||||
|
||||
def where(self, where, param):
|
||||
# WHERE条件
|
||||
if where:
|
||||
self.__OPT_WHERE = " WHERE " + where
|
||||
self.__OPT_PARAM = param
|
||||
return self
|
||||
|
||||
def andWhere(self, where, param):
|
||||
# WHERE条件
|
||||
if where:
|
||||
self.__OPT_WHERE = self.__OPT_WHERE + " and " + where
|
||||
# print(param)
|
||||
# print(self.__OPT_PARAM)
|
||||
self.__OPT_PARAM = self.__OPT_PARAM + param
|
||||
return self
|
||||
|
||||
def order(self, order):
|
||||
# ORDER条件
|
||||
if len(order):
|
||||
self.__OPT_ORDER = " ORDER BY " + order
|
||||
else:
|
||||
self.__OPT_ORDER = ""
|
||||
return self
|
||||
|
||||
def group(self, group):
|
||||
if len(group):
|
||||
self.__OPT_GROUP = " GROUP BY " + group
|
||||
else:
|
||||
self.__OPT_GROUP = ""
|
||||
return self
|
||||
|
||||
def limit(self, limit):
|
||||
# LIMIT条件
|
||||
if len(limit):
|
||||
self.__OPT_LIMIT = " LIMIT " + limit
|
||||
else:
|
||||
self.__OPT_LIMIT = ""
|
||||
return self
|
||||
|
||||
def field(self, field):
|
||||
# FIELD条件
|
||||
if len(field):
|
||||
self.__OPT_FIELD = field
|
||||
return self
|
||||
|
||||
def find(self):
|
||||
# 取一行数据
|
||||
result = self.limit("1").select()
|
||||
# print(result)
|
||||
if len(result) == 1:
|
||||
return result[0]
|
||||
return result
|
||||
|
||||
def select(self):
|
||||
# 查询数据集
|
||||
|
||||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
||||
self.__OPT_WHERE + self.__OPT_GROUP + self.__OPT_ORDER + self.__OPT_LIMIT
|
||||
# print(sql)
|
||||
# print(self.__OPT_PARAM)
|
||||
result = self.query(sql, self.__OPT_PARAM)
|
||||
return result
|
||||
|
||||
def getField(self, keyName):
|
||||
# 取回指定字段
|
||||
result = self.field(keyName).select()
|
||||
# print(result[0][keyName])
|
||||
if len(result) == 1:
|
||||
return result[0][keyName]
|
||||
return result
|
||||
|
||||
def setField(self, keyName, keyValue):
|
||||
# 更新指定字段
|
||||
return self.save(keyName, (keyValue,))
|
||||
|
||||
# 构造数据
|
||||
def __format_pdata(self, pdata):
|
||||
keys = pdata.keys()
|
||||
keys_str = ','.join(keys)
|
||||
param = []
|
||||
for k in keys:
|
||||
param.append(pdata[k])
|
||||
return keys_str, tuple(param)
|
||||
|
||||
def delete(self, id=None):
|
||||
# 删除数据
|
||||
|
||||
if id:
|
||||
self.__OPT_WHERE = " WHERE id=%s"
|
||||
self.__OPT_PARAM = (id,)
|
||||
sql = "DELETE FROM " + self.__DB_TABLE + self.__OPT_WHERE
|
||||
# print(sql)
|
||||
result = self.execute(sql, self.__OPT_PARAM)
|
||||
return result
|
||||
|
||||
|
||||
def save(self, keys, param):
|
||||
# 更新数据
|
||||
|
||||
opt = ""
|
||||
for key in keys.split(','):
|
||||
opt += key + "=%s,"
|
||||
opt = opt[0:len(opt) - 1]
|
||||
sql = "UPDATE " + self.__DB_TABLE + " SET " + opt + self.__OPT_WHERE
|
||||
|
||||
# 处理拼接WHERE与UPDATE参数
|
||||
tmp = list(param)
|
||||
for arg in self.__OPT_PARAM:
|
||||
tmp.append(arg)
|
||||
self.__OPT_PARAM = tuple(tmp)
|
||||
|
||||
# print(sql,self.__OPT_PARAM)
|
||||
result = self.execute(sql, self.__OPT_PARAM)
|
||||
return result
|
||||
|
||||
# 更新数据
|
||||
def update(self, pdata):
|
||||
if not pdata:
|
||||
return False
|
||||
keys, param = self.__format_pdata(pdata)
|
||||
return self.save(keys, param)
|
||||
|
||||
def add(self, keys, param):
|
||||
# 插入数据
|
||||
values = ""
|
||||
for key in keys.split(','):
|
||||
values += "%s,"
|
||||
values = self.checkInput(values[0:len(values) - 1])
|
||||
sql = "INSERT INTO " + self.__DB_TABLE + \
|
||||
"(" + keys + ") " + "VALUES(" + values + ")"
|
||||
|
||||
# print(sql)
|
||||
result = self.execute(sql, param)
|
||||
return result
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
[mysqld]
|
||||
# SHOW GLOBAL VARIABLES LIKE '%gtid%'
|
||||
gtid_mode=ON
|
||||
enforce_gtid_consistency=ON
|
||||
enforce_gtid_consistency=ON
|
||||
binlog_checksum=NONE
|
||||
@@ -20,7 +20,7 @@ basedir = {$SERVER_APP_PATH}
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
server-id = {$SERVER_ID}
|
||||
sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||||
#sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
|
||||
@@ -48,7 +48,6 @@ skip_name_resolve=1
|
||||
#skip-grant-tables
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=10
|
||||
@@ -84,8 +83,6 @@ replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
master_info_repository = table
|
||||
relay_log_info_repository = table
|
||||
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
[client]
|
||||
user = root
|
||||
#password = your_password
|
||||
port = 3306
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
default-character-set = UTF8MB4
|
||||
|
||||
[mysqld]
|
||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
||||
|
||||
sha256_password_private_key_path={$SERVER_APP_PATH}/data/mysql.pem
|
||||
sha256_password_public_key_path={$SERVER_APP_PATH}/data/mysql.pub
|
||||
authentication_policy=mysql_native_password
|
||||
|
||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
||||
user = mysql
|
||||
port = 3306
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
basedir = {$SERVER_APP_PATH}
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
server-id = {$SERVER_ID}
|
||||
#sql-mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
net_buffer_length = 4K
|
||||
read_buffer_size = 128K
|
||||
read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=0
|
||||
tmp_table_size = 8M
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
max_allowed_packet = 128M
|
||||
|
||||
skip_name_resolve=1
|
||||
#skip-networking
|
||||
#skip-external-locking
|
||||
#loose-skip-innodb
|
||||
#skip-grant-tables
|
||||
|
||||
log-bin=mysql-bin
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=10
|
||||
#log_queries_not_using_indexes=1
|
||||
#log_slow_admin_statements=1
|
||||
#log_slow_replica_statements=1
|
||||
binlog_expire_logs_seconds=2592000
|
||||
|
||||
relay-log=mdserver
|
||||
relay-log-index=mdserver
|
||||
|
||||
#多主设置
|
||||
#auto_increment_offset=2
|
||||
#auto_increment_increment=2
|
||||
|
||||
#master
|
||||
#sync_binlog=1
|
||||
|
||||
#binlog-do-db
|
||||
binlog-ignore-db = test
|
||||
binlog-ignore-db = mysql
|
||||
binlog-ignore-db = information_schema
|
||||
binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log_replica_updates = 1
|
||||
# Prevent replication from starting automatically with MySQL
|
||||
#skip_replica_start = 1
|
||||
#replicate-do-db
|
||||
replica_skip_errors=1062,1396
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_buffer_pool_size = 16M
|
||||
#innodb_log_file_size = 5M
|
||||
innodb_redo_log_capacity=10485760
|
||||
innodb_log_buffer_size = 8M
|
||||
innodb_flush_log_at_trx_commit = 1
|
||||
innodb_lock_wait_timeout = 120
|
||||
innodb_max_dirty_pages_pct = 90
|
||||
innodb_read_io_threads = 1
|
||||
innodb_write_io_threads = 1
|
||||
innodb_file_per_table=1
|
||||
|
||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[myisamchk]
|
||||
key_buffer_size = 20M
|
||||
sort_buffer_size = 20M
|
||||
read_buffer = 2M
|
||||
write_buffer = 2M
|
||||
|
||||
[mysqlhotcopy]
|
||||
interactive-timeout
|
||||
+143
-46
@@ -116,6 +116,16 @@ def getErrorLogsFile():
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
def getAuthPolicy():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'authentication_policy\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
if tmp:
|
||||
return tmp.groups()[0].strip()
|
||||
# caching_sha2_password
|
||||
return 'mysql_native_password'
|
||||
|
||||
|
||||
def getInitdTpl(version=''):
|
||||
path = getPluginDir() + '/init.d/mysql' + version + '.tpl'
|
||||
@@ -182,7 +192,11 @@ def pMysqlDb():
|
||||
|
||||
|
||||
def makeInitRsaKey(version=''):
|
||||
datadir = getServerDir() + "/data"
|
||||
try:
|
||||
datadir = getDataDir()
|
||||
except Exception as e:
|
||||
datadir = getServerDir() + "/data"
|
||||
|
||||
mysql_pem = datadir + "/mysql.pem"
|
||||
if not os.path.exists(mysql_pem):
|
||||
rdata = mw.execShell(
|
||||
@@ -395,22 +409,6 @@ def cleanBinLog():
|
||||
db.execute("PURGE MASTER LOGS BEFORE '" + cleanTime + "';")
|
||||
return mw.returnJson(True, '清理BINLOG成功!')
|
||||
|
||||
|
||||
def setSkipGrantTables(v):
|
||||
'''
|
||||
设置是否密码验证
|
||||
'''
|
||||
conf = getConf()
|
||||
con = mw.readFile(conf)
|
||||
if v:
|
||||
if con.find('#skip-grant-tables') != -1:
|
||||
con = con.replace('#skip-grant-tables', 'skip-grant-tables')
|
||||
else:
|
||||
con = con.replace('skip-grant-tables', '#skip-grant-tables')
|
||||
mw.writeFile(conf, con)
|
||||
return True
|
||||
|
||||
|
||||
def getErrorLog():
|
||||
args = getArgs()
|
||||
filename = getErrorLogsFile()
|
||||
@@ -516,20 +514,22 @@ def initMysqlPwd():
|
||||
hostname = mw.execShell('hostname')[0].strip()
|
||||
if hostname != 'localhost':
|
||||
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
myconf + ' -uroot -p"' + pwd + '" -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
|
||||
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
myconf + ' -uroot -p"' + pwd + '" -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
return True
|
||||
|
||||
|
||||
def initMysql8Pwd():
|
||||
time.sleep(8)
|
||||
|
||||
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
|
||||
@@ -543,7 +543,7 @@ def initMysql8Pwd():
|
||||
alter_root_pwd = alter_root_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED by '" + pwd + "';"
|
||||
alter_root_pwd = alter_root_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '" + pwd + "';"
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH "+auth_policy+" by '" + pwd + "';"
|
||||
alter_root_pwd = alter_root_pwd + "flush privileges;"
|
||||
|
||||
cmd_pass = serverdir + '/bin/mysqladmin --defaults-file=' + \
|
||||
@@ -562,7 +562,7 @@ def initMysql8Pwd():
|
||||
|
||||
# 删除测试数据库
|
||||
drop_test_db = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop database test";'
|
||||
myconf + ' -uroot -p"' + pwd + '" -e "drop database test";'
|
||||
mw.execShell(drop_test_db)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
@@ -571,11 +571,11 @@ def initMysql8Pwd():
|
||||
hostname = mw.execShell('hostname')[0].strip()
|
||||
if hostname != 'localhost':
|
||||
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
myconf + ' -uroot -p"' + pwd + '" -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
|
||||
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
myconf + ' -uroot -p"' + pwd + '" -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
|
||||
return True
|
||||
@@ -620,6 +620,8 @@ def my8cmd(version, method):
|
||||
isInited = initMysql57Data()
|
||||
elif version == '8.0':
|
||||
isInited = initMysql8Data()
|
||||
elif version == '8.2':
|
||||
isInited = initMysql8Data()
|
||||
|
||||
if not isInited:
|
||||
|
||||
@@ -660,7 +662,7 @@ def my8cmd(version, method):
|
||||
|
||||
def appCMD(version, action):
|
||||
makeInitRsaKey(version)
|
||||
if version == '8.0' or version == '5.7':
|
||||
if float(version) >= 5.7:
|
||||
status = my8cmd(version, action)
|
||||
else:
|
||||
status = myOp(version, action)
|
||||
@@ -792,7 +794,7 @@ def getMyPort():
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def setMyPort():
|
||||
def setMyPort(version):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['port'])
|
||||
if not data[0]:
|
||||
@@ -804,7 +806,7 @@ def setMyPort():
|
||||
rep = "port\s*=\s*([0-9]+)\s*\n"
|
||||
content = re.sub(rep, 'port = ' + port + '\n', content)
|
||||
mw.writeFile(file, content)
|
||||
restart()
|
||||
restart(version)
|
||||
return mw.returnJson(True, '编辑成功!')
|
||||
|
||||
|
||||
@@ -1052,7 +1054,7 @@ def importDbExternal():
|
||||
|
||||
myPass(True, pwd)
|
||||
mysql_cmd = getServerDir() + '/bin/mysql --defaults-file=' + my_cnf + \
|
||||
' -uroot -p\"' + pwd + '\" -f ' + name + ' < ' + import_sql
|
||||
' -uroot -p"' + pwd + '" -f ' + name + ' < ' + import_sql
|
||||
|
||||
# print(mysql_cmd)
|
||||
rdata = mw.execShell(mysql_cmd)
|
||||
@@ -1090,8 +1092,8 @@ def importDbBackup():
|
||||
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
|
||||
' ' + name + ' < ' + file_path_sql
|
||||
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p"' + pwd + \
|
||||
'" ' + name + ' < ' + file_path_sql
|
||||
|
||||
# print(mysql_cmd)
|
||||
# os.system(mysql_cmd)
|
||||
@@ -1259,7 +1261,7 @@ def syncGetDatabases():
|
||||
host = user["Host"]
|
||||
break
|
||||
|
||||
ps = mw.getMsg('INPUT_PS')
|
||||
ps = vdb_name
|
||||
if vdb_name == 'test':
|
||||
ps = mw.getMsg('DATABASE_TEST')
|
||||
addTime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
@@ -1331,12 +1333,20 @@ def setRootPwd(version=''):
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
#强制修改
|
||||
force = 0
|
||||
if 'force' in args and args['force'] == '1':
|
||||
force = 1
|
||||
|
||||
password = args['password']
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
result = pdb.query("show databases")
|
||||
isError = isSqlError(result)
|
||||
if isError != None:
|
||||
if force == 1:
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '【强制修改】数据库root密码修改成功(不意为成功连接数据)!')
|
||||
return isError
|
||||
|
||||
if version.find('5.7') > -1 or version.find('8.0') > -1:
|
||||
@@ -1351,7 +1361,12 @@ def setRootPwd(version=''):
|
||||
"update mysql.user set Password=password('" + password + "') where User='root'")
|
||||
pdb.execute("flush privileges")
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
|
||||
return mw.returnJson(True, '数据库root密码修改成功!')
|
||||
|
||||
msg = ''
|
||||
if force == 1:
|
||||
msg = ',无须强制!'
|
||||
|
||||
return mw.returnJson(True, '数据库root密码修改成功!'+msg)
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '修改错误:' + str(ex))
|
||||
|
||||
@@ -1561,15 +1576,79 @@ def setDbAccess():
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def openSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('#skip-grant-tables','skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
def closeSkipGrantTables():
|
||||
mycnf = getConf()
|
||||
content = mw.readFile(mycnf)
|
||||
content = content.replace('skip-grant-tables','#skip-grant-tables')
|
||||
mw.writeFile(mycnf, content)
|
||||
return True
|
||||
|
||||
|
||||
def resetDbRootPwd(version):
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
pwd = mw.getRandomString(16)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
|
||||
if float(version) < 5.7:
|
||||
cmd_pass = serverdir + '/bin/mysql --defaults-file=' + myconf + ' -uroot -e'
|
||||
cmd_pass = cmd_pass + '"UPDATE mysql.user SET password=PASSWORD(\'' + pwd + "') WHERE user='root';"
|
||||
cmd_pass = cmd_pass + 'flush privileges;"'
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
else:
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
reset_pwd = 'flush privileges;'
|
||||
reset_pwd = reset_pwd + \
|
||||
"UPDATE mysql.user SET authentication_string='' WHERE user='root';"
|
||||
reset_pwd = reset_pwd + "flush privileges;"
|
||||
reset_pwd = reset_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED by '" + pwd + "';"
|
||||
reset_pwd = reset_pwd + \
|
||||
"alter user 'root'@'localhost' IDENTIFIED WITH "+auth_policy+" by '" + pwd + "';"
|
||||
reset_pwd = reset_pwd + "flush privileges;"
|
||||
|
||||
tmp_file = "/tmp/mysql_init_tmp.log"
|
||||
mw.writeFile(tmp_file, reset_pwd)
|
||||
cmd_pass = serverdir + '/bin/mysql --defaults-file=' + myconf + ' -uroot -proot < ' + tmp_file
|
||||
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(data)
|
||||
os.remove(tmp_file)
|
||||
return True
|
||||
|
||||
def fixDbAccess(version):
|
||||
|
||||
pdb = pMysqlDb()
|
||||
mdb_ddir = getDataDir()
|
||||
if not os.path.exists(mdb_ddir):
|
||||
return mw.returnJson(False, '数据目录不存在,尝试重启重建!')
|
||||
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
|
||||
# 重置密码
|
||||
appCMD(version, 'stop')
|
||||
mw.execShell("rm -rf " + getServerDir() + "/data")
|
||||
openSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
time.sleep(3)
|
||||
resetDbRootPwd(version)
|
||||
|
||||
appCMD(version, 'stop')
|
||||
closeSkipGrantTables()
|
||||
appCMD(version, 'start')
|
||||
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
except Exception as e:
|
||||
@@ -2123,12 +2202,14 @@ def addMasterRepSlaveUser(version=''):
|
||||
pdb = pMysqlDb()
|
||||
psdb = pSqliteDb('master_replication_user')
|
||||
|
||||
auth_policy = getAuthPolicy()
|
||||
|
||||
if psdb.where("username=?", (username)).count() > 0:
|
||||
return mw.returnJson(False, '用户已存在!')
|
||||
|
||||
if version == "8.0":
|
||||
sql = "CREATE USER '" + username + \
|
||||
"' IDENTIFIED WITH mysql_native_password BY '" + password + "';"
|
||||
"' IDENTIFIED WITH "+auth_policy+" BY '" + password + "';"
|
||||
pdb.execute(sql)
|
||||
sql = "grant replication slave on *.* to '" + username + "'@'%';"
|
||||
result = pdb.execute(sql)
|
||||
@@ -2517,6 +2598,10 @@ def trySlaveSyncBugfix(version=''):
|
||||
|
||||
gtid_purged = ''
|
||||
|
||||
var_slave_gtid = sdb.query('show VARIABLES like "%gtid_purged%"')
|
||||
if len(var_slave_gtid) > 0:
|
||||
gtid_purged += var_slave_gtid[0]['Value'] + ','
|
||||
|
||||
for i in range(len(slave_sync_data)):
|
||||
port = slave_sync_data[i]['port']
|
||||
password = slave_sync_data[i]['pass']
|
||||
@@ -2536,6 +2621,8 @@ def trySlaveSyncBugfix(version=''):
|
||||
if len(var_gtid) > 0:
|
||||
gtid_purged += var_gtid[0]['Value'] + ','
|
||||
|
||||
|
||||
|
||||
gtid_purged = gtid_purged.strip(',')
|
||||
sql = "set @@global.gtid_purged='" + gtid_purged + "'"
|
||||
|
||||
@@ -2865,6 +2952,8 @@ def doFullSyncUser(version=''):
|
||||
ip = data['ip']
|
||||
|
||||
bak_file = '/tmp/tmp.sql'
|
||||
if os.path.exists(bak_file):
|
||||
os.system("rm -rf " + bak_file)
|
||||
|
||||
writeDbSyncStatus({'code': 0, 'msg': '开始同步...', 'progress': 0})
|
||||
dmp_option = ''
|
||||
@@ -2872,22 +2961,32 @@ def doFullSyncUser(version=''):
|
||||
if mode == 'gtid':
|
||||
dmp_option = ' --set-gtid-purged=off '
|
||||
|
||||
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 20})
|
||||
time.sleep(1)
|
||||
writeDbSyncStatus({'code': 1, 'msg': '正在停止从库...', 'progress': 15})
|
||||
if version == '8.0':
|
||||
db.query("stop slave user='{}' password='{}';".format(user, apass))
|
||||
else:
|
||||
db.query("stop slave")
|
||||
|
||||
time.sleep(2)
|
||||
|
||||
writeDbSyncStatus({'code': 2, 'msg': '远程导出数据...', 'progress': 20})
|
||||
|
||||
if not os.path.exists(bak_file):
|
||||
dump_sql_data = getServerDir() + "/bin/mysqldump " + dmp_option + " --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
|
||||
port + " -u" + user + " -p\"" + apass + \
|
||||
"\" --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
||||
# print(dump_sql_data)
|
||||
port + " -u" + user + " -p'" + apass + \
|
||||
"' --ssl-mode=DISABLED " + sync_db + " > " + bak_file
|
||||
print(dump_sql_data)
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
||||
|
||||
writeDbSyncStatus({'code': 3, 'msg': '正在到本地导入数据中...', 'progress': 40})
|
||||
if os.path.exists(bak_file):
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
my_import_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
|
||||
' ' + sync_db_import + ' < ' + bak_file
|
||||
# print(my_import_cmd)
|
||||
my_import_cmd = getServerDir() + '/bin/mysql -S ' + sock + " -uroot -p'" + pwd + \
|
||||
"' " + sync_db_import + ' < ' + bak_file
|
||||
print(my_import_cmd)
|
||||
mw.execShell(my_import_cmd)
|
||||
|
||||
if version == '8.0':
|
||||
@@ -3133,8 +3232,6 @@ if __name__ == "__main__":
|
||||
print(binLog())
|
||||
elif func == 'binlog_list':
|
||||
print(binLogList())
|
||||
elif func == 'binlog_look':
|
||||
print(binLogListLook())
|
||||
elif func == 'clean_bin_log':
|
||||
print(cleanBinLog())
|
||||
elif func == 'error_log':
|
||||
@@ -3148,7 +3245,7 @@ if __name__ == "__main__":
|
||||
elif func == 'my_port':
|
||||
print(getMyPort())
|
||||
elif func == 'set_my_port':
|
||||
print(setMyPort())
|
||||
print(setMyPort(version))
|
||||
elif func == 'init_pwd':
|
||||
print(initMysqlPwd())
|
||||
elif func == 'root_pwd':
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
"uninstall_pre_inspection":true,
|
||||
"checks": "server/mysql/VERSION/bin/mysql",
|
||||
"path": "server/mysql/VERSION",
|
||||
"todo_versions":["5.6","5.7","8.0"],
|
||||
"versions":["5.5", "5.6", "5.7","8.0"],
|
||||
"updates":["5.5.62","5.6.50", "5.7.32","8.0.34"],
|
||||
"todo_versions":["5.6","5.7","8.0","8.2"],
|
||||
"versions":["5.5", "5.6", "5.7","8.0","8.2"],
|
||||
"updates":["5.5.62","5.6.50", "5.7.32","8.0.34","8.2.0"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/mysql",
|
||||
"path":"server/mysql",
|
||||
|
||||
@@ -5,6 +5,9 @@ export PATH
|
||||
# 手动主从设置
|
||||
# https://www.cnblogs.com/whiteY/p/17331882.html
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/mysql && bash install.sh install 8.2
|
||||
# cd /www/server/mdserver-web && source bin/activate && python3 /www/server/mdserver-web/plugins/mysql/index.py try_slave_sync_bugfix {}
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
|
||||
+52
-14
@@ -161,7 +161,7 @@ function runInfo(){
|
||||
<tr><th>活动/峰值连接数</th><td>' + rdata.Threads_running + '/' + rdata.Max_used_connections + '</td><td colspan="2">若值过大,增加max_connections</td></tr>\
|
||||
<tr><th>线程缓存命中率</th><td>' + ((1 - rdata.Threads_created / rdata.Connections) * 100).toFixed(2) + '%</td><td colspan="2">若过低,增加thread_cache_size</td></tr>\
|
||||
<tr><th>索引命中率</th><td>' + ((1 - rdata.Key_reads / rdata.Key_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">若过低,增加key_buffer_size</td></tr>\
|
||||
<tr><th>Innodb索引命中率</th><td>' + ((1 - rdata.Innodb_buffer_pool_reads / rdata.Innodb_buffer_pool_read_requests) * 100).toFixed(2) + '%</td><td colspan="2">若过低,增加innodb_buffer_pool_size</td></tr>\
|
||||
<tr><th>Innodb索引命中率</th><td>' + (rdata.Innodb_buffer_pool_read_requests / (rdata.Innodb_buffer_pool_read_requests+rdata.Innodb_buffer_pool_reads)).toFixed(2) + '%</td><td colspan="2">若过低,增加innodb_buffer_pool_size</td></tr>\
|
||||
<tr><th>查询缓存命中率</th><td>' + cache_size + '</td><td colspan="2">' + lan.soft.mysql_status_ps5 + '</td></tr>\
|
||||
<tr><th>创建临时表到磁盘</th><td>' + ((rdata.Created_tmp_disk_tables / rdata.Created_tmp_tables) * 100).toFixed(2) + '%</td><td colspan="2">若过大,尝试增加tmp_table_size</td></tr>\
|
||||
<tr><th>已打开的表</th><td>' + rdata.Open_tables + '</td><td colspan="2">若过大,增加table_cache_size</td></tr>\
|
||||
@@ -200,7 +200,7 @@ function myPort(){
|
||||
myPost('my_port','',function(data){
|
||||
var con = '<div class="line ">\
|
||||
<div class="info-r ml0">\
|
||||
<input name="port" class="bt-input-text mr5 port" type="text" style="width:100px" value="'+data.data+'">\
|
||||
<input name="port" class="bt-input-text mr5 port" type="number" style="width:100px" value="'+data.data+'">\
|
||||
<button id="btn_change_port" name="btn_change_port" class="btn btn-success btn-sm mr5 ml5 btn_change_port">修改</button>\
|
||||
</div></div>';
|
||||
$(".soft-man-con").html(con);
|
||||
@@ -496,7 +496,6 @@ function setRootPwd(type, pwd){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
@@ -508,7 +507,7 @@ function setRootPwd(type, pwd){
|
||||
title: '修改数据库密码',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
btn:["提交","关闭"],
|
||||
btn:["提交", "关闭", "复制ROOT密码", "强制修改"],
|
||||
shadeClose: true,
|
||||
content: "<form class='bt-form pd20' id='mod_pwd'>\
|
||||
<div class='line'>\
|
||||
@@ -518,8 +517,36 @@ function setRootPwd(type, pwd){
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
yes:function(){
|
||||
setRootPwd(1);
|
||||
yes:function(layerIndex){
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
},
|
||||
btn3:function(){
|
||||
var password = $("#MyPassword").val();
|
||||
copyText(password);
|
||||
return false;
|
||||
},
|
||||
btn4:function(layerIndex){
|
||||
layer.confirm('强制修改,是为了在重建时使用,确定强制?', {
|
||||
btn: ['确定', '取消']
|
||||
}, function(index, layero){
|
||||
layer.close(index);
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password,force:'1'}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(layerIndex);
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -674,7 +701,7 @@ function setDbPass(id, username, password){
|
||||
<span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
|
||||
</div>\
|
||||
<input type='hidden' name='id' value='"+id+"'>\
|
||||
</form>",
|
||||
</form>",
|
||||
yes:function(index){
|
||||
// var data = $("#mod_pwd").serialize();
|
||||
var data = {};
|
||||
@@ -877,7 +904,7 @@ function openPhpmyadmin(name,username,password){
|
||||
|
||||
setTimeout(function(){
|
||||
$("#toPHPMyAdmin").submit();
|
||||
},3000);
|
||||
},2000);
|
||||
layer.msg('phpMyAdmin['+data.data+']需要手动登录😭',{icon:16,shade: [0.3, '#000'],time:4000});
|
||||
|
||||
} else{
|
||||
@@ -890,7 +917,7 @@ function openPhpmyadmin(name,username,password){
|
||||
|
||||
setTimeout(function(){
|
||||
$("#toPHPMyAdmin").submit();
|
||||
},3000);
|
||||
},2000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1281,6 +1308,7 @@ function myBinRollingLogs(_name, func, _args, line){
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function myBinLogsRender(page){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
@@ -2567,10 +2595,20 @@ function masterOrSlaveConf(version=''){
|
||||
</div>\
|
||||
</form>",
|
||||
success:function(){
|
||||
// copyText(v['Error']);
|
||||
// $('.class-copy-db-err').click(function(){
|
||||
// copyText(v['Error']);
|
||||
// });
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
copyText(info['Last_IO_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Last_SQL_Error'] != ''){
|
||||
copyText(info['Last_SQL_Error']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info['Slave_SQL_Running_State'] != ''){
|
||||
copyText(info['Slave_SQL_Running_State']);
|
||||
return;
|
||||
}
|
||||
},
|
||||
yes:function(){
|
||||
if (info['Last_IO_Error'] != ''){
|
||||
@@ -2665,7 +2703,7 @@ function masterOrSlaveConf(version=''){
|
||||
<p class="conf_p">\
|
||||
<span class="f14 c6 mr20">Master[主]配置</span><span class="f14 c6 mr20"></span>\
|
||||
<button class="btn '+(!rdata.status ? 'btn-danger' : 'btn-success')+' btn-xs btn-master">'+(!rdata.status ? '未开启' : '已开启') +'</button>\
|
||||
<button class="btn btn-success btn-xs" onclick="resetMaster()" >重置</button>\
|
||||
<button class="btn btn-success btn-xs" onclick="resetMaster()">重置</button>\
|
||||
</p>\
|
||||
<hr/>\
|
||||
<!-- master list -->\
|
||||
|
||||
@@ -159,7 +159,7 @@ Install_mysql()
|
||||
apt install -y libssl-dev
|
||||
apt install -y libgssglue-dev
|
||||
apt install -y software-properties-common
|
||||
add-apt-repository ppa:ubuntu-toolchain-r/test
|
||||
add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
|
||||
LIBTIRPC_VER=`pkg-config libtirpc --modversion`
|
||||
if [ ! -f ${mysqlDir}/libtirpc_1.3.3.orig.tar.bz2 ];then
|
||||
|
||||
Executable
+236
@@ -0,0 +1,236 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.7.html
|
||||
#https://dev.mysql.com/downloads/file/?id=489855
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mysqlDir=${serverPath}/source/mysql
|
||||
|
||||
_os=`uname`
|
||||
echo "use system: ${_os}"
|
||||
if [ ${_os} == "Darwin" ]; then
|
||||
OSNAME='macos'
|
||||
elif grep -Eq "openSUSE" /etc/*-release; then
|
||||
OSNAME='opensuse'
|
||||
zypper refresh
|
||||
elif grep -Eq "FreeBSD" /etc/*-release; then
|
||||
OSNAME='freebsd'
|
||||
pkg install -y wget unzip
|
||||
elif grep -Eqi "Arch" /etc/issue || grep -Eq "Arch" /etc/*-release; then
|
||||
OSNAME='arch'
|
||||
echo y | pacman -Sy unzip
|
||||
elif grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
|
||||
OSNAME='centos'
|
||||
yum install -y wget zip unzip
|
||||
elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
|
||||
OSNAME='fedora'
|
||||
yum install -y wget zip unzip
|
||||
elif grep -Eqi "Rocky" /etc/issue || grep -Eq "Rocky" /etc/*-release; then
|
||||
OSNAME='rocky'
|
||||
yum install -y wget zip unzip
|
||||
elif grep -Eqi "AlmaLinux" /etc/issue || grep -Eq "AlmaLinux" /etc/*-release; then
|
||||
OSNAME='alma'
|
||||
yum install -y wget zip unzip
|
||||
elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
|
||||
OSNAME='debian'
|
||||
apt update -y
|
||||
apt install -y devscripts
|
||||
apt install -y wget zip unzip
|
||||
elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
|
||||
OSNAME='ubuntu'
|
||||
apt install -y wget zip unzip
|
||||
else
|
||||
OSNAME='unknow'
|
||||
fi
|
||||
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
|
||||
VERSION=8.2.0
|
||||
Install_mysql()
|
||||
{
|
||||
mkdir -p ${mysqlDir}
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql UID is `id -u www`"
|
||||
echo "mysql Shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ -f /proc/cpuinfo ];then
|
||||
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
|
||||
fi
|
||||
|
||||
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
|
||||
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
|
||||
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
|
||||
cpuCore="${MEM_INFO}"
|
||||
fi
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
cd ${rootPath}/plugins/mysql/lib && /bin/bash rpcgen.sh
|
||||
|
||||
INSTALL_CMD=cmake
|
||||
# check cmake version
|
||||
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
|
||||
if [ "$CMAKE_VERSION" -eq "2" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
INSTALL_CMD=cmake3
|
||||
fi
|
||||
|
||||
if [ ! -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
|
||||
#wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.2/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_mysql_ok=704ad9fb4779e76ce5e327285813c97c
|
||||
if [ -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
|
||||
md5_mysql=`md5sum ${mysqlDir}/mysql-boost-${VERSION}.tar.gz | awk '{print $1}'`
|
||||
if [ "${md5_mysql_ok}" == "${md5_mysql}" ]; then
|
||||
echo "mysql8.0 file check ok"
|
||||
else
|
||||
# 重新下载
|
||||
rm -rf ${mysqlDir}/mysql-${VERSION}
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d ${mysqlDir}/mysql-${VERSION} ];then
|
||||
cd ${mysqlDir} && tar -zxvf ${mysqlDir}/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
OPTIONS=''
|
||||
##check openssl version
|
||||
OPENSSL_VERSION=`openssl version|awk '{print $2}'|awk -F '.' '{print $1}'`
|
||||
if [ "${OPENSSL_VERSION}" -ge "3" ];then
|
||||
#openssl version to high
|
||||
cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh
|
||||
export PKG_CONFIG_PATH=$serverPath/lib/openssl/lib/pkgconfig
|
||||
OPTIONS="-DWITH_SSL=${serverPath}/lib/openssl"
|
||||
fi
|
||||
|
||||
WHERE_DIR_GCC=/usr/bin/gcc
|
||||
WHERE_DIR_GPP=/usr/bin/g++
|
||||
if [ "$OSNAME" == "centos" ] && [ "$VERSION_ID" == "7" ];then
|
||||
yum install -y libudev-devel
|
||||
yum install -y centos-release-scl
|
||||
yum install -y devtoolset-11-gcc devtoolset-11-gcc-c++ devtoolset-11-binutils
|
||||
|
||||
gcc --version
|
||||
WHERE_DIR_GCC=/opt/rh/devtoolset-11/root/usr/bin/gcc
|
||||
WHERE_DIR_GPP=/opt/rh/devtoolset-11/root/usr/bin/g++
|
||||
echo $WHERE_DIR_GCC
|
||||
echo $WHERE_DIR_GPP
|
||||
fi
|
||||
|
||||
if [ "$OSNAME" == "ubuntu" ];then
|
||||
apt install -y libudev-dev
|
||||
apt install -y libtirpc-dev
|
||||
apt install -y libssl-dev
|
||||
apt install -y libgssglue-dev
|
||||
apt install -y software-properties-common
|
||||
add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
|
||||
LIBTIRPC_VER=`pkg-config libtirpc --modversion`
|
||||
if [ ! -f ${mysqlDir}/libtirpc_1.3.3.orig.tar.bz2 ];then
|
||||
wget --no-check-certificate -O ${mysqlDir}/libtirpc_1.3.3.orig.tar.bz2 https://downloads.sourceforge.net/libtirpc/libtirpc-1.3.3.tar.bz2
|
||||
cd ${mysqlDir} && tar -jxvf libtirpc_1.3.3.orig.tar.bz2
|
||||
cd libtirpc-1.3.3 && ./configure
|
||||
fi
|
||||
|
||||
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
apt install -y gcc-11 g++-11
|
||||
WHERE_DIR_GCC=/usr/bin/gcc-11
|
||||
WHERE_DIR_GPP=/usr/bin/g++-11
|
||||
fi
|
||||
|
||||
|
||||
if [ "$OSNAME" == "opensuse" ];then
|
||||
zypper install -y gcc11
|
||||
zypper install -y gcc11-c++
|
||||
|
||||
|
||||
WHERE_DIR_GCC=/usr/bin/gcc-11
|
||||
WHERE_DIR_GPP=/usr/bin/g++-11
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mysql ];then
|
||||
# -DCMAKE_CXX_STANDARD=17 \
|
||||
cd ${mysqlDir}/mysql-${VERSION} && ${INSTALL_CMD} \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mysql \
|
||||
-DMYSQL_USER=mysql \
|
||||
-DMYSQL_TCP_PORT=3306 \
|
||||
-DMYSQL_UNIX_ADDR=/var/tmp/mysql.sock \
|
||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
||||
-DENABLED_LOCAL_INFILE=1 \
|
||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
||||
-DWITH_READLINE=1 \
|
||||
-DEXTRA_CHARSETS=all \
|
||||
-DDEFAULT_CHARSET=utf8mb4 \
|
||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
||||
-DDOWNLOAD_BOOST=1 \
|
||||
-DFORCE_INSOURCE_BUILD=1 \
|
||||
$OPTIONS \
|
||||
-DCMAKE_C_COMPILER=$WHERE_DIR_GCC \
|
||||
-DCMAKE_CXX_COMPILER=$WHERE_DIR_GPP \
|
||||
-DDOWNLOAD_BOOST=0 \
|
||||
-DWITH_BOOST=${mysqlDir}/mysql-${VERSION}/boost/
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mysql ];then
|
||||
rm -rf ${mysqlDir}/mysql-${VERSION}
|
||||
echo '8.2' > $serverPath/mysql/version.pl
|
||||
echo "${VERSION}安装完成"
|
||||
else
|
||||
# rm -rf ${mysqlDir}/mysql-${VERSION}
|
||||
echo "${VERSION}安装失败"
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
rm -rf $serverPath/mysql
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == "install" ];then
|
||||
Install_mysql
|
||||
else
|
||||
Uninstall_mysql
|
||||
fi
|
||||
@@ -579,6 +579,12 @@ def reload():
|
||||
mw.opWeb('start')
|
||||
return 'ok'
|
||||
|
||||
def reload_hook():
|
||||
s = status()
|
||||
if s == 'start':
|
||||
return reload()
|
||||
return 'ok'
|
||||
|
||||
|
||||
def getJsonPath(name):
|
||||
path = getServerDir() + "/waf/" + name + ".json"
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"site_cb": {
|
||||
"title":"网站统计",
|
||||
"name":"op_waf",
|
||||
"add":{"func":"reload"},
|
||||
"update":{"func":"reload"},
|
||||
"delete":{"func":"reload"}
|
||||
"add":{"func":"reload_hook"},
|
||||
"update":{"func":"reload_hook"},
|
||||
"delete":{"func":"reload_hook"}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/op_waf && bash install.sh install 0.4.1
|
||||
@@ -87,7 +87,7 @@ Install_App(){
|
||||
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
HTTP_PREFIX="https://"
|
||||
if [ ! -z "$cn" ];then
|
||||
HTTP_PREFIX="https://ghproxy.com/"
|
||||
HTTP_PREFIX="https://mirror.ghproxy.com/"
|
||||
fi
|
||||
|
||||
# download GeoLite Data
|
||||
|
||||
@@ -1614,8 +1614,9 @@ function wafSite(){
|
||||
<label class="btswitch-btn" for="closeget_'+ i + '" onclick="setSiteObjState(\'' + k + '\',\'open\')"></label>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td class="text-right"><a onclick="wafLogs(\''+ k + '\')" class="btlink ' + (v.log_size > 0 ? 'dot' : '') + '">日志</a> | <a onclick="siteWafConfig(\'' + k + '\')" class="btlink">设置</a></td>\
|
||||
<td class="text-right"><a onclick="wafLogs(\''+ k + '\')" class="btlink ' + (v.log_size > 0 ? 'dot' : '') + '">日志</a> </td>\
|
||||
</tr>';
|
||||
//| <a onclick="siteWafConfig(\'' + k + '\')" class="btlink">设置</a>
|
||||
});
|
||||
|
||||
var con = '<div class="lib-box">\
|
||||
|
||||
@@ -3,7 +3,7 @@ worker_processes auto;
|
||||
error_log {$SERVER_PATH}/openresty/nginx/logs/error.log crit;
|
||||
pid {$SERVER_PATH}/openresty/nginx/logs/nginx.pid;
|
||||
|
||||
worker_rlimit_nofile 51200;
|
||||
worker_rlimit_nofile 65535;
|
||||
|
||||
events
|
||||
{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="orPluginService('openresty');">服务</p>
|
||||
<p onclick="pluginInitD('openresty');">自启动</p>
|
||||
<p class="bgw" onclick="orPluginService('openresty',$('.plugin_version').attr('version'));">服务</p>
|
||||
<p onclick="pluginInitD('openresty', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="pluginConfig('openresty');">配置修改</p>
|
||||
<p onclick="getOpStatus();">负载状态</p>
|
||||
<p onclick="setOpCfg();">性能调整</p>
|
||||
|
||||
@@ -320,7 +320,7 @@ def restyOp_restart():
|
||||
return 'ERROR: 配置出错<br><a style="color:red;">' + check_data[1].replace("\n", '<br>') + '</a>'
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
threading.Timer(2, op_submit_systemctl_restart, args=()).start()
|
||||
threading.Timer(2, op_submit_systemctl_restart).start()
|
||||
return 'ok'
|
||||
|
||||
threading.Timer(2, op_submit_init_restart, args=(file,)).start()
|
||||
@@ -339,7 +339,7 @@ def stop():
|
||||
return r
|
||||
|
||||
|
||||
def restart():
|
||||
def restart(version=()):
|
||||
return restyOp_restart()
|
||||
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ Install_openresty()
|
||||
|
||||
# Last Download Method
|
||||
if [ ! -f ${openrestyDir}/openresty-${VERSION}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${openrestyDir}/openresty-${VERSION}.tar.gz http://dl.midoks.me/soft/openresty/openresty-${VERSION}.tar.gz -T 3
|
||||
wget --no-check-certificate -O ${openrestyDir}/openresty-${VERSION}.tar.gz http://dl.midoks.icu/soft/openresty/openresty-${VERSION}.tar.gz -T 3
|
||||
fi
|
||||
|
||||
cd ${openrestyDir} && tar -zxvf openresty-${VERSION}.tar.gz
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
<style type="text/css">
|
||||
.bt-w-main{
|
||||
height: 600px;
|
||||
height: 552px;
|
||||
}
|
||||
|
||||
.session_clear_list {
|
||||
@@ -44,8 +44,7 @@
|
||||
<p onclick="pluginInitD('php-apt', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="phpLibConfig($('.plugin_version').attr('version'));">安装扩展</p>
|
||||
<p onclick="phpSetConfig($('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="phpUploadLimitReq($('.plugin_version').attr('version'));">上传限制</p>
|
||||
<p onclick="phpTimeLimitReq($('.plugin_version').attr('version'));">超时限制</p>
|
||||
<p onclick="phpCommonFunc($('.plugin_version').attr('version'));">常用功能</p>
|
||||
<p onclick="pluginConfig('php-apt', $('.plugin_version').attr('version'));">配置文件</p>
|
||||
<p onclick="pluginConfig('php-apt', $('.plugin_version').attr('version'),'get_fpm_conf_file');">FPM配置</p>
|
||||
<p onclick="disableFunc($('.plugin_version').attr('version'));">禁用函数</p>
|
||||
@@ -54,7 +53,6 @@
|
||||
<p onclick="getSessionConfig($('.plugin_version').attr('version'));" title="session管理">会话管理</p>
|
||||
<p onclick="pluginLogs('php-apt',$('.plugin_version').attr('version'),'fpm_log');">FPM日志</p>
|
||||
<p onclick="pluginLogs('php-apt',$('.plugin_version').attr('version'),'fpm_slow_log');">慢日志</p>
|
||||
<p onclick="getPhpinfo($('.plugin_version').attr('version'));">PHPIFNO</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
|
||||
Executable
+171
@@ -0,0 +1,171 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import shutil
|
||||
|
||||
# reload(sys)
|
||||
# sys.setdefaultencoding('utf8')
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
if mw.isAppleSystem():
|
||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
||||
info = mw.execShell(cmd)
|
||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
||||
sys.path.append(p)
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'php-apt'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return '/etc/php'
|
||||
|
||||
|
||||
def getInitDFile(version):
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return '/tmp/' + getPluginName()
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
return '/etc/rc.d/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName() + version
|
||||
|
||||
|
||||
def getConf(version):
|
||||
path = getServerDir() + '/' + version + '/fpm/php.ini'
|
||||
return path
|
||||
|
||||
|
||||
def getFpmConfFile(version):
|
||||
return getServerDir() + '/' + version + '/fpm/pool.d/mw.conf'
|
||||
|
||||
|
||||
def status_progress(version):
|
||||
# ps -ef|grep 'php/81' |grep -v grep | grep -v python | awk '{print $2}
|
||||
cmd = "ps aux|grep 'php/" + version + \
|
||||
"' |grep -v grep | grep -v python | awk '{print $2}'"
|
||||
data = mw.execShell(cmd)
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def getPhpSocket(version):
|
||||
path = getFpmConfFile(version)
|
||||
content = mw.readFile(path)
|
||||
rep = 'listen\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def status(version):
|
||||
'''
|
||||
sock文件判断是否启动
|
||||
'''
|
||||
sock = getPhpSocket(version)
|
||||
if sock.find(':'):
|
||||
return status_progress(version)
|
||||
|
||||
if not os.path.exists(sock):
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def getFpmAddress(version):
|
||||
fpm_address = '/run/php/php{}-fpm.sock'.format(version)
|
||||
php_fpm_file = getFpmConfFile(version)
|
||||
try:
|
||||
content = readFile(php_fpm_file)
|
||||
tmp = re.findall(r"listen\s*=\s*(.+)", content)
|
||||
if not tmp:
|
||||
return fpm_address
|
||||
if tmp[0].find('sock') != -1:
|
||||
return fpm_address
|
||||
if tmp[0].find(':') != -1:
|
||||
listen_tmp = tmp[0].split(':')
|
||||
if bind:
|
||||
fpm_address = (listen_tmp[0], int(listen_tmp[1]))
|
||||
else:
|
||||
fpm_address = ('127.0.0.1', int(listen_tmp[1]))
|
||||
else:
|
||||
fpm_address = ('127.0.0.1', int(tmp[0]))
|
||||
return fpm_address
|
||||
except:
|
||||
return fpm_address
|
||||
|
||||
|
||||
def getPhpinfo(version):
|
||||
stat = status(version)
|
||||
if stat == 'stop':
|
||||
return 'PHP[' + version + ']未启动,不可访问!!!'
|
||||
|
||||
sock_file = getFpmAddress(version)
|
||||
print(sock_file)
|
||||
root_dir = mw.getRootDir() + '/phpinfo'
|
||||
|
||||
mw.execShell("rm -rf " + root_dir)
|
||||
mw.execShell("mkdir -p " + root_dir)
|
||||
mw.writeFile(root_dir + '/phpinfo.php', '<?php phpinfo(); ?>')
|
||||
sock_data = mw.requestFcgiPHP(sock_file, '/phpinfo.php', root_dir)
|
||||
os.system("rm -rf " + root_dir)
|
||||
phpinfo = str(sock_data, encoding='utf-8')
|
||||
return phpinfo
|
||||
|
||||
|
||||
def libConfCommon(version):
|
||||
fname = getConf(version)
|
||||
if not os.path.exists(fname):
|
||||
return mw.returnJson(False, '指定PHP版本不存在!')
|
||||
|
||||
phpini = mw.readFile(fname)
|
||||
|
||||
libpath = getPluginDir() + '/versions/phplib.conf'
|
||||
phplib = json.loads(mw.readFile(libpath))
|
||||
|
||||
libs = []
|
||||
tasks = mw.M('tasks').where(
|
||||
"status!=?", ('1',)).field('status,name').select()
|
||||
for lib in phplib:
|
||||
lib['task'] = '1'
|
||||
for task in tasks:
|
||||
tmp = mw.getStrBetween('[', ']', task['name'])
|
||||
if not tmp:
|
||||
continue
|
||||
tmp1 = tmp.split('-')
|
||||
if tmp1[0].lower() == lib['name'].lower():
|
||||
lib['task'] = task['status']
|
||||
lib['phpversions'] = []
|
||||
lib['phpversions'].append(tmp1[1])
|
||||
if phpini.find(lib['check']) == -1:
|
||||
lib['status'] = False
|
||||
else:
|
||||
lib['status'] = True
|
||||
libs.append(lib)
|
||||
return libs
|
||||
|
||||
|
||||
def get_php_info(args):
|
||||
version = args['version']
|
||||
apt_ver = version[0:1]+'.'+version[1:2]
|
||||
return getPhpinfo(apt_ver)
|
||||
|
||||
|
||||
def get_lib_conf(data):
|
||||
libs = libConfCommon(data['version'])
|
||||
return mw.returnData(True, 'OK!', libs)
|
||||
@@ -5,7 +5,7 @@
|
||||
"name": "php-apt",
|
||||
"title": "PHP[APT]",
|
||||
"coexist": true,
|
||||
"versions": ["56","70","71","72","73","74","80","81","82"],
|
||||
"versions": ["56","70","71","72","73","74","80","81","82","83"],
|
||||
"install_pre_inspection":true,
|
||||
"tip": "soft",
|
||||
"checks": "server/php-apt/VERSION",
|
||||
|
||||
+35
-40
@@ -1,14 +1,3 @@
|
||||
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function phpPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
@@ -18,7 +7,7 @@ function phpPost(method, version, args,callback){
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(str2Obj(args));
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
@@ -43,10 +32,11 @@ function phpPostCallbak(method, version, args,callback){
|
||||
var req_data = {};
|
||||
req_data['name'] = 'php-apt';
|
||||
req_data['func'] = method;
|
||||
req_data['script']='index_php_apt';
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(str2Obj(args));
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
@@ -128,35 +118,29 @@ function submitConf(version) {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//php上传限制
|
||||
function phpUploadLimitReq(version){
|
||||
phpPost('get_limit_conf', version, '', function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
phpUploadLimit(version,rdata['max']);
|
||||
});
|
||||
}
|
||||
|
||||
function phpUploadLimit(version,max){
|
||||
var LimitCon = '<p class="conf_p"><input class="phpUploadLimit bt-input-text mr5" type="number" value="'+
|
||||
max+'" name="max">MB<button class="btn btn-success btn-sm" onclick="setPHPMaxSize(\''+
|
||||
version+'\')" style="margin-left:20px">保存</button></p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
}
|
||||
|
||||
|
||||
//php超时限制
|
||||
function phpTimeLimitReq(version){
|
||||
function phpCommonFunc(version){
|
||||
phpPost('get_limit_conf', version, '', function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
phpTimeLimit(version,rdata['maxTime']);
|
||||
});
|
||||
}
|
||||
var con = '<p class="conf_p">\
|
||||
<span>超时限制</span>\
|
||||
<input class="phpTimeLimit bt-input-text mr5" type="number" value="' + rdata['maxTime'] + '">, 秒\
|
||||
<button class="btn btn-success btn-sm" onclick="setPHPMaxTime(\'' + version + '\')" style="margin-left:20px">保存</button>\
|
||||
</p>';
|
||||
|
||||
function phpTimeLimit(version, max) {
|
||||
var LimitCon = '<p class="conf_p"><input class="phpTimeLimit bt-input-text mr5" type="number" value="' + max + '">秒<button class="btn btn-success btn-sm" onclick="setPHPMaxTime(\'' + version + '\')" style="margin-left:20px">保存</button></p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
con += '<p class="conf_p">\
|
||||
<span>上传限制</span>\
|
||||
<input class="phpUploadLimit bt-input-text mr5" type="number" value="' + rdata['max']+'" name="max">,MB\
|
||||
<button class="btn btn-success btn-sm" onclick="setPHPMaxSize(\''+ version+'\')" style="margin-left:20px">保存</button>\
|
||||
</p>';
|
||||
|
||||
// <button class="btn btn-default btn-sm" onclick="phpPreload(\'' + version + '\')">预加载脚本</button>\
|
||||
con += '<hr/><p class="conf_p" style="text-align:center;">\
|
||||
<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button> \
|
||||
</p>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
//设置超时限制
|
||||
@@ -164,7 +148,10 @@ function setPHPMaxTime(version) {
|
||||
var max = $(".phpTimeLimit").val();
|
||||
phpPost('set_max_time',version,{'time':max},function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
showMsg(rdata.msg,function(){
|
||||
phpCommonFunc(version);
|
||||
},{ icon: rdata.status ? 1 : 2 });
|
||||
|
||||
});
|
||||
}
|
||||
//设置PHP上传限制
|
||||
@@ -182,6 +169,13 @@ function setPHPMaxSize(version) {
|
||||
});
|
||||
}
|
||||
|
||||
function phpPreload(version){
|
||||
phpPost('app_start',version,{},function(data){
|
||||
onlineEditFile(0, data['data']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getFpmConfig(version){
|
||||
phpPost('get_fpm_conf', version, {}, function(data){
|
||||
@@ -320,6 +314,7 @@ function getFpmStatus(version){
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = tmp_data.data;
|
||||
var php_fpm_status = '动态';
|
||||
if (rdata['process manager'] == 'dynamic'){
|
||||
php_fpm_status = '动态';
|
||||
@@ -329,7 +324,7 @@ function getFpmStatus(version){
|
||||
php_fpm_status = '按需';
|
||||
}
|
||||
|
||||
var rdata = tmp_data.data;
|
||||
|
||||
var con = "<div style='height:420px;overflow:hidden;'><table class='table table-hover table-bordered GetPHPStatus' style='margin:0;padding:0'>\
|
||||
<tr><th>应用池(pool)</th><td>" + rdata.pool + "</td></tr>\
|
||||
<tr><th>进程管理方式(process manager)</th><td>" + php_fpm_status + "</td></tr>\
|
||||
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sourcePath=${serverPath}/source
|
||||
sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
#获取信息和版本
|
||||
# bash /www/server/mdsever-web/scripts/getos.sh
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
version=8.3
|
||||
PHP_VER=83
|
||||
|
||||
|
||||
Install_php()
|
||||
{
|
||||
#------------------------ install start ------------------------------------#
|
||||
apt -y install php${version} php${version}-fpm php${version}-dev
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/php-apt/${PHP_VER}
|
||||
fi
|
||||
|
||||
#------------------------ install end ------------------------------------#
|
||||
}
|
||||
|
||||
Uninstall_php()
|
||||
{
|
||||
#------------------------ uninstall start ------------------------------------#
|
||||
apt -y remove php${version} php${version}-*
|
||||
rm -rf $serverPath/php-apt/${PHP_VER}
|
||||
echo "卸载php-${version}..." > $install_tmp
|
||||
#------------------------ uninstall start ------------------------------------#
|
||||
}
|
||||
|
||||
action=${1}
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_php
|
||||
else
|
||||
Uninstall_php
|
||||
fi
|
||||
@@ -10,7 +10,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "数据库访问抽象模块!",
|
||||
@@ -28,7 +29,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用MySQL数据库的模块!",
|
||||
@@ -46,7 +48,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用MySQL数据库的模块!",
|
||||
@@ -64,7 +67,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用sqlite3数据库的模块!",
|
||||
@@ -90,7 +94,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用ODBC数据库的模块!",
|
||||
@@ -142,7 +147,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "用于加速PHP脚本!",
|
||||
@@ -175,7 +181,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "高精度计算!",
|
||||
@@ -239,7 +246,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "通用CURL库!",
|
||||
@@ -252,7 +260,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "通用GD库!",
|
||||
@@ -270,7 +279,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "提供国际化支持",
|
||||
@@ -300,7 +310,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "强大的内容缓存器,支持集群",
|
||||
@@ -317,7 +328,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "更强大的内容缓存器,支持集群",
|
||||
@@ -334,7 +347,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "脚本缓存器",
|
||||
@@ -352,7 +367,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "比GD更强大的图形库",
|
||||
@@ -369,7 +385,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "调试器",
|
||||
"msg": "不多说,不了解的不要安装",
|
||||
@@ -386,7 +404,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "性能分析",
|
||||
"msg": "不多说,不了解的不要安装!",
|
||||
@@ -403,7 +423,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "异步、并行、高性能网络通信引擎",
|
||||
@@ -463,7 +485,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "框架",
|
||||
"msg": "Yar是一个RPC框架",
|
||||
@@ -541,7 +565,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "日志",
|
||||
"msg": "SeasLog高性能日志记录",
|
||||
@@ -559,7 +585,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于需要多字节字符串处理的模块",
|
||||
@@ -577,7 +604,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "压缩",
|
||||
"msg": "压缩组件",
|
||||
@@ -594,7 +622,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "压缩",
|
||||
"msg": "压缩组件",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<style type="text/css">
|
||||
.bt-w-main{
|
||||
height: 600px;
|
||||
height: 552px;
|
||||
}
|
||||
|
||||
.session_clear_list {
|
||||
@@ -43,8 +43,7 @@
|
||||
<p onclick="pluginInitD('php-yum', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="phpLibConfig($('.plugin_version').attr('version'));">安装扩展</p>
|
||||
<p onclick="phpSetConfig($('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="phpUploadLimitReq($('.plugin_version').attr('version'));">上传限制</p>
|
||||
<p onclick="phpTimeLimitReq($('.plugin_version').attr('version'));">超时限制</p>
|
||||
<p onclick="phpCommonFunc($('.plugin_version').attr('version'));">常用功能</p>
|
||||
<p onclick="pluginConfig('php-yum', $('.plugin_version').attr('version'));">配置文件</p>
|
||||
<p onclick="pluginConfig('php-yum', $('.plugin_version').attr('version'),'get_fpm_conf_file');">FPM配置</p>
|
||||
<p onclick="disableFunc($('.plugin_version').attr('version'));">禁用函数</p>
|
||||
@@ -53,7 +52,6 @@
|
||||
<p onclick="getSessionConfig($('.plugin_version').attr('version'));" title="session管理">会话管理</p>
|
||||
<p onclick="pluginLogs('php-yum',$('.plugin_version').attr('version'),'fpm_log');">FPM日志</p>
|
||||
<p onclick="pluginLogs('php-yum',$('.plugin_version').attr('version'),'fpm_slow_log');">慢日志</p>
|
||||
<p onclick="getPhpinfo($('.plugin_version').attr('version'));">PHPIFNO</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"name": "php-yum",
|
||||
"title": "PHP[YUM]",
|
||||
"coexist": true,
|
||||
"versions": ["74","80","81","82"],
|
||||
"versions": ["74","80","81","82","83"],
|
||||
"install_pre_inspection":true,
|
||||
"tip": "soft",
|
||||
"checks": "server/php-yum/VERSION",
|
||||
|
||||
+37
-43
@@ -1,14 +1,3 @@
|
||||
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function phpPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
@@ -18,7 +7,7 @@ function phpPost(method, version, args,callback){
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(str2Obj(args));
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
@@ -46,7 +35,7 @@ function phpPostCallbak(method, version, args,callback){
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(str2Obj(args));
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
@@ -130,33 +119,29 @@ function submitConf(version) {
|
||||
|
||||
|
||||
|
||||
//php上传限制
|
||||
function phpUploadLimitReq(version){
|
||||
phpPost('get_limit_conf', version, '', function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
phpUploadLimit(version,rdata['max']);
|
||||
});
|
||||
}
|
||||
|
||||
function phpUploadLimit(version,max){
|
||||
var LimitCon = '<p class="conf_p"><input class="phpUploadLimit bt-input-text mr5" type="number" value="'+
|
||||
max+'" name="max">MB<button class="btn btn-success btn-sm" onclick="setPHPMaxSize(\''+
|
||||
version+'\')" style="margin-left:20px">保存</button></p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
}
|
||||
|
||||
|
||||
//php超时限制
|
||||
function phpTimeLimitReq(version){
|
||||
function phpCommonFunc(version){
|
||||
phpPost('get_limit_conf', version, '', function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
phpTimeLimit(version,rdata['maxTime']);
|
||||
});
|
||||
}
|
||||
var con = '<p class="conf_p">\
|
||||
<span>超时限制</span>\
|
||||
<input class="phpTimeLimit bt-input-text mr5" type="number" value="' + rdata['maxTime'] + '">, 秒\
|
||||
<button class="btn btn-success btn-sm" onclick="setPHPMaxTime(\'' + version + '\')" style="margin-left:20px">保存</button>\
|
||||
</p>';
|
||||
|
||||
function phpTimeLimit(version, max) {
|
||||
var LimitCon = '<p class="conf_p"><input class="phpTimeLimit bt-input-text mr5" type="number" value="' + max + '">秒<button class="btn btn-success btn-sm" onclick="setPHPMaxTime(\'' + version + '\')" style="margin-left:20px">保存</button></p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
con += '<p class="conf_p">\
|
||||
<span>上传限制</span>\
|
||||
<input class="phpUploadLimit bt-input-text mr5" type="number" value="' + rdata['max']+'" name="max">,MB\
|
||||
<button class="btn btn-success btn-sm" onclick="setPHPMaxSize(\''+ version+'\')" style="margin-left:20px">保存</button>\
|
||||
</p>';
|
||||
|
||||
con += '<hr/><p class="conf_p" style="text-align:center;">\
|
||||
<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button> \
|
||||
<button class="btn btn-default btn-sm" onclick="phpPreload(\'' + version + '\')">预加载脚本</button>\
|
||||
</p>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
//设置超时限制
|
||||
@@ -164,7 +149,10 @@ function setPHPMaxTime(version) {
|
||||
var max = $(".phpTimeLimit").val();
|
||||
phpPost('set_max_time',version,{'time':max},function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
showMsg(rdata.msg,function(){
|
||||
phpCommonFunc(version);
|
||||
},{ icon: rdata.status ? 1 : 2 });
|
||||
|
||||
});
|
||||
}
|
||||
//设置PHP上传限制
|
||||
@@ -182,6 +170,12 @@ function setPHPMaxSize(version) {
|
||||
});
|
||||
}
|
||||
|
||||
function phpPreload(version){
|
||||
phpPost('app_start',version,{},function(data){
|
||||
onlineEditFile(0, data['data']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function getFpmConfig(version){
|
||||
phpPost('get_fpm_conf', version, {}, function(data){
|
||||
@@ -326,6 +320,7 @@ function getFpmStatus(version){
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = tmp_data.data;
|
||||
var php_fpm_status = '动态';
|
||||
if (rdata['process manager'] == 'dynamic'){
|
||||
php_fpm_status = '动态';
|
||||
@@ -334,8 +329,7 @@ function getFpmStatus(version){
|
||||
} else if(rdata['process manager'] == 'ondemand'){
|
||||
php_fpm_status = '按需';
|
||||
}
|
||||
|
||||
var rdata = tmp_data.data;
|
||||
|
||||
var con = "<div style='height:420px;overflow:hidden;'><table class='table table-hover table-bordered GetPHPStatus' style='margin:0;padding:0'>\
|
||||
<tr><th>应用池(pool)</th><td>" + rdata.pool + "</td></tr>\
|
||||
<tr><th>进程管理方式(process manager)</th><td>" + php_fpm_status + "</td></tr>\
|
||||
@@ -564,10 +558,10 @@ function setDisableFunc(version, act, fs) {
|
||||
|
||||
|
||||
//phpinfo
|
||||
function getPhpinfo(version) {
|
||||
var con = '<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button>';
|
||||
$(".soft-man-con").html(con);
|
||||
}
|
||||
// function getPhpinfo(version) {
|
||||
// var con = '<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button>';
|
||||
// $(".soft-man-con").html(con);
|
||||
// }
|
||||
|
||||
//获取PHPInfo
|
||||
function getPHPInfo_old(version) {
|
||||
|
||||
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sourcePath=${serverPath}/source
|
||||
sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
version=8.3.x
|
||||
PHP_VER=83
|
||||
|
||||
|
||||
Install_php()
|
||||
{
|
||||
#------------------------ install start ------------------------------------#
|
||||
yum install -y php83 php83-php-fpm
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/php-yum/${PHP_VER}
|
||||
fi
|
||||
|
||||
#------------------------ install end ------------------------------------#
|
||||
}
|
||||
|
||||
Uninstall_php()
|
||||
{
|
||||
yum remove -y php83 php83-php-fpm php83-*
|
||||
rm -rf $serverPath/php-yum/${PHP_VER}
|
||||
echo "卸载php-${version}..." > $install_tmp
|
||||
}
|
||||
|
||||
action=${1}
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_php
|
||||
else
|
||||
Uninstall_php
|
||||
fi
|
||||
@@ -5,7 +5,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "数据库访问抽象模块!",
|
||||
@@ -18,7 +19,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用MySQL数据库的模块!",
|
||||
@@ -31,7 +33,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用MySQL数据库的模块!",
|
||||
@@ -44,7 +47,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用OCI8数据库的模块!",
|
||||
@@ -57,7 +61,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "数据库",
|
||||
"msg": "用于使用ODBC数据库的模块!",
|
||||
@@ -128,7 +133,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "用于加速PHP脚本!",
|
||||
@@ -163,7 +169,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于FILE!",
|
||||
@@ -183,7 +191,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于XML!",
|
||||
@@ -203,7 +213,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于图像文件格式!",
|
||||
@@ -216,7 +228,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "通用GD库!",
|
||||
@@ -238,7 +251,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "提供国际化支持",
|
||||
@@ -271,7 +285,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "强大的内容缓存器,支持集群",
|
||||
@@ -292,7 +307,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "更强大的内容缓存器,支持集群",
|
||||
@@ -323,7 +340,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "比GD更强大的图形库",
|
||||
@@ -343,7 +361,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "调试器",
|
||||
"msg": "不多说,不了解的不要安装",
|
||||
@@ -364,7 +384,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "性能分析",
|
||||
"msg": "不多说,不了解的不要安装!",
|
||||
@@ -384,7 +406,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "异步、并行、高性能网络通信引擎",
|
||||
@@ -415,7 +439,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "框架",
|
||||
"msg": "Yaf是一个C语言编写的PHP框架",
|
||||
@@ -435,7 +461,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "框架",
|
||||
"msg": "Yar是一个RPC框架",
|
||||
@@ -466,7 +494,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "Mongodb数据库连接驱动",
|
||||
@@ -482,7 +512,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "缓存器",
|
||||
"msg": "高性能无锁共享内存Cache",
|
||||
@@ -502,7 +534,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "大数据",
|
||||
"msg": "SOLR全文搜索服务",
|
||||
@@ -522,7 +556,9 @@
|
||||
"73",
|
||||
"74",
|
||||
"80",
|
||||
"81"
|
||||
"81",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "日志",
|
||||
"msg": "SeasLog高性能日志记录",
|
||||
@@ -543,7 +579,8 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "通用扩展",
|
||||
"msg": "用于需要多字节字符串处理的模块",
|
||||
@@ -560,7 +597,9 @@
|
||||
"74",
|
||||
"80",
|
||||
"81",
|
||||
"82"
|
||||
"82",
|
||||
"82",
|
||||
"83"
|
||||
],
|
||||
"type": "压缩",
|
||||
"msg": "压缩组件",
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<?php
|
||||
|
||||
if (isset($_GET['mw_opcache_reset']) && $_GET['mw_opcache_reset'] == 'ok'){
|
||||
opcache_reset();
|
||||
}
|
||||
|
||||
define('XHProf_Name', 'mdd');
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
[backup]
|
||||
user = {$PHP_USER}
|
||||
group = {$PHP_GROUP}
|
||||
|
||||
listen = /tmp/php-cgi-{$PHP_VERSION}.backup.sock
|
||||
listen.owner = {$PHP_USER}
|
||||
listen.group = {$PHP_GROUP}
|
||||
listen.backlog = 4096
|
||||
|
||||
pm = dynamic
|
||||
pm.max_children = 30
|
||||
pm.start_servers = 5
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 20
|
||||
pm.status_path = /phpfpm_status_{$PHP_VERSION}_backup
|
||||
pm.max_requests = 1000
|
||||
request_terminate_timeout = 30
|
||||
request_slowlog_timeout = 10
|
||||
slowlog = {$SERVER_PATH}/php/{$PHP_VERSION}/var/log/www-slow.log
|
||||
@@ -0,0 +1,4 @@
|
||||
upstream MW-UPSTREAM-PHP{$PHP_VERSION} {
|
||||
server unix:/tmp/php-cgi-{$PHP_VERSION}.sock;
|
||||
server unix:/tmp/php-cgi-{$PHP_VERSION}.backup.sock;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
set $PHP_ENV 1;
|
||||
location ~ [^/]\.php(/|$)
|
||||
{
|
||||
try_files $uri =404;
|
||||
fastcgi_pass unix:/tmp/php-cgi-{$PHP_VERSION}.sock;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi.conf;
|
||||
include {$SERVER_PATH}/web_conf/php/pathinfo.conf;
|
||||
}
|
||||
@@ -2,7 +2,8 @@ set $PHP_ENV 1;
|
||||
location ~ [^/]\.php(/|$)
|
||||
{
|
||||
try_files $uri =404;
|
||||
fastcgi_pass unix:/tmp/php-cgi-{$PHP_VERSION}.sock;
|
||||
#fastcgi_pass unix:/tmp/php-cgi-{$PHP_VERSION}.sock;
|
||||
fastcgi_pass MW-UPSTREAM-PHP{$PHP_VERSION};
|
||||
fastcgi_index index.php;
|
||||
include fastcgi.conf;
|
||||
include {$SERVER_PATH}/web_conf/php/pathinfo.conf;
|
||||
|
||||
@@ -8,10 +8,10 @@ listen.group = {$PHP_GROUP}
|
||||
listen.backlog = 4096
|
||||
|
||||
pm = dynamic
|
||||
pm.max_children = 50
|
||||
pm.max_children = 30
|
||||
pm.start_servers = 5
|
||||
pm.min_spare_servers = 5
|
||||
pm.max_spare_servers = 35
|
||||
pm.max_spare_servers = 20
|
||||
pm.status_path = /phpfpm_status_{$PHP_VERSION}
|
||||
pm.max_requests = 1000
|
||||
request_terminate_timeout = 30
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
<style type="text/css">
|
||||
.bt-w-main{
|
||||
height: 642px;
|
||||
height: 552px;
|
||||
}
|
||||
|
||||
.session_clear_list {
|
||||
@@ -43,18 +43,15 @@
|
||||
<p onclick="pluginInitD('php', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="phpLibConfig($('.plugin_version').attr('version'));">安装扩展</p>
|
||||
<p onclick="phpSetConfig($('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="phpUploadLimitReq($('.plugin_version').attr('version'));">上传限制</p>
|
||||
<p onclick="phpTimeLimitReq($('.plugin_version').attr('version'));">超时限制</p>
|
||||
<p onclick="phpCommonFunc($('.plugin_version').attr('version'));">常用功能</p>
|
||||
<p onclick="pluginConfig('php', $('.plugin_version').attr('version'));">配置文件</p>
|
||||
<p onclick="pluginConfig('php', $('.plugin_version').attr('version'),'get_fpm_conf_file');">FPM配置</p>
|
||||
<p onclick="disableFunc($('.plugin_version').attr('version'));">禁用函数</p>
|
||||
<p onclick="phpFpmConfigFile($('.plugin_version').attr('version'),'get_fpm_conf_file');">FPM配置</p>
|
||||
<p onclick="getFpmConfig($('.plugin_version').attr('version'));">性能调整</p>
|
||||
<p onclick="getFpmStatus($('.plugin_version').attr('version'));">负载状况</p>
|
||||
<p onclick="getSessionConfig($('.plugin_version').attr('version'));" title="session管理">会话管理</p>
|
||||
<p onclick="pluginLogs('php',$('.plugin_version').attr('version'),'fpm_log');">FPM日志</p>
|
||||
<p onclick="pluginLogs('php',$('.plugin_version').attr('version'),'fpm_slow_log');">慢日志</p>
|
||||
<p onclick="getPhpinfo($('.plugin_version').attr('version'));">PHPIFNO</p>
|
||||
<p onclick="pluginConfig('php',$('.plugin_version').attr('version'),'app_start');">预加载脚本</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
|
||||
+77
-31
@@ -59,7 +59,6 @@ def getArgs():
|
||||
else:
|
||||
t = t.split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
@@ -79,8 +78,14 @@ def getConf(version):
|
||||
return path
|
||||
|
||||
|
||||
def getFpmConfFile(version):
|
||||
return getServerDir() + '/' + version + '/etc/php-fpm.d/www.conf'
|
||||
def getFpmConfFile(version, pool='www'):
|
||||
args = getArgs()
|
||||
if 'pool' in args:
|
||||
pool = args['pool']
|
||||
return getServerDir() + '/' + version + '/etc/php-fpm.d/'+pool+'.conf'
|
||||
|
||||
def getFpmFile(version):
|
||||
return getServerDir() + '/' + version + '/etc/php-fpm.conf'
|
||||
|
||||
|
||||
def status_progress(version):
|
||||
@@ -157,17 +162,21 @@ def makeOpenrestyConf():
|
||||
sdir = mw.getServerDir()
|
||||
|
||||
dst_dir = sdir + '/web_conf/php'
|
||||
dst_dir_conf = sdir + '/web_conf/php/conf'
|
||||
if not os.path.exists(dst_dir):
|
||||
mw.execShell('mkdir -p ' + dst_dir)
|
||||
|
||||
dst_dir_conf = sdir + '/web_conf/php/conf'
|
||||
if not os.path.exists(dst_dir_conf):
|
||||
mw.execShell('mkdir -p ' + dst_dir_conf)
|
||||
|
||||
d_pathinfo = sdir + '/web_conf/php/pathinfo.conf'
|
||||
if not os.path.exists(d_pathinfo):
|
||||
s_pathinfo = getPluginDir() + '/conf/pathinfo.conf'
|
||||
shutil.copyfile(s_pathinfo, d_pathinfo)
|
||||
dst_dir_upstream = sdir + '/web_conf/php/upstream'
|
||||
if not os.path.exists(dst_dir_upstream):
|
||||
mw.execShell('mkdir -p ' + dst_dir_upstream)
|
||||
|
||||
dst_pathinfo = sdir + '/web_conf/php/pathinfo.conf'
|
||||
if not os.path.exists(dst_pathinfo):
|
||||
src_pathinfo = getPluginDir() + '/conf/pathinfo.conf'
|
||||
shutil.copyfile(src_pathinfo, dst_pathinfo)
|
||||
|
||||
info = getPluginDir() + '/info.json'
|
||||
content = mw.readFile(info)
|
||||
@@ -179,19 +188,31 @@ def makeOpenrestyConf():
|
||||
dfile = sdir + '/web_conf/php/conf/enable-php-' + x + '.conf'
|
||||
if not os.path.exists(dfile):
|
||||
if x == '00':
|
||||
mw.writeFile(dfile, 'set $PHP_ENV 0;')
|
||||
mw.writeFile(dfile, '')
|
||||
else:
|
||||
w_content = contentReplace(tpl_content, x)
|
||||
mw.writeFile(dfile, w_content)
|
||||
content = contentReplace(tpl_content, x)
|
||||
mw.writeFile(dfile, content)
|
||||
|
||||
upstream_tpl = getPluginDir() + '/conf/enable-php-upstream.conf'
|
||||
upstream_tpl_content = mw.readFile(upstream_tpl)
|
||||
for x in phpversions:
|
||||
dfile = sdir + '/web_conf/php/upstream/enable-php-' + x + '.conf'
|
||||
if not os.path.exists(dfile):
|
||||
if x == '00':
|
||||
mw.writeFile(dfile, '')
|
||||
else:
|
||||
content = contentReplace(upstream_tpl_content, x)
|
||||
mw.writeFile(dfile, content)
|
||||
|
||||
vhost_dir = mw.getServerDir() + '/web_conf/nginx/vhost'
|
||||
write_php_upstream_conf = mw.getServerDir()+'/web_conf/php/upstream/*.conf;'
|
||||
if not os.path.exists(vhost_dir):
|
||||
mw.execShell('mkdir -p ' + vhost_dir)
|
||||
|
||||
vhost_php_upstream = vhost_dir+'/0.php_upstream.conf'
|
||||
if not os.path.exists(vhost_php_upstream):
|
||||
mw.writeFile(vhost_php_upstream,'include '+write_php_upstream_conf)
|
||||
|
||||
# php-fpm status
|
||||
# for version in phpversions:
|
||||
# dfile = sdir + '/web_conf/php/status/phpfpm_status_' + version + '.conf'
|
||||
# tpl = getPluginDir() + '/conf/phpfpm_status.conf'
|
||||
# if not os.path.exists(dfile):
|
||||
# content = mw.readFile(tpl)
|
||||
# content = contentReplace(content, version)
|
||||
# mw.writeFile(dfile, content)
|
||||
|
||||
|
||||
def phpPrependFile(version):
|
||||
@@ -217,15 +238,16 @@ def phpFpmReplace(version):
|
||||
mw.writeFile(desc_php_fpm, content)
|
||||
|
||||
|
||||
def phpFpmWwwReplace(version):
|
||||
|
||||
def phpFpmPoolReplace(version, pool = 'www'):
|
||||
service_php_fpm_dir = getServerDir() + '/' + version + '/etc/php-fpm.d/'
|
||||
|
||||
if not os.path.exists(service_php_fpm_dir):
|
||||
os.mkdir(service_php_fpm_dir)
|
||||
|
||||
service_php_fpmwww = service_php_fpm_dir + '/www.conf'
|
||||
service_php_fpmwww = service_php_fpm_dir + '/'+pool+'.conf'
|
||||
if not os.path.exists(service_php_fpmwww):
|
||||
tpl_php_fpmwww = getPluginDir() + '/conf/www.conf'
|
||||
tpl_php_fpmwww = getPluginDir() + '/conf/'+pool+'.conf'
|
||||
content = mw.readFile(tpl_php_fpmwww)
|
||||
content = contentReplace(content, version)
|
||||
mw.writeFile(service_php_fpmwww, content)
|
||||
@@ -266,7 +288,8 @@ def initReplace(version):
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
phpPrependFile(version)
|
||||
phpFpmWwwReplace(version)
|
||||
phpFpmPoolReplace(version, 'www')
|
||||
phpFpmPoolReplace(version, 'backup')
|
||||
phpFpmReplace(version)
|
||||
|
||||
session_path = getServerDir() + '/tmp/session'
|
||||
@@ -539,9 +562,13 @@ def setMaxSize(version):
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def getFpmConfig(version):
|
||||
def getFpmConfig(version, pool = 'www'):
|
||||
args = getArgs()
|
||||
pool = 'www'
|
||||
if 'pool' in args:
|
||||
pool = args['pool']
|
||||
|
||||
filefpm = getServerDir() + '/' + version + '/etc/php-fpm.d/www.conf'
|
||||
filefpm = getServerDir() + '/' + version + '/etc/php-fpm.d/'+pool+'.conf'
|
||||
conf = mw.readFile(filefpm)
|
||||
data = {}
|
||||
rep = "\s*pm.max_children\s*=\s*([0-9]+)\s*"
|
||||
@@ -577,8 +604,10 @@ def setFpmConfig(version):
|
||||
min_spare_servers = args['min_spare_servers']
|
||||
max_spare_servers = args['max_spare_servers']
|
||||
pm = args['pm']
|
||||
pool = args['pool']
|
||||
|
||||
file = getServerDir() + '/' + version + '/etc/php-fpm.d/www.conf'
|
||||
|
||||
file = getServerDir() + '/' + version + '/etc/php-fpm.d/'+pool+'.conf'
|
||||
conf = mw.readFile(file)
|
||||
|
||||
rep = "\s*pm.max_children\s*=\s*([0-9]+)\s*"
|
||||
@@ -621,8 +650,10 @@ def setFpmConfig(version):
|
||||
# return True
|
||||
|
||||
|
||||
def getFpmAddress(version):
|
||||
def getFpmAddress(version, pool='www'):
|
||||
fpm_address = '/tmp/php-cgi-{}.sock'.format(version)
|
||||
if pool != 'www':
|
||||
fpm_address = '/tmp/php-cgi-{}.{}.sock'.format(version,pool)
|
||||
php_fpm_file = getFpmConfFile(version)
|
||||
try:
|
||||
content = readFile(php_fpm_file)
|
||||
@@ -653,14 +684,21 @@ def getFpmStatus(version):
|
||||
if stat == 'stop':
|
||||
return mw.returnJson(False, 'PHP[' + version + ']未启动!!!')
|
||||
|
||||
sock_file = getFpmAddress(version)
|
||||
args = getArgs()
|
||||
pool = 'www'
|
||||
if 'pool' in args:
|
||||
pool = args['pool']
|
||||
|
||||
sock_file = getFpmAddress(version, pool)
|
||||
uri = '/phpfpm_status_' + version + '?json'
|
||||
if pool != 'www':
|
||||
uri = '/phpfpm_status_' + version + '_'+pool+'?json'
|
||||
try:
|
||||
sock_data = mw.requestFcgiPHP(
|
||||
sock_file, '/phpfpm_status_' + version + '?json')
|
||||
sock_data = mw.requestFcgiPHP(sock_file, uri)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, str(e))
|
||||
|
||||
# print(data)
|
||||
|
||||
result = str(sock_data, encoding='utf-8')
|
||||
data = json.loads(result)
|
||||
fTime = time.localtime(int(data['start time']))
|
||||
@@ -976,6 +1014,10 @@ def getConfAppStart():
|
||||
pstart = mw.getServerDir() + '/php/app_start.php'
|
||||
return pstart
|
||||
|
||||
def opcacheBlacklistFile():
|
||||
op_bl = mw.getServerDir() + '/php/opcache-blacklist.txt'
|
||||
return op_bl
|
||||
|
||||
|
||||
def installPreInspection(version):
|
||||
# 仅对PHP52检查
|
||||
@@ -1047,10 +1089,14 @@ if __name__ == "__main__":
|
||||
print(getConf(version))
|
||||
elif func == 'app_start':
|
||||
print(getConfAppStart())
|
||||
elif func == 'opcache_blacklist_file':
|
||||
print(opcacheBlacklistFile())
|
||||
elif func == 'get_php_conf':
|
||||
print(getPhpConf(version))
|
||||
elif func == 'get_fpm_conf_file':
|
||||
print(getFpmConfFile(version))
|
||||
elif func == 'get_fpm_file':
|
||||
print(getFpmFile(version))
|
||||
elif func == 'submit_php_conf':
|
||||
print(submitPhpConf(version))
|
||||
elif func == 'get_limit_conf':
|
||||
|
||||
+174
-39
@@ -123,34 +123,31 @@ function submitConf(version) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//php上传限制
|
||||
function phpUploadLimitReq(version){
|
||||
phpPost('get_limit_conf', version, '', function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
phpUploadLimit(version,rdata['max']);
|
||||
});
|
||||
}
|
||||
|
||||
function phpUploadLimit(version,max){
|
||||
var LimitCon = '<p class="conf_p"><input class="phpUploadLimit bt-input-text mr5" type="number" value="'+
|
||||
max+'" name="max">MB<button class="btn btn-success btn-sm" onclick="setPHPMaxSize(\''+
|
||||
version+'\')" style="margin-left:20px">保存</button></p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
}
|
||||
|
||||
|
||||
//php超时限制
|
||||
function phpTimeLimitReq(version){
|
||||
function phpCommonFunc(version){
|
||||
phpPost('get_limit_conf', version, '', function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
phpTimeLimit(version,rdata['maxTime']);
|
||||
});
|
||||
}
|
||||
var con = '<p class="conf_p">\
|
||||
<span>超时限制</span>\
|
||||
<input class="phpTimeLimit bt-input-text mr5" type="number" value="' + rdata['maxTime'] + '">, 秒\
|
||||
<button class="btn btn-success btn-sm" onclick="setPHPMaxTime(\'' + version + '\')" style="margin-left:20px">保存</button>\
|
||||
</p>';
|
||||
|
||||
function phpTimeLimit(version, max) {
|
||||
var LimitCon = '<p class="conf_p"><input class="phpTimeLimit bt-input-text mr5" type="number" value="' + max + '">秒<button class="btn btn-success btn-sm" onclick="setPHPMaxTime(\'' + version + '\')" style="margin-left:20px">保存</button></p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
con += '<p class="conf_p">\
|
||||
<span>上传限制</span>\
|
||||
<input class="phpUploadLimit bt-input-text mr5" type="number" value="' + rdata['max']+'" name="max">,MB\
|
||||
<button class="btn btn-success btn-sm" onclick="setPHPMaxSize(\''+ version+'\')" style="margin-left:20px">保存</button>\
|
||||
</p>';
|
||||
|
||||
con += '<hr/><p class="conf_p" style="text-align:center;">\
|
||||
<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button> \
|
||||
<button class="btn btn-default btn-sm" onclick="phpPreload(\'' + version + '\')">预加载脚本</button>\
|
||||
<button class="btn btn-default btn-sm" onclick="phpOpcacheBlacklist(\'' + version + '\')">OPCACHE黑名单</button>\
|
||||
<button class="btn btn-default btn-sm" onclick="phpFpmRoot(\'' + version + '\')">PHP-FPM(global)</button>\
|
||||
</p>';
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
//设置超时限制
|
||||
@@ -158,7 +155,10 @@ function setPHPMaxTime(version) {
|
||||
var max = $(".phpTimeLimit").val();
|
||||
phpPost('set_max_time',version,{'time':max},function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
showMsg(rdata.msg,function(){
|
||||
phpCommonFunc(version);
|
||||
},{ icon: rdata.status ? 1 : 2 });
|
||||
|
||||
});
|
||||
}
|
||||
//设置PHP上传限制
|
||||
@@ -176,9 +176,108 @@ function setPHPMaxSize(version) {
|
||||
});
|
||||
}
|
||||
|
||||
function phpPreload(version){
|
||||
phpPost('app_start',version,{},function(data){
|
||||
onlineEditFile(0, data['data']);
|
||||
});
|
||||
}
|
||||
|
||||
function getFpmConfig(version){
|
||||
phpPost('get_fpm_conf', version, {}, function(data){
|
||||
function phpOpcacheBlacklist(version){
|
||||
phpPost('opcache_blacklist_file',version,{},function(data){
|
||||
onlineEditFile(0, data['data']);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function phpFpmRoot(version){
|
||||
phpPost('get_fpm_file',version,{},function(data){
|
||||
onlineEditFile(0, data['data']);
|
||||
});
|
||||
}
|
||||
|
||||
function phpFpmConfigFile(version, func, pool = 'www'){
|
||||
var _name = 'php';
|
||||
if ( typeof(version) == 'undefined' ){
|
||||
version = '';
|
||||
}
|
||||
|
||||
var func_name = 'conf';
|
||||
if ( typeof(func) != 'undefined' ){
|
||||
func_name = func;
|
||||
}
|
||||
|
||||
var poolSelect = "<select class='bt-input-text' name='pool' style='width:100px;'>\
|
||||
<option value='www' " + (pool == 'www' ? 'selected' : '') + ">www</option>\
|
||||
<option value='backup' " + (pool == 'backup' ? 'selected' : '') + ">backup</option>\
|
||||
</select>";
|
||||
|
||||
var con = '<p style="color: #666; margin-bottom: 7px">提示:Ctrl+F 搜索关键字,Ctrl+G 查找下一个,Ctrl+S 保存,Ctrl+Shift+R 查找替换!</p>\
|
||||
<textarea class="bt-input-text" style="height: 320px; line-height:18px;" id="textBody"></textarea>\
|
||||
<button id="onlineEditFileBtn" class="btn btn-success btn-sm" style="margin-top:10px;">保存</button>\
|
||||
'+poolSelect+'\
|
||||
<ul class="help-info-text c7 ptb15">\
|
||||
<li>此处为'+ _name + version +'应用池配置文件,若您不了解配置规则,请勿随意修改。</li>\
|
||||
</ul>';
|
||||
|
||||
|
||||
var loadT = layer.msg('配置文件路径获取中...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
|
||||
var request_data = {name:_name, func:func_name,version:version};
|
||||
request_data['args'] = JSON.stringify({'pool':pool});
|
||||
|
||||
$.post('/plugins/run', request_data, function (data) {
|
||||
layer.close(loadT);
|
||||
|
||||
try{
|
||||
var jdata = $.parseJSON(data.data);
|
||||
if (!jdata['status']){
|
||||
layer.msg(jdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
}catch(err){/*console.log(err);*/}
|
||||
|
||||
$(".soft-man-con").html(con);
|
||||
|
||||
var loadT2 = layer.msg('文件内容获取中...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
var fileName = data.data;
|
||||
$.post('/files/get_body', 'path=' + fileName, function(rdata) {
|
||||
layer.close(loadT2);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
$("#textBody").empty().text(rdata.data.data);
|
||||
$(".CodeMirror").remove();
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("textBody"), {
|
||||
extraKeys: {
|
||||
"Ctrl-Space": "autocomplete",
|
||||
"Ctrl-F": "findPersistent",
|
||||
"Ctrl-H": "replaceAll",
|
||||
"Ctrl-S": function() {
|
||||
$("#textBody").text(editor.getValue());
|
||||
pluginConfigSave(fileName);
|
||||
}
|
||||
},
|
||||
lineNumbers: true,
|
||||
matchBrackets:true,
|
||||
});
|
||||
editor.focus();
|
||||
$(".CodeMirror-scroll").css({"height":"300px","margin":0,"padding":0});
|
||||
$("#onlineEditFileBtn").click(function(){
|
||||
$("#textBody").text(editor.getValue());
|
||||
pluginConfigSave(fileName);
|
||||
});
|
||||
},'json');
|
||||
|
||||
$('select[name="pool"]').change(function(){
|
||||
var pool = $(this).val();
|
||||
phpFpmConfigFile(version, func, pool);
|
||||
});
|
||||
},'json');
|
||||
}
|
||||
|
||||
function getFpmConfig(version, pool = 'www'){
|
||||
phpPost('get_fpm_conf', version, {'pool':pool}, function(data){
|
||||
// console.log(data);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
@@ -188,14 +287,19 @@ function getFpmConfig(version){
|
||||
"<option value='3' " + (rdata.max_children == 100 ? 'selected' : '') + ">100并发</option>" +
|
||||
"<option value='4' " + (rdata.max_children == 200 ? 'selected' : '') + ">200并发</option>" +
|
||||
"<option value='5' " + (rdata.max_children == 300 ? 'selected' : '') + ">300并发</option>" +
|
||||
"<option value='5' " + (rdata.max_children == 500 ? 'selected' : '') + ">500并发</option>" +
|
||||
"<option value='6' " + (rdata.max_children == 2000 ? 'selected' : '') + ">2000并发</option>";
|
||||
"<option value='6' " + (rdata.max_children == 500 ? 'selected' : '') + ">500并发</option>" +
|
||||
"<option value='7' " + (rdata.max_children == 2000 ? 'selected' : '') + ">2000并发</option>";
|
||||
var pms = [{ 'name': 'static', 'title': '静态' }, { 'name': 'dynamic', 'title': '动态' },{ 'name': 'ondemand', 'title': '按需' }];
|
||||
var pmList = '';
|
||||
for (var i = 0; i < pms.length; i++) {
|
||||
pmList += '<option value="' + pms[i].name + '" ' + ((pms[i].name == rdata.pm) ? 'selected' : '') + '>' + pms[i].title + '</option>';
|
||||
}
|
||||
|
||||
var poolHtml = "<option value='www' " + (pool == 'www' ? 'selected' : '') + ">www</option>" +
|
||||
"<option value='backup' " + (pool == 'backup' ? 'selected' : '') + ">backup</option>";
|
||||
|
||||
var body = "<div class='bingfa'>" +
|
||||
"<p class='line'><span class='span_tit'>应用池[pool]:</span><select class='bt-input-text' name='pool' style='width:100px;'>" + poolHtml + "</select></p>" +
|
||||
"<p class='line'><span class='span_tit'>并发方案:</span><select class='bt-input-text' name='limit' style='width:100px;'>" + limitList + "</select></p>" +
|
||||
"<p class='line'><span class='span_tit'>运行模式:</span><select class='bt-input-text' name='pm' style='width:100px;'>" + pmList + "</select><span class='c9'>*PHP-FPM运行模式</span></p>" +
|
||||
"<p class='line'><span class='span_tit'>max_children:</span><input class='bt-input-text' type='number' name='max_children' value='" + rdata.max_children + "' /><span class='c9'>*允许创建的最大子进程数</span></p>" +
|
||||
@@ -248,6 +352,7 @@ function getFpmConfig(version){
|
||||
start_servers = 35;
|
||||
min_spare_servers = 35;
|
||||
max_spare_servers = 250;
|
||||
break;
|
||||
case '7':
|
||||
max_children = 2000;
|
||||
start_servers = 40;
|
||||
@@ -261,11 +366,17 @@ function getFpmConfig(version){
|
||||
$("input[name='min_spare_servers']").val(min_spare_servers);
|
||||
$("input[name='max_spare_servers']").val(max_spare_servers);
|
||||
});
|
||||
|
||||
$('select[name="pool"]').change(function(){
|
||||
var pool = $(this).val();
|
||||
getFpmConfig(version, pool);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setFpmConfig(version){
|
||||
var max_children = Number($("input[name='max_children']").val());
|
||||
var pool = $("select[name='pool']").val();
|
||||
var start_servers = Number($("input[name='start_servers']").val());
|
||||
var min_spare_servers = Number($("input[name='min_spare_servers']").val());
|
||||
var max_spare_servers = Number($("input[name='max_spare_servers']").val());
|
||||
@@ -303,6 +414,7 @@ function setFpmConfig(version){
|
||||
min_spare_servers:min_spare_servers,
|
||||
max_spare_servers:max_spare_servers,
|
||||
pm:pm,
|
||||
pool:pool,
|
||||
};
|
||||
phpPost('set_fpm_conf', version, data, function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
@@ -311,14 +423,15 @@ function setFpmConfig(version){
|
||||
}
|
||||
|
||||
|
||||
function getFpmStatus(version){
|
||||
phpPost('get_fpm_status', version, '', function(ret_data){
|
||||
function getFpmStatus(version, pool = 'www'){
|
||||
phpPost('get_fpm_status', version, {'pool':pool}, function(ret_data){
|
||||
var tmp_data = $.parseJSON(ret_data.data);
|
||||
if(!tmp_data.status){
|
||||
layer.msg(tmp_data.msg, { icon: tmp_data.status ? 1 : 2 });
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = tmp_data.data;
|
||||
var php_fpm_status = '动态';
|
||||
if (rdata['process manager'] == 'dynamic'){
|
||||
php_fpm_status = '动态';
|
||||
@@ -328,8 +441,23 @@ function getFpmStatus(version){
|
||||
php_fpm_status = '按需';
|
||||
}
|
||||
|
||||
var rdata = tmp_data.data;
|
||||
var con = "<div style='height:420px;overflow:hidden;'><table class='table table-hover table-bordered GetPHPStatus' style='margin:0;padding:0'>\
|
||||
var select_pool_www = '';
|
||||
var select_pool_backup = '';
|
||||
if (pool == 'www'){
|
||||
select_pool_www = 'selected';
|
||||
}
|
||||
if (pool == 'backup'){
|
||||
select_pool_backup = 'selected';
|
||||
}
|
||||
|
||||
var con = "<div style='height:430px;'>\
|
||||
<p style='text-align:center;padding-bottom:10px;'>\
|
||||
<select class='bt-input-text' name='pool' style='width:200px;'>\
|
||||
<option value='www' "+select_pool_www+">www</option>\
|
||||
<option value='backup' "+select_pool_backup+">backup</option>\
|
||||
</select>\
|
||||
</p>\
|
||||
<table class='table table-hover table-bordered get_fpm_status' style='margin:0;padding:0'>\
|
||||
<tr><th>应用池(pool)</th><td>" + rdata.pool + "</td></tr>\
|
||||
<tr><th>进程管理方式(process manager)</th><td>" + php_fpm_status + "</td></tr>\
|
||||
<tr><th>启动日期(start time)</th><td>" + rdata['start time'] + "</td></tr>\
|
||||
@@ -343,9 +471,16 @@ function getFpmStatus(version){
|
||||
<tr><th>最大活跃进程数量(max active processes)</th><td>" + rdata['max active processes'] + "</td></tr>\
|
||||
<tr><th>到达进程上限次数(max children reached)</th><td>" + rdata['max children reached'] + "</td></tr>\
|
||||
<tr><th>慢请求数量(slow requests)</th><td>" + rdata['slow requests'] + "</td></tr>\
|
||||
</table></div>";
|
||||
</table>\
|
||||
</div>";
|
||||
$(".soft-man-con").html(con);
|
||||
$(".GetPHPStatus td,.GetPHPStatus th").css("padding", "7px");
|
||||
$(".get_fpm_status td,.get_fpm_status th").css("padding", "7px");
|
||||
|
||||
|
||||
$('select[name="pool"]').change(function(){
|
||||
var pool = $(this).val();
|
||||
getFpmStatus(version, pool);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -559,10 +694,10 @@ function setDisableFunc(version, act, fs) {
|
||||
|
||||
|
||||
//phpinfo
|
||||
function getPhpinfo(version) {
|
||||
var con = '<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button>';
|
||||
$(".soft-man-con").html(con);
|
||||
}
|
||||
// function getPhpinfo(version) {
|
||||
// var con = '<button class="btn btn-default btn-sm" onclick="getPHPInfo(\'' + version + '\')">查看phpinfo()</button>';
|
||||
// $(".soft-man-con").html(con);
|
||||
// }
|
||||
|
||||
//获取PHPInfo
|
||||
function getPHPInfo_old(version) {
|
||||
|
||||
@@ -18,7 +18,7 @@ LOCAL_ADDR=common
|
||||
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
LOCAL_ADDR=cn
|
||||
HTTP_PREFIX="https://ghproxy.com/"
|
||||
HTTP_PREFIX="https://mirror.ghproxy.com/"
|
||||
fi
|
||||
|
||||
if [ ! -d ${SERVER_ROOT}/icu ];then
|
||||
@@ -27,7 +27,7 @@ if [ ! -d ${SERVER_ROOT}/icu ];then
|
||||
|
||||
if [ "$LOCAL_ADDR" == 'cn' ];then
|
||||
if [ ! -f ${SOURCE_ROOT}/icu4c-52_2-src.tgz ];then
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/icu4c-52_2-src.tgz https://dl.midoks.me/lib/icu4c-52_2-src.tgz -T 20
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/icu4c-52_2-src.tgz https://dl.midoks.icu/lib/icu4c-52_2-src.tgz -T 20
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/php/lib && bash libedit.sh
|
||||
|
||||
# echo $rootPath
|
||||
|
||||
SERVER_ROOT=$rootPath/lib
|
||||
SOURCE_ROOT=$rootPath/source/lib
|
||||
|
||||
|
||||
# LOCAL_ADDR=common
|
||||
# cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
# if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
# LOCAL_ADDR=cn
|
||||
# fi
|
||||
|
||||
if [ ! -d ${SERVER_ROOT}/libedit ];then
|
||||
cd $SOURCE_ROOT
|
||||
|
||||
VERSION="20230828-3.1"
|
||||
|
||||
if [ ! -f ${SOURCE_ROOT}/libedit-${VERSION}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/libedit-${VERSION}.tar.gz https://thrysoee.dk/editline/libedit-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${SOURCE_ROOT}/libedit-${VERSION} ];then
|
||||
cd $SOURCE_ROOT && tar -zxvf libedit-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
cd ${SOURCE_ROOT}/libedit-${VERSION}
|
||||
|
||||
./configure --prefix=${SERVER_ROOT}/libedit && make && make install
|
||||
|
||||
if [ -d $SOURCE_ROOT/libedit-${VERSION} ];then
|
||||
cd $SOURCE_ROOT && rm -rf $SOURCE_ROOT/libedit-${VERSION}
|
||||
fi
|
||||
fi
|
||||
@@ -8,6 +8,8 @@ rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/php/lib && bash libiconv.sh
|
||||
|
||||
# echo $rootPath
|
||||
|
||||
SERVER_ROOT=$rootPath/lib
|
||||
@@ -18,7 +20,7 @@ LOCAL_ADDR=common
|
||||
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
LOCAL_ADDR=cn
|
||||
HTTP_PREFIX="https://ghproxy.com/"
|
||||
HTTP_PREFIX="https://mirror.ghproxy.com/"
|
||||
fi
|
||||
|
||||
if [ ! -d ${SERVER_ROOT}/libiconv ];then
|
||||
@@ -26,12 +28,12 @@ if [ ! -d ${SERVER_ROOT}/libiconv ];then
|
||||
|
||||
if [ "$LOCAL_ADDR" == 'cn' ];then
|
||||
if [ ! -f ${SOURCE_ROOT}/libiconv-1.15.tar.gz ];then
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/libiconv-1.15.tar.gz https://dl.midoks.me/lib/libiconv-1.15.tar.gz -T 20
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/libiconv-1.15.tar.gz https://dl.midoks.icu/lib/libiconv-1.15.tar.gz -T 20
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f ${SOURCE_ROOT}/libiconv-1.15.tar.gz ];then
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/libiconv-1.15.tar.gz https:/github.com/midoks/mdserver-web/releases/download/init/libiconv-1.15.tar.gz -T 5
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/libiconv-1.15.tar.gz https://github.com/midoks/mdserver-web/releases/download/init/libiconv-1.15.tar.gz -T 5
|
||||
fi
|
||||
|
||||
if [ ! -d ${SOURCE_ROOT}/libiconv-1.15 ];then
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user