mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 02:09:26 +08:00
Compare commits
467
Commits
midoks-patch-1
...
0.16.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6f7334f5e | ||
|
|
27b77f8570 | ||
|
|
3d888961bc | ||
|
|
5edc4fb713 | ||
|
|
214954b298 | ||
|
|
13b0b2752e | ||
|
|
a2918e651f | ||
|
|
55dd1d7d5a | ||
|
|
df50eceeed | ||
|
|
e1de6dd514 | ||
|
|
08328bbb86 | ||
|
|
6abc5b365b | ||
|
|
6cc1279729 | ||
|
|
aeafaa2832 | ||
|
|
e74a511763 | ||
|
|
f86159eeac | ||
|
|
8097164475 | ||
|
|
4ebb44e4c0 | ||
|
|
584f93461a | ||
|
|
e21f0a53e5 | ||
|
|
1d31a0eae0 | ||
|
|
ded33ed6b4 | ||
|
|
b703758d0e | ||
|
|
33493ac03c | ||
|
|
74e63c5bbd | ||
|
|
f2d34e5551 | ||
|
|
89c529f44c | ||
|
|
56b728601b | ||
|
|
bf1d2daeaa | ||
|
|
cac45b3732 | ||
|
|
ee498b7094 | ||
|
|
385113fe4d | ||
|
|
5dbfc5bd51 | ||
|
|
b76e0f606a | ||
|
|
047702f26d | ||
|
|
eb219caada | ||
|
|
78b2046f19 | ||
|
|
5fe85730e6 | ||
|
|
adb72ef33b | ||
|
|
d9c8a46031 | ||
|
|
24f520bdc9 | ||
|
|
7492756997 | ||
|
|
616af16635 | ||
|
|
916d39e205 | ||
|
|
017958b6b0 | ||
|
|
d403c4c4ad | ||
|
|
9f1481db07 | ||
|
|
47e0ec5fae | ||
|
|
a2377d960e | ||
|
|
60f1ce2575 | ||
|
|
0e368f7157 | ||
|
|
3cf5c5b190 | ||
|
|
4ed07beca3 | ||
|
|
cee9619883 | ||
|
|
5db4a96fc9 | ||
|
|
2e6b7bf5cd | ||
|
|
f404caa763 | ||
|
|
062a518492 | ||
|
|
0310cab3ae | ||
|
|
4a0b8df57f | ||
|
|
63e427b488 | ||
|
|
c688c692f9 | ||
|
|
c9f074b319 | ||
|
|
38b4042c5a | ||
|
|
bf32390f0e | ||
|
|
91a9be4cc0 | ||
|
|
be5f438f84 | ||
|
|
2705fd7ba2 | ||
|
|
4de7e72f0a | ||
|
|
da668c723c | ||
|
|
20624217bf | ||
|
|
2403af08c6 | ||
|
|
2350b73896 | ||
|
|
464fa9cc0f | ||
|
|
9a79f0b728 | ||
|
|
52cfff7038 | ||
|
|
8d42f8137c | ||
|
|
41fb9759a3 | ||
|
|
7d3833b2ef | ||
|
|
0badb053e0 | ||
|
|
80b9e7cbf7 | ||
|
|
94df21192f | ||
|
|
346d687368 | ||
|
|
46ec655365 | ||
|
|
e852020c38 | ||
|
|
d06e83676b | ||
|
|
7a511f8217 | ||
|
|
8c5021b9dc | ||
|
|
b7d50540ac | ||
|
|
2a95fcc59a | ||
|
|
2b04cb3947 | ||
|
|
7f0ad25342 | ||
|
|
09f7e6f5b5 | ||
|
|
17a7ffa0b4 | ||
|
|
ba6dcabd04 | ||
|
|
0ff5c170d3 | ||
|
|
b78e020993 | ||
|
|
9586eeda07 | ||
|
|
ea462aa51d | ||
|
|
aaac8b5239 | ||
|
|
2b86c375b0 | ||
|
|
600e2688f9 | ||
|
|
3537bc520f | ||
|
|
9ffdffadd6 | ||
|
|
3942f2fbf5 | ||
|
|
8ff2f217b3 | ||
|
|
480bd154c6 | ||
|
|
5eb3ed4524 | ||
|
|
50e78ae6f6 | ||
|
|
0ec9b31c2f | ||
|
|
191b54821e | ||
|
|
c2188a2c7e | ||
|
|
d23b64a92c | ||
|
|
3ae97e1c75 | ||
|
|
f0e7361436 | ||
|
|
5f85d41352 | ||
|
|
6fc8803446 | ||
|
|
b3120f3435 | ||
|
|
f9f1b1a113 | ||
|
|
2645297cee | ||
|
|
7f171f5986 | ||
|
|
c3b3e3b01c | ||
|
|
3824b394ad | ||
|
|
270660fb53 | ||
|
|
c4171a9506 | ||
|
|
222943e312 | ||
|
|
92f8a4e949 | ||
|
|
eff1f55a21 | ||
|
|
0b54da9747 | ||
|
|
0bec57937f | ||
|
|
6c64f8ee5e | ||
|
|
b65ad9de80 | ||
|
|
07be263d81 | ||
|
|
bf9cb52fec | ||
|
|
f7135a6ded | ||
|
|
7b98dde1aa | ||
|
|
b51f3fdd68 | ||
|
|
e02c52df49 | ||
|
|
730bc7171b | ||
|
|
c065eabb48 | ||
|
|
1ad1e3326d | ||
|
|
d4346a51bc | ||
|
|
8260cc5f4a | ||
|
|
021b299b7d | ||
|
|
a767e7e578 | ||
|
|
57da2aef27 | ||
|
|
5b43438cb1 | ||
|
|
7ab88a1bea | ||
|
|
31291a13c7 | ||
|
|
43d0b75d98 | ||
|
|
5490197b8a | ||
|
|
8f03574bce | ||
|
|
94487e0b3d | ||
|
|
45cc0159af | ||
|
|
504a618eb1 | ||
|
|
5e25849464 | ||
|
|
9bb59a1559 | ||
|
|
6883316efc | ||
|
|
de7ea503e5 | ||
|
|
4fcad95c79 | ||
|
|
75dc1bd70d | ||
|
|
44758e3e55 | ||
|
|
140624e62f | ||
|
|
65f90b473c | ||
|
|
0a089fcedf | ||
|
|
010624023f | ||
|
|
9399a14a92 | ||
|
|
2875b40e62 | ||
|
|
78c3686091 | ||
|
|
d7447197ec | ||
|
|
9b64ec5c6d | ||
|
|
dad51dad77 | ||
|
|
d89751f733 | ||
|
|
1dc486711b | ||
|
|
60a2f85f02 | ||
|
|
830d387ddb | ||
|
|
ae225780f9 | ||
|
|
e0a0a82d68 | ||
|
|
0b23c5f330 | ||
|
|
fb01c68f5a | ||
|
|
5755121fa5 | ||
|
|
3d1c613864 | ||
|
|
9590c4bb7d | ||
|
|
32c0bdf093 | ||
|
|
4f5424a746 | ||
|
|
81ba3bce9d | ||
|
|
22b3a1bc42 | ||
|
|
df9a34aa31 | ||
|
|
2400213533 | ||
|
|
465eb118a9 | ||
|
|
7e81aa109f | ||
|
|
b23b41c7a7 | ||
|
|
724a77ae81 | ||
|
|
3499ed74ee | ||
|
|
52997049e2 | ||
|
|
a96a36b087 | ||
|
|
5926f688a6 | ||
|
|
1b754f5c43 | ||
|
|
c4c20de520 | ||
|
|
616895785f | ||
|
|
29d6c8740a | ||
|
|
64aa9a9d01 | ||
|
|
ffbe8ba6d4 | ||
|
|
ed39c5d243 | ||
|
|
4bb2115040 | ||
|
|
6b0cf8129d | ||
|
|
ab7bbe942b | ||
|
|
a8a3fa1754 | ||
|
|
e343f33b47 | ||
|
|
f55367ab5e | ||
|
|
050bd158c1 | ||
|
|
d35a680fec | ||
|
|
4a4ddeaabe | ||
|
|
0e74b0cccf | ||
|
|
806e29577e | ||
|
|
75923f5363 | ||
|
|
834196883c | ||
|
|
341826c641 | ||
|
|
1bd1ce5b31 | ||
|
|
eef504e172 | ||
|
|
a0434ef7d6 | ||
|
|
893bbb8ea7 | ||
|
|
92e3e277cc | ||
|
|
58e48bf013 | ||
|
|
644760d5b0 | ||
|
|
d6ccd81def | ||
|
|
d32e71b2d9 | ||
|
|
ae9e56c56c | ||
|
|
d7c0285bbf | ||
|
|
5cc0957ffd | ||
|
|
1e44d64ace | ||
|
|
907851c413 | ||
|
|
0faafc654b | ||
|
|
4cdc399b77 | ||
|
|
a085e5b1ea | ||
|
|
bdbf4dddc6 | ||
|
|
5cee2f2b6d | ||
|
|
b9652a7940 | ||
|
|
dc7ddbcf6b | ||
|
|
87a8bfe59e | ||
|
|
cfdd5e5f73 | ||
|
|
e2acf621ca | ||
|
|
0711a922d2 | ||
|
|
055ea0ca0c | ||
|
|
772d9c50f6 | ||
|
|
0809b51725 | ||
|
|
4e901e6750 | ||
|
|
5c62397234 | ||
|
|
63021a3eab | ||
|
|
e617b07790 | ||
|
|
960eeed4ce | ||
|
|
ccf020bf6b | ||
|
|
c4918d8cd7 | ||
|
|
b3d3ceb058 | ||
|
|
17a301c745 | ||
|
|
1bfa2ae3ab | ||
|
|
9be5dcfd8a | ||
|
|
d9e8f1d4ad | ||
|
|
d85f544773 | ||
|
|
577ac1f8ee | ||
|
|
ed117a1b40 | ||
|
|
9d54f0b6cd | ||
|
|
707eced7bf | ||
|
|
dd96833c09 | ||
|
|
4c61143918 | ||
|
|
8cb8a1bc70 | ||
|
|
c55c3c23d1 | ||
|
|
04e6b9367a | ||
|
|
f4f25b8ab3 | ||
|
|
a0b0b9b294 | ||
|
|
699ad0b8ca | ||
|
|
a45eaf1c3b | ||
|
|
0f51a6d481 | ||
|
|
142d5f7ed8 | ||
|
|
72bd528a24 | ||
|
|
af2dc0585b | ||
|
|
0a0021b09d | ||
|
|
c5811d4494 | ||
|
|
e329892cd2 | ||
|
|
368324a813 | ||
|
|
6a7cc4f054 | ||
|
|
1d3cba599c | ||
|
|
7d902a50eb | ||
|
|
25feb7c0ad | ||
|
|
e15d1716e5 | ||
|
|
ee16e0142e | ||
|
|
68e06aa8f5 | ||
|
|
d88003ca52 | ||
|
|
8757c646f6 | ||
|
|
c3e9d8aa4c | ||
|
|
7e3983f612 | ||
|
|
a4e43b492d | ||
|
|
1f57517ea7 | ||
|
|
b2fe35771d | ||
|
|
00ce3e00d3 | ||
|
|
c7c28731a4 | ||
|
|
3305eab770 | ||
|
|
b595359f38 | ||
|
|
5dc06b90ca | ||
|
|
651fa7672c | ||
|
|
7a0db5abef | ||
|
|
d21a5dfacc | ||
|
|
0c49749b63 | ||
|
|
11bb65a739 | ||
|
|
ce44353cbf | ||
|
|
2e5c5ef5b9 | ||
|
|
d1b687476b | ||
|
|
a46eabce10 | ||
|
|
08e378a3e4 | ||
|
|
c80ce63a4b | ||
|
|
72bb94df42 | ||
|
|
e9b7aca47a | ||
|
|
f25d4f5a4f | ||
|
|
59fcef76fe | ||
|
|
4ab6ccbcbb | ||
|
|
fd457df3c8 | ||
|
|
147bec02a5 | ||
|
|
34c126fbb7 | ||
|
|
4d21c920a8 | ||
|
|
2d810fe7ab | ||
|
|
fb5260b9a5 | ||
|
|
32b5542534 | ||
|
|
c665486122 | ||
|
|
d3b885b1f9 | ||
|
|
e476e36420 | ||
|
|
587503dc67 | ||
|
|
cecfe9470f | ||
|
|
abc37acacc | ||
|
|
e0197fef3a | ||
|
|
04c4e7ddc8 | ||
|
|
6fb3e29a91 | ||
|
|
66fe66b479 | ||
|
|
4329d2470c | ||
|
|
0cd4527234 | ||
|
|
bdba9149f2 | ||
|
|
e05f7a9c3f | ||
|
|
bddd81c94d | ||
|
|
f470392382 | ||
|
|
895a250f06 | ||
|
|
dd579b7e5c | ||
|
|
cd0653d092 | ||
|
|
f2bc938ade | ||
|
|
dc694cae35 | ||
|
|
0b98e40fec | ||
|
|
10c40800ff | ||
|
|
424d9fa799 | ||
|
|
1350fc7a4a | ||
|
|
d678ade262 | ||
|
|
0b0b0bc9c5 | ||
|
|
f3eee40e1e | ||
|
|
8e0327a084 | ||
|
|
0a4b5529b9 | ||
|
|
a8c17e1f3c | ||
|
|
4d242dd322 | ||
|
|
272a08f4eb | ||
|
|
453009da40 | ||
|
|
9c8880e1bb | ||
|
|
4f716830ef | ||
|
|
b4d799f8bd | ||
|
|
e9fc7d5344 | ||
|
|
585d3d1839 | ||
|
|
3278dd23b5 | ||
|
|
5b406eaeb1 | ||
|
|
0a354f649d | ||
|
|
176dd4a5b8 | ||
|
|
4bb9cc2d67 | ||
|
|
f1edb26540 | ||
|
|
0692537cbd | ||
|
|
0710ca590a | ||
|
|
c19b12e8df | ||
|
|
99eeee19ef | ||
|
|
fff3707031 | ||
|
|
0d0cb4add1 | ||
|
|
5ed37443da | ||
|
|
25b836e6f5 | ||
|
|
4ca5c8e1a8 | ||
|
|
b522287a87 | ||
|
|
05cec7e0bf | ||
|
|
b731868e06 | ||
|
|
9c4ceca41f | ||
|
|
22d266e710 | ||
|
|
d35bf118ff | ||
|
|
1adb2f751c | ||
|
|
54e743037e | ||
|
|
6debb93fd1 | ||
|
|
7229f9c569 | ||
|
|
844dcbda00 | ||
|
|
af2b45a6f4 | ||
|
|
d848d41a71 | ||
|
|
826ebfb2e5 | ||
|
|
e1807c1585 | ||
|
|
6e9d5a19c0 | ||
|
|
6eadad5db4 | ||
|
|
2b2fc08120 | ||
|
|
175061884d | ||
|
|
cc3fa8ac95 | ||
|
|
c9d736e338 | ||
|
|
e4437e42f3 | ||
|
|
644fc2c81f | ||
|
|
d2314bf26f | ||
|
|
c17314b634 | ||
|
|
92a4b28fbf | ||
|
|
733e4e81be | ||
|
|
8b99ae2515 | ||
|
|
2a72422402 | ||
|
|
145a259ef9 | ||
|
|
a34b7719c8 | ||
|
|
4d98455c35 | ||
|
|
c0c9def1fb | ||
|
|
02d8416466 | ||
|
|
d505740269 | ||
|
|
b1f6314df7 | ||
|
|
533653fe47 | ||
|
|
dff4551fb1 | ||
|
|
79723149a5 | ||
|
|
76da8a2ad5 | ||
|
|
645538e633 | ||
|
|
1a1b4e9f3a | ||
|
|
3afde01f93 | ||
|
|
a14db23971 | ||
|
|
316f06911b | ||
|
|
698d049314 | ||
|
|
d397d74f73 | ||
|
|
8a7447a4ee | ||
|
|
98414db41d | ||
|
|
7024185b59 | ||
|
|
495f16f2cf | ||
|
|
62444b7b6d | ||
|
|
50b11457f7 | ||
|
|
393cbc3974 | ||
|
|
ce3bfc2ebd | ||
|
|
b68e8f3650 | ||
|
|
08c83edeb9 | ||
|
|
c114e9aca8 | ||
|
|
c5123268d0 | ||
|
|
54bbc3ff57 | ||
|
|
4658b991a9 | ||
|
|
52145e710b | ||
|
|
4acc48ded2 | ||
|
|
0d858f87ea | ||
|
|
f37f08a9f5 | ||
|
|
0b5fc1de55 | ||
|
|
8748777101 | ||
|
|
48ed0b8034 | ||
|
|
41c9f6b7b6 | ||
|
|
c47336b65f | ||
|
|
24d7204ccc | ||
|
|
8c00fb8859 | ||
|
|
c573b28f16 | ||
|
|
afad548cf9 | ||
|
|
2605849de2 | ||
|
|
77598fa8a7 | ||
|
|
b175ab735d | ||
|
|
54ed17ab8f | ||
|
|
cadf72ea69 | ||
|
|
dadb737f88 | ||
|
|
fef2acf683 | ||
|
|
4b6dbf8887 | ||
|
|
06c99e1cc1 | ||
|
|
afb3e920f8 | ||
|
|
2c346c9850 | ||
|
|
5b6c5be288 | ||
|
|
63bd806222 | ||
|
|
afe3848b71 | ||
|
|
cd361ec7ec | ||
|
|
eb399fe799 | ||
|
|
53e588b6fc |
+2
-3
@@ -163,7 +163,6 @@ plugins/l2tp
|
||||
plugins/openlitespeed
|
||||
plugins/tamper_proof
|
||||
plugins/cryptocurrency_trade
|
||||
plugins/gdrive
|
||||
plugins/mtproxy
|
||||
plugins/zimg
|
||||
plugins/bk_demo
|
||||
@@ -177,5 +176,5 @@ debug.out
|
||||
|
||||
|
||||
|
||||
mdioks.session-journal
|
||||
*.session
|
||||
mdioks.session-journal
|
||||
*.session
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
|
||||
复制了后台管理界面,按照自己想要的方式写了一版。
|
||||
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
@@ -80,6 +80,7 @@ PHP[72-82]支持phpMyAdmin[5.2.0]
|
||||
# 特别赞助
|
||||
|
||||
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.pw/)
|
||||
- [鲲鹏vpn,免费试用,解锁流媒体和chatGPT](https://down.xbjc888.top/?agent_code=github)
|
||||
|
||||
# AD - VPS推荐 - 🙏
|
||||
|
||||
@@ -99,15 +100,14 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.15.2
|
||||
### 版本更新 0.16.1
|
||||
|
||||
* OpenResty升级到1.21.4.2
|
||||
* 计划任务自动脚本运行时间
|
||||
* rsyncd添加优化
|
||||
* 使用mariadb二进制导入备份文件
|
||||
* docker插件-镜像导入导出功能
|
||||
* 网站设置反向代理升级功能
|
||||
* 优化初始化安装SSH端口识别
|
||||
* 给防盗链增加禁止空来源。
|
||||
* OpenResty安装兼容。
|
||||
* Debian10安装优化。
|
||||
* 安装时默认监控开启。
|
||||
* MySQL/MYSQL-YUM/MySQL-APT添加重置master功能。
|
||||
* 支持华为欧拉系统。
|
||||
|
||||
### JSDelivr安装地址
|
||||
|
||||
@@ -166,6 +166,8 @@ curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
|
||||
|
||||
wget --no-check-certificate -O install.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install.sh && bash install.sh
|
||||
|
||||
wget --no-check-certificate -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/uninstall.sh && bash uninstall.sh
|
||||
|
||||
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/debug.sh | bash
|
||||
|
||||
+12
-8
@@ -1496,8 +1496,9 @@ fullchain.pem 粘贴到证书输入框
|
||||
'cert_timeout'] = int(time.time())
|
||||
|
||||
if self.__config['orders'][i]['cert_timeout'] > start_time:
|
||||
writeLog(
|
||||
"|-本次跳过域名: {},未过期!".format(self.__config['orders'][i]['domains'][0]))
|
||||
msg = "|-本次跳过域名: {},未过期!".format(
|
||||
self.__config['orders'][i]['domains'][0])
|
||||
writeLog(msg)
|
||||
continue
|
||||
|
||||
# 已删除的网站直接跳过续签
|
||||
@@ -1514,8 +1515,9 @@ fullchain.pem 粘贴到证书输入框
|
||||
break
|
||||
if not mw.M('domain').where("name=?", (domain,)).count() and not mw.M('binding').where("domain=?", domain).count():
|
||||
auth_to = None
|
||||
writeLog(
|
||||
"|-跳过被删除的域名: {}".format(self.__config['orders'][i]['domains']))
|
||||
msg = "|-跳过被删除的域名: {}".format(
|
||||
self.__config['orders'][i]['domains'])
|
||||
writeLog(msg)
|
||||
if not auth_to:
|
||||
continue
|
||||
|
||||
@@ -1526,15 +1528,17 @@ fullchain.pem 粘贴到证书输入框
|
||||
timeout = self.__config['orders'][i][
|
||||
'next_retry_time'] - int(time.time())
|
||||
if timeout > 0:
|
||||
writeLog('|-本次跳过域名:{},因第上次续签失败,还需要等待{}小时后再重试'.format(
|
||||
self.__config['orders'][i]['domains'], int(timeout / 60 / 60)))
|
||||
msg = '|-本次跳过域名:{},因第上次续签失败,还需要等待{}小时后再重试'.format(
|
||||
self.__config['orders'][i]['domains'], int(timeout / 60 / 60))
|
||||
writeLog(msg)
|
||||
continue
|
||||
|
||||
# 是否到了最大重试次数
|
||||
if 'retry_count' in self.__config['orders'][i]:
|
||||
if self.__config['orders'][i]['retry_count'] >= 5:
|
||||
writeLog('|-本次跳过域名:{},因连续5次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
|
||||
self.__config['orders'][i]['domains']))
|
||||
msg = '|-本次跳过域名:{},因连续5次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
|
||||
self.__config['orders'][i]['domains'])
|
||||
writeLog(msg)
|
||||
continue
|
||||
|
||||
# 加入到续签订单
|
||||
|
||||
@@ -32,6 +32,7 @@ from flask import redirect
|
||||
|
||||
|
||||
def init():
|
||||
initSystemControl()
|
||||
initDB()
|
||||
initDBSshPort()
|
||||
initUserInfo()
|
||||
@@ -145,10 +146,22 @@ def initInitTask():
|
||||
api.createCertCron()
|
||||
|
||||
|
||||
def initSystemControl():
|
||||
path = 'data/default.db'
|
||||
if os.path.exists(path):
|
||||
return False
|
||||
|
||||
import system_api
|
||||
sapi = system_api.system_api()
|
||||
r = sapi.setControl(1, 30)
|
||||
print(r)
|
||||
|
||||
|
||||
def initUserInfo():
|
||||
|
||||
data = mw.M('users').where('id=?', (1,)).getField('password')
|
||||
if data == '21232f297a57a5a743894a0e4a801fc3':
|
||||
|
||||
pwd = mw.getRandomString(8).lower()
|
||||
file_pw = mw.getRunDir() + '/data/default.pl'
|
||||
mw.writeFile(file_pw, pwd)
|
||||
|
||||
@@ -27,7 +27,7 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.15.2'
|
||||
__version = '0.16.1'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -602,20 +602,22 @@ echo "--------------------------------------------------------------------------
|
||||
|
||||
# 将Shell脚本写到文件
|
||||
def writeShell(self, config):
|
||||
u_file = '/var/spool/cron/crontabs/root'
|
||||
if not os.path.exists(u_file):
|
||||
file = '/var/spool/cron/crontabs/root'
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
file = '/etc/crontab'
|
||||
elif current_os.startswith("freebsd"):
|
||||
file = '/var/cron/tabs/root'
|
||||
|
||||
if not os.path.exists(file):
|
||||
file = '/var/spool/cron/root'
|
||||
if mw.isAppleSystem():
|
||||
file = '/etc/crontab'
|
||||
else:
|
||||
file = u_file
|
||||
|
||||
if not os.path.exists(file):
|
||||
mw.writeFile(file, '')
|
||||
conf = mw.readFile(file)
|
||||
conf += str(config) + "\n"
|
||||
if mw.writeFile(file, conf):
|
||||
if not os.path.exists(u_file):
|
||||
if not os.path.exists(file):
|
||||
mw.execShell("chmod 600 '" + file +
|
||||
"' && chown root.root " + file)
|
||||
else:
|
||||
|
||||
@@ -64,8 +64,13 @@ class files_api:
|
||||
filename = request.args.get('filename', '')
|
||||
if not os.path.exists(filename):
|
||||
return ''
|
||||
|
||||
is_attachment = True
|
||||
if filename.endswith(".svg"):
|
||||
is_attachment = False
|
||||
|
||||
response = make_response(send_from_directory(
|
||||
os.path.dirname(filename), os.path.basename(filename), as_attachment=True))
|
||||
os.path.dirname(filename), os.path.basename(filename), as_attachment=is_attachment))
|
||||
return response
|
||||
|
||||
def zipApi(self):
|
||||
@@ -708,10 +713,7 @@ class files_api:
|
||||
return not path in nDirs
|
||||
|
||||
def getDirSize(self, path):
|
||||
if mw.isAppleSystem():
|
||||
tmp = mw.execShell('du -sh ' + path)
|
||||
else:
|
||||
tmp = mw.execShell('du -sbh ' + path)
|
||||
tmp = mw.execShell('du -sh ' + path)
|
||||
return tmp
|
||||
|
||||
def checkFileName(self, filename):
|
||||
|
||||
@@ -178,12 +178,6 @@ class firewall_api:
|
||||
limit = request.form.get('limit', '10').strip()
|
||||
return self.getList(int(p), int(limit))
|
||||
|
||||
def getLogListApi(self):
|
||||
p = request.form.get('p', '1').strip()
|
||||
limit = request.form.get('limit', '10').strip()
|
||||
search = request.form.get('search', '').strip()
|
||||
return self.getLogList(int(p), int(limit), search)
|
||||
|
||||
def getSshInfoApi(self):
|
||||
data = {}
|
||||
|
||||
@@ -389,11 +383,6 @@ class firewall_api:
|
||||
|
||||
return mw.returnData(True, '设置成功!')
|
||||
|
||||
def delPanelLogsApi(self):
|
||||
mw.M('logs').where('id>?', (0,)).delete()
|
||||
mw.writeLog('面板设置', '面板操作日志已清空!')
|
||||
return mw.returnJson(True, '面板操作日志已清空!')
|
||||
|
||||
##### ----- start ----- ###
|
||||
|
||||
def getList(self, page, limit):
|
||||
@@ -414,28 +403,6 @@ class firewall_api:
|
||||
data['page'] = mw.getPage(_page)
|
||||
return mw.getJson(data)
|
||||
|
||||
def getLogList(self, page, limit, search=''):
|
||||
find_search = ''
|
||||
if search != '':
|
||||
find_search = "type like '%" + search + "%' or log like '%" + \
|
||||
search + "%' or addtime like '%" + search + "%'"
|
||||
|
||||
start = (page - 1) * limit
|
||||
|
||||
_list = mw.M('logs').where(find_search, ()).field(
|
||||
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
|
||||
data = {}
|
||||
data['data'] = _list
|
||||
|
||||
count = mw.M('logs').where(find_search, ()).count()
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['tojs'] = 'getLogs'
|
||||
_page['p'] = page
|
||||
|
||||
data['page'] = mw.getPage(_page)
|
||||
return mw.getJson(data)
|
||||
|
||||
def addAcceptPort(self, port):
|
||||
if self.__isUfw:
|
||||
mw.execShell('ufw allow ' + port + '/tcp')
|
||||
|
||||
@@ -0,0 +1,352 @@
|
||||
# coding: utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 日志类操作
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import psutil
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import mw
|
||||
import re
|
||||
import json
|
||||
import pwd
|
||||
|
||||
from datetime import datetime
|
||||
from flask import request
|
||||
|
||||
|
||||
class logs_api:
|
||||
|
||||
__months = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
|
||||
'Jul': '07', 'Aug': '08', 'Sep': '09', 'Sept': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'}
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def delPanelLogsApi(self):
|
||||
mw.M('logs').where('id>?', (0,)).delete()
|
||||
mw.writeLog('面板设置', '面板操作日志已清空!')
|
||||
return mw.returnJson(True, '面板操作日志已清空!')
|
||||
|
||||
def getLogListApi(self):
|
||||
p = request.form.get('p', '1').strip()
|
||||
limit = request.form.get('limit', '10').strip()
|
||||
search = request.form.get('search', '').strip()
|
||||
return self.getLogList(int(p), int(limit), search)
|
||||
|
||||
def getLogList(self, page, limit, search=''):
|
||||
find_search = ''
|
||||
if search != '':
|
||||
find_search = "type like '%" + search + "%' or log like '%" + \
|
||||
search + "%' or addtime like '%" + search + "%'"
|
||||
|
||||
start = (page - 1) * limit
|
||||
|
||||
_list = mw.M('logs').where(find_search, ()).field(
|
||||
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
|
||||
data = {}
|
||||
data['data'] = _list
|
||||
|
||||
count = mw.M('logs').where(find_search, ()).count()
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['tojs'] = 'getLogs'
|
||||
_page['p'] = page
|
||||
|
||||
data['page'] = mw.getPage(_page)
|
||||
return mw.getJson(data)
|
||||
|
||||
def getLogsTitle(self, log_name):
|
||||
log_name = log_name.replace('.1', '')
|
||||
if log_name in ['mw-update.log']:
|
||||
return '面板更新日志'
|
||||
if log_name in ['mw-install.log']:
|
||||
return '面板安装日志'
|
||||
if log_name in ['auth.log', 'secure'] or log_name.find('auth.') == 0:
|
||||
return '授权日志'
|
||||
if log_name in ['dmesg'] or log_name.find('dmesg') == 0:
|
||||
return '内核缓冲区日志'
|
||||
if log_name in ['syslog'] or log_name.find('syslog') == 0:
|
||||
return '系统警告/错误日志'
|
||||
if log_name in ['btmp']:
|
||||
return '失败的登录记录'
|
||||
if log_name in ['utmp', 'wtmp']:
|
||||
return '登录和重启记录'
|
||||
if log_name in ['lastlog']:
|
||||
return '用户最后登录'
|
||||
if log_name in ['yum.log']:
|
||||
return 'yum包管理器日志'
|
||||
if log_name in ['anaconda.log']:
|
||||
return 'Anaconda日志'
|
||||
if log_name in ['dpkg.log']:
|
||||
return 'dpkg日志'
|
||||
if log_name in ['daemon.log']:
|
||||
return '系统后台守护进程日志'
|
||||
if log_name in ['boot.log']:
|
||||
return '启动日志'
|
||||
if log_name in ['kern.log']:
|
||||
return '内核日志'
|
||||
if log_name in ['maillog', 'mail.log']:
|
||||
return '邮件日志'
|
||||
if log_name.find('Xorg') == 0:
|
||||
return 'Xorg日志'
|
||||
if log_name in ['cron.log']:
|
||||
return '定时任务日志'
|
||||
if log_name in ['alternatives.log']:
|
||||
return '更新替代信息'
|
||||
if log_name in ['debug']:
|
||||
return '调试信息'
|
||||
if log_name.find('apt') == 0:
|
||||
return 'apt-get相关日志'
|
||||
if log_name.find('installer') == 0:
|
||||
return '系统安装相关日志'
|
||||
if log_name in ['messages']:
|
||||
return '综合日志'
|
||||
return '{}日志'.format(log_name.split('.')[0])
|
||||
|
||||
def getAuditLogsFilesApi(self):
|
||||
log_dir = '/var/log'
|
||||
log_files = []
|
||||
for log_file in os.listdir(log_dir):
|
||||
log_suffix = log_file.split('.')[-1:]
|
||||
if log_suffix[0] in ['gz', 'xz', 'bz2', 'asl']:
|
||||
continue
|
||||
|
||||
if log_file in ['.', '..', 'faillog', 'fontconfig.log', 'unattended-upgrades', 'tallylog']:
|
||||
continue
|
||||
|
||||
filename = os.path.join(log_dir, log_file)
|
||||
if os.path.isfile(filename):
|
||||
file_size = os.path.getsize(filename)
|
||||
if not file_size:
|
||||
continue
|
||||
|
||||
tmp = {
|
||||
'name': log_file,
|
||||
'size': file_size,
|
||||
'log_file': filename,
|
||||
'title': self.getLogsTitle(log_file),
|
||||
'uptime': os.path.getmtime(filename)
|
||||
}
|
||||
|
||||
log_files.append(tmp)
|
||||
else:
|
||||
for next_name in os.listdir(filename):
|
||||
if next_name[-3:] in ['.gz', '.xz']:
|
||||
continue
|
||||
next_file = os.path.join(filename, next_name)
|
||||
if not os.path.isfile(next_file):
|
||||
continue
|
||||
file_size = os.path.getsize(next_file)
|
||||
if not file_size:
|
||||
continue
|
||||
log_name = '{}/{}'.format(log_file, next_name)
|
||||
tmp = {
|
||||
'name': log_name,
|
||||
'size': file_size,
|
||||
'log_file': next_file,
|
||||
'title': self.getLogsTitle(log_name),
|
||||
'uptime': os.path.getmtime(next_file)
|
||||
}
|
||||
log_files.append(tmp)
|
||||
log_files = sorted(log_files, key=lambda x: x['name'], reverse=True)
|
||||
return mw.getJson(log_files)
|
||||
|
||||
def getAuditFileApi(self):
|
||||
log_name = request.form.get('log_name', '').strip()
|
||||
return self.getAuditLogsName(log_name)
|
||||
|
||||
def __to_date2(self, date_str):
|
||||
tmp = date_str.split()
|
||||
s_date = str(tmp[-1]) + '-' + self.__months.get(tmp[1],
|
||||
tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
|
||||
return s_date
|
||||
|
||||
def __to_date3(self, date_str):
|
||||
tmp = date_str.split()
|
||||
s_date = str(datetime.now().year) + '-' + \
|
||||
self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
|
||||
return s_date
|
||||
|
||||
def __to_date4(self, date_str):
|
||||
tmp = date_str.split()
|
||||
s_date = str(datetime.now().year) + '-' + \
|
||||
self.__months.get(tmp[0], tmp[0]) + '-' + tmp[1] + ' ' + tmp[2]
|
||||
return s_date
|
||||
|
||||
def getAuditLast(self, log_name):
|
||||
# 获取日志
|
||||
cmd = '''LANG=en_US.UTF-8 last -n 200 -x -f {} |grep -v 127.0.0.1|grep -v " begins"'''.format(
|
||||
'/var/log/' + log_name)
|
||||
result = mw.execShell(cmd)
|
||||
lastlog_list = []
|
||||
for _line in result[0].split("\n"):
|
||||
if not _line:
|
||||
continue
|
||||
tmp = {}
|
||||
sp_arr = _line.split()
|
||||
tmp['用户'] = sp_arr[0]
|
||||
if sp_arr[0] == 'runlevel':
|
||||
tmp['来源'] = sp_arr[4]
|
||||
tmp['端口'] = ' '.join(sp_arr[1:4])
|
||||
tmp['时间'] = self.__to_date3(
|
||||
' '.join(sp_arr[5:])) + ' ' + ' '.join(sp_arr[-2:])
|
||||
elif sp_arr[0] in ['reboot', 'shutdown']:
|
||||
tmp['来源'] = sp_arr[3]
|
||||
tmp['端口'] = ' '.join(sp_arr[1:3])
|
||||
if sp_arr[-3] == '-':
|
||||
tmp['时间'] = self.__to_date3(
|
||||
' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-3:])
|
||||
else:
|
||||
tmp['时间'] = self.__to_date3(
|
||||
' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-2:])
|
||||
elif sp_arr[1] in ['tty1', 'tty', 'tty2', 'tty3', 'hvc0', 'hvc1', 'hvc2'] or len(sp_arr) == 9:
|
||||
tmp['来源'] = ''
|
||||
tmp['端口'] = sp_arr[1]
|
||||
tmp['时间'] = self.__to_date3(
|
||||
' '.join(sp_arr[2:])) + ' ' + ' '.join(sp_arr[-3:])
|
||||
else:
|
||||
tmp['来源'] = sp_arr[2]
|
||||
tmp['端口'] = sp_arr[1]
|
||||
tmp['时间'] = self.__to_date3(
|
||||
' '.join(sp_arr[3:])) + ' ' + ' '.join(sp_arr[-3:])
|
||||
|
||||
# tmp['_line'] = _line
|
||||
lastlog_list.append(tmp)
|
||||
# lastlog_list = sorted(lastlog_list,key=lambda x:x['时间'],reverse=True)
|
||||
return mw.returnData(True, 'ok!', lastlog_list)
|
||||
|
||||
def getAuditLastLog(self):
|
||||
cmd = '''LANG=en_US.UTF-8 lastlog|grep -v Username'''
|
||||
result = mw.execShell(cmd)
|
||||
lastlog_list = []
|
||||
for _line in result[0].split("\n"):
|
||||
if not _line:
|
||||
continue
|
||||
tmp = {}
|
||||
sp_arr = _line.split()
|
||||
tmp['用户'] = sp_arr[0]
|
||||
# tmp['_line'] = _line
|
||||
if _line.find('Never logged in') != -1:
|
||||
tmp['最后登录时间'] = '0'
|
||||
tmp['最后登录来源'] = '-'
|
||||
tmp['最后登录端口'] = '-'
|
||||
lastlog_list.append(tmp)
|
||||
continue
|
||||
tmp['最后登录来源'] = sp_arr[2]
|
||||
tmp['最后登录端口'] = sp_arr[1]
|
||||
tmp['最后登录时间'] = self.__to_date2(' '.join(sp_arr[3:]))
|
||||
|
||||
lastlog_list.append(tmp)
|
||||
lastlog_list = sorted(lastlog_list, key=lambda x: x[
|
||||
'最后登录时间'], reverse=True)
|
||||
for i in range(len(lastlog_list)):
|
||||
if lastlog_list[i]['最后登录时间'] == '0':
|
||||
lastlog_list[i]['最后登录时间'] = '从未登录过'
|
||||
return mw.returnData(True, 'ok!', lastlog_list)
|
||||
|
||||
def parseAuditFile(self, log_name, result):
|
||||
log_list = []
|
||||
is_string = True
|
||||
for _line in result.split("\n"):
|
||||
if not _line.strip():
|
||||
continue
|
||||
if log_name.find('sa/sa') == -1:
|
||||
if _line[:3] in self.__months:
|
||||
_msg = _line[16:]
|
||||
_tmp = _msg.split(": ")
|
||||
_act = ''
|
||||
if len(_tmp) > 1:
|
||||
_act = _tmp[0]
|
||||
_msg = _tmp[1]
|
||||
else:
|
||||
_msg = _tmp[0]
|
||||
_line = {
|
||||
"时间": self.__to_date4(_line[:16].strip()),
|
||||
"角色": _act,
|
||||
"事件": _msg
|
||||
}
|
||||
is_string = False
|
||||
elif _line[:2] in ['19', '20', '21', '22', '23', '24']:
|
||||
_msg = _line[19:]
|
||||
_tmp = _msg.split(" ")
|
||||
_act = _tmp[1]
|
||||
_msg = ' '.join(_tmp[2:])
|
||||
_line = {
|
||||
"时间": _line[:19].strip(),
|
||||
"角色": _act,
|
||||
"事件": _msg
|
||||
}
|
||||
is_string = False
|
||||
elif log_name.find('alternatives') == 0:
|
||||
_tmp = _line.split(": ")
|
||||
_last = _tmp[0].split(" ")
|
||||
_act = _last[0]
|
||||
_msg = ' '.join(_tmp[1:])
|
||||
_line = {
|
||||
"时间": ' '.join(_last[1:]).strip(),
|
||||
"角色": _act,
|
||||
"事件": _msg
|
||||
}
|
||||
is_string = False
|
||||
else:
|
||||
if not is_string:
|
||||
if type(_line) != dict:
|
||||
continue
|
||||
|
||||
log_list.append(_line)
|
||||
|
||||
return log_list
|
||||
|
||||
def getAuditLogsName(self, log_name):
|
||||
# print(log_name)
|
||||
if log_name in ['wtmp', 'btmp', 'utmp'] or log_name.find('wtmp') == 0 or log_name.find('btmp') == 0 or log_name.find('utmp') == 0:
|
||||
return self.getAuditLast(log_name)
|
||||
|
||||
if log_name.find('lastlog') == 0:
|
||||
return self.getAuditLastLog()
|
||||
|
||||
if log_name.find('sa/sa') == 0:
|
||||
if log_name.find('sa/sar') == -1:
|
||||
return mw.execShell("sar -f /var/log/{}".format(log_name))[0]
|
||||
log_dir = '/var/log'
|
||||
log_file = log_dir + '/' + log_name
|
||||
if not os.path.exists(log_file):
|
||||
return mw.returnData(False, '日志文件不存在!')
|
||||
result = mw.getLastLine(log_file, 100)
|
||||
try:
|
||||
log_list = self.parseAuditFile(log_name, result)
|
||||
_string = []
|
||||
_dict = []
|
||||
_list = []
|
||||
for _line in log_list:
|
||||
if isinstance(_line, str):
|
||||
_string.append(_line.strip())
|
||||
elif isinstance(_line, dict):
|
||||
_dict.append(_line)
|
||||
elif isinstance(_line, list):
|
||||
_list.append(_line)
|
||||
else:
|
||||
continue
|
||||
_str_len = len(_string)
|
||||
_dict_len = len(_dict)
|
||||
_list_len = len(_list)
|
||||
if _str_len > _dict_len + _list_len:
|
||||
return "\n".join(_string)
|
||||
elif _dict_len > _str_len + _list_len:
|
||||
return mw.returnData(True, 'ok!', _dict)
|
||||
else:
|
||||
return mw.returnData(True, 'ok!', _list)
|
||||
|
||||
except:
|
||||
return mw.returnData(True, 'ok!', result)
|
||||
+16
-7
@@ -349,7 +349,8 @@ def restartMw():
|
||||
|
||||
def checkWebConfig():
|
||||
op_dir = getServerDir() + '/openresty/nginx'
|
||||
cmd = "ulimit -n 10240 && " + op_dir + \
|
||||
# "ulimit -n 10240 && " +
|
||||
cmd = op_dir + \
|
||||
"/sbin/nginx -t -c " + op_dir + "/conf/nginx.conf"
|
||||
result = execShell(cmd)
|
||||
searchStr = 'test is successful'
|
||||
@@ -1355,6 +1356,12 @@ def getCpuType():
|
||||
cpuinfo = execShell(cmd)
|
||||
return cpuinfo[0].strip()
|
||||
|
||||
current_os = getOs()
|
||||
if current_os.startswith('freebsd'):
|
||||
cmd = "sysctl -a | egrep -i 'hw.model' | awk -F ':' '{print $2}'"
|
||||
cpuinfo = execShell(cmd)
|
||||
return cpuinfo[0].strip()
|
||||
|
||||
# 取CPU类型
|
||||
cpuinfo = open('/proc/cpuinfo', 'r').read()
|
||||
rep = "model\s+name\s+:\s+(.+)"
|
||||
@@ -1411,7 +1418,7 @@ def makeConf():
|
||||
file = getRunDir() + '/data/json/config.json'
|
||||
if not os.path.exists(file):
|
||||
c = {}
|
||||
c['title'] = '金灵面板'
|
||||
c['title'] = '老子面板'
|
||||
c['home'] = 'http://github/midoks/mdserver-web'
|
||||
c['recycle_bin'] = True
|
||||
c['template'] = 'default'
|
||||
@@ -1550,7 +1557,9 @@ def checkInput(data):
|
||||
|
||||
def checkCert(certPath='ssl/certificate.pem'):
|
||||
# 验证证书
|
||||
openssl = '/usr/local/openssl/bin/openssl'
|
||||
openssl = '/usr/bin/openssl'
|
||||
if not os.path.exists(openssl):
|
||||
openssl = '/usr/local/openssl/bin/openssl'
|
||||
if not os.path.exists(openssl):
|
||||
openssl = 'openssl'
|
||||
certPem = readFile(certPath)
|
||||
@@ -2097,15 +2106,15 @@ done
|
||||
|
||||
|
||||
def echoStart(tag):
|
||||
print("=" * 90)
|
||||
print("=" * 89)
|
||||
print("★开始{}[{}]".format(tag, formatDate()))
|
||||
print("=" * 90)
|
||||
print("=" * 89)
|
||||
|
||||
|
||||
def echoEnd(tag):
|
||||
print("=" * 90)
|
||||
print("=" * 89)
|
||||
print("☆{}完成[{}]".format(tag, formatDate()))
|
||||
print("=" * 90)
|
||||
print("=" * 89)
|
||||
print("\n")
|
||||
|
||||
|
||||
|
||||
+37
-9
@@ -1149,8 +1149,9 @@ class site_api:
|
||||
domains = request.form.get('domains', '')
|
||||
status = request.form.get('status', '')
|
||||
name = request.form.get('name', '')
|
||||
none = request.form.get('none', '')
|
||||
sid = request.form.get('id', '')
|
||||
return self.setSecurity(sid, name, fix, domains, status)
|
||||
return self.setSecurity(sid, name, fix, domains, status, none)
|
||||
|
||||
def getLogsApi(self):
|
||||
siteName = request.form.get('siteName', '')
|
||||
@@ -2430,9 +2431,28 @@ location ^~ {from} {\n\
|
||||
tmp = re.search(rep, conf).group()
|
||||
data['fix'] = re.search(
|
||||
"\(.+\)\$", tmp).group().replace('(', '').replace(')$', '').replace('|', ',')
|
||||
data['domains'] = ','.join(re.search(
|
||||
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp).groups()[0].split())
|
||||
data['status'] = True
|
||||
|
||||
data['status'] = False
|
||||
data['none'] = False
|
||||
|
||||
valid_referers = re.search(
|
||||
"valid_referers\s+(.+);\n", tmp)
|
||||
valid_referers_none = re.search(
|
||||
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp)
|
||||
|
||||
if valid_referers or valid_referers_none:
|
||||
data['status'] = True
|
||||
|
||||
if valid_referers_none:
|
||||
domain_t = valid_referers_none.groups()[0].split()
|
||||
data['domains'] = ','.join(domain_t)
|
||||
data['none'] = True
|
||||
elif valid_referers:
|
||||
domain_t = valid_referers.groups()[0].split()
|
||||
data['domains'] = ','.join(domain_t)
|
||||
data['none'] = False
|
||||
|
||||
# print(data)
|
||||
else:
|
||||
data['fix'] = 'jpg,jpeg,gif,png,js,css'
|
||||
domains = mw.M('domain').where(
|
||||
@@ -2442,19 +2462,27 @@ location ^~ {from} {\n\
|
||||
tmp.append(domain['name'])
|
||||
data['domains'] = ','.join(tmp)
|
||||
data['status'] = False
|
||||
data['none'] = False
|
||||
return mw.getJson(data)
|
||||
|
||||
def setSecurity(self, sid, name, fix, domains, status):
|
||||
def setSecurity(self, sid, name, fix, domains, status, none=''):
|
||||
if len(fix) < 2:
|
||||
return mw.returnJson(False, 'URL后缀不能为空!')
|
||||
file = self.getHostConf(name)
|
||||
if os.path.exists(file):
|
||||
conf = mw.readFile(file)
|
||||
if conf.find('SECURITY-START') != -1:
|
||||
if status == 'false':
|
||||
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeLog('网站管理', '站点[' + name + ']已关闭防盗链设置!')
|
||||
else:
|
||||
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
conf = re.sub(rep, '', conf)
|
||||
|
||||
valid_referers = domains.strip().replace(',', ' ')
|
||||
if none == 'true':
|
||||
valid_referers = 'none blocked ' + valid_referers
|
||||
|
||||
pre_path = self.setupPath + "/php/conf"
|
||||
re_path = "include\s+" + pre_path + "/enable-php-"
|
||||
rconf = '''#SECURITY-START 防盗链配置
|
||||
@@ -2462,13 +2490,13 @@ location ^~ {from} {\n\
|
||||
{
|
||||
expires 30d;
|
||||
access_log /dev/null;
|
||||
valid_referers none blocked %s;
|
||||
valid_referers %s;
|
||||
if ($invalid_referer){
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
#SECURITY-END
|
||||
include %s/enable-php-''' % (fix.strip().replace(',', '|'), domains.strip().replace(',', ' '), pre_path)
|
||||
include %s/enable-php-''' % (fix.strip().replace(',', '|'), valid_referers, pre_path)
|
||||
conf = re.sub(re_path, rconf, conf)
|
||||
mw.writeLog('网站管理', '站点[' + name + ']已开启防盗链!')
|
||||
mw.writeFile(file, conf)
|
||||
@@ -2760,7 +2788,7 @@ location ^~ {from} {\n\
|
||||
|
||||
self.saveCert(keyPath, certPath)
|
||||
|
||||
msg = mw.getInfo('网站[{1}]开启SSL成功!', siteName)
|
||||
msg = mw.getInfo('网站[{}]开启SSL成功!', siteName)
|
||||
mw.writeLog('网站管理', msg)
|
||||
|
||||
mw.restartWeb()
|
||||
|
||||
@@ -274,26 +274,43 @@ class system_api:
|
||||
return title
|
||||
|
||||
def getSystemVersion(self):
|
||||
#
|
||||
# 取操作系统版本
|
||||
if mw.getOs() == 'darwin':
|
||||
current_os = mw.getOs()
|
||||
# mac
|
||||
if current_os == 'darwin':
|
||||
data = mw.execShell('sw_vers')[0]
|
||||
data_list = data.strip().split("\n")
|
||||
mac_version = ''
|
||||
for x in data_list:
|
||||
mac_version += x.split("\t")[1] + ' '
|
||||
return mac_version
|
||||
|
||||
arch_ver = mw.execShell("arch")
|
||||
return mac_version + " (" + arch_ver[0].strip() + ")"
|
||||
|
||||
# freebsd
|
||||
if current_os.startswith('freebsd'):
|
||||
version = mw.execShell(
|
||||
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
|
||||
arch_ver = mw.execShell(
|
||||
"sysctl -a | egrep -i 'hw.machine_arch' | awk -F ':' '{print $2}'")
|
||||
return version[0].strip() + " (" + arch_ver[0].strip() + ")"
|
||||
|
||||
redhat_series = '/etc/redhat-release'
|
||||
if os.path.exists(redhat_series):
|
||||
version = mw.readFile('/etc/redhat-release')
|
||||
version = version.replace('release ', '').strip()
|
||||
return version
|
||||
|
||||
arch_ver = mw.execShell("arch")
|
||||
return version + " (" + arch_ver[0].strip() + ")"
|
||||
|
||||
os_series = '/etc/os-release'
|
||||
if os.path.exists(os_series):
|
||||
version = mw.execShell(
|
||||
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
|
||||
return version[0].strip()
|
||||
|
||||
arch_ver = mw.execShell("arch")
|
||||
return version[0].strip() + " (" + arch_ver[0].strip() + ")"
|
||||
|
||||
return '未识别系统信息'
|
||||
|
||||
@@ -318,7 +335,7 @@ class system_api:
|
||||
cpuCount = psutil.cpu_count()
|
||||
cpuLogicalNum = psutil.cpu_count(logical=False)
|
||||
used = psutil.cpu_percent(interval=interval)
|
||||
|
||||
cpuLogicalNum = 0
|
||||
if os.path.exists('/proc/cpuinfo'):
|
||||
c_tmp = mw.readFile('/proc/cpuinfo')
|
||||
d_tmp = re.findall("physical id.+", c_tmp)
|
||||
|
||||
@@ -7,6 +7,10 @@ MDIR=$(dirname "$DIR")
|
||||
PATH=$PATH:$DIR/bin
|
||||
if [ -f bin/activate ];then
|
||||
source bin/activate
|
||||
|
||||
if [ "$?" != "0" ];then
|
||||
echo "load local python env fail!"
|
||||
fi
|
||||
fi
|
||||
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
|
||||
@@ -14,6 +14,7 @@ if sys.platform != "darwin":
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
import db
|
||||
|
||||
_ver = sys.version_info
|
||||
is_py2 = (_ver[0] == 2)
|
||||
@@ -185,6 +186,35 @@ def backupAllFunc(stype):
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
backups = []
|
||||
sql = db.Sql()
|
||||
|
||||
# print("stype:", stype)
|
||||
# 提前获取-清理多余备份
|
||||
if stype == 'site':
|
||||
pid = sql.table('sites').where('name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('0', pid)).field('id,filename').select()
|
||||
if stype == 'database':
|
||||
db_path = mw.getServerDir() + '/mysql'
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
if stype == 'path':
|
||||
backup_path = backup_dir + '/path'
|
||||
_name = 'path_{}'.format(os.path.basename(name))
|
||||
backups = findPathName(backup_path, _name)
|
||||
|
||||
# 其他类型关系性数据库(mysql类的)
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
db_path = mw.getServerDir() + '/' + plugin_name
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
|
||||
args = stype + " " + name + " " + num
|
||||
cmd = 'python3 ' + mw.getRunDir() + '/scripts/backup.py ' + args
|
||||
if stype.find('database_') > -1:
|
||||
@@ -213,19 +243,31 @@ def backupAllFunc(stype):
|
||||
filename = mw.execShell(find_new_file)[0].strip()
|
||||
if filename == "":
|
||||
mw.echoInfo("not find upload file!")
|
||||
return False
|
||||
return ''
|
||||
|
||||
print("|-准备上传文件 {}".format(filename))
|
||||
ftp = FtpPSClient()
|
||||
ftp.uploadFile(filename, stype)
|
||||
|
||||
# print(backups)
|
||||
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
|
||||
mw.echoStart('开始删除远程备份')
|
||||
num = int(num)
|
||||
sep = len(backups) - num
|
||||
if sep > -1:
|
||||
for backup in backups:
|
||||
fn = os.path.basename(backup['filename'])
|
||||
object_name = ftp.buildDirName(stype, fn)
|
||||
ftp.deleteFile(object_name)
|
||||
mw.echoInfo("---已清理远程过期备份文件:" + object_name)
|
||||
sep -= 1
|
||||
if sep < 0:
|
||||
break
|
||||
mw.echoEnd('结束删除远程备份')
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def backupSite():
|
||||
# 备份站点
|
||||
pass
|
||||
|
||||
|
||||
def in_array(name, arr=[]):
|
||||
for x in arr:
|
||||
if name == x:
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Executable
+19
@@ -0,0 +1,19 @@
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('dynamic-tracking');">服务</p>
|
||||
<p onclick="pluginInitD('dynamic-tracking');">自启动</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(300);
|
||||
resetPluginWinWidth(500);
|
||||
$.getScript( "/plugins/file?name=dynamic-tracking&f=static/js/dynamic-tracking.js", function(){
|
||||
pluginService('dynamic-tracking', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+228
@@ -0,0 +1,228 @@
|
||||
# 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 'dynamic-tracking'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
return '/tmp/' + getPluginName()
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
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():
|
||||
dir_path = getServerDir() + '/trace'
|
||||
if not os.path.exists(dir_path):
|
||||
os.mkdir(dir_path)
|
||||
return 'start'
|
||||
|
||||
|
||||
def dtOp(method):
|
||||
return 'ok'
|
||||
|
||||
|
||||
def start():
|
||||
return dtOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return dtOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = dtOp('restart')
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return dtOp('reload')
|
||||
|
||||
|
||||
def initdStatus():
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
return 'ok'
|
||||
|
||||
|
||||
def get_file(args):
|
||||
dir_path = getServerDir() + '/trace'
|
||||
|
||||
path = dir_path + '/' + args['file'] + '/main.svg'
|
||||
|
||||
if os.path.exists(path):
|
||||
d = mw.readFile(path)
|
||||
return mw.returnData(True, 'ok', d)
|
||||
else:
|
||||
return mw.returnData(False, '无效目录')
|
||||
|
||||
|
||||
def get_file_path(args):
|
||||
dir_path = getServerDir() + '/trace'
|
||||
path = dir_path + '/' + args['file'] + '/main.svg'
|
||||
if os.path.exists(path):
|
||||
return mw.returnData(True, 'ok', path)
|
||||
else:
|
||||
return mw.returnData(False, '无效目录')
|
||||
|
||||
|
||||
def dtGetFilePath():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
dir_path = getServerDir() + '/trace'
|
||||
path = dir_path + '/' + args['file'] + '/main.svg'
|
||||
if os.path.exists(path):
|
||||
return mw.returnJson(True, 'ok', path)
|
||||
else:
|
||||
return mw.returnJson(False, '无效目录')
|
||||
|
||||
|
||||
def dtRemoveFilePath():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
dir_path = getServerDir() + '/trace'
|
||||
path = dir_path + '/' + args['file']
|
||||
if os.path.exists(path):
|
||||
mw.execShell('rm -rf ' + path)
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
|
||||
|
||||
def dtFileList():
|
||||
dir_path = getServerDir() + '/trace'
|
||||
if not os.path.exists(dir_path):
|
||||
os.mkdir(dir_path)
|
||||
|
||||
file_info = []
|
||||
for name in os.listdir(dir_path):
|
||||
if name == ".DS_Store":
|
||||
continue
|
||||
|
||||
# print(name)
|
||||
info = {}
|
||||
try:
|
||||
info['name'] = name
|
||||
info['abs_path'] = dir_path + '/' + name + '/main.svg'
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, str(e))
|
||||
|
||||
file_info.append(info)
|
||||
|
||||
file_info = sorted(file_info, key=lambda x: x['name'], reverse=False)
|
||||
return mw.returnJson(True, 'ok!', file_info)
|
||||
|
||||
|
||||
def dtSimpleTrace():
|
||||
if mw.isAppleSystem():
|
||||
return mw.returnJson(False, 'macosx只能手动执行!')
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['pid'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
plugins_shell = getPluginDir() + '/shell/simple_trace.sh'
|
||||
cmd = plugins_shell + ' "' + args['pid'] + '"'
|
||||
|
||||
data = mw.execShell("bash " + cmd + " &")
|
||||
return mw.returnJson(True, '执行成功!')
|
||||
|
||||
|
||||
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())
|
||||
elif func == 'initd_status':
|
||||
print(initdStatus())
|
||||
elif func == 'initd_install':
|
||||
print(initdInstall())
|
||||
elif func == 'initd_uninstall':
|
||||
print(initdUinstall())
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'file_list':
|
||||
print(dtFileList())
|
||||
elif func == 'get_file_path':
|
||||
print(dtGetFilePath())
|
||||
elif func == 'remove_file_path':
|
||||
print(dtRemoveFilePath())
|
||||
elif func == 'simple_trace':
|
||||
print(dtSimpleTrace())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"hook":[
|
||||
{
|
||||
"tag":"menu",
|
||||
"menu": {
|
||||
"title":"动态追踪",
|
||||
"name":"dynamic-tracking",
|
||||
"path":"static/html/index.html",
|
||||
"css_path":"static/css/dynamic-tracking.css",
|
||||
"js_path":"static/js/dynamic-tracking.js"
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag":"global_static",
|
||||
"global_static": {
|
||||
"title":"动态追踪",
|
||||
"name":"dynamic-tracking",
|
||||
"css_path":"static/css/ico.css"
|
||||
}
|
||||
}
|
||||
],
|
||||
"sort": 7,
|
||||
"ps": "专业使用,动态追踪调试程序<无侵入>![<span style='color:red;'>潜龙勿用|实验</span>]",
|
||||
"name": "dynamic-tracking",
|
||||
"title": "动态追踪",
|
||||
"shell": "install.sh",
|
||||
"versions":["0.1"],
|
||||
"tip": "soft",
|
||||
"checks": "server/dynamic-tracking",
|
||||
"path": "server/dynamic-tracking",
|
||||
"display": 1,
|
||||
"author": "midoks",
|
||||
"date": "2023-08-17",
|
||||
"type": 0,
|
||||
"pid": "4"
|
||||
}
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/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")
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/dynamic-tracking && /bin/bash install.sh uninstall 1.0
|
||||
# cd /www/server/mdserver-web/plugins/dynamic-tracking && /bin/bash install.sh install 1.0
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
|
||||
OSNAME=`bash ${rootPath}/scripts/getos.sh`
|
||||
|
||||
if [ "" == "$OSNAME" ];then
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
fi
|
||||
|
||||
if [ "macos" != "$OSNAME" ];then
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
fi
|
||||
|
||||
Install_App()
|
||||
{
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
mkdir -p $serverPath/dynamic-tracking
|
||||
|
||||
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
HTTP_PREFIX="https://"
|
||||
if [ ! -z "$cn" ];then
|
||||
HTTP_PREFIX="https://ghproxy.com/"
|
||||
fi
|
||||
|
||||
# FlameGraph start
|
||||
if [ ! -d $serverPath/dynamic-tracking/FlameGraph ];then
|
||||
if [ ! -f $serverPath/source/FlameGraph.zip ]; then
|
||||
wget --no-check-certificate -O $serverPath/source/FlameGraph.zip ${HTTP_PREFIX}github.com/brendangregg/FlameGraph/archive/refs/heads/master.zip
|
||||
fi
|
||||
|
||||
cd $serverPath/source && unzip $serverPath/source/FlameGraph.zip
|
||||
mv $serverPath/source/FlameGraph-master $serverPath/dynamic-tracking/FlameGraph
|
||||
fi
|
||||
# FlameGraph end
|
||||
|
||||
|
||||
|
||||
shell_file=${curPath}/versions/${OSNAME}.sh
|
||||
echo $shell_file
|
||||
if [ ! -f $shell_file ];then
|
||||
echo '不支持...' > $install_tmp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
bash -x $shell_file
|
||||
|
||||
echo "cp -rf ${curPath}/shell $serverPath/dynamic-tracking"
|
||||
cp -rf ${curPath}/shell $serverPath/dynamic-tracking
|
||||
|
||||
echo "${VERSION}" > $serverPath/dynamic-tracking/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/dynamic-tracking/index.py start
|
||||
# cd ${rootPath} && python3 ${rootPath}/plugins/dynamic-tracking/index.py initd_install
|
||||
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/dynamic-tracking
|
||||
echo "Uninstall_App" > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
|
||||
# debug
|
||||
# cd /www/server/mdserver-web
|
||||
# bash /www/server/mdserver-web/plugins/dynamic-tracking/shell/simple_macosx_trace.sh "22431"
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web
|
||||
# bash /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/dynamic-tracking/shell/simple_macosx_trace.sh "22431"
|
||||
|
||||
# dtrace -x ustackframes=100 -n 'pid$target::mach_msg_trap:entry { @[ustack()] = count(); } tick-30s { exit(0); }' -p 18572 -o out.SystemUIServer_stacks
|
||||
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/stackcollapse.pl out.SystemUIServer_stacks > kernel.cbt
|
||||
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/flamegraph.pl kernel.cbt > kernel.svg
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
sysName=`uname`
|
||||
PID=$1
|
||||
|
||||
echo $rootPath # /Users/midoks/Desktop/mwdev/server
|
||||
echo $curPath # /Users/midoks/Desktop/mwdev/server/mdserver-web
|
||||
|
||||
APP_DIR=${rootPath}/dynamic-tracking
|
||||
DST_FILE_DIR=${APP_DIR}/trace/PID_${PID}
|
||||
mkdir -p $DST_FILE_DIR
|
||||
|
||||
DST_FILE=${DST_FILE_DIR}/out.SystemUIServer_stacks
|
||||
|
||||
if [ ! -f $DST_FILE ];then
|
||||
sudo dtrace -x ustackframes=100 -n 'pid$target::mach_msg_trap:entry { @[ustack()] = count(); } tick-30s { exit(0); }' -p "$PID" -o $DST_FILE
|
||||
fi
|
||||
|
||||
${APP_DIR}/FlameGraph/stackcollapse.pl $DST_FILE > ${DST_FILE_DIR}/kernel.cbt
|
||||
${APP_DIR}/FlameGraph/flamegraph.pl ${DST_FILE_DIR}/kernel.cbt > ${DST_FILE_DIR}/main.svg
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
|
||||
# debug
|
||||
# cd /www/server/mdserver-web
|
||||
# bash /www/server/mdserver-web/plugins/dynamic-tracking/shell/simple_trace.sh "2401699"
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
sysName=`uname`
|
||||
PID=$1
|
||||
|
||||
echo $rootPath # /Users/midoks/Desktop/mwdev/server
|
||||
echo $curPath # /Users/midoks/Desktop/mwdev/server/mdserver-web
|
||||
|
||||
APP_DIR=/www/server/dynamic-tracking
|
||||
DST_FILE_DIR=${APP_DIR}/trace/PID_${PID}
|
||||
mkdir -p $DST_FILE_DIR
|
||||
|
||||
# DST_FILE=${DST_FILE_DIR}/main.strace
|
||||
|
||||
# perf record -F 99 -p 335584 -g -- sleep 30
|
||||
|
||||
cd ${DST_FILE_DIR}
|
||||
perf record -F 99 -p ${PID} -g -- sleep 30
|
||||
|
||||
perf script > out.perf
|
||||
${APP_DIR}/FlameGraph/stackcollapse-perf.pl ${DST_FILE_DIR}/out.perf > ${DST_FILE_DIR}/out.folded
|
||||
${APP_DIR}/FlameGraph/flamegraph.pl ${DST_FILE_DIR}/out.folded > ${DST_FILE_DIR}/main.svg
|
||||
|
||||
# perf record -F 99 -p 2401699 -g -- sleep 30
|
||||
# perf script > out.perf
|
||||
# /www/server/dynamic-tracking/FlameGraph/stackcollapse-perf.pl out.perf > out.folded
|
||||
# /www/server/dynamic-tracking/FlameGraph/flamegraph.pl out.folded > php-zend-flame-graph.svg
|
||||
|
||||
# ${APP_DIR}/FlameGraph/stackcollapse.pl $DST_FILE > ${DST_FILE_DIR}/kernel.cbt
|
||||
# ${APP_DIR}/FlameGraph/flamegraph.pl ${DST_FILE_DIR}/kernel.cbt > ${DST_FILE_DIR}/main.svg
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
.screen-all {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.s-right .panel-default{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.s-left .panel-default{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.data-collect {
|
||||
width: 45px;
|
||||
height: 30px;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
margin-right: 2px;
|
||||
margin-top: 10px;
|
||||
color: #fff;
|
||||
background-color: #20a53a;
|
||||
border-color: #20a53a;
|
||||
}
|
||||
|
||||
|
||||
#file_list .list {
|
||||
list-style: none;
|
||||
border-top: none;
|
||||
border: 1px solid #ececec;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#file_list .list li.active {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
#file_list .tab-con{
|
||||
padding: 0px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#file_list .list li>span {
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#file_list .list li {
|
||||
display: inline-block;
|
||||
height: 38px;
|
||||
line-height: 38px;
|
||||
color: #444;
|
||||
border-bottom: 1px solid #ececec;
|
||||
font-size: 13px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#file_list .file {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
#file_list .list li .tootls{
|
||||
width: 70px;
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
/* display: none; */
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
/*.tab-con .tab-block.on {
|
||||
display: inline-block;
|
||||
}*/
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
/* menu start */
|
||||
.menu .current .menu_dynamic-tracking:hover {
|
||||
background-image: url("/plugins/file?name=dynamic-tracking&f=ico.png");
|
||||
}
|
||||
|
||||
.menu .menu_plugin_dynamic-tracking {
|
||||
background-image: url("/plugins/file?name=dynamic-tracking&f=ico.png");
|
||||
}
|
||||
|
||||
/* menu end */
|
||||
@@ -0,0 +1,81 @@
|
||||
<style>
|
||||
.weblog{
|
||||
font-size: 12px;
|
||||
display:inline-block;
|
||||
line-height:30px;
|
||||
}
|
||||
.weblog em{
|
||||
font-style:normal;
|
||||
color:#666;
|
||||
margin: 0 30px;
|
||||
}
|
||||
.weblog span{
|
||||
margin-right:5px;
|
||||
}
|
||||
.weblog a{
|
||||
color:#20a53a;
|
||||
}
|
||||
.firewall-port-box{
|
||||
margin-bottom:15px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="container-fluid">
|
||||
<div class="pos-box bgw mtb15">
|
||||
<div class="position f14 c9 pull-left">
|
||||
<a class="plr10 c4" href="/">首页</a>/<span class="plr10 c4">动态追踪</span>
|
||||
</div>
|
||||
|
||||
<div class="search pull-right">
|
||||
<form target="hid" onsubmit='return false;'>
|
||||
<input type="text" id="searchValue" class="ser-text pull-left" placeholder="进程ID" />
|
||||
<button type="button" class="data-collect pull-left">采样</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- //// -->
|
||||
<div class="safe bgw pd15 mtb15" id="ff_box">
|
||||
|
||||
<div id="file_list" style="float:left;width:300px;">
|
||||
<div class="tab-nav">
|
||||
<span class="on">文件列表</span>
|
||||
</div>
|
||||
|
||||
<div class="tab-con">
|
||||
<div class="tab-block on">
|
||||
<ul class="list" style="display: block; height: 94px;"></ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="flame_graph" style="float:left;">
|
||||
<div class="tab-nav">
|
||||
<span class="on">火焰图</span>
|
||||
</div>
|
||||
|
||||
<div class="tab-con">
|
||||
<iframe class="tab-block on" width="100%" height="100%"
|
||||
src=""
|
||||
frameborder="0"
|
||||
border="0"
|
||||
marginwidth="0"
|
||||
marginheight="0"
|
||||
scrolling="yes"
|
||||
noresize=""
|
||||
allowfullscreen="allowfullscreen"
|
||||
mozallowfullscreen="mozallowfullscreen"
|
||||
msallowfullscreen="msallowfullscreen"
|
||||
oallowfullscreen="oallowfullscreen"
|
||||
webkitallowfullscreen="webkitallowfullscreen"
|
||||
allowfullscreen="true"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- //// -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
function changeDivH(){
|
||||
var l = $(window).height();
|
||||
var w = $(window).width();
|
||||
|
||||
$('#ff_box').css('height',l-80-60);
|
||||
|
||||
$('#file_list').css('height',l-80-60);
|
||||
$('#file_list .tab-con .list').css('height', l-80-60-70);
|
||||
|
||||
|
||||
$('#flame_graph').css('height',l-80-60).css('width',w-300-200-40);
|
||||
$('#flame_graph iframe').css('height',l-80-60-70);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
var tag = $.getUrlParam('tag');
|
||||
if(tag == 'dynamic-tracking'){
|
||||
dynamicTrackingLoad();
|
||||
}
|
||||
});
|
||||
|
||||
function dynamicTrackingLoad(){
|
||||
changeDivH();
|
||||
$(window).resize(function(){
|
||||
changeDivH();
|
||||
});
|
||||
|
||||
//加载采样数据列表
|
||||
dtFileList();
|
||||
}
|
||||
|
||||
|
||||
$('.data-collect').click(function(){
|
||||
layer.msg('开始采样',{icon:0,time:2000});
|
||||
var pid = $('#searchValue').val();
|
||||
|
||||
dtPost('simple_trace', '', {pid:pid}, function(rdata){
|
||||
// console.log(rdata);
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
layer.msg(rdata['msg'],{icon:rdata['status']?1:2,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function dtPost(method, version, args,callback){
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
var req_data = {};
|
||||
req_data['name'] = 'dynamic-tracking';
|
||||
req_data['func'] = method;
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
//错误展示10S
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function dtPostCb(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var pdata = {};
|
||||
pdata['name'] = 'dynamic-tracking';
|
||||
pdata['func'] = method;
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
pdata['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
pdata['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', pdata, 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 dtFileList(){
|
||||
dtPost('file_list', '', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var alist = rdata.data;
|
||||
|
||||
if (alist.length == 0){
|
||||
var em ='<li class="data-file-list" style="text-align: center;">无数据</li>';
|
||||
$('#file_list .list').html(em);
|
||||
return;
|
||||
}
|
||||
|
||||
var tli = '';
|
||||
for (var i = 0; i < alist.length; i++) {
|
||||
if (i==0){
|
||||
tli +='<li title="双击打开浏览" class="data-file-list active" data-index="'+i+'" data-file="'+alist[i]['name']+'">\
|
||||
<span class="file">'+alist[i]['name']+'</span>\
|
||||
<span class="tootls">\
|
||||
<span class="glyphicon glyphicon-link" aria-hidden="true" title="外部连接"></span>\
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true" title="删除"></span>\
|
||||
</span>\
|
||||
</li>';
|
||||
} else{
|
||||
tli +='<li class="data-file-list" data-index="'+i+'" data-file="'+alist[i]['name']+'">\
|
||||
<span class="file">'+alist[i]['name']+'</span>\
|
||||
<span class="tootls">\
|
||||
<span class="glyphicon glyphicon-link" aria-hidden="true" title="外部连接"></span>\
|
||||
<span class="glyphicon glyphicon-trash" aria-hidden="true" title="删除"></span>\
|
||||
</span>\
|
||||
</li>';
|
||||
}
|
||||
}
|
||||
|
||||
$('#file_list .list').html(tli);
|
||||
|
||||
dtGetFile(alist[0]['name']);
|
||||
$('#file_list li .file').click(function(){
|
||||
$('#file_list li').removeClass('active');
|
||||
$(this).parent().addClass('active');
|
||||
var i = $(this).parent().data('index');
|
||||
dtGetFile(alist[i]['name']);
|
||||
});
|
||||
|
||||
|
||||
$('#file_list li .glyphicon-link').click(function(){
|
||||
var i = $(this).parent().parent().data('index');
|
||||
var abs_p = alist[i]['abs_path'];
|
||||
|
||||
var durl = '/files/download?filename='+abs_p;
|
||||
window.open(durl);
|
||||
});
|
||||
|
||||
$('#file_list li .glyphicon-trash').click(function(){
|
||||
var i = $(this).parent().parent().data('index');
|
||||
var f = alist[i]['name'];
|
||||
dtPost('remove_file_path', '',{file:f}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
layer.msg(rdata['msg'],{icon:rdata['status']?1:2,time:2000});
|
||||
if (rdata.status){
|
||||
dtFileList();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function dtGetFile(file){
|
||||
dtPost('get_file_path', '', {file:file}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:0,time:2000,shade: [2, '#000']});
|
||||
return;
|
||||
}
|
||||
var durl = '/files/download?filename='+rdata.data;
|
||||
$('#flame_graph .tab-con .tab-block').attr('src',durl);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
SYS_ARCH=`arch`
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
# apt-get install linux-perf
|
||||
# apt-get update -y
|
||||
# strace -p $(ps -ef|grep "pool www" | awk '{print $2}' | grep -v grep | tr '\n' ',' )
|
||||
|
||||
# perf record -F 99 -p 2401699 -g -- sleep 30
|
||||
# perf script > out.perf
|
||||
# /www/server/dynamic-tracking/FlameGraph/stackcollapse-perf.pl out.perf > out.folded
|
||||
# /www/server/dynamic-tracking/FlameGraph/flamegraph.pl out.folded > php-zend-flame-graph.svg
|
||||
|
||||
# WWW_PID=$(ps -ef|grep "pool www" | awk '{print $2}' | grep -v grep | tr '\n' ',')
|
||||
# WWW_PID=${WWW_PID//,/}
|
||||
# WWW_PID=${var%,}
|
||||
# perf record -F 99 -p "1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1127,1128,1129,1130,1131,1473,1768,2848,2962,21582,35891" \
|
||||
# -g -- sleep 30
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
# 关于macosx使用dtrace
|
||||
|
||||
# https://groups.google.com/g/openresty/c/MswlH_8DDHA
|
||||
# http://dtrace.org/blogs/brendan/2012/11/14/dtracing-in-anger/
|
||||
|
||||
|
||||
# dtrace -x ustackframes=100 -n 'pid$target::mach_msg_trap:entry { @[ustack()] = count(); } tick-30s { exit(0); }' -p 18572 -o out.SystemUIServer_stacks
|
||||
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/stackcollapse.pl out.SystemUIServer_stacks > kernel.cbt
|
||||
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/flamegraph.pl kernel.cbt > kernel.svg
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
SYS_ARCH=`arch`
|
||||
@@ -0,0 +1,365 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import io
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
# -----------------------------
|
||||
import google.oauth2.credentials
|
||||
import google_auth_oauthlib.flow
|
||||
from googleapiclient.discovery import build
|
||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||
from google.auth.transport.requests import Request
|
||||
from googleapiclient.http import MediaFileUpload
|
||||
from googleapiclient.http import MediaIoBaseDownload
|
||||
|
||||
|
||||
class gdriveclient():
|
||||
__plugin_dir = ''
|
||||
__server_dir = ''
|
||||
|
||||
__credentials = "/root/credentials.json"
|
||||
__backup_dir_name = "backup"
|
||||
__creds = None
|
||||
__exclude = ""
|
||||
__scpos = ['https://www.googleapis.com/auth/drive.file']
|
||||
_title = 'Google Drive'
|
||||
_name = 'Google Drive'
|
||||
__debug = False
|
||||
|
||||
_DEFAULT_AUTH_PROMPT_MESSAGE = (
|
||||
'Please visit this URL to authorize this application: {url}')
|
||||
"""str: The message to display when prompting the user for
|
||||
authorization."""
|
||||
_DEFAULT_AUTH_CODE_MESSAGE = (
|
||||
'Enter the authorization code: ')
|
||||
"""str: The message to display when prompting the user for the
|
||||
authorization code. Used only by the console strategy."""
|
||||
|
||||
_DEFAULT_WEB_SUCCESS_MESSAGE = (
|
||||
'The authentication flow has completed, you may close this window.')
|
||||
|
||||
def __init__(self, plugin_dir, server_dir):
|
||||
self.__plugin_dir = plugin_dir
|
||||
self.__server_dir = server_dir
|
||||
self.set_creds()
|
||||
|
||||
# self.get_exclode()
|
||||
|
||||
def setDebug(self, d=False):
|
||||
self.__debug = d
|
||||
|
||||
def D(self, msg=''):
|
||||
if self.__debug:
|
||||
print(msg)
|
||||
|
||||
# 检查gdrive连接
|
||||
def _check_connect(self):
|
||||
try:
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(
|
||||
pageSize=10, fields="nextPageToken, files(id, name)").execute()
|
||||
results.get('files', [])
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
# 设置creds
|
||||
def set_creds(self):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
if os.path.exists(token_file):
|
||||
with open(token_file, 'rb') as token:
|
||||
tmp_data = json.load(token)['credentials']
|
||||
self.__creds = google.oauth2.credentials.Credentials(
|
||||
tmp_data['token'],
|
||||
tmp_data['refresh_token'],
|
||||
tmp_data['id_token'],
|
||||
tmp_data['token_uri'],
|
||||
tmp_data['client_id'],
|
||||
tmp_data['client_secret'],
|
||||
tmp_data['scopes'])
|
||||
# if not self._check_connect():
|
||||
# return False
|
||||
# else:
|
||||
# return True
|
||||
|
||||
def get_sign_in_url(self):
|
||||
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
|
||||
self.__plugin_dir + '/credentials.json',
|
||||
scopes=self.__scpos)
|
||||
# flow.redirect_uri = 'https://drive.aapanel.com'
|
||||
flow.redirect_uri = 'https://drive.aapanel.com'
|
||||
auth_url, state = flow.authorization_url(
|
||||
access_type='offline',
|
||||
prompt='consent',
|
||||
include_granted_scopes='false')
|
||||
return auth_url, state
|
||||
|
||||
def set_auth_url(self, url):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
if os.path.exists(token_file):
|
||||
return mw.returnJson(True, "验证成功")
|
||||
|
||||
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
|
||||
self.__plugin_dir + '/credentials.json',
|
||||
scopes=self.__scpos,
|
||||
state=url.split('state=')[1].split('&code=')[0])
|
||||
# flow.redirect_uri = 'https://localhost'
|
||||
flow.redirect_uri = 'https://drive.aapanel.com'
|
||||
flow.fetch_token(authorization_response=url)
|
||||
credentials = flow.credentials
|
||||
|
||||
credentials_data = {}
|
||||
credentials_data['credentials'] = {
|
||||
'token': credentials.token,
|
||||
'id_token': credentials.id_token,
|
||||
'refresh_token': credentials.refresh_token,
|
||||
'token_uri': credentials.token_uri,
|
||||
'client_id': credentials.client_id,
|
||||
'client_secret': credentials.client_secret,
|
||||
'scopes': credentials.scopes}
|
||||
with open(token_file, 'w') as token:
|
||||
json.dump(credentials_data, token)
|
||||
if not self.set_creds():
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
return mw.returnJson(True, "验证成功")
|
||||
|
||||
# 获取token
|
||||
def get_token(self, get):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
import requests
|
||||
try:
|
||||
respone = requests.get("https://www.google.com", timeout=2)
|
||||
except:
|
||||
return mw.returnJson(False, "连接谷歌失败")
|
||||
if respone.status_code != 200:
|
||||
return mw.returnJson(False, "连接谷歌失败")
|
||||
if not self.set_creds():
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
if not os.path.exists(token_file):
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
return mw.returnJson(True, "验证成功")
|
||||
|
||||
# 获取auth_url
|
||||
def get_auth_url(self, get):
|
||||
self.get_sign_in_url()
|
||||
if os.path.exists("/tmp/auth_url"):
|
||||
return mw.readFile("/tmp/auth_url")
|
||||
|
||||
# 检查连接
|
||||
def check_connect(self, get):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
if os.path.exists(token_file):
|
||||
with open(token_file, 'rb') as token:
|
||||
self.set_creds()
|
||||
else:
|
||||
self.D("Failed to get Google token, please verify before use")
|
||||
return mw.returnJson(True, "Failed to get Google token, please verify before use")
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(
|
||||
pageSize=10, fields="nextPageToken, files(id, name)").execute()
|
||||
try:
|
||||
results.get('files', [])
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
return mw.returnJson(True, "验证成功")
|
||||
except:
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
|
||||
def _get_filename(self, filename):
|
||||
l = filename.split("/")
|
||||
return l[-1]
|
||||
|
||||
def _create_folder_cycle(self, filepath):
|
||||
l = filepath.split("/")
|
||||
fid_list = []
|
||||
for i in l:
|
||||
if not i:
|
||||
continue
|
||||
fid = self.__get_folder_id(i)
|
||||
if fid:
|
||||
fid_list.append(fid)
|
||||
continue
|
||||
if not fid_list:
|
||||
fid_list.append("")
|
||||
fid_list.append(self.create_folder(i, fid_list[-1]))
|
||||
return fid_list[-1]
|
||||
|
||||
def build_object_name(self, data_type, file_name):
|
||||
"""根据数据类型构建对象存储名称
|
||||
|
||||
:param data_type:
|
||||
:param file_name:
|
||||
:return:
|
||||
"""
|
||||
|
||||
import re
|
||||
prefix_dict = {
|
||||
"site": "web",
|
||||
"database": "db",
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
if not prefix_dict.get(data_type):
|
||||
print("data_type 类型错误!!!")
|
||||
exit(1)
|
||||
|
||||
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+\."
|
||||
sub_search = re.search(file_regx.lower(), file_name)
|
||||
sub_path_name = ""
|
||||
if sub_search:
|
||||
sub_path_name = sub_search.groups()[0]
|
||||
sub_path_name += '/'
|
||||
# 构建OS存储路径
|
||||
object_name = self.__backup_dir_name + \
|
||||
'/{}/{}'.format(data_type, sub_path_name)
|
||||
|
||||
if object_name[:1] == "/":
|
||||
object_name = object_name[1:]
|
||||
return object_name
|
||||
|
||||
# 上传文件
|
||||
def upload_file(self, filename, data_type=None):
|
||||
"""
|
||||
get.filename 上传后的文件名
|
||||
get.filepath 上传文件路径
|
||||
被面板新版计划任务调用时
|
||||
get表示file_name
|
||||
:param get:
|
||||
:return:
|
||||
"""
|
||||
# filename = filename
|
||||
filepath = self.build_object_name(data_type, filename)
|
||||
_filename = self._get_filename(filename)
|
||||
self.D(filepath)
|
||||
self.D(filename)
|
||||
|
||||
parents = self._create_folder_cycle(filepath)
|
||||
self.D(parents)
|
||||
drive_service = build('drive', 'v3', credentials=self.__creds)
|
||||
file_metadata = {'name': _filename, 'parents': [parents]}
|
||||
media = MediaFileUpload(filename, resumable=True)
|
||||
file = drive_service.files().create(
|
||||
body=file_metadata, media_body=media, fields='id').execute()
|
||||
self.D('Upload Success ,File ID: %s' % file.get('id'))
|
||||
return True
|
||||
|
||||
def _get_file_id(self, filename):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, q="name='{}'".format(
|
||||
filename), fields="nextPageToken, files(id, name)").execute()
|
||||
items = results.get('files', [])
|
||||
if not items:
|
||||
return []
|
||||
else:
|
||||
for item in items:
|
||||
return item["id"]
|
||||
|
||||
def delete_file(self, filename=None, data_type=None):
|
||||
file_id = self._get_file_id(filename)
|
||||
self.delete_file_by_id(file_id)
|
||||
return True
|
||||
|
||||
def delete_file_by_id(self, file_id):
|
||||
self.D("delete id:{}".format(file_id))
|
||||
try:
|
||||
drive_service = build('drive', 'v3', credentials=self.__creds)
|
||||
drive_service.files().delete(fileId=file_id).execute()
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
# 创建目录
|
||||
def create_folder(self, folder_name, parents=""):
|
||||
self.D(self.__creds)
|
||||
self.D("folder_name: {}".format(folder_name))
|
||||
self.D("parents: {}".format(parents))
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
file_metadata = {
|
||||
'name': folder_name,
|
||||
'mimeType': 'application/vnd.google-apps.folder'
|
||||
}
|
||||
if parents:
|
||||
file_metadata['parents'] = [parents]
|
||||
folder = service.files().create(body=file_metadata, fields='id').execute()
|
||||
self.D('Create Folder ID: %s' % folder.get('id'))
|
||||
return folder.get('id')
|
||||
|
||||
def get_rootdir_id(self, folder_name='backup'):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, q="name='{}' and mimeType='application/vnd.google-apps.folder'".format(folder_name),
|
||||
fields="nextPageToken, files(id, name,size,parents,webViewLink)").execute()
|
||||
items = results.get('files', [])
|
||||
if len(items) == 0:
|
||||
self.create_folder(folder_name)
|
||||
return self.get_rootdir_id(folder_name)
|
||||
|
||||
return items[0]['parents'][0]
|
||||
|
||||
# 获取目录id
|
||||
def __get_folder_id(self, floder_name):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, q="name='{}' and mimeType='application/vnd.google-apps.folder'".format(floder_name),
|
||||
fields="nextPageToken, files(id, name)").execute()
|
||||
items = results.get('files', [])
|
||||
if not items:
|
||||
return []
|
||||
else:
|
||||
for item in items:
|
||||
return item["id"]
|
||||
|
||||
def get_res_info(self, rid):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().get(fileId='{}'.format(rid)).execute()
|
||||
return results
|
||||
|
||||
def get_id_list(self, driveId=''):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, driveId="{}".format(driveId),
|
||||
fields="nextPageToken, files(id, name,size,parents)").execute()
|
||||
items = results.get('files', [])
|
||||
return items
|
||||
|
||||
def get_list(self, dir_id='', next_page_token=''):
|
||||
if dir_id == '':
|
||||
dir_id = self.get_rootdir_id(self.__backup_dir_name)
|
||||
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
cmd_query = "trashed=false and '{}' in parents".format(dir_id)
|
||||
results = service.files().list(pageSize=10, q=cmd_query, orderBy='folder asc',
|
||||
fields="nextPageToken, files(id, name,size,createdTime,parents,webViewLink)").execute()
|
||||
items = results.get('files', [])
|
||||
nextPageToken = results.get('nextPageToken', [])
|
||||
# print(items)
|
||||
# print(nextPageToken)
|
||||
return items
|
||||
|
||||
def get_exclode(self, exclude=[]):
|
||||
if not exclude:
|
||||
tmp_exclude = os.getenv('MW_EXCLUDE')
|
||||
if tmp_exclude:
|
||||
exclude = tmp_exclude.split(',')
|
||||
if not exclude:
|
||||
return ""
|
||||
for ex in exclude:
|
||||
self.__exclude += " --exclude=\"" + ex + "\""
|
||||
self.__exclude += " "
|
||||
return self.__exclude
|
||||
|
||||
def download_file(self, filename):
|
||||
file_id = self._get_file_id(filename)
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
request = service.files().get_media(fileId=file_id)
|
||||
with open('/tmp/{}'.format(filename), 'wb') as fh:
|
||||
downloader = MediaIoBaseDownload(fh, request)
|
||||
done = False
|
||||
while done is False:
|
||||
status, done = downloader.next_chunk()
|
||||
print("Download %d%%." % int(status.progress() * 100))
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"web": {
|
||||
"client_id": "226011946234-d3e1vashgag64utjedu1ljt9u39ncrpq.apps.googleusercontent.com",
|
||||
"project_id": "light-willow-341609",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_secret": "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",
|
||||
"redirect_uris": [
|
||||
"https://drive.aapanel.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"web": {
|
||||
"client_id": "540181629246-1horo9i4htamdbhiqar9rcbq33bqe2ob.apps.googleusercontent.com",
|
||||
"project_id": "plated-inn-369901",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_secret": "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",
|
||||
"redirect_uris": ["https://drive.aapanel.com"]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,310 @@
|
||||
<style>
|
||||
.upyunCon {
|
||||
height: 428px;
|
||||
}
|
||||
|
||||
.up-place {
|
||||
height: 62px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.up-place .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.up-place .place-input {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
overflow: hidden;
|
||||
margin: 1px 0 0 -1px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
.place-input ul {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.place-input ul li {
|
||||
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.place-input ul li a {
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upyunlist {
|
||||
height: 516px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.up-bottom {
|
||||
background-color: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.up-use {
|
||||
line-height: 50px
|
||||
}
|
||||
|
||||
.list-list .cursor span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.btn-title {
|
||||
margin-top: 1px
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 10px;
|
||||
font-style: oblique;
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<div class="upyunCon">
|
||||
<div class="up-place pd15">
|
||||
<button id="backBtn" class="btn btn-default btn-sm glyphicon glyphicon-arrow-left pull-left" title="后退"></button>
|
||||
<input id="myPath" type="hidden" value="">
|
||||
<input id="curPath" type="hidden" value="">
|
||||
<div class="place-input pull-left">
|
||||
<div style="width:1400px;height:28px"><ul></ul></div>
|
||||
</div>
|
||||
<button class="refreshBtn btn btn-default btn-sm glyphicon glyphicon-refresh pull-left mr20" title="刷新" style="margin-left:-1px;"></button>
|
||||
<button class="btn btn-default btn-sm pull-right btn-title" onclick="authApi()">授权</button>
|
||||
<button class="btn btn-default btn-sm pull-right mr20 btn-title" onclick="createDir()">新建文件夹</button>
|
||||
</div>
|
||||
|
||||
<div class="upyunlist pd15">
|
||||
<div class="divtable" style="margin-bottom:15px">
|
||||
<table class="table table-hover">
|
||||
<thead><tr><th>名称</th><th>大小</th><th>更新时间</th><th class="text-right">操作</th></tr></thead>
|
||||
<tbody class="list-list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style type="text/css">
|
||||
.check_api {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.up-place {
|
||||
height: 62px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.up-place .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.up-place .place-input {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
overflow: hidden;
|
||||
margin: 1px 0 0 -1px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
.place-input ul {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.place-input ul li {
|
||||
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.place-input ul li a {
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upyunlist {
|
||||
height: 546px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.up-bottom {
|
||||
background-color: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.up-use {
|
||||
line-height: 50px
|
||||
}
|
||||
|
||||
.list-list .cursor span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.btn-title {
|
||||
margin-top: 1px
|
||||
}
|
||||
|
||||
.step_item{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.step_item .serial_box{
|
||||
display: inline-block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.step_item .serial{
|
||||
width: 70px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
.step_item .serial span{
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 28px;
|
||||
font-size: 11px;
|
||||
border-radius: 50%;
|
||||
color: #20a53a;
|
||||
border: 2px solid #20a53a;
|
||||
}
|
||||
.step_item .serial_title{
|
||||
margin-bottom: 10px;
|
||||
font-size: 15px;
|
||||
line-height: 30px;
|
||||
color: #666;
|
||||
}
|
||||
.step_two_url{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
width: 380px;
|
||||
/*text-overflow: ellipsis;*/
|
||||
white-space: nowrap;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
margin-right: 15px;
|
||||
border-radius: 2px;
|
||||
padding: 0 10px;
|
||||
float: left;
|
||||
width:360px;
|
||||
padding-right: 35px;
|
||||
}
|
||||
.btn_btlink{
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
border: 1px solid #20a53a;
|
||||
color: #fff;
|
||||
background-color: #20a53a;
|
||||
margin-right:10px;
|
||||
}
|
||||
.btn_btlink:hover{
|
||||
color: #fff;
|
||||
background-color: #10952a;
|
||||
border-color: #398439;
|
||||
}
|
||||
.btn_btlink a:visited{
|
||||
color: #fff;
|
||||
background-color: #10952a;
|
||||
border-color: #398439;
|
||||
}
|
||||
.view_video{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.view_video ul li{
|
||||
line-height: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.setp_one i{
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 25px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.google_drive{
|
||||
width:465px;
|
||||
height:100px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/html" id="check_api">
|
||||
<div class="check_api">
|
||||
<div class="step_two">
|
||||
<div class="step_item">
|
||||
<div class="serial"><span>1</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">阅读简易操作教程:如何获取Google Drive授权?</div>
|
||||
<div class="serial_conter">
|
||||
<div class="view_video">
|
||||
<ul>
|
||||
<li>1. 点击下面第<div class="serial" style="float: none;width: 45px;"><span>2</span></div>步中的 打开授权链接。<li>
|
||||
<li>2. 在新窗口页面上登录Google Drive账号。阅读授权权限,并同意。<li>
|
||||
<li>3. 页面跳转后,将浏览器的地址栏地址复制到第<div class="serial" style="float: none;width: 45px;"><span>3</span></div>步的文本框中。<li>
|
||||
<li>4. 点击 获取授权,随即完成授权。<li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step_item pb15">
|
||||
<div class="serial"><span>2</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">操作1:👇打开授权链接,根据网页提示对插件进行授权。</div>
|
||||
<div class="serial_conter step_two" style="width: 500px;">
|
||||
<input class="bt-input-text mr5 step_two_url" type="text" disabled>
|
||||
<span class="ico-copy mr10" data-copy="" style="vertical-align: middle;cursor: pointer;margin-left: -37px;margin-right: 20px;"></span>
|
||||
<a href="" class="btn_btlink open_btlink" target="_blank" style="padding: 7px 10px;">打开授权链接</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="step_item">
|
||||
<div class="serial"><span>3</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">操作2:复制回浏览器跳转后的地址:</div>
|
||||
<div class="serial_conter">
|
||||
<textarea row="3" placeholder="验证URL地址" class="bt-input-text google_drive" style="resize: none;"/></br>
|
||||
<button type="button" class="btn btn-success btn-sm set_auth_btn">获取授权</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/javascript" src="/plugins/file?name=gdrive&f=js/gdrive.js"></script>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=gdrive&f=js/gdrive.js", function(){
|
||||
gdList('');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,338 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
# print(sys.platform)
|
||||
if sys.platform != "darwin":
|
||||
os.chdir("/www/server/mdserver-web")
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
import db
|
||||
|
||||
_ver = sys.version_info
|
||||
is_py2 = (_ver[0] == 2)
|
||||
is_py3 = (_ver[0] == 3)
|
||||
|
||||
DEBUG = False
|
||||
|
||||
if is_py2:
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'gdrive'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def in_array(name, arr=[]):
|
||||
for x in arr:
|
||||
if name == x:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
sys.path.append(getPluginDir() + "/class")
|
||||
from gdriveclient import gdriveclient
|
||||
|
||||
|
||||
gd = gdriveclient(getPluginDir(), getServerDir())
|
||||
gd.setDebug(False)
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':', 1)
|
||||
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 isAuthApi():
|
||||
cfg = getServerDir() + "/token.json"
|
||||
if os.path.exists(cfg):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getConf():
|
||||
if not isAuthApi():
|
||||
sign_in_url, state = gd.get_sign_in_url()
|
||||
return mw.returnJson(False, "未授权!", {'auth_url': sign_in_url})
|
||||
return mw.returnJson(True, "OK")
|
||||
|
||||
|
||||
def setAuthUrl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['url'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
url = args['url']
|
||||
|
||||
try:
|
||||
if url.startswith("http://"):
|
||||
url = url.replace("http://", "https://")
|
||||
token = gd.set_auth_url(url)
|
||||
# gd.store_token(token)
|
||||
# gd.store_user()
|
||||
return mw.returnJson(True, "授权成功!")
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "授权失败2!:" + str(e))
|
||||
return mw.returnJson(False, "授权失败!:" + str(e))
|
||||
|
||||
|
||||
def clearAuth():
|
||||
token = getServerDir() + "/token.json"
|
||||
if os.path.exists(token):
|
||||
os.remove(token)
|
||||
return mw.returnJson(True, "清空授权成功!")
|
||||
|
||||
|
||||
def getList():
|
||||
if not isAuthApi():
|
||||
return mw.returnJson(False, "未配置,请点击`授权`", [])
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file_id'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
try:
|
||||
flist = gd.get_list(args['file_id'])
|
||||
return mw.returnJson(True, "ok", flist)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, str(e), [])
|
||||
|
||||
|
||||
def createDir():
|
||||
if not isAuthApi():
|
||||
return mw.returnJson(False, "未配置,请点击`授权`", [])
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['parents', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
isok = gd.create_folder(args['name'], args['parents'])
|
||||
if isok:
|
||||
return mw.returnJson(True, "创建成功")
|
||||
return mw.returnJson(False, "创建失败")
|
||||
|
||||
|
||||
def deleteDir():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['dir_name', 'path'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
isok = gd.delete_file_by_id(args['dir_name'])
|
||||
if isok:
|
||||
return mw.returnJson(True, "删除成功")
|
||||
return mw.returnJson(False, "文件不为空,删除失败!")
|
||||
|
||||
|
||||
def deleteFile():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['path', 'filename'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
isok = gd.delete_file(args['filename'])
|
||||
if isok:
|
||||
return mw.returnJson(True, "删除成功")
|
||||
return mw.returnJson(False, "删除失败")
|
||||
|
||||
|
||||
def findPathName(path, filename):
|
||||
f = os.scandir(path)
|
||||
l = []
|
||||
for ff in f:
|
||||
t = {}
|
||||
if ff.name.find(filename) > -1:
|
||||
t['filename'] = path + '/' + ff.name
|
||||
l.append(t)
|
||||
return l
|
||||
|
||||
|
||||
def backupAllFunc(stype):
|
||||
if not isAuthApi():
|
||||
mw.echoInfo("未授权API,无法使用!!!")
|
||||
return ''
|
||||
|
||||
os.chdir(mw.getRunDir())
|
||||
backup_dir = mw.getBackupDir()
|
||||
run_dir = mw.getRunDir()
|
||||
|
||||
stype = sys.argv[1]
|
||||
name = sys.argv[2]
|
||||
num = sys.argv[3]
|
||||
|
||||
prefix_dict = {
|
||||
"site": "web",
|
||||
"database": "db",
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
backups = []
|
||||
sql = db.Sql()
|
||||
|
||||
# print("stype:", stype)
|
||||
# 提前获取-清理多余备份
|
||||
if stype == 'site':
|
||||
pid = sql.table('sites').where('name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('0', pid)).field('id,filename').select()
|
||||
if stype == 'database':
|
||||
db_path = mw.getServerDir() + '/mysql'
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
if stype == 'path':
|
||||
backup_path = backup_dir + '/path'
|
||||
_name = 'path_{}'.format(os.path.basename(name))
|
||||
backups = findPathName(backup_path, _name)
|
||||
|
||||
# 其他类型关系性数据库(mysql类的)
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
db_path = mw.getServerDir() + '/' + plugin_name
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
|
||||
args = stype + " " + name + " " + num
|
||||
cmd = 'python3 ' + run_dir + '/scripts/backup.py ' + args
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
args = "database " + name + " " + num
|
||||
cmd = 'python3 ' + run_dir + '/plugins/' + \
|
||||
plugin_name + '/scripts/backup.py ' + args
|
||||
|
||||
if stype == 'path':
|
||||
name = os.path.basename(name)
|
||||
|
||||
# print("cmd:", cmd)
|
||||
os.system(cmd)
|
||||
|
||||
# 开始执行上传信息.
|
||||
if stype.find('database_') > -1:
|
||||
bk_name = 'database'
|
||||
plugin_name = stype.replace('database_', '')
|
||||
bk_prefix = plugin_name + '/db'
|
||||
stype = 'database'
|
||||
else:
|
||||
bk_prefix = prefix_dict[stype]
|
||||
bk_name = stype
|
||||
|
||||
find_path = backup_dir + '/' + bk_name + '/' + bk_prefix + '_' + name
|
||||
find_new_file = "ls " + find_path + \
|
||||
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
|
||||
|
||||
# print(find_new_file)
|
||||
|
||||
filename = mw.execShell(find_new_file)[0].strip()
|
||||
if filename == "":
|
||||
mw.echoInfo("not find upload file!")
|
||||
return False
|
||||
|
||||
mw.echoInfo("准备上传文件 {}".format(filename))
|
||||
mw.echoStart('开始上传')
|
||||
# gd.setDebug(False)
|
||||
gd.upload_file(filename, stype)
|
||||
mw.echoEnd('上传成功')
|
||||
|
||||
# print(backups)
|
||||
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
|
||||
mw.echoStart('开始删除远程备份')
|
||||
num = int(num)
|
||||
sep = len(backups) - num
|
||||
if sep > -1:
|
||||
for backup in backups:
|
||||
fn = os.path.basename(backup['filename'])
|
||||
gd.delete_file(fn, stype)
|
||||
mw.echoInfo("---已清理远程过期备份文件:" + fn)
|
||||
sep -= 1
|
||||
if sep < 0:
|
||||
break
|
||||
mw.echoEnd('结束删除远程备份')
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def installPreInspection():
|
||||
return 'ok'
|
||||
|
||||
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())
|
||||
elif func == 'install_pre_inspection':
|
||||
print(installPreInspection())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'set_auth_url':
|
||||
print(setAuthUrl())
|
||||
elif func == 'clear_auth':
|
||||
print(clearAuth())
|
||||
elif func == "get_list":
|
||||
print(getList())
|
||||
elif func == "create_dir":
|
||||
print(createDir())
|
||||
elif func == "delete_dir":
|
||||
print(deleteDir())
|
||||
elif func == 'delete_file':
|
||||
print(deleteFile())
|
||||
elif in_array(func, ['site', 'database', 'path']) or func.find('database_') > -1:
|
||||
print(backupAllFunc(func))
|
||||
else:
|
||||
print('error')
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"hook":["backup"],
|
||||
"id":998,
|
||||
"title":"谷歌云网盘",
|
||||
"tip":"lib",
|
||||
"name":"gdrive",
|
||||
"type":"扩展",
|
||||
"ps":"备份你的数据到谷歌云网盘",
|
||||
"versions":"2.0",
|
||||
"shell":"install.sh",
|
||||
"checks": "server/gdrive",
|
||||
"path":"server/gdrive",
|
||||
"author":"google",
|
||||
"home":"https://drive.google.com/",
|
||||
"api_doc":"https://developers.google.com/drive/api/guides/about-sdk?hl=zh_CN",
|
||||
"api_doc2":"https://developers.google.cn/drive/api/reference/rest/v3/comments/list?hl=zh-cn",
|
||||
"date":"2022-06-26",
|
||||
"pid":"4"
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/gdrive && /bin/bash install.sh install 2.0
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
PATH=$PATH:${rootPath}/bin
|
||||
export PATH
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
VERSION=$2
|
||||
|
||||
Install_App()
|
||||
{
|
||||
tmp_ping=`ping -c 1 google.com 2>&1`
|
||||
echo $tmp_ping
|
||||
if [ $? -eq 0 ];then
|
||||
tmp=`python -V 2>&1|awk '{print $2}'`
|
||||
pVersion=${tmp:0:3}
|
||||
|
||||
|
||||
which pip
|
||||
if [ "$?" -eq "0" ];then
|
||||
tmp=$(pip list|grep google-api-python-client|awk '{print $2}')
|
||||
if [ "$tmp" != '2.39.0' ];then
|
||||
pip install --upgrade google-api-python-client
|
||||
# pip uninstall google-api-python-client -y
|
||||
pip install -I google-api-python-client==2.39.0 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
tmp=$(pip list|grep google-auth-httplib2|awk '{print $2}')
|
||||
if [ "$tmp" != '0.1.0' ];then
|
||||
pip uninstall google-auth-httplib2 -y
|
||||
pip install -I google-auth-httplib2==0.1.0 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
tmp=$(pip list|grep google-auth-oauthlib|awk '{print $2}')
|
||||
if [ "$tmp" != '0.5.0' ];then
|
||||
# pip uninstall google-auth-oauthlib -y
|
||||
pip install -I google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
tmp=$(pip list|grep -E '^httplib2'|awk '{print $2}')
|
||||
if [ "$tmp" != '0.18.1' ];then
|
||||
# pip uninstall httplib2 -y
|
||||
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
else
|
||||
pip install -I pyOpenSSL
|
||||
pip install -I google-api-python-client==2.39.0 google-auth-httplib2==0.1.0 google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
|
||||
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
mkdir -p $serverPath/gdrive
|
||||
echo "${VERSION}" > $serverPath/gdrive/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo '服务器连接不上谷歌云!安装失败!' > $install_tmp
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/gdrive
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
action=$1
|
||||
type=$2
|
||||
|
||||
echo $action $type
|
||||
if [ "${action}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
@@ -0,0 +1,260 @@
|
||||
|
||||
function gdPost(method,args,callback){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'gdrive', func:method, args:_args}, 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 createDir(){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: "400px",
|
||||
title: "创建目录",
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
btn: ['确定','取消'],
|
||||
content:'<div class="bingfa bt-form c6" style="padding-bottom: 10px;">\
|
||||
<p>\
|
||||
<span class="span_tit">目录名称:</span>\
|
||||
<input style="width: 200px;" type="text" name="newPath" value="">\
|
||||
</p>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("input[name='newPath']").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(index,layero){
|
||||
var name = $("input[name='newPath']").val();
|
||||
if(name == ''){
|
||||
layer.msg('目录名称不能为空!',{icon:2});
|
||||
return;
|
||||
}
|
||||
var parents = $("#myPath").val();
|
||||
var cur_file_id = $('#curPath').val();
|
||||
if (cur_file_id!=''){
|
||||
parents = cur_file_id;
|
||||
}
|
||||
|
||||
var dirname = name;
|
||||
var loadT = layer.msg('正在创建目录['+dirname+']...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
gdPost('create_dir', {parents:parents,name:dirname}, function(data){
|
||||
layer.close(loadT);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if(rdata.status) {
|
||||
showMsg(rdata.msg, function(){
|
||||
layer.close(index);
|
||||
var file_id = $('#myPath').val();
|
||||
if (cur_file_id!=''){
|
||||
file_id = cur_file_id;
|
||||
}
|
||||
gdList(file_id);
|
||||
} ,{icon:1}, 2000);
|
||||
} else{
|
||||
layer.msg(rdata.msg,{icon:2});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//设置API
|
||||
function authApi(){
|
||||
|
||||
gdPost('conf', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
|
||||
// console.log(rdata);
|
||||
// console.log(rdata.data.auth_url);
|
||||
var apicon = '';
|
||||
if (rdata.status){
|
||||
|
||||
var html = '';
|
||||
html += '<button id="clear_auth" onclick="clearAuth();" class="btn btn-default btn-sm">清空配置</button>';
|
||||
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '已授权',
|
||||
area: '240px',
|
||||
content:'<div class="change-default pd20">'+html+'</div>',
|
||||
success: function(){
|
||||
$('#clear_auth').click(function(){
|
||||
gdPost('clear_auth', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(loadOpen);
|
||||
gdList('');
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
||||
} else{
|
||||
apicon = '<div class="new_form">'+$("#check_api").html()+'</div>';
|
||||
}
|
||||
|
||||
var layer_auth = layer.open({
|
||||
type: 1,
|
||||
area: "620px",
|
||||
title: "Google Drive 授权",
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:apicon,
|
||||
success:function(layero,index){
|
||||
// console.log(layero,index);
|
||||
if (!rdata.status){
|
||||
$('.check_api .step_two_url').val(rdata.data['auth_url']);
|
||||
$('.check_api .open_btlink').attr('href',rdata.data['auth_url']);
|
||||
|
||||
$('.check_api .ico-copy').click(function(){
|
||||
copyPass(rdata.data['auth_url']);
|
||||
});
|
||||
|
||||
$('.check_api .set_auth_btn').click(function(){
|
||||
|
||||
var url = $('.check_api .google_drive').val();
|
||||
if ( url == ''){
|
||||
layer.msg("验证URL不能为空",{icon:2});
|
||||
return;
|
||||
}
|
||||
// console.log(url);
|
||||
gdPost('set_auth_url', {url:url}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
var show_time = 2000;
|
||||
if (!rdata.status){
|
||||
show_time = 10000;
|
||||
}
|
||||
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(layer_auth);
|
||||
gdList('');
|
||||
}
|
||||
},{icon:rdata.status?1:2},show_time);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//计算当前目录偏移
|
||||
function upPathLeft(){
|
||||
var UlWidth = $(".place-input ul").width();
|
||||
var SpanPathWidth = $(".place-input").width() - 20;
|
||||
var Ml = UlWidth - SpanPathWidth;
|
||||
if(UlWidth > SpanPathWidth ){
|
||||
$(".place-input ul").css("left",-Ml)
|
||||
}
|
||||
else{
|
||||
$(".place-input ul").css("left",0)
|
||||
}
|
||||
}
|
||||
|
||||
function getGDTime(a) {
|
||||
return new Date(a).format("yyyy/MM/dd hh:mm:ss")
|
||||
}
|
||||
|
||||
function gdList(file_id){
|
||||
$('#curPath').val(file_id);
|
||||
gdPost('get_list', {file_id:file_id}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
console.log(rdata);
|
||||
if(rdata.status === false){
|
||||
showMsg(rdata.msg,function(){
|
||||
authApi();
|
||||
},{icon:2},2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var mlist = rdata.data;
|
||||
var listBody = '';
|
||||
var listFiles = '';
|
||||
for(var i=0;i<mlist.length;i++){
|
||||
if(mlist[i].size == null){
|
||||
listFiles += '<tr><td class="cursor" onclick="gdList(\''+(mlist[i].id).replace('//','/')+'\')"><span class="ico ico-folder"></span>\<span>'+mlist[i].name+'</span></td>\
|
||||
<td>-</td>\
|
||||
<td>-</td>\
|
||||
<td class="text-right"><a class="btlink" onclick="deleteFile(\''+mlist[i].id+'\', true)">删除</a></td></tr>'
|
||||
}else{
|
||||
listFiles += '<tr><td class="cursor"><span class="ico ico-file"></span><span>'+mlist[i].name+'</span></td>\
|
||||
<td>'+toSize(mlist[i].size)+'</td>\
|
||||
<td>'+getGDTime(mlist[i].createdTime)+'</td>\
|
||||
<td class="text-right"><a target="_blank" href="'+mlist[i].webViewLink+'" class="btlink">下载</a> | <a class="btlink" onclick="deleteFile(\''+mlist[i].name+'\', false)">删除</a></td></tr>'
|
||||
}
|
||||
}
|
||||
listBody += listFiles;
|
||||
var pathLi = '<li><a title="根目录" onclick="gdList(\'\')">根目录</a></li>';
|
||||
|
||||
if (mlist.length>0){
|
||||
$('#myPath').val(mlist[0]['parents'][0]);
|
||||
}
|
||||
|
||||
$(".upyunCon .place-input ul").html(pathLi);
|
||||
$(".upyunlist .list-list").html(listBody);
|
||||
|
||||
$('#backBtn').unbind().click(function() {
|
||||
gdList('');
|
||||
});
|
||||
|
||||
$('.upyunCon .refreshBtn').unbind().click(function(){
|
||||
var file_id = $('#myPath').val();
|
||||
gdList(file_id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//删除文件
|
||||
function deleteFile(name, is_dir){
|
||||
if (is_dir === false){
|
||||
safeMessage('删除文件','删除后将无法恢复,真的要删除['+name+']吗?',function(){
|
||||
var path = $("#myPath").val();
|
||||
var filename = name;
|
||||
gdPost('delete_file', {filename:filename,path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
var file_id = $('#myPath').val();
|
||||
gdList(file_id);
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
safeMessage('删除文件夹','删除后将无法恢复,真的要删除文件资源['+name+']吗?',function(){
|
||||
var path = $("#myPath").val();
|
||||
gdPost('delete_dir', {dir_name:name,path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
var file_id = $('#myPath').val();
|
||||
gdList(file_id);
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
# python3 plugins/gdrive/t/test.py
|
||||
# https://console.cloud.google.com/apis/credentials/consent?project=plated-inn-369901
|
||||
|
||||
# https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=226011946234-d3e1vashgag64utjedu1ljt9u39ncrpq.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fdrive.aapanel.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&state=I2da4aZUwqgmikrgrqAwwSjyoEHVs1&access_type=offline&prompt=consent&include_granted_scopes=false
|
||||
|
||||
|
||||
# https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/08125e6b-6502-4ac9-9548-ad682f00848d/objectId/62b1d655-9828-47ed-be99-65eb18c3a929/isMSAApp~/false/defaultBlade/Overview/appSignInAudience/AzureADandPersonalMicrosoftAccount/servicePrincipalCreated~/true
|
||||
|
||||
# 0WA8Q~sZkZFZKv50ryP4ux~.fpVtbHw7BuTZmbQB
|
||||
# client_id:d9878fac-8526-4ff6-8036-e1c92dd9dd80
|
||||
|
||||
# 08125e6b-6502-4ac9-9548-ad682f00848d
|
||||
|
||||
|
||||
# /drive/v2internal/files?openDrive=false&reason=102&syncType=0&errorRecovery=false&q=trashed = false and '1-z6gUXseXmlxmntvkLzOe_tYFT5tdhM9' in parents&fields=kind,nextPageToken,items(kind,modifiedDate,hasVisitorPermissions,containsUnsubscribedChildren,modifiedByMeDate,lastViewedByMeDate,alternateLink,fileSize,owners(kind,permissionId,emailAddressFromAccount,id),lastModifyingUser(kind,permissionId,emailAddressFromAccount,id),customerId,ancestorHasAugmentedPermissions,hasThumbnail,thumbnailVersion,title,id,resourceKey,abuseIsAppealable,abuseNoticeReason,shared,accessRequestsCount,sharedWithMeDate,userPermission(role),explicitlyTrashed,mimeType,quotaBytesUsed,copyable,subscribed,folderColor,hasChildFolders,fileExtension,primarySyncParentId,sharingUser(kind,permissionId,emailAddressFromAccount,id),flaggedForAbuse,folderFeatures,spaces,sourceAppId,recency,recencyReason,version,actionItems,teamDriveId,hasAugmentedPermissions,createdDate,primaryDomainName,organizationDisplayName,passivelySubscribed,trashingUser(kind,permissionId,emailAddressFromAccount,id),trashedDate,parents(id),capabilities(canMoveItemIntoTeamDrive,canUntrash,canModifyContentRestriction,canMoveItemWithinTeamDrive,canMoveItemOutOfTeamDrive,canDeleteChildren,canTrashChildren,canRequestApproval,canReadCategoryMetadata,canEditCategoryMetadata,canAddMyDriveParent,canRemoveMyDriveParent,canShareChildFiles,canShareChildFolders,canRead,canMoveItemWithinDrive,canMoveChildrenWithinDrive,canAddFolderFromAnotherDrive,canChangeSecurityUpdateEnabled,canBlockOwner,canReportSpamOrAbuse,canCopy,canDownload,canEdit,canAddChildren,canDelete,canRemoveChildren,canShare,canTrash,canRename,canReadTeamDrive,canMoveTeamDriveItem),contentRestrictions(readOnly),approvalMetadata(approvalVersion,approvalSummaries,hasIncomingApproval),shortcutDetails(targetId,targetMimeType,targetLookupStatus,targetFile,canRequestAccessToTarget),spamMetadata(markedAsSpamDate,inSpamView),labels(starred,trashed,restricted,viewed)),incompleteSearch&appDataFilter=NO_APP_DATA&spaces=drive&maxResults=200&supportsTeamDrives=true&includeItemsFromAllDrives=true&corpora=default&orderBy=folder,title_natural asc&retryCount=0&key=AIzaSyD_InbmSFufIEps5UAt2NmB_3LvBH3Sz_8 HTTP/1.1
|
||||
|
||||
# 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 database t1 3
|
||||
# python3 /www/server/mdserver-web/plugins/msonedrive/index.py path
|
||||
# /Users/midoks/Desktop/dev/python 3
|
||||
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'gdrive'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
# print(getPluginDir())
|
||||
sys.path.append(getPluginDir() + "/class")
|
||||
from gdriveclient import gdriveclient
|
||||
|
||||
|
||||
gd = gdriveclient(getPluginDir(), getServerDir())
|
||||
gd.setDebug(True)
|
||||
# sign_in_url, state = gd.get_sign_in_url()
|
||||
# print(sign_in_url)
|
||||
|
||||
# url = 'https://localhost/?state=GH2YZ1VeytzVB1BqJJpQZIBk2GGAub&code=4/0Adeu5BXnD2dQvXx8Sg0WPn1XiMpihcRBNaG1yaFKIo86gUiG7q65KU1MaNCxrj_f2bjkwQ&scope=https://www.googleapis.com/auth/drive.file'
|
||||
# t = gd.set_auth_url(url)
|
||||
# print(t)
|
||||
|
||||
# def set_auth_url(url):
|
||||
# try:
|
||||
# if url.startswith("http://"):
|
||||
# url = url.replace("http://", "https://")
|
||||
# token = msodc.get_token_from_authorized_url(
|
||||
# authorized_url=url)
|
||||
# msodc.store_token(token)
|
||||
# msodc.store_user()
|
||||
# return mw.returnJson(True, "授权成功!")
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
# return mw.returnJson(False, "授权失败2!:" + str(e))
|
||||
# return mw.returnJson(False, "授权失败!:" + str(e))
|
||||
|
||||
# url = 'http://localhost/?code=M.C106_BAY.2.310112f3-a158-c400-9667-d158cbd1de6c&state=jEJz0ucR9bpZYD9PGxp2GgRDotrzO6'
|
||||
# token = set_auth_url(url)
|
||||
# print(token)
|
||||
|
||||
# token = msodc.get_token()
|
||||
# print("token:", token)
|
||||
|
||||
# t = gd.get_list('')
|
||||
# print(t)
|
||||
|
||||
# t = gd.get_id_list('1u7LjXGj1KoN-ltAdTRaib7IZJpsEnPdz')
|
||||
# print(t)
|
||||
|
||||
# t = gd.create_folder('backup_demo')
|
||||
# print(t)
|
||||
|
||||
# t = msodc.delete_object('backup')
|
||||
# print(t)
|
||||
|
||||
|
||||
# t = gd.upload_file('web_t1.cn_20230830_134549.tar.gz', 'site')
|
||||
# print(t)
|
||||
# print(gd.error_msg)
|
||||
|
||||
# /Users/midoks/Desktop/mwdev/server/mdserver-web/paramiko.log
|
||||
# backup/site/paramiko.log
|
||||
# |-正在上传到 backup/site/paramiko.log...
|
||||
# True
|
||||
|
||||
|
||||
t = gd.upload_file(
|
||||
'db_zzzvps_20230830_210727.sql.gz', 'datebase')
|
||||
print(t)
|
||||
@@ -2,7 +2,7 @@
|
||||
"ps": "Gogs是一款极易搭建的自助Git服务",
|
||||
"name": "gogs",
|
||||
"title": "Gogs",
|
||||
"versions": ["0.11.86","0.12.9"],
|
||||
"versions": ["0.11.86","0.12.9","0.13.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/gogs",
|
||||
"path":"server/gogs",
|
||||
|
||||
@@ -9,6 +9,10 @@ serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
|
||||
GOGS_DOWNLOAD='https://dl.gogs.io'
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log-slave-updates
|
||||
slave_skip_errors=1062
|
||||
#replicate-do-db
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<script type="text/javascript">console.log($('.plugin_version').attr('version'));</script>
|
||||
<!-- <script type="text/javascript">console.log($('.plugin_version').attr('version'));</script> -->
|
||||
<p class="bgw" onclick="pluginService('mariadb', $('.plugin_version').attr('version'));">服务</p>
|
||||
<p onclick="pluginInitD('mariadb', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="pluginConfig('mariadb', $('.plugin_version').attr('version'));">配置文件</p>
|
||||
@@ -15,14 +15,12 @@
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="bt-w-con pd15" style="height:555px;overflow: auto;">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
.db_list{
|
||||
padding: 0px 0 10px 0;
|
||||
@@ -52,10 +50,7 @@
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(800);
|
||||
|
||||
var loading = layer.msg("资源加载中...", { icon: 16, time: 0, shade: 0.3 });
|
||||
$.getScript( "/plugins/file?name=mariadb&f=js/mariadb.js", function(){
|
||||
layer.close(loading);
|
||||
pluginService('mariadb',$('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
+258
-203
@@ -48,19 +48,19 @@ def getInitDFile():
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = args[0].strip('{').strip('}').strip()
|
||||
if (t == ''):
|
||||
return tmp
|
||||
t = t.split(':')
|
||||
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
|
||||
|
||||
|
||||
@@ -107,6 +107,14 @@ def getDbPort():
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getDbServerId():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'server-id\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getSocketFile():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
@@ -664,15 +672,15 @@ def isSqlError(mysqlMsg):
|
||||
return mw.returnJson(False, "Can't connect to MySQL server on '127.0.0.1' (61)")
|
||||
if "using password:" in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库密码错误,在管理列表-点击【修复】!')
|
||||
if "1045" in mysqlMsg:
|
||||
if "1045," in mysqlMsg:
|
||||
return mw.returnJson(False, '连接错误!')
|
||||
if "SQL syntax" in mysqlMsg:
|
||||
return mw.returnJson(False, 'SQL语法错误!')
|
||||
if "Connection refused" in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库连接失败,请检查数据库服务是否启动!')
|
||||
if "1133" in mysqlMsg:
|
||||
if "1133," in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库用户不存在!')
|
||||
if "1007" in mysqlMsg:
|
||||
if "1007," in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库已经存在!')
|
||||
return None
|
||||
|
||||
@@ -940,7 +948,7 @@ def getDbList():
|
||||
|
||||
|
||||
def syncGetDatabases():
|
||||
pdb = pMysqlDb()
|
||||
pdb = pMysqlDb('mysql')
|
||||
psdb = pSqliteDb('databases')
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
@@ -1706,12 +1714,14 @@ def getMasterStatus(version=''):
|
||||
data['mode'] = recognizeDbMode()
|
||||
data['status'] = master_status
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
pdb = pMysqlDb('mysql')
|
||||
dlist = pdb.query('show slave status')
|
||||
if len(dlist) < 1:
|
||||
dlist = pdb.query("show all slaves status")
|
||||
|
||||
# print(dlist[0])
|
||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
||||
data['slave_status'] = True
|
||||
for v in dlist:
|
||||
if v["Slave_IO_Running"] == 'Yes' or v["Slave_SQL_Running"] == 'Yes':
|
||||
data['slave_status'] = True
|
||||
|
||||
return mw.returnJson(master_status, '设置成功', data)
|
||||
except Exception as e:
|
||||
@@ -1855,6 +1865,9 @@ def getMasterRepSlaveUserCmd(version):
|
||||
clist = psdb.field(f).where("username=?", (username,)).limit(
|
||||
'1').order('id desc').select()
|
||||
|
||||
if len(clist) == 0:
|
||||
return mw.returnJson(False, '错误同步账户!')
|
||||
|
||||
ip = mw.getLocalIp()
|
||||
port = getMyPort()
|
||||
db = pMysqlDb()
|
||||
@@ -1868,15 +1881,23 @@ def getMasterRepSlaveUserCmd(version):
|
||||
# 查找同步点
|
||||
# SELECT BINLOG_GTID_POS('master1-bin.000002', 561866201);
|
||||
|
||||
sid = getDbServerId()
|
||||
connection_name = ""
|
||||
if sid != '':
|
||||
connection_name = "'r{}' ".format(sid)
|
||||
|
||||
# MASTER_USE_GTID={current_pos|slave_pos|no}
|
||||
# current_pos 依赖-> select @@global.gtid_current_pos;
|
||||
# slave_pos 依赖-> select @@global.gtid_slave_pos;
|
||||
# no -> 啥都不依赖,保证多主同步成功。同步出现问题,根据日志查找问题。
|
||||
|
||||
if mode == "gtid":
|
||||
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||
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_LOG_POS=" + \
|
||||
str(mstatus[0]["Position"]) + \
|
||||
",MASTER_USE_GTID=slave_pos,MASTER_CONNECT_RETRY=10;"
|
||||
"',MASTER_USE_GTID=no,MASTER_CONNECT_RETRY=10;"
|
||||
else:
|
||||
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||
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"] + \
|
||||
@@ -2151,48 +2172,20 @@ def updateSlaveSSH(version=''):
|
||||
|
||||
|
||||
def getSlaveList(version=''):
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
ret = []
|
||||
for x in range(0, len(dlist)):
|
||||
tmp = {}
|
||||
tmp['Master_User'] = dlist[x]["Master_User"]
|
||||
tmp['Master_Host'] = dlist[x]["Master_Host"]
|
||||
tmp['Master_Port'] = dlist[x]["Master_Port"]
|
||||
tmp['Master_Log_File'] = dlist[x]["Master_Log_File"]
|
||||
tmp['Slave_IO_Running'] = dlist[x]["Slave_IO_Running"]
|
||||
tmp['Slave_SQL_Running'] = dlist[x]["Slave_SQL_Running"]
|
||||
tmp['Last_Error'] = dlist[x]["Last_Error"]
|
||||
tmp['Last_IO_Error'] = dlist[x]["Last_IO_Error"]
|
||||
tmp['Last_SQL_Error'] = dlist[x]["Last_SQL_Error"]
|
||||
tmp['Slave_SQL_Running_State'] = dlist[x]["Slave_SQL_Running_State"]
|
||||
if len(dlist) == 0:
|
||||
dlist = db.query('show all slaves status')
|
||||
|
||||
tmp['Error'] = ''
|
||||
if tmp['Last_Error'] != '':
|
||||
tmp['Error'] = tmp['Last_Error']
|
||||
|
||||
if tmp['Last_IO_Error'] != '':
|
||||
tmp['Error'] = tmp['Last_IO_Error']
|
||||
|
||||
if tmp['Last_SQL_Error'] != '':
|
||||
tmp['Error'] = tmp['Last_SQL_Error']
|
||||
|
||||
if tmp['Error'] == '':
|
||||
tmp['Error'] = tmp['Slave_SQL_Running_State']
|
||||
|
||||
ret.append(tmp)
|
||||
data = {}
|
||||
data['data'] = ret
|
||||
|
||||
data['data'] = dlist
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
def getSlaveSyncCmd(version=''):
|
||||
|
||||
root = mw.getRunDir()
|
||||
cmd = 'cd ' + root + ' && python3 ' + root + \
|
||||
'/plugins/mysql/index.py do_full_sync {"db":"all"}'
|
||||
'/plugins/mariadb/index.py do_full_sync {"db":"all","sign":""}'
|
||||
return mw.returnJson(True, 'ok', cmd)
|
||||
|
||||
|
||||
@@ -2208,102 +2201,151 @@ def initSlaveStatus(version=''):
|
||||
return initSlaveStatusSyncUser(version)
|
||||
|
||||
|
||||
def parseSlaveSyncCmd(cmd):
|
||||
a = {}
|
||||
vlist = cmd.split(',')
|
||||
|
||||
has_connection_name = vlist[0]
|
||||
|
||||
pattern_c = r"CHANGE MASTER \'(.*)\' TO MASTER_HOST"
|
||||
match_val = re.match(pattern_c, has_connection_name, re.I)
|
||||
if match_val:
|
||||
m_groups = match_val.groups()
|
||||
a['Connection_name'] = m_groups[0]
|
||||
|
||||
for i in vlist:
|
||||
tmp = i.strip()
|
||||
tmp_a = tmp.split(" ")
|
||||
real_tmp = tmp_a[len(tmp_a) - 1]
|
||||
kv = real_tmp.split("=")
|
||||
a[kv[0]] = kv[1].replace("'", '').replace("'", '').replace(";", '')
|
||||
return a
|
||||
|
||||
|
||||
def initSlaveStatusSyncUser(version=''):
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
if len(data) < 1:
|
||||
|
||||
slave_data = conn.field('id,ip,port,user,pass,mode,cmd').select()
|
||||
if len(slave_data) < 1:
|
||||
return mw.returnJson(False, '需要先添加同步用户配置!')
|
||||
|
||||
# print(data)
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) > 0:
|
||||
return mw.returnJson(False, '已经初始化好了zz...')
|
||||
pdb = pMysqlDb()
|
||||
if len(slave_data) == 1:
|
||||
dlist = pdb.query('show slave status')
|
||||
if len(dlist) > 0:
|
||||
return mw.returnJson(False, '已经初始化好了zz...')
|
||||
|
||||
u = data
|
||||
msg = ''
|
||||
|
||||
mode_name = 'classic'
|
||||
if u['mode'] == '1':
|
||||
mode_name = 'gtid'
|
||||
pdb.query("stop slave")
|
||||
pdb.query("stop all slaves")
|
||||
|
||||
local_mode = recognizeDbMode()
|
||||
if local_mode != mode_name:
|
||||
return mw.returnJson(False, '同步模式不一致!')
|
||||
for x in range(len(slave_data)):
|
||||
slave_t = slave_data[x]
|
||||
base_t = 'IP:' + slave_t['ip'] + ",PORT:" + \
|
||||
slave_t['port'] + ",USER:" + slave_t['user']
|
||||
|
||||
# print(u['cmd'])
|
||||
t = db.query(u['cmd'])
|
||||
# print(t)
|
||||
db.query("start slave")
|
||||
return mw.returnJson(True, '初始化成功!')
|
||||
mode_name = 'classic'
|
||||
if slave_data[x]['mode'] == '1':
|
||||
mode_name = 'gtid'
|
||||
|
||||
if local_mode != mode_name:
|
||||
msg += base_t + '->同步模式不一致'
|
||||
continue
|
||||
|
||||
cmd_sql = slave_t['cmd']
|
||||
if cmd_sql == '':
|
||||
msg += base_t + '->同步命令不能为空'
|
||||
continue
|
||||
|
||||
try:
|
||||
pinfo = parseSlaveSyncCmd(cmd_sql)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, base_t + '->CMD同步命令不合规范!')
|
||||
|
||||
pdb.query(cmd_sql)
|
||||
|
||||
pdb.query("start slave")
|
||||
pdb.query("start all slaves ")
|
||||
|
||||
if msg == '':
|
||||
msg = '初始化成功!'
|
||||
return mw.returnJson(True, msg)
|
||||
|
||||
|
||||
def initSlaveStatusSSH(version=''):
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) > 0:
|
||||
return mw.returnJson(False, '已经初始化好了zz...')
|
||||
if len(dlist) == 0:
|
||||
dlist = db.query('show all slaves status')
|
||||
|
||||
conn = pSqliteDb('slave_id_rsa')
|
||||
data = conn.field('ip,port,id_rsa,db_user').find()
|
||||
ssh_list = conn.field('ip,port,id_rsa,db_user').select()
|
||||
|
||||
if len(data) < 1:
|
||||
if len(ssh_list) < 1:
|
||||
return mw.returnJson(False, '需要先配置【[主]SSH配置】!')
|
||||
|
||||
SSH_PRIVATE_KEY = "/tmp/t_ssh.txt"
|
||||
ip = data['ip']
|
||||
master_port = data['port']
|
||||
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
|
||||
|
||||
import paramiko
|
||||
paramiko.util.log_to_file('paramiko.log')
|
||||
ssh = paramiko.SSHClient()
|
||||
|
||||
try:
|
||||
for data in ssh_list:
|
||||
ip = data['ip']
|
||||
master_port = data['port']
|
||||
SSH_PRIVATE_KEY = "/tmp/t_ssh_" + ip + ".txt"
|
||||
|
||||
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
|
||||
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
|
||||
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=ip, port=int(master_port),
|
||||
username='root', pkey=key)
|
||||
|
||||
db_user = data['db_user']
|
||||
cmd = 'cd /www/server/mdserver-web && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
result = result.decode('utf-8')
|
||||
cmd_data = json.loads(result)
|
||||
time.sleep(1)
|
||||
ssh.close()
|
||||
if not cmd_data['status']:
|
||||
return mw.returnJson(False, '[主]:' + cmd_data['msg'])
|
||||
try:
|
||||
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=ip, port=int(master_port),
|
||||
username='root', pkey=key)
|
||||
|
||||
local_mode = recognizeDbMode()
|
||||
if local_mode != cmd_data['data']['mode']:
|
||||
return mw.returnJson(False, '主【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
|
||||
db_user = data['db_user']
|
||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
result = result.decode('utf-8')
|
||||
if result.strip() == "":
|
||||
return mw.returnJson(False, '[主][' + ip + ']:获取同步命令失败!')
|
||||
cmd_data = json.loads(result)
|
||||
time.sleep(1)
|
||||
ssh.close()
|
||||
if not cmd_data['status']:
|
||||
return mw.returnJson(False, '[主][' + ip + ']:' + cmd_data['msg'])
|
||||
|
||||
u = cmd_data['data']['info']
|
||||
ps = u['username'] + "|" + u['password']
|
||||
conn.where('ip=?', (ip,)).setField('ps', ps)
|
||||
db.query('stop slave')
|
||||
local_mode = recognizeDbMode()
|
||||
if local_mode != cmd_data['data']['mode']:
|
||||
return mw.returnJson(False, '[主][' + ip + ']【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
|
||||
|
||||
# 保证同步IP一致
|
||||
cmd = cmd_data['data']['cmd']
|
||||
if cmd.find('SOURCE_HOST') > -1:
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
u = cmd_data['data']['info']
|
||||
ps = u['username'] + "|" + u['password']
|
||||
conn.where('ip=?', (ip,)).setField('ps', ps)
|
||||
db.query('stop slave')
|
||||
db.query('stop all slaves')
|
||||
|
||||
if cmd.find('MASTER_HOST') > -1:
|
||||
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||
# 保证同步IP一致
|
||||
cmd = cmd_data['data']['cmd']
|
||||
if cmd.find('SOURCE_HOST') > -1:
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
|
||||
# print(cmd)
|
||||
db.query(cmd)
|
||||
db.query("start slave")
|
||||
if cmd.find('MASTER_HOST') > -1:
|
||||
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, 'SSH认证配置连接失败!' + str(e))
|
||||
# print(cmd)
|
||||
db.query(cmd)
|
||||
db.query("start slave")
|
||||
db.query("start all slaves")
|
||||
if os.path.exists(SSH_PRIVATE_KEY):
|
||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '[主][' + ip + ']:SSH认证配置连接失败!' + str(e))
|
||||
|
||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||
return mw.returnJson(True, '初始化成功!')
|
||||
|
||||
|
||||
@@ -2312,61 +2354,39 @@ def setSlaveStatus(version=''):
|
||||
if not os.path.exists(mode_file):
|
||||
return mw.returnJson(False, '需要先设置同步配置')
|
||||
|
||||
mode = mw.readFile(mode_file)
|
||||
if mode == 'ssh':
|
||||
return setSlaveStatusSSH(version)
|
||||
if mode == 'sync-user':
|
||||
return setSlaveStatusSyncUser(version)
|
||||
pdb = pMysqlDb()
|
||||
dlist = pdb.query('show slave status')
|
||||
if len(dlist) == 0:
|
||||
dlist = pdb.query('show all slaves status')
|
||||
|
||||
|
||||
def setSlaveStatusSyncUser(version=''):
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) == 0:
|
||||
return mw.returnJson(False, '需要手动添加同步账户或者执行初始化!')
|
||||
|
||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
||||
db.query('stop slave')
|
||||
else:
|
||||
ip = dlist[0]['Master_Host']
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
if len(data) == 0:
|
||||
return mw.returnJson(False, '没有数据无法重启!')
|
||||
user = data['user']
|
||||
apass = data['pass']
|
||||
for v in dlist:
|
||||
connection_name = ''
|
||||
cmd = "slave"
|
||||
if 'Connection_name' in v:
|
||||
connection_name = v['Connection_name']
|
||||
cmd = "slave '{}'".format(connection_name)
|
||||
|
||||
db.query("start slave")
|
||||
# db.query("start slave user='{}' password='{}';".format(user, apass))
|
||||
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def setSlaveStatusSSH(version=''):
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) == 0:
|
||||
return mw.returnJson(False, '需要手动添加主服务命令或者执行[初始化]!')
|
||||
|
||||
# print(dlist)
|
||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
||||
db.query('stop slave')
|
||||
else:
|
||||
ip = dlist[0]['Master_Host']
|
||||
conn = pSqliteDb('slave_id_rsa')
|
||||
data = conn.field('ip,ps').where("ip=?", (ip,)).find()
|
||||
if len(data) == 0:
|
||||
return mw.returnJson(False, '没有数据无法重启!')
|
||||
db.query("start slave")
|
||||
if (v["Slave_IO_Running"] == 'Yes' or v["Slave_SQL_Running"] == 'Yes'):
|
||||
pdb.query("stop {}".format(cmd))
|
||||
else:
|
||||
pdb.query("start {}".format(cmd))
|
||||
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def deleteSlave(version=''):
|
||||
args = getArgs()
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('stop slave')
|
||||
dlist = db.query('reset slave all')
|
||||
if 'sign' in args:
|
||||
sign = args['sign']
|
||||
db.query("stop slave '{}'".format(sign))
|
||||
db.query("reset slave '{}' all".format(sign))
|
||||
else:
|
||||
db.query('stop slave')
|
||||
db.query('reset slave all')
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
|
||||
|
||||
@@ -2402,14 +2422,54 @@ def dumpMysqlData(version=''):
|
||||
|
||||
############### --- 重要 同步---- ###########
|
||||
|
||||
|
||||
def asyncTmpfile():
|
||||
path = '/tmp/mariadb_async_status.txt'
|
||||
return path
|
||||
|
||||
|
||||
def writeDbSyncStatus(data):
|
||||
path = '/tmp/db_async_status.txt'
|
||||
# status_data['code'] = 1
|
||||
# status_data['msg'] = '主服务器备份完成...'
|
||||
# status_data['progress'] = 30
|
||||
path = asyncTmpfile()
|
||||
mw.writeFile(path, json.dumps(data))
|
||||
|
||||
|
||||
def fullSync(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['db', 'begin'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
sign = ''
|
||||
if 'sign' in args:
|
||||
sign = args['sign']
|
||||
|
||||
status_file = asyncTmpfile()
|
||||
if args['begin'] == '1':
|
||||
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
|
||||
getPluginDir() + \
|
||||
'/index.py do_full_sync {"db":"' + \
|
||||
args['db'] + '","sign":"' + sign + '"} &'
|
||||
# print(cmd)
|
||||
mw.execShell(cmd)
|
||||
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
|
||||
|
||||
if os.path.exists(status_file):
|
||||
c = mw.readFile(status_file)
|
||||
tmp = json.loads(c)
|
||||
if tmp['code'] == 1:
|
||||
sys_dump_sql = "/tmp/dump.sql"
|
||||
if os.path.exists(sys_dump_sql):
|
||||
dump_size = os.path.getsize(sys_dump_sql)
|
||||
tmp['msg'] = tmp['msg'] + ":" + "同步文件:" + mw.toSize(dump_size)
|
||||
c = json.dumps(tmp)
|
||||
|
||||
# if tmp['code'] == 6:
|
||||
# os.remove(status_file)
|
||||
return c
|
||||
|
||||
return json.dumps({'code': 0, 'msg': '点击开始,开始同步!', 'progress': 0})
|
||||
|
||||
|
||||
def doFullSync(version=''):
|
||||
mode_file = getSyncModeFile()
|
||||
if not os.path.exists(mode_file):
|
||||
@@ -2424,16 +2484,23 @@ def doFullSync(version=''):
|
||||
|
||||
def doFullSyncUser(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['db'])
|
||||
data = checkArgs(args, ['db', 'sign'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
sync_db = args['db']
|
||||
sync_sign = args['sign']
|
||||
|
||||
# print(sync_sign, sync_db)
|
||||
db = pMysqlDb()
|
||||
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
if sync_sign != '':
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').where(
|
||||
'ip=?', (sync_sign,)).find()
|
||||
else:
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
|
||||
user = data['user']
|
||||
apass = data['pass']
|
||||
port = data['port']
|
||||
@@ -2442,12 +2509,12 @@ def doFullSyncUser(version=''):
|
||||
bak_file = '/tmp/tmp.sql'
|
||||
|
||||
writeDbSyncStatus({'code': 0, 'msg': '开始同步...', 'progress': 0})
|
||||
|
||||
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 20})
|
||||
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
|
||||
print(dump_sql_data)
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
|
||||
@@ -2458,24 +2525,38 @@ def doFullSyncUser(version=''):
|
||||
' ' + sync_db + ' < ' + bak_file
|
||||
mw.execShell(my_import_cmd)
|
||||
|
||||
db.query("start slave")
|
||||
pinfo = parseSlaveSyncCmd(data['cmd'])
|
||||
# print(pinfo)
|
||||
if 'Connection_name' in pinfo:
|
||||
db.query("start slave '{}'".format(pinfo['Connection_name']))
|
||||
else:
|
||||
db.query("start slave")
|
||||
|
||||
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
||||
os.system("rm -rf " + bak_file)
|
||||
|
||||
if os.path.exists(bak_file):
|
||||
os.system("rm -rf " + bak_file)
|
||||
return True
|
||||
|
||||
|
||||
def doFullSyncSSH(version=''):
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['db'])
|
||||
data = checkArgs(args, ['db', 'sign'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
db = pMysqlDb()
|
||||
|
||||
sync_db = args['db']
|
||||
sync_sign = args['sign']
|
||||
|
||||
id_rsa_conn = pSqliteDb('slave_id_rsa')
|
||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
|
||||
if sync_sign != '':
|
||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').where(
|
||||
'ip=?', (sync_sign,)).find()
|
||||
else:
|
||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
|
||||
|
||||
SSH_PRIVATE_KEY = "/tmp/mysql_sync_id_rsa.txt"
|
||||
id_rsa = data['id_rsa'].replace('\\n', '\n')
|
||||
@@ -2498,7 +2579,6 @@ def doFullSyncSSH(version=''):
|
||||
return 'fail'
|
||||
|
||||
try:
|
||||
# ssh.load_system_host_keys()
|
||||
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
|
||||
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
@@ -2516,7 +2596,7 @@ def doFullSyncSSH(version=''):
|
||||
|
||||
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
|
||||
dbname = args['db']
|
||||
cmd = "cd /www/server/mdserver-web && python3 plugins/mariadb/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||
print(cmd)
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
@@ -2539,13 +2619,19 @@ def doFullSyncSSH(version=''):
|
||||
if copy_status == None:
|
||||
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
|
||||
|
||||
cmd = 'cd /www/server/mdserver-web && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
result = result.decode('utf-8')
|
||||
|
||||
if result == '':
|
||||
writeDbSyncStatus({'code': 1, 'msg': '同步命令获取失败!', 'progress': 100})
|
||||
return 'fail'
|
||||
|
||||
cmd_data = json.loads(result)
|
||||
|
||||
db.query('stop slave')
|
||||
db.query('stop all slaves')
|
||||
writeDbSyncStatus({'code': 3, 'msg': '停止从库完成...', 'progress': 45})
|
||||
|
||||
cmd = cmd_data['data']['cmd']
|
||||
@@ -2578,6 +2664,7 @@ def doFullSyncSSH(version=''):
|
||||
return 'fail'
|
||||
|
||||
db.query("start slave")
|
||||
db.query("start all slaves")
|
||||
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
||||
|
||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||
@@ -2585,38 +2672,6 @@ def doFullSyncSSH(version=''):
|
||||
return True
|
||||
|
||||
|
||||
def fullSync(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['db', 'begin'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
status_file = '/tmp/db_async_status.txt'
|
||||
if args['begin'] == '1':
|
||||
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
|
||||
getPluginDir() + \
|
||||
'/index.py do_full_sync {"db":"' + args['db'] + '"} &'
|
||||
print(cmd)
|
||||
mw.execShell(cmd)
|
||||
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
|
||||
|
||||
if os.path.exists(status_file):
|
||||
c = mw.readFile(status_file)
|
||||
tmp = json.loads(c)
|
||||
if tmp['code'] == 1:
|
||||
sys_dump_sql = "/tmp/dump.sql"
|
||||
if os.path.exists(sys_dump_sql):
|
||||
dump_size = os.path.getsize(sys_dump_sql)
|
||||
tmp['msg'] = tmp['msg'] + ":" + "同步文件:" + mw.toSize(dump_size)
|
||||
c = json.dumps(tmp)
|
||||
|
||||
# if tmp['code'] == 6:
|
||||
# os.remove(status_file)
|
||||
return c
|
||||
|
||||
return json.dumps({'code': 0, 'msg': '点击开始,开始同步!', 'progress': 0})
|
||||
|
||||
|
||||
def installPreInspection(version):
|
||||
swap_path = mw.getServerDir() + "/swap"
|
||||
if not os.path.exists(swap_path):
|
||||
|
||||
+178
-86
@@ -431,7 +431,6 @@ function syncToDatabase(type){
|
||||
var postData = 'type='+type+'&ids='+JSON.stringify(data);
|
||||
myPost('sync_to_databases', postData, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
},{ icon: rdata.status ? 1 : 2 });
|
||||
@@ -439,18 +438,6 @@ 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();
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var index = layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
@@ -467,8 +454,16 @@ function setRootPwd(type, pwd){
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
yes:function(){
|
||||
setRootPwd(1);
|
||||
yes:function(index,layero){
|
||||
var password = $("#MyPassword").val();
|
||||
myPost('set_root_pwd', {password:password}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
layer.close(index);
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -490,7 +485,6 @@ function showHidePass(obj){
|
||||
function checkSelect(){
|
||||
setTimeout(function () {
|
||||
var num = $('input[type="checkbox"].check:checked').length;
|
||||
// console.log(num);
|
||||
if (num == 1) {
|
||||
$('button[batch="true"]').hide();
|
||||
$('button[batch="false"]').show();
|
||||
@@ -861,7 +855,6 @@ function downloadBackup(file){
|
||||
|
||||
function importBackup(file,name){
|
||||
myPost('import_db_backup',{file:file,name:name}, function(data){
|
||||
// console.log(data);
|
||||
layer.msg('执行成功!');
|
||||
});
|
||||
}
|
||||
@@ -1619,7 +1612,6 @@ function getMasterRepSlaveList(){
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
myPost('get_master_rep_slave_list', _data, function(data){
|
||||
// console.log(data);
|
||||
var rdata = [];
|
||||
try {
|
||||
rdata = $.parseJSON(data.data);
|
||||
@@ -1672,12 +1664,12 @@ function getMasterRepSlaveListPage(){
|
||||
}
|
||||
|
||||
|
||||
function deleteSlave(){
|
||||
myPost('delete_slave', {}, function(data){
|
||||
function deleteSlave(sign = ''){
|
||||
myPost('delete_slave', {sign:sign}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata['msg'], function(){
|
||||
masterOrSlaveConf();
|
||||
},{},3000);
|
||||
},{icon:rdata.status?1:2,time:3000},3000);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1685,28 +1677,72 @@ function deleteSlave(){
|
||||
function getFullSyncStatus(db){
|
||||
var timeId = null;
|
||||
|
||||
var btn = '<div class="table_toolbar" style="left:0px;"><span data-status="init" class="sync btn btn-default btn-sm" id="begin_full_sync" title="">开始</span></div>';
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '全量同步['+db+']',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<span id='full_msg'></span>\
|
||||
<div class='progress'>\
|
||||
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
"+btn+"\
|
||||
</div>",
|
||||
cancel: function(){
|
||||
clearInterval(timeId);
|
||||
myPost('get_slave_list', {page:1,page_size:100}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var rsource = rdata.data;
|
||||
|
||||
if (db == 'ALL' && rsource.length>1){
|
||||
layer.msg("多主不支持该模式!",{icon:2});
|
||||
return;
|
||||
}
|
||||
|
||||
var dataSource = '';
|
||||
if (rsource.length>1){
|
||||
var sourceList = '';
|
||||
for (var i = 0; i < rsource.length; i++) {
|
||||
if ('Connection_name' in rsource[i]){
|
||||
sourceList += '<option val="'+rsource[i]['Master_Host']+'">'+rsource[i]['Master_Host']+'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
dataSource = "<p class='line' style='text-align:center;'>\
|
||||
<span>同步数据源:</span>\
|
||||
<select class='bt-input-text' name='data_source' style='width:200px;'>" + sourceList + "</select>\
|
||||
</p>";
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '全量同步['+db+']',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd15'>\
|
||||
<div class='divtable mtb10'>\
|
||||
"+dataSource+"\
|
||||
<span id='full_msg'></span>\
|
||||
<div class='progress'>\
|
||||
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class='table_toolbar' style='left:0px;'>\
|
||||
<span data-status='init' class='sync btn btn-default btn-sm' id='begin_full_sync'>开始</span>\
|
||||
</div>\
|
||||
</div>",
|
||||
cancel: function(){
|
||||
clearInterval(timeId);
|
||||
},
|
||||
success:function(){
|
||||
$('#begin_full_sync').click(function(){
|
||||
var val = $(this).data('status');
|
||||
var sign = '';
|
||||
if (dataSource !=''){
|
||||
sign = $('select[name="data_source"]').val();
|
||||
}
|
||||
if (val == 'init'){
|
||||
fullSync(db, sign, 1);
|
||||
timeId = setInterval(function(){
|
||||
fullSync(db,sign,0);
|
||||
}, 1000);
|
||||
$(this).data('status','starting');
|
||||
} else {
|
||||
layer.msg("正在同步中..",{icon:0});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function fullSync(db,begin){
|
||||
|
||||
myPostN('full_sync', {db:db,begin:begin}, function(data){
|
||||
function fullSync(db, sign, begin){
|
||||
myPostN('full_sync', {db:db,sign:sign,begin:begin}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
$('#full_msg').text(rdata['msg']);
|
||||
$('.progress-bar').css('width',rdata['progress']+'%');
|
||||
@@ -1715,23 +1751,11 @@ function getFullSyncStatus(db){
|
||||
if (rdata['code']==6 ||rdata['code']<0){
|
||||
layer.msg(rdata['msg']);
|
||||
clearInterval(timeId);
|
||||
$("#begin_full_sync").attr('data-status','init');
|
||||
$("#begin_full_sync").data('status','init');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#begin_full_sync').click(function(){
|
||||
var val = $(this).attr('data-status');
|
||||
if (val == 'init'){
|
||||
fullSync(db,1);
|
||||
timeId = setInterval(function(){
|
||||
fullSync(db,0);
|
||||
}, 1000);
|
||||
$(this).attr('data-status','starting');
|
||||
} else {
|
||||
layer.msg("正在同步中..");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function addSlaveSSH(ip=''){
|
||||
@@ -2077,7 +2101,7 @@ function getSlaveUserList(){
|
||||
layerId = layer.open({
|
||||
type: 1,
|
||||
title: '同步账户列表',
|
||||
area: '500px',
|
||||
area: '600px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div><table class='table table-hover get-slave-ssh-list'>\
|
||||
@@ -2101,7 +2125,7 @@ function getSlaveSSHList(page=1){
|
||||
layerId = layer.open({
|
||||
type: 1,
|
||||
title: 'SSH列表',
|
||||
area: '500px',
|
||||
area: '600px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div><table class='table table-hover get-slave-ssh-list'>\
|
||||
@@ -2142,11 +2166,15 @@ function handlerRun(){
|
||||
function initSlaveStatus(){
|
||||
myPost('init_slave_status', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (!rdata.status ){
|
||||
layer.msg(rdata.msg,{icon:2,time:10000});
|
||||
return;
|
||||
}
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
masterOrSlaveConf();
|
||||
}
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
},{icon:1},2000);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2204,33 +2232,48 @@ function masterOrSlaveConf(version=''){
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
_data['page_size'] = 100;
|
||||
|
||||
myPost('get_slave_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var list = '';
|
||||
|
||||
var isHasSign = false;
|
||||
for(i in rdata.data){
|
||||
|
||||
var v = rdata.data[i];
|
||||
var status = "<a class='btlink db_error'>异常</>";
|
||||
if ('Connection_name' in v){
|
||||
isHasSign = true;
|
||||
}
|
||||
|
||||
var status = "<a data-id="+i+" class='btlink db_error'>异常</>";
|
||||
if (v['Slave_SQL_Running'] == 'Yes' && v['Slave_IO_Running'] == 'Yes'){
|
||||
status = "正常";
|
||||
}
|
||||
|
||||
list += '<tr>';
|
||||
list += '<td>' + rdata.data[i]['Master_Host'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Master_Port'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Master_User'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Master_Log_File'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Slave_IO_Running'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Slave_SQL_Running'] +'</td>';
|
||||
list += '<td>' + v['Master_Host'] +'</td>';
|
||||
list += '<td>' + v['Master_Port'] +'</td>';
|
||||
list += '<td>' + v['Master_User'] +'</td>';
|
||||
list += '<td>' + v['Master_Log_File'] +'</td>';
|
||||
list += '<td>' + v['Slave_IO_Running'] +'</td>';
|
||||
list += '<td>' + v['Slave_SQL_Running'] +'</td>';
|
||||
if (isHasSign){
|
||||
list += '<td>' + v['Connection_name'] +'</td>';
|
||||
}
|
||||
|
||||
list += '<td>' + status +'</td>';
|
||||
list += '<td style="text-align:right">' +
|
||||
'<a href="javascript:;" class="btlink" onclick="deleteSlave()" title="删除">删除</a>' +
|
||||
'</td>';
|
||||
list += '<td style="text-align:right">\
|
||||
<a data-id="'+i+'" href="javascript:;" class="btlink btn_delete_slave" title="删除">删除</a>\
|
||||
</td>';
|
||||
list += '</tr>';
|
||||
}
|
||||
|
||||
var signThead_th = '';
|
||||
if (isHasSign){
|
||||
var signThead_th = '<th>标识</th>';
|
||||
}
|
||||
|
||||
var con = '<div class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
@@ -2241,6 +2284,7 @@ function masterOrSlaveConf(version=''){
|
||||
<th>日志</th>\
|
||||
<th>IO</th>\
|
||||
<th>SQL</th>\
|
||||
'+signThead_th+'\
|
||||
<th>状态</th>\
|
||||
<th style="text-align:right;">操作</th></tr></thead>\
|
||||
<tbody>\
|
||||
@@ -2255,22 +2299,75 @@ function masterOrSlaveConf(version=''){
|
||||
// </div>
|
||||
$(".table_slave_status_list").html(con);
|
||||
|
||||
|
||||
$(".btn_delete_slave").click(function(){
|
||||
var id = $(this).data('id');
|
||||
var v = rdata.data[id];
|
||||
if ('Connection_name' in v){
|
||||
deleteSlave(v['Connection_name']);
|
||||
} else{
|
||||
deleteSlave();
|
||||
}
|
||||
});
|
||||
|
||||
$('.db_error').click(function(){
|
||||
var id = $(this).data('id');
|
||||
var info = rdata.data[id];
|
||||
|
||||
var err_line = "";
|
||||
err_line +="<tr>\
|
||||
<td>IO错误</td>\
|
||||
<td>"+ (info['Last_IO_Error'] == '' ? '无':info['Last_IO_Error'])+"</td>\
|
||||
</tr>";
|
||||
err_line +="<tr>\
|
||||
<td>SQL错误</td>\
|
||||
<td>"+(info['Last_SQL_Error'] == '' ? '无':info['Last_SQL_Error'])+"</td>\
|
||||
</tr>";
|
||||
|
||||
err_line +="<tr>\
|
||||
<td>状态</td>\
|
||||
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
|
||||
</tr>";
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '同步异常信息',
|
||||
area: '500px',
|
||||
content:"<form class='bt-form pd20 pb70'>\
|
||||
<div class='line'>"+v['Error']+"</div>\
|
||||
<div class='bt-form-submit-btn'>\
|
||||
<button type='button' class='btn btn-success btn-sm btn-title class-copy-db-err'>复制</button>\
|
||||
area: ['600px','300px'],
|
||||
btn:['复制错误',"取消"],
|
||||
content:"<form class='bt-form pd15'>\
|
||||
<div 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 style='width:80px;'>类型</th>\
|
||||
<th>内容</th>\
|
||||
</tr></thead>\
|
||||
<tbody>"+ err_line +"</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
</form>",
|
||||
success:function(){
|
||||
copyText(v['Error']);
|
||||
$('.class-copy-db-err').click(function(){
|
||||
copyText(v['Error']);
|
||||
});
|
||||
// copyText(v['Error']);
|
||||
// $('.class-copy-db-err').click(function(){
|
||||
// copyText(v['Error']);
|
||||
// });
|
||||
},
|
||||
yes:function(){
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2320,14 +2417,12 @@ function masterOrSlaveConf(version=''){
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getMasterStatus(){
|
||||
myPost('get_master_status', '', function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
// console.log('mode:',rdata.data);
|
||||
if ( typeof(rdata.status) != 'undefined' && !rdata.status && rdata.data == 'pwd'){
|
||||
layer.msg(rdata.msg, {icon:2});
|
||||
layer.msg(rdata.msg, {icon:2,time:2000});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2409,7 +2504,6 @@ function masterOrSlaveConf(version=''){
|
||||
return false;
|
||||
},
|
||||
change:function(index,mode,reload){
|
||||
console.log(index,mode,reload);
|
||||
myPost('set_dbrun_mode',{'mode':mode,'reload':reload},function(data){
|
||||
layer.close(index);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
@@ -2425,10 +2519,8 @@ function masterOrSlaveConf(version=''){
|
||||
getMasterDbList();
|
||||
}
|
||||
|
||||
// if (rdata.slave_status){
|
||||
getAsyncMasterDbList();
|
||||
getAsyncDataList()
|
||||
// }
|
||||
getAsyncMasterDbList();
|
||||
getAsyncDataList()
|
||||
});
|
||||
}
|
||||
getMasterStatus();
|
||||
|
||||
@@ -87,7 +87,7 @@ class backupTools:
|
||||
pid = mw.M('databases').dbPos(db_path, db_name).where(
|
||||
'name=?', (name,)).getField('id')
|
||||
|
||||
mw.M('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename(
|
||||
mw.M('backup').add('type,name,pid,filename,addtime,size', (3, os.path.basename(
|
||||
filename), pid, filename, endDate, os.path.getsize(filename)))
|
||||
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
|
||||
mw.writeLog('计划任务', log)
|
||||
@@ -97,7 +97,7 @@ class backupTools:
|
||||
|
||||
# 清理多余备份
|
||||
backups = mw.M('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
'type=? and pid=?', ('3', pid)).field('id,filename').select()
|
||||
|
||||
num = len(backups) - int(count)
|
||||
if num > 0:
|
||||
|
||||
@@ -71,10 +71,19 @@ Install_app()
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
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 [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
|
||||
@@ -73,8 +73,17 @@ Install_app()
|
||||
fi
|
||||
|
||||
|
||||
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 [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
|
||||
@@ -72,9 +72,17 @@ Install_app()
|
||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
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 [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
|
||||
+50
-11
@@ -14,6 +14,10 @@ if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'memcached'
|
||||
|
||||
@@ -27,8 +31,13 @@ def getServerDir():
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
if app_debug:
|
||||
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()
|
||||
|
||||
|
||||
@@ -84,7 +93,7 @@ def checkArgs(data, ck=[]):
|
||||
|
||||
def status():
|
||||
data = mw.execShell(
|
||||
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
||||
"ps aux|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
@@ -109,8 +118,8 @@ def initDreplace():
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/memcached.service'
|
||||
systemServiceTpl = getPluginDir() + '/init.d/memcached.service.tpl'
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
systemServiceTpl = getPluginDir() + '/init.d/memcached.service.tpl'
|
||||
service_path = mw.getServerDir()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
||||
@@ -133,13 +142,20 @@ def initDreplace():
|
||||
def memOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if current_os.startswith("freebsd"):
|
||||
data = mw.execShell('service ' + getPluginName() + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
@@ -222,9 +238,15 @@ def saveConf():
|
||||
|
||||
|
||||
def initdStatus():
|
||||
if mw.isAppleSystem():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
|
||||
shell_cmd = 'systemctl status ' + \
|
||||
getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
@@ -234,17 +256,34 @@ def initdStatus():
|
||||
|
||||
|
||||
def initdInstall():
|
||||
if mw.isAppleSystem():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
# freebsd initd install
|
||||
if current_os.startswith('freebsd'):
|
||||
import shutil
|
||||
source_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(source_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl enable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
if not app_debug:
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl disable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"title": "Memcached",
|
||||
"shell": "install.sh",
|
||||
"versions":["1.6"],
|
||||
"updates":["1.6.15"],
|
||||
"updates":["1.6.21"],
|
||||
"tip": "soft",
|
||||
"checks": "server/memcached",
|
||||
"path":"server/memcached",
|
||||
|
||||
@@ -6,7 +6,7 @@ port = 27017
|
||||
fork = true
|
||||
auth = false
|
||||
|
||||
# 5.0.2 - Master/slave replication is no longer supported
|
||||
# Master/slave replication is no longer supported
|
||||
#master = true
|
||||
|
||||
pidfilepath = {$SERVER_PATH}/mongodb/mongodb.pid
|
||||
|
||||
+37
-51
@@ -35,13 +35,8 @@ def getInitDFile():
|
||||
|
||||
|
||||
def getConf():
|
||||
if mw.isAppleSystem():
|
||||
path = getServerDir() + "/mongodb.conf"
|
||||
return path
|
||||
|
||||
if os.path.exists("/etc/mongodb.conf"):
|
||||
return "/etc/mongodb.conf"
|
||||
return "/etc/mongod.conf"
|
||||
path = getServerDir() + "/mongodb.conf"
|
||||
return path
|
||||
|
||||
|
||||
def getConfTpl():
|
||||
@@ -90,6 +85,14 @@ def initDreplace():
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
logs_dir = getServerDir() + '/logs'
|
||||
if not os.path.exists(logs_dir):
|
||||
os.mkdir(logs_dir)
|
||||
|
||||
data_dir = getServerDir() + '/data'
|
||||
if not os.path.exists(data_dir):
|
||||
os.mkdir(data_dir)
|
||||
|
||||
# initd replace
|
||||
content = mw.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
@@ -101,6 +104,17 @@ def initDreplace():
|
||||
conf_content = conf_content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(getServerDir() + '/mongodb.conf', conf_content)
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/mongodb.service'
|
||||
systemServiceTpl = getPluginDir() + '/init.d/mongodb.service.tpl'
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
service_path = mw.getServerDir()
|
||||
se_content = mw.readFile(systemServiceTpl)
|
||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(systemService, se_content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
@@ -112,14 +126,10 @@ def mgOp(method):
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
cmd = 'systemctl ' + method + ' mongod'
|
||||
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
|
||||
cmd = 'systemctl ' + start + ' mongodb'
|
||||
|
||||
data = mw.execShell(cmd)
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
return 'fail'
|
||||
|
||||
|
||||
def start():
|
||||
@@ -162,13 +172,7 @@ def runInfo():
|
||||
result["version"] = serverStatus['version']
|
||||
result["uptime"] = serverStatus['uptime']
|
||||
|
||||
result['db_path'] = '/var/lib/mongo'
|
||||
|
||||
if os.path.exists("/var/lib/mongodb"):
|
||||
result['db_path'] = '/var/lib/mongodb'
|
||||
|
||||
if mw.isAppleSystem():
|
||||
result['db_path'] = getServerDir() + "/data"
|
||||
result['db_path'] = getServerDir() + "/data"
|
||||
|
||||
result["connections"] = serverStatus['connections']['current']
|
||||
if 'catalogStats' in serverStatus:
|
||||
@@ -182,11 +186,7 @@ def initdStatus():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
shell_cmd = 'systemctl status mongod | grep loaded | grep "enabled;"'
|
||||
|
||||
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
|
||||
shell_cmd = 'systemctl status mongodb | grep loaded | grep "enabled;"'
|
||||
|
||||
shell_cmd = 'systemctl status mongodb | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
@@ -197,10 +197,7 @@ def initdInstall():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
|
||||
mw.execShell('systemctl enable mongodb')
|
||||
else:
|
||||
mw.execShell('systemctl enable mongod')
|
||||
mw.execShell('systemctl enable mongodb')
|
||||
return 'ok'
|
||||
|
||||
|
||||
@@ -208,24 +205,21 @@ def initdUinstall():
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
|
||||
mw.execShell('systemctl disable mongodb')
|
||||
else:
|
||||
mw.execShell('systemctl disable mongod')
|
||||
mw.execShell('systemctl disable mongodb')
|
||||
return 'ok'
|
||||
|
||||
|
||||
def runLog():
|
||||
if mw.isAppleSystem():
|
||||
return getServerDir() + '/logs/mongodb.log'
|
||||
|
||||
if os.path.exists("/var/log/mongodb/mongodb.log"):
|
||||
return "/var/log/mongodb/mongodb.log"
|
||||
|
||||
return "/var/log/mongodb/mongod.log"
|
||||
f = getServerDir() + '/logs/mongodb.log'
|
||||
if os.path.exists(f):
|
||||
return f
|
||||
return getServerDir() + '/logs.pl'
|
||||
|
||||
|
||||
def installPreInspection(version):
|
||||
if mw.isAppleSystem():
|
||||
return 'ok'
|
||||
|
||||
sys = mw.execShell(
|
||||
"cat /etc/*-release | grep PRETTY_NAME |awk -F = '{print $2}' | awk -F '\"' '{print $2}'| awk '{print $1}'")
|
||||
|
||||
@@ -238,17 +232,9 @@ def installPreInspection(version):
|
||||
sysName = sys[0].strip().lower()
|
||||
sysId = sys_id[0].strip()
|
||||
|
||||
if not sysName in ('centos', 'fedora', 'ubuntu', 'debian'):
|
||||
return '暂时仅不支持{}'.format(sysName)
|
||||
|
||||
if sysName == 'debian':
|
||||
if version > 10:
|
||||
return 'mongodb[' + version + ']不支持安装在debian[' + sysId + ']'
|
||||
|
||||
if sysName == 'ubuntu':
|
||||
if version < 16:
|
||||
return 'mongodb[' + version + ']不支持安装在ubuntu[' + sysId + ']'
|
||||
|
||||
supportOs = ['centos', 'ubuntu', 'debian', 'opensuse']
|
||||
if not sysName in supportOs:
|
||||
return '暂时仅支持{}'.format(','.join(supportOs))
|
||||
return 'ok'
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"name": "mongodb",
|
||||
"title": "Mongodb",
|
||||
"shell": "install.sh",
|
||||
"versions":["4.4","5.0"],
|
||||
"updates":["4.4","5.0"],
|
||||
"install_pre_inspection":true,
|
||||
"versions":["4.4","5.0","6.0","7.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/mongodb",
|
||||
"path": "server/mongodb",
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
[Unit]
|
||||
Description=MongoDB Database Server
|
||||
Documentation=https://docs.mongodb.org/manual
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
#EnvironmentFile=-/etc/default/mongod
|
||||
Environment="MONGODB_CONFIG_OVERRIDE_NOFORK=1"
|
||||
PIDFile={$SERVER_PATH}/mongodb/mongodb.pid
|
||||
ExecStart={$SERVER_PATH}/mongodb/bin/mongod -f {$SERVER_PATH}/mongodb/mongodb.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
#RuntimeDirectory=mongodb
|
||||
# file size
|
||||
LimitFSIZE=infinity
|
||||
# cpu time
|
||||
LimitCPU=infinity
|
||||
# virtual memory size
|
||||
LimitAS=infinity
|
||||
# open files
|
||||
LimitNOFILE=64000
|
||||
# processes/threads
|
||||
LimitNPROC=64000
|
||||
# locked memory
|
||||
LimitMEMLOCK=infinity
|
||||
# total threads (user+kernel)
|
||||
TasksMax=infinity
|
||||
TasksAccounting=false
|
||||
|
||||
# Recommended limits for mongod as specified in
|
||||
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -30,8 +30,9 @@ app_start(){
|
||||
|
||||
echo "Starting mongodb server..."
|
||||
echo $EXEC -f $CONF
|
||||
$EXEC -f $CONF >> {$SERVER_PATH}/mongodb/logs.pl 2>&1 &
|
||||
$EXEC -f $CONF >> {$SERVER_PATH}/mongodb/logs.pl 1>&1 2>&1 &
|
||||
}
|
||||
|
||||
app_stop(){
|
||||
if [ ! -f $PIDFILE ]
|
||||
then
|
||||
@@ -42,10 +43,10 @@ app_stop(){
|
||||
kill -9 $PID
|
||||
while [ -x /proc/${PID} ]
|
||||
do
|
||||
echo "Waiting for Redis to shutdown ..."
|
||||
echo "Waiting for mongodb to shutdown ..."
|
||||
sleep 1
|
||||
done
|
||||
echo "Redis stopped"
|
||||
echo "mongodb stopped"
|
||||
rm -rf $PIDFILE
|
||||
fi
|
||||
}
|
||||
|
||||
Executable
+287
@@ -0,0 +1,287 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
sysName=`uname`
|
||||
echo "use system: ${sysName}"
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
|
||||
Install_app_mac()
|
||||
{
|
||||
mkdir -p $serverPath/mongodb
|
||||
if [ "$VERSION" == "5.0" ];then
|
||||
G_VERSION="5.0.11"
|
||||
elif [[ "$VERSION" == "4.4" ]]; then
|
||||
G_VERSION="4.4.11"
|
||||
fi
|
||||
|
||||
if [ ! -f $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz ];then
|
||||
wget -O $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${G_VERSION}.tgz
|
||||
fi
|
||||
|
||||
cd $serverPath/source && tar -zxvf mongodb-macos-x86_64-${G_VERSION}.tgz
|
||||
cd mongodb-macos-x86_64-${G_VERSION} && mv ./* $serverPath/mongodb
|
||||
}
|
||||
|
||||
|
||||
Install_Linux_Ubuntu()
|
||||
{
|
||||
##################### Ubuntu start #####################
|
||||
if [ "$SYS_VERSION_ID" == "22" ]; then
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
echo $SYS_VERSION_ID
|
||||
|
||||
SOURCE_NAME=bionic
|
||||
if [ "$SYS_VERSION_ID" == "18.04" ];then
|
||||
SOURCE_NAME=bionic
|
||||
elif [ "$SYS_VERSION_ID" == "16.04" ];then
|
||||
SOURCE_NAME=xenial
|
||||
elif [ "$SYS_VERSION_ID" == "20.04" ];then
|
||||
SOURCE_NAME=focal
|
||||
fi
|
||||
|
||||
# wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
|
||||
# apt install -y gnupg
|
||||
# touch /etc/apt/sources.list.d/mongodb-org-4.4.list
|
||||
# echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
|
||||
|
||||
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
|
||||
apt install -y gnupg
|
||||
touch /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
|
||||
lsb_release -dc
|
||||
|
||||
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${SOURCE_NAME}/mongodb-org/${VERSION} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
|
||||
|
||||
apt update -y
|
||||
apt install -y mongodb-org
|
||||
##################### Ubuntu end #####################
|
||||
}
|
||||
|
||||
|
||||
Uninstall_Linux_Ubuntu()
|
||||
{
|
||||
|
||||
if [ -f /lib/systemd/system/mongod.service ] || [ -f /usr/lib/systemd/system/mongod.service ] ;then
|
||||
systemctl stop mongod
|
||||
fi
|
||||
|
||||
|
||||
|
||||
apt purge -y mongodb-org*
|
||||
apt autoremove -y
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongodb
|
||||
}
|
||||
|
||||
|
||||
Install_Linux_Debian()
|
||||
{
|
||||
##################### debian start #####################
|
||||
if [ "$SYS_VERSION_ID" -eq "11" ] && [ "$VERSION" -eq "4.4" ]; then
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mongod.service ];then
|
||||
echo 'alreay install exist!'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
|
||||
apt install -y gnupg
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
|
||||
|
||||
echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/${VERSION} main" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
|
||||
|
||||
apt update -y
|
||||
apt install -y mongodb-org
|
||||
|
||||
|
||||
echo "mongodb-org hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-server hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
|
||||
|
||||
##################### debian end #####################
|
||||
}
|
||||
|
||||
|
||||
|
||||
Uninstall_Linux_Debian()
|
||||
{
|
||||
systemctl stop mongod
|
||||
apt purge -y mongodb-org*
|
||||
apt autoremove -y
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongodb
|
||||
}
|
||||
|
||||
|
||||
Install_Linux_Opensuse()
|
||||
{
|
||||
##################### opensuse start #####################
|
||||
if [ "$SYS_VERSION_ID" -gt "15" ]; then
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mongod.service ];then
|
||||
echo 'alreay exist!'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
rpm --import https://www.mongodb.org/static/pgp/server-${VERSION}.asc
|
||||
zypper addrepo --gpgcheck "https://repo.mongodb.org/zypper/suse/15/mongodb-org/${VERSION}/x86_64/" mongodb
|
||||
zypper -n install mongodb-org
|
||||
# zypper install mongodb-org-4.4.15 mongodb-org-server-4.4.15 mongodb-org-shell-4.4.15 mongodb-org-mongos-4.4.15 mongodb-org-tools-4.4.15
|
||||
|
||||
|
||||
##################### opensuse end #####################
|
||||
}
|
||||
|
||||
|
||||
Uninstall_Linux_Opensuse()
|
||||
{
|
||||
systemctl stop mongod
|
||||
zypper remove -y $(rpm -qa | grep mongodb-org)
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongo
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# https://repo.mongodb.org/yum/redhat/7/mongodb-org/5.0/x86_64/RPMS/mongodb-org-server-5.0.4-1.el7.x86_64.rpm
|
||||
Install_Linux_CentOS()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/mongod.service ];then
|
||||
echo 'alreay exist!'
|
||||
exit 0
|
||||
fi
|
||||
#清空mongo的repo源
|
||||
rm -rf /etc/yum.repos.d/mongodb-org-*
|
||||
##################### centos start #####################
|
||||
echo "
|
||||
[mongodb-org-${VERSION}]
|
||||
name=MongoDB Repository
|
||||
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/${VERSION}/x86_64/
|
||||
gpgcheck=1
|
||||
enabled=1
|
||||
gpgkey=https://www.mongodb.org/static/pgp/server-${VERSION}.asc
|
||||
" > /etc/yum.repos.d/mongodb-org-${VERSION}.repo
|
||||
|
||||
yum install -y mongodb-org
|
||||
##################### centos end #####################
|
||||
}
|
||||
|
||||
Uninstall_Linux_CentOS()
|
||||
{
|
||||
systemctl stop mongod
|
||||
yum erase -y $(rpm -qa | grep mongodb-org)
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongo
|
||||
rm -rf /etc/yum.repos.d/mongodb-org-${VERSION}.repo
|
||||
}
|
||||
|
||||
|
||||
Install_app_linux()
|
||||
{
|
||||
if [ "$OSNAME" == "ubuntu" ];then
|
||||
Install_Linux_Ubuntu
|
||||
elif [ "$OSNAME" == "debian" ];then
|
||||
Install_Linux_Debian
|
||||
elif [ "$OSNAME" == "centos" ];then
|
||||
Install_Linux_CentOS
|
||||
elif [ "$OSNAME" == "opensuse" ];then
|
||||
Install_Linux_Opensuse
|
||||
else
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Install_app()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
|
||||
if [ "macos" == "$OSNAME" ];then
|
||||
Install_app_mac
|
||||
else
|
||||
Install_app_linux
|
||||
fi
|
||||
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
echo "${VERSION}" > $serverPath/mongodb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
|
||||
#初始化
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py initd_install
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
Uninstall_app_linux()
|
||||
{
|
||||
##################
|
||||
if [ "$OSNAME" == "ubuntu" ];then
|
||||
Uninstall_Linux_Ubuntu
|
||||
elif [ "$OSNAME" == "debian" ];then
|
||||
Uninstall_Linux_Debian
|
||||
elif [ "$OSNAME" == "centos" ];then
|
||||
Uninstall_Linux_CentOS
|
||||
elif [ "$OSNAME" == "opensuse" ];then
|
||||
Uninstall_Linux_Opensuse
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
##################
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
if [ "macos" == "$OSNAME" ];then
|
||||
echo 'mac'
|
||||
else
|
||||
Uninstall_app_linux
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/mongodb
|
||||
echo "Uninstall_mongodb" > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
sysName=`uname`
|
||||
echo "use system: ${sysName}"
|
||||
|
||||
# bash ${rootPath}/scripts/getos.sh
|
||||
# OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
# SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
|
||||
Install_app()
|
||||
{
|
||||
# ----- 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 ------
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh
|
||||
echo "cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh"
|
||||
export PKG_CONFIG_PATH=$serverPath/lib/openssl/lib/pkgconfig
|
||||
|
||||
if [ ! -f $MG_DIR/mongodb-src-r${VERSION}.tar.gz ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/mongodb-src-r${VERSION}.tar.gz https://fastdl.mongodb.org/src/mongodb-src-r${VERSION}.tar.gz
|
||||
echo "wget --no-check-certificate -O $MG_DIR/mongodb-src-r${VERSION}.tar.gz https://fastdl.mongodb.org/src/mongodb-src-r${VERSION}.tar.gz"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/mongodb-src-r${VERSION} ];then
|
||||
cd $MG_DIR && tar -zxvf $MG_DIR/mongodb-src-r${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
cd $MG_DIR/mongodb-src-r${VERSION} && python3 -m pip install requirements_parser
|
||||
cd $MG_DIR/mongodb-src-r${VERSION} && python3 -m pip install -r etc/pip/compile-requirements.txt
|
||||
|
||||
# cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py all -j 2
|
||||
# echo "cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py all -j 2"
|
||||
# cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py all MONGO_VERSION=${VERSION} -j 4
|
||||
|
||||
|
||||
cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py install-mongod MONGO_VERSION=${VERSION} -j ${cpuCore}
|
||||
cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py DESTDIR=$serverPath/mongodb install-mongod MONGO_VERSION=${VERSION} \
|
||||
--ssl=off
|
||||
echo "cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py DESTDIR=$serverPath/mongodb install MONGO_VERSION=${VERSION} \
|
||||
--ssl=off CPPPATH=$serverPath/lib/openssl/include \
|
||||
LIBPATH=$serverPath/lib/openssl/lib"
|
||||
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
echo "${VERSION}" > $serverPath/mongodb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
|
||||
#初始化
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py initd_install
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
|
||||
rm -rf $serverPath/mongodb
|
||||
echo "Uninstall_mongodb" > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
+51
-240
@@ -2,8 +2,15 @@
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
# https://www.mongodb.com/try/download/community
|
||||
|
||||
'''
|
||||
cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 7.0
|
||||
|
||||
cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mongodb/index.py start
|
||||
'''
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
@@ -16,230 +23,48 @@ VERSION=$2
|
||||
sysName=`uname`
|
||||
echo "use system: ${sysName}"
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
OSNAME=`bash ${rootPath}/scripts/getos.sh`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Install_app_mac()
|
||||
{
|
||||
mkdir -p $serverPath/mongodb
|
||||
if [ "$VERSION" == "5.0" ];then
|
||||
G_VERSION="5.0.11"
|
||||
elif [[ "$VERSION" == "4.4" ]]; then
|
||||
G_VERSION="4.4.11"
|
||||
fi
|
||||
|
||||
if [ ! -f $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz ];then
|
||||
wget -O $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${G_VERSION}.tgz
|
||||
fi
|
||||
|
||||
cd $serverPath/source && tar -zxvf mongodb-macos-x86_64-${G_VERSION}.tgz
|
||||
cd mongodb-macos-x86_64-${G_VERSION} && mv ./* $serverPath/mongodb
|
||||
}
|
||||
|
||||
|
||||
Install_Linux_Ubuntu()
|
||||
{
|
||||
##################### Ubuntu start #####################
|
||||
if [ "$SYS_VERSION_ID" == "22" ]; then
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
if [ "" == "$OSNAME" ];then
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
echo $SYS_VERSION_ID
|
||||
|
||||
SOURCE_NAME=bionic
|
||||
if [ "$SYS_VERSION_ID" == "18.04" ];then
|
||||
SOURCE_NAME=bionic
|
||||
elif [ "$SYS_VERSION_ID" == "16.04" ];then
|
||||
SOURCE_NAME=xenial
|
||||
elif [ "$SYS_VERSION_ID" == "20.04" ];then
|
||||
SOURCE_NAME=focal
|
||||
if [ "macos" != "$OSNAME" ];then
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
fi
|
||||
|
||||
# wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
|
||||
# apt install -y gnupg
|
||||
# touch /etc/apt/sources.list.d/mongodb-org-4.4.list
|
||||
# echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
|
||||
|
||||
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
|
||||
apt install -y gnupg
|
||||
touch /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
|
||||
lsb_release -dc
|
||||
|
||||
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${SOURCE_NAME}/mongodb-org/${VERSION} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
|
||||
|
||||
apt update -y
|
||||
apt install -y mongodb-org
|
||||
##################### Ubuntu end #####################
|
||||
}
|
||||
|
||||
|
||||
Uninstall_Linux_Ubuntu()
|
||||
{
|
||||
|
||||
if [ -f /lib/systemd/system/mongod.service ] || [ -f /usr/lib/systemd/system/mongod.service ] ;then
|
||||
systemctl stop mongod
|
||||
fi
|
||||
|
||||
|
||||
|
||||
apt purge -y mongodb-org*
|
||||
apt autoremove -y
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongodb
|
||||
}
|
||||
|
||||
|
||||
Install_Linux_Debian()
|
||||
{
|
||||
##################### debian start #####################
|
||||
if [ "$SYS_VERSION_ID" -eq "11" ] && [ "$VERSION" -eq "4.4" ]; then
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mongod.service ];then
|
||||
echo 'alreay install exist!'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
|
||||
apt install -y gnupg
|
||||
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
|
||||
|
||||
echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/${VERSION} main" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
|
||||
|
||||
apt update -y
|
||||
apt install -y mongodb-org
|
||||
|
||||
|
||||
echo "mongodb-org hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-server hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
|
||||
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
|
||||
|
||||
##################### debian end #####################
|
||||
}
|
||||
|
||||
|
||||
|
||||
Uninstall_Linux_Debian()
|
||||
{
|
||||
systemctl stop mongod
|
||||
apt purge -y mongodb-org*
|
||||
apt autoremove -y
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongodb
|
||||
}
|
||||
|
||||
|
||||
Install_Linux_Opensuse()
|
||||
{
|
||||
##################### opensuse start #####################
|
||||
if [ "$SYS_VERSION_ID" -gt "15" ]; then
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mongod.service ];then
|
||||
echo 'alreay exist!'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
rpm --import https://www.mongodb.org/static/pgp/server-${VERSION}.asc
|
||||
zypper addrepo --gpgcheck "https://repo.mongodb.org/zypper/suse/15/mongodb-org/${VERSION}/x86_64/" mongodb
|
||||
zypper -n install mongodb-org
|
||||
# zypper install mongodb-org-4.4.15 mongodb-org-server-4.4.15 mongodb-org-shell-4.4.15 mongodb-org-mongos-4.4.15 mongodb-org-tools-4.4.15
|
||||
|
||||
|
||||
##################### opensuse end #####################
|
||||
}
|
||||
|
||||
|
||||
Uninstall_Linux_Opensuse()
|
||||
{
|
||||
systemctl stop mongod
|
||||
zypper remove -y $(rpm -qa | grep mongodb-org)
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongo
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
# https://repo.mongodb.org/yum/redhat/7/mongodb-org/5.0/x86_64/RPMS/mongodb-org-server-5.0.4-1.el7.x86_64.rpm
|
||||
Install_Linux_CentOS()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/mongod.service ];then
|
||||
echo 'alreay exist!'
|
||||
exit 0
|
||||
fi
|
||||
#清空mongo的repo源
|
||||
rm -rf /etc/yum.repos.d/mongodb-org-*
|
||||
##################### centos start #####################
|
||||
echo "
|
||||
[mongodb-org-${VERSION}]
|
||||
name=MongoDB Repository
|
||||
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/${VERSION}/x86_64/
|
||||
gpgcheck=1
|
||||
enabled=1
|
||||
gpgkey=https://www.mongodb.org/static/pgp/server-${VERSION}.asc
|
||||
" > /etc/yum.repos.d/mongodb-org-${VERSION}.repo
|
||||
|
||||
yum install -y mongodb-org
|
||||
##################### centos end #####################
|
||||
}
|
||||
|
||||
Uninstall_Linux_CentOS()
|
||||
{
|
||||
systemctl stop mongod
|
||||
yum erase -y $(rpm -qa | grep mongodb-org)
|
||||
rm -r /var/log/mongodb
|
||||
rm -r /var/lib/mongo
|
||||
rm -rf /etc/yum.repos.d/mongodb-org-${VERSION}.repo
|
||||
}
|
||||
|
||||
|
||||
Install_app_linux()
|
||||
{
|
||||
if [ "$OSNAME" == "ubuntu" ];then
|
||||
Install_Linux_Ubuntu
|
||||
elif [ "$OSNAME" == "debian" ];then
|
||||
Install_Linux_Debian
|
||||
elif [ "$OSNAME" == "centos" ];then
|
||||
Install_Linux_CentOS
|
||||
elif [ "$OSNAME" == "opensuse" ];then
|
||||
Install_Linux_Opensuse
|
||||
else
|
||||
echo "Not yet supported"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Install_app()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
mkdir -p $serverPath/source
|
||||
|
||||
if [ "macos" == "$OSNAME" ];then
|
||||
Install_app_mac
|
||||
|
||||
# if id mongodb &> /dev/null ;then
|
||||
# echo "mongodb uid is `id -u mongodb`"
|
||||
# echo "mongodb shell is `grep "^mongodb:" /etc/passwd |cut -d':' -f7 `"
|
||||
# else
|
||||
# groupadd mongodb
|
||||
# useradd -g mongodb mongodb
|
||||
# fi
|
||||
|
||||
# if [ "centos" == "$OSNAME" ];then
|
||||
# OSNAME=rhel
|
||||
# fi
|
||||
|
||||
# if [ "fedora" == "$OSNAME" ];then
|
||||
# OSNAME=rhel
|
||||
# fi
|
||||
|
||||
# if [ "rocky" == "$OSNAME" ];then
|
||||
# OSNAME=rhel
|
||||
# fi
|
||||
|
||||
shell_file=${curPath}/versions/${VERSION}/${OSNAME}.sh
|
||||
|
||||
if [ -f $shell_file ];then
|
||||
bash -x $shell_file
|
||||
else
|
||||
Install_app_linux
|
||||
echo '不支持...' > $install_tmp
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$?" == "0" ];then
|
||||
@@ -253,34 +78,20 @@ Install_app()
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
||||
Uninstall_app_linux()
|
||||
{
|
||||
##################
|
||||
if [ "$OSNAME" == "ubuntu" ];then
|
||||
Uninstall_Linux_Ubuntu
|
||||
elif [ "$OSNAME" == "debian" ];then
|
||||
Uninstall_Linux_Debian
|
||||
elif [ "$OSNAME" == "centos" ];then
|
||||
Uninstall_Linux_CentOS
|
||||
elif [ "$OSNAME" == "opensuse" ];then
|
||||
Uninstall_Linux_Opensuse
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
##################
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
if [ "macos" == "$OSNAME" ];then
|
||||
echo 'mac'
|
||||
else
|
||||
Uninstall_app_linux
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py stop
|
||||
rm -rf $serverPath/mongodb
|
||||
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mongodb.service ] || [ -f /lib/systemd/system/mongodb.service ];then
|
||||
systemctl stop mongodb
|
||||
systemctl disable mongodb
|
||||
rm -rf /usr/lib/systemd/system/mongodb.service
|
||||
rm -rf /lib/systemd/system/mongodb.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/mongodb
|
||||
echo "Uninstall_mongodb" > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=4.4.23
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
|
||||
|
||||
if [ "$SYS_NAME_LEN" == "1" ];then
|
||||
SYS_NAME=${SYS_NAME}0
|
||||
fi
|
||||
|
||||
if [ "$SYS_ARCH" == "aarch64" ];then
|
||||
if [ "$SYS_NAME" -gt "82" ];then
|
||||
SYS_NAME="82"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "62" ];then
|
||||
SYS_NAME="62"
|
||||
fi
|
||||
else
|
||||
|
||||
if [ "$SYS_NAME" -gt "80" ];then
|
||||
SYS_NAME="80"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "70" ];then
|
||||
SYS_NAME="70"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-rhel82-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-rhel82-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-4.4.23.tgz
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=4.4.23
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
if [ "$SYS_NAME" -gt "10" ];then
|
||||
SYS_NAME="10"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "10" ];then
|
||||
SYS_NAME="10"
|
||||
fi
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=4.4.23
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
|
||||
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
|
||||
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=4.4.23
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
SYS_NAME="15"
|
||||
if [ "$SYS_VERSION_ID" -gt "15" ];then
|
||||
SYS_NAME="15"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "12" ];then
|
||||
SYS_NAME="12"
|
||||
fi
|
||||
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=4.4.23
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
|
||||
|
||||
if [ "$SYS_NAME_LEN" == "1" ];then
|
||||
SYS_NAME=${SYS_NAME}0
|
||||
fi
|
||||
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.23.tgz
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=4.4.23
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
|
||||
|
||||
if [ "$SYS_NAME" -gt "2004" ];then
|
||||
SYS_NAME="2004"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "1604" ];then
|
||||
SYS_NAME="1604"
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
|
||||
|
||||
if [ "$SYS_NAME_LEN" == "1" ];then
|
||||
SYS_NAME=${SYS_NAME}0
|
||||
fi
|
||||
|
||||
if [ "$SYS_ARCH" == "aarch64" ];then
|
||||
SYS_NAME="82"
|
||||
else
|
||||
|
||||
if [ "$SYS_NAME" -gt "80" ];then
|
||||
SYS_NAME="80"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "70" ];then
|
||||
SYS_NAME="70"
|
||||
fi
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
if [ "$SYS_NAME" -gt "11" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "10" ];then
|
||||
SYS_NAME="10"
|
||||
fi
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
|
||||
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
|
||||
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
SYS_NAME="15"
|
||||
if [ "$SYS_VERSION_ID" -gt "15" ];then
|
||||
SYS_NAME="15"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "12" ];then
|
||||
SYS_NAME="12"
|
||||
fi
|
||||
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=5.0.20
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
|
||||
|
||||
if [ "$SYS_NAME" -gt "2004" ];then
|
||||
SYS_NAME="2004"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "1804" ];then
|
||||
SYS_NAME="1804"
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
|
||||
|
||||
if [ "$SYS_NAME_LEN" == "1" ];then
|
||||
SYS_NAME=${SYS_NAME}0
|
||||
fi
|
||||
|
||||
if [ "$SYS_ARCH" == "aarch64" ];then
|
||||
if [ "$SYS_NAME" -gt "90" ];then
|
||||
SYS_NAME="90"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "82" ];then
|
||||
SYS_NAME="82"
|
||||
fi
|
||||
else
|
||||
|
||||
if [ "$SYS_NAME" -gt "90" ];then
|
||||
SYS_NAME="90"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "70" ];then
|
||||
SYS_NAME="70"
|
||||
fi
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
if [ "$SYS_NAME" -gt "11" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "10" ];then
|
||||
SYS_NAME="10"
|
||||
fi
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
|
||||
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
|
||||
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
SYS_NAME="15"
|
||||
if [ "$SYS_VERSION_ID" -gt "15" ];then
|
||||
SYS_NAME="15"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "12" ];then
|
||||
SYS_NAME="12"
|
||||
fi
|
||||
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=6.0.9
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
|
||||
|
||||
if [ "$SYS_NAME" -gt "2204" ];then
|
||||
SYS_NAME="2204"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "1804" ];then
|
||||
SYS_NAME="1804"
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.0
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
|
||||
|
||||
if [ "$SYS_NAME_LEN" == "1" ];then
|
||||
SYS_NAME=${SYS_NAME}0
|
||||
fi
|
||||
|
||||
if [ "$SYS_ARCH" == "aarch64" ];then
|
||||
if [ "$SYS_NAME" -gt "90" ];then
|
||||
SYS_NAME="90"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "82" ];then
|
||||
SYS_NAME="82"
|
||||
fi
|
||||
else
|
||||
|
||||
if [ "$SYS_NAME" -gt "90" ];then
|
||||
SYS_NAME="90"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "70" ];then
|
||||
SYS_NAME="70"
|
||||
fi
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.0
|
||||
SYS_ARCH=`arch`
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
|
||||
if [ "$SYS_NAME" -gt "11" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "11" ];then
|
||||
SYS_NAME="11"
|
||||
fi
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.0
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
|
||||
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
|
||||
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.0
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
|
||||
|
||||
SYS_NAME="15"
|
||||
if [ "$SYS_VERSION_ID" -gt "15" ];then
|
||||
SYS_NAME="15"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "12" ];then
|
||||
SYS_NAME="12"
|
||||
fi
|
||||
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=7.0.0
|
||||
SYS_ARCH=`arch`
|
||||
|
||||
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
SYS_NAME=${SYS_VERSION_ID/./}
|
||||
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
|
||||
|
||||
if [ "$SYS_NAME" -gt "2204" ];then
|
||||
SYS_NAME="2204"
|
||||
fi
|
||||
|
||||
if [ "$SYS_NAME" -lt "2004" ];then
|
||||
SYS_NAME="2004"
|
||||
fi
|
||||
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
|
||||
FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
|
||||
if [ ! -d $MG_DIR/${FILE_NAME} ];then
|
||||
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
@@ -0,0 +1,825 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import io
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
import oauthlib
|
||||
import requests
|
||||
import datetime
|
||||
from requests_oauthlib import OAuth2Session
|
||||
|
||||
DEBUG = False
|
||||
|
||||
|
||||
def setDebug(d=False):
|
||||
DEBUG = d
|
||||
|
||||
|
||||
class UnauthorizedError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ObjectNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class msodclient:
|
||||
|
||||
plugin_dir = ''
|
||||
server_dir = ''
|
||||
credential_file = 'credentials.json'
|
||||
user_conf = "user.conf"
|
||||
token_file = 'token.pickle'
|
||||
|
||||
def __init__(self, plugin_dir, server_dir):
|
||||
self.plugin_dir = plugin_dir
|
||||
self.server_dir = server_dir
|
||||
self.load()
|
||||
|
||||
def setDebug(self, d=False):
|
||||
DEBUG = d
|
||||
|
||||
def load(self):
|
||||
credential_path = os.path.join(self.plugin_dir, self.credential_file)
|
||||
credential = json.loads(mw.readFile(credential_path))
|
||||
# print(credential)
|
||||
self.credential = credential["onedrive-international"]
|
||||
|
||||
self.authorize_url = '{0}{1}'.format(
|
||||
self.credential['authority'],
|
||||
self.credential['authorize_endpoint'])
|
||||
self.token_url = '{0}{1}'.format(
|
||||
self.credential['authority'],
|
||||
self.credential['token_endpoint'])
|
||||
|
||||
self.token_path = os.path.join(self.server_dir, self.token_file)
|
||||
self.root_uri = self.credential["api_uri"] + "/me/drive/root"
|
||||
|
||||
self.backup_path = 'backup'
|
||||
|
||||
def store_token(self, token):
|
||||
"""存储token"""
|
||||
enstr = mw.enDoubleCrypt('msodc', json.dumps(token))
|
||||
mw.writeFile(self.token_path, enstr)
|
||||
return True
|
||||
|
||||
def get_store_token(self):
|
||||
rdata = mw.readFile(self.token_path)
|
||||
destr = mw.deDoubleCrypt('msodc', rdata)
|
||||
return json.loads(destr)
|
||||
|
||||
def clear_token(self):
|
||||
"""清除token记录"""
|
||||
try:
|
||||
if os.path.isfile(self.token_path):
|
||||
os.remove(self.token_path)
|
||||
except:
|
||||
if DEBUG:
|
||||
print("清除token失败。")
|
||||
|
||||
def refresh_token(self, origin_token):
|
||||
"""刷新token"""
|
||||
|
||||
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
|
||||
os.environ['OAUTHLIB_IGNORE_SCOPE_CHANGE'] = '1'
|
||||
refresh_token = origin_token["refresh_token"]
|
||||
aad_auth = OAuth2Session(
|
||||
self.credential["client_id"],
|
||||
scope=self.credential["scopes"],
|
||||
redirect_uri=self.credential["redirect_uri"])
|
||||
|
||||
new_token = aad_auth.refresh_token(
|
||||
self.token_url,
|
||||
refresh_token=refresh_token,
|
||||
client_id=self.credential["client_id"],
|
||||
client_secret=self.credential["client_secret"])
|
||||
return new_token
|
||||
|
||||
def get_token_from_authorized_url(self, authorized_url, expected_state=None):
|
||||
"""通过授权编码获取访问token"""
|
||||
|
||||
# 忽略token scope与已请求的scope不一致
|
||||
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
|
||||
os.environ['OAUTHLIB_IGNORE_SCOPE_CHANGE'] = '1'
|
||||
aad_auth = OAuth2Session(self.credential["client_id"],
|
||||
state=expected_state,
|
||||
scope=self.credential['scopes'],
|
||||
redirect_uri=self.credential['redirect_uri'])
|
||||
|
||||
token = aad_auth.fetch_token(
|
||||
self.token_url,
|
||||
client_secret=self.credential["client_secret"],
|
||||
authorization_response=authorized_url)
|
||||
|
||||
return token
|
||||
|
||||
def get_token(self):
|
||||
token = self.get_store_token()
|
||||
now = time.time()
|
||||
|
||||
expire_time = token["expires_at"] - 300
|
||||
if now >= expire_time:
|
||||
new_token = self.refresh_token(token)
|
||||
self.store_token(new_token)
|
||||
return new_token
|
||||
|
||||
return token
|
||||
|
||||
def get_sign_in_url(self):
|
||||
"""生成签名地址"""
|
||||
|
||||
# Initialize the OAuth client
|
||||
aad_auth = OAuth2Session(self.credential["client_id"],
|
||||
scope=self.credential['scopes'],
|
||||
redirect_uri=self.credential['redirect_uri'])
|
||||
|
||||
sign_in_url, state = aad_auth.authorization_url(self.authorize_url,
|
||||
prompt='login')
|
||||
|
||||
return sign_in_url, state
|
||||
|
||||
def get_authorized_header(self):
|
||||
token_obj = self.get_token()
|
||||
token = token_obj["access_token"]
|
||||
header = {
|
||||
"Authorization": "Bearer " + token,
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) '
|
||||
'AppleWebKit/537.36 (KHTML, like Gecko) '
|
||||
'Chrome/67.0.3396.99 Safari/537.36'
|
||||
}
|
||||
return header
|
||||
|
||||
def get_user_from_ms(self):
|
||||
"""查询用户信息"""
|
||||
try:
|
||||
headers = self.get_authorized_header()
|
||||
user_api_base = self.credential["api_uri"] + "/me"
|
||||
# select_user_info_uri = self.build_uri(base=user_api_base)
|
||||
response = requests.get(user_api_base, headers=headers)
|
||||
if DEBUG:
|
||||
print("Debug get user:")
|
||||
print(response.status_code)
|
||||
print(response.text)
|
||||
if response.status_code == 200:
|
||||
response_data = response.json()
|
||||
user_principal_name = response_data["userPrincipalName"]
|
||||
return user_principal_name
|
||||
except oauthlib.oauth2.rfc6749.errors.InvalidGrantError:
|
||||
self.clear_auth()
|
||||
if DEBUG:
|
||||
print("用户授权已过期。")
|
||||
return None
|
||||
|
||||
def clear_auth(self):
|
||||
self.clear_token()
|
||||
self.clear_user()
|
||||
|
||||
def clear_user(self):
|
||||
try:
|
||||
# 清空user
|
||||
path = os.path.join(self.server_dir, self.user_conf)
|
||||
if os.path.isfile(path):
|
||||
os.remove(path)
|
||||
except:
|
||||
if DEBUG:
|
||||
print("清除user失败。")
|
||||
|
||||
def store_user(self):
|
||||
"""更新并存储用户信息"""
|
||||
user = self.get_user_from_ms()
|
||||
if user:
|
||||
path = os.path.join(self.server_dir, self.user_conf)
|
||||
mw.writeFile(path, user)
|
||||
else:
|
||||
raise RuntimeError("无法获取用户信息。")
|
||||
|
||||
# --------------------- 文件操作功能 ----------------------
|
||||
|
||||
# 取目录路径
|
||||
def get_path(self, path):
|
||||
sep = ":"
|
||||
if path == '/':
|
||||
path = ''
|
||||
if path[-1:] == '/':
|
||||
path = path[:-1]
|
||||
if path[:1] != "/" and path[:1] != sep:
|
||||
path = "/" + path
|
||||
if path == '/':
|
||||
path = ''
|
||||
# if path[:1] != sep:
|
||||
# path = sep + path
|
||||
try:
|
||||
from urllib.parse import quote
|
||||
except:
|
||||
from urllib import quote
|
||||
# path = quote(path)
|
||||
|
||||
return path.replace('//', '/')
|
||||
|
||||
def build_uri(self, path="", operate=None, base=None):
|
||||
"""构建请求URL
|
||||
|
||||
API请求URI格式参考:
|
||||
https://graph.microsoft.com/v1.0/me/drive/root:/bt_backup/:content
|
||||
--------------------------------------------- ---------- --------
|
||||
base path operate
|
||||
各部分之间用“:”连接。
|
||||
:param path 子资源路径
|
||||
:param operate 对文件进行的操作,比如content,children
|
||||
:return 请求url
|
||||
"""
|
||||
|
||||
if base is None:
|
||||
base = self.root_uri
|
||||
path = self.get_path(path)
|
||||
sep = ":"
|
||||
if operate:
|
||||
if operate[:1] != "/":
|
||||
operate = "/" + operate
|
||||
|
||||
if path:
|
||||
uri = base + sep + path
|
||||
if operate:
|
||||
uri += sep + operate
|
||||
else:
|
||||
uri = base
|
||||
if operate:
|
||||
uri += operate
|
||||
|
||||
return uri
|
||||
|
||||
def get_list(self, path="/"):
|
||||
"""获取存储空间中的所有文件对象"""
|
||||
|
||||
list_uri = self.build_uri(path, operate="/children")
|
||||
if DEBUG:
|
||||
print("List uri:")
|
||||
print(list_uri)
|
||||
|
||||
data = []
|
||||
response = requests.get(list_uri, headers=self.get_authorized_header())
|
||||
status_code = response.status_code
|
||||
if status_code == 200:
|
||||
if DEBUG:
|
||||
print("DEBUG:")
|
||||
print(response.json())
|
||||
response_data = response.json()
|
||||
drive_items = response_data["value"]
|
||||
|
||||
for item in drive_items:
|
||||
tmp = {}
|
||||
tmp['name'] = item["name"]
|
||||
tmp['size'] = item["size"]
|
||||
if "folder" in item:
|
||||
# print("{} is folder:".format(item["name"]))
|
||||
# print(item["folder"])
|
||||
tmp["type"] = None
|
||||
tmp['download'] = ""
|
||||
if "file" in item:
|
||||
tmp["type"] = "File"
|
||||
tmp['download'] = item["@microsoft.graph.downloadUrl"]
|
||||
# print("{} is file:".format(item["name"]))
|
||||
# print(item["file"])
|
||||
|
||||
formats = ["%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ"]
|
||||
t = None
|
||||
for time_format in formats:
|
||||
try:
|
||||
t = datetime.datetime.strptime(
|
||||
item["lastModifiedDateTime"], time_format)
|
||||
break
|
||||
except:
|
||||
continue
|
||||
t += datetime.timedelta(hours=8)
|
||||
ts = int(
|
||||
(time.mktime(t.timetuple()) + t.microsecond / 1000000.0))
|
||||
tmp['time'] = ts
|
||||
data.append(tmp)
|
||||
|
||||
mlist = {'path': path, 'list': data}
|
||||
return mlist
|
||||
|
||||
def get_object(self, object_name):
|
||||
"""查询对象信息"""
|
||||
try:
|
||||
get_uri = self.build_uri(path=object_name)
|
||||
if DEBUG:
|
||||
print("Get uri:")
|
||||
print(get_uri)
|
||||
response = requests.get(get_uri,
|
||||
headers=self.get_authorized_header())
|
||||
if response.status_code in [200]:
|
||||
response_data = response.json()
|
||||
if DEBUG:
|
||||
print("Object info:")
|
||||
print(response_data)
|
||||
return response_data
|
||||
if response.status_code == 404:
|
||||
if DEBUG:
|
||||
print("对象不存在。")
|
||||
if DEBUG:
|
||||
print("Get Object debug:")
|
||||
print(response.status_code)
|
||||
print(response.text)
|
||||
except Exception as e:
|
||||
if DEBUG:
|
||||
print("Get object has excepiton:")
|
||||
print(e)
|
||||
return None
|
||||
|
||||
def is_folder(self, obj):
|
||||
if "folder" in obj:
|
||||
return True
|
||||
return False
|
||||
|
||||
def delete_object_by_os(self, object_name):
|
||||
"""删除对象
|
||||
|
||||
:param object_name:
|
||||
:return: True 删除成功
|
||||
其他 删除失败
|
||||
"""
|
||||
obj = self.get_object(object_name)
|
||||
if obj is None:
|
||||
if DEBUG:
|
||||
print("对象不存在,删除操作未执行。")
|
||||
return True
|
||||
if self.is_folder(obj):
|
||||
child_count = obj["folder"]["childCount"]
|
||||
if child_count > 0:
|
||||
if DEBUG:
|
||||
print("文件夹不是空文件夹无法删除。")
|
||||
return False
|
||||
|
||||
headers = self.get_authorized_header()
|
||||
delete_uri = self.build_uri(object_name)
|
||||
response = requests.delete(delete_uri, headers=headers)
|
||||
if response.status_code == 204:
|
||||
if DEBUG:
|
||||
print("对象: {} 已被删除。".format(object_name))
|
||||
return True
|
||||
return False
|
||||
|
||||
def delete_object(self, object_name, retries=2):
|
||||
"""删除对象
|
||||
|
||||
:param object_name:
|
||||
:param retries: 重试次数,默认2次
|
||||
:return: True 删除成功
|
||||
其他 删除失败
|
||||
"""
|
||||
|
||||
try:
|
||||
return self.delete_object_by_os(object_name)
|
||||
except Exception as e:
|
||||
print("删除文件异常:")
|
||||
print(e)
|
||||
|
||||
# 重试
|
||||
if retries > 0:
|
||||
print("重新尝试删除文件{}...".format(object_name))
|
||||
return self.delete_object(
|
||||
object_name,
|
||||
retries=retries - 1)
|
||||
return False
|
||||
|
||||
def build_object_name(self, data_type, file_name):
|
||||
"""根据数据类型构建对象存储名称
|
||||
|
||||
:param data_type:
|
||||
:param file_name:
|
||||
:return:
|
||||
"""
|
||||
|
||||
import re
|
||||
|
||||
prefix_dict = {
|
||||
"site": "web",
|
||||
"database": "db",
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
if not prefix_dict.get(data_type):
|
||||
print("data_type 类型错误!!!")
|
||||
exit(1)
|
||||
|
||||
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+(?:\.|_)"
|
||||
sub_search = re.search(file_regx, file_name)
|
||||
sub_path_name = ""
|
||||
if sub_search:
|
||||
sub_path_name = sub_search.groups()[0]
|
||||
sub_path_name += '/'
|
||||
|
||||
# 构建OS存储路径
|
||||
object_name = self.backup_path + '/' + \
|
||||
data_type + '/' + \
|
||||
sub_path_name + \
|
||||
file_name
|
||||
|
||||
if object_name[:1] == "/":
|
||||
object_name = object_name[1:]
|
||||
|
||||
return object_name
|
||||
|
||||
def delete_file(self, file_name, data_type=None):
|
||||
"""删除文件
|
||||
|
||||
根据传入的文件名称和文件数据类型构建对象名称,再删除
|
||||
:param file_name:
|
||||
:param data_type: 数据类型 site/database/path
|
||||
:return: True 删除成功
|
||||
其他 删除失败
|
||||
"""
|
||||
|
||||
object_name = self.build_object_name(data_type, file_name)
|
||||
return self.delete_object(object_name)
|
||||
|
||||
def create_dir_by_step(self, parent_folder, sub_folder):
|
||||
create_uri = self.build_uri(path=parent_folder, operate="/children")
|
||||
|
||||
if DEBUG:
|
||||
print("Create dir uri:")
|
||||
print(create_uri)
|
||||
post_data = {
|
||||
"name": sub_folder,
|
||||
"folder": {"@odata.type": "microsoft.graph.folder"},
|
||||
"@microsoft.graph.conflictBehavior": "fail"
|
||||
}
|
||||
|
||||
headers = self.get_authorized_header()
|
||||
headers.update({"Content-type": "application/json"})
|
||||
response = requests.post(create_uri, headers=headers, json=post_data)
|
||||
if response.status_code in [201, 409]:
|
||||
if DEBUG:
|
||||
if response.status_code == 409:
|
||||
print("目录:{} 已经存在。".format(sub_folder))
|
||||
return True
|
||||
else:
|
||||
if DEBUG:
|
||||
print("目录:{} 创建失败:".format(sub_folder))
|
||||
print(response.status_code)
|
||||
print(response.text)
|
||||
return False
|
||||
|
||||
def create_dir(self, dir_name):
|
||||
"""创建远程目录
|
||||
|
||||
# API 请求结构
|
||||
# POST /me/drive/root/children
|
||||
# or
|
||||
# POST /me/drive/root:/bt_backup/:/children
|
||||
# Content - Type: application / json
|
||||
|
||||
# {
|
||||
# "name": "New Folder",
|
||||
# "folder": {},
|
||||
# "@microsoft.graph.conflictBehavior": "rename"
|
||||
# }
|
||||
|
||||
# Response: status code == 201 新创建/ 409 已存在
|
||||
# @microsoft.graph.conflictBehavior: fail/rename/replace
|
||||
|
||||
:param dir_name: 目录名称
|
||||
:param parent_id: 父目录ID
|
||||
:return: True/False
|
||||
"""
|
||||
|
||||
dir_name = self.get_path(dir_name.strip())
|
||||
onedrive_business_reserved = r"[\*<>?:|#%]"
|
||||
if re.search(onedrive_business_reserved, dir_name) \
|
||||
or dir_name[-1] == "." or dir_name[:1] == "~":
|
||||
if DEBUG:
|
||||
print("文件夹名称包含非法字符。")
|
||||
return False
|
||||
|
||||
parent_folder = self.get_path(os.path.split(dir_name)[0])
|
||||
sub_folder = os.path.split(dir_name)[1]
|
||||
|
||||
# print("create_dir:", dir_name)
|
||||
obj = self.get_object(dir_name)
|
||||
# 判断对象是否存在
|
||||
if obj is None:
|
||||
if not self.create_dir_by_step(parent_folder, sub_folder):
|
||||
|
||||
# 兼容OneDrive 商业版文件夹创建
|
||||
folder_array = dir_name.split("/")
|
||||
parent_folder = self.get_path(folder_array[0])
|
||||
for i in range(1, len(folder_array)):
|
||||
sub_folder = folder_array[i]
|
||||
if DEBUG:
|
||||
print("Parent folder: {}".format(parent_folder))
|
||||
print("Sub folder: {}".format(sub_folder))
|
||||
if self.create_dir_by_step(parent_folder, sub_folder):
|
||||
parent_folder += "/" + folder_array[i]
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
else:
|
||||
if self.is_folder(obj):
|
||||
if DEBUG:
|
||||
print("文件夹已存在。")
|
||||
return True
|
||||
|
||||
def resumable_upload(self,
|
||||
local_file_name,
|
||||
object_name=None,
|
||||
progress_callback=None,
|
||||
progress_file_name=None,
|
||||
multipart_threshold=1024 * 1024 * 2,
|
||||
part_size=1024 * 1024 * 5,
|
||||
store_dir="/tmp",
|
||||
auto_cancel=True,
|
||||
retries=5,
|
||||
):
|
||||
"""断点续传
|
||||
|
||||
:param local_file_name: 本地文件名称
|
||||
:param object_name: 指定OS中存储的对象名称
|
||||
:param part_size: 指定分片上传的每个分片的大小。必须是320*1024的整数倍。
|
||||
:param multipart_threshold: 文件长度大于该值时,则用分片上传。
|
||||
:param progress_callback: 进度回调函数,默认是把进度信息输出到标准输出。
|
||||
:param progress_file_name: 进度信息保存文件,进度格式参见[report_progress]
|
||||
:param store_dir: 上传分片存储目录, 默认/tmp。
|
||||
:param auto_cancel: 当备份失败是否自动取消上传记录
|
||||
:param retries: 上传重试次数
|
||||
:return: True上传成功/False or None上传失败
|
||||
"""
|
||||
|
||||
try:
|
||||
file_size_separation_value = 4 * 1024 * 1024
|
||||
if part_size % 320 != 0:
|
||||
if DEBUG:
|
||||
print("Part size 必须是320的整数倍。")
|
||||
return False
|
||||
|
||||
if object_name is None:
|
||||
temp_file_name = os.path.split(local_file_name)[1]
|
||||
object_name = os.path.join(self.backup_path, temp_file_name)
|
||||
|
||||
# if progress_file_name:
|
||||
# os.environ[PROGRESS_FILE_NAME] = progress_file_name
|
||||
# progress_callback = report_progress
|
||||
|
||||
print("|-正在上传到 {}...".format(object_name))
|
||||
dir_name = os.path.split(object_name)[0]
|
||||
if not self.create_dir(dir_name):
|
||||
if DEBUG:
|
||||
print("目录创建失败!")
|
||||
return False
|
||||
|
||||
local_file_size = os.path.getsize(local_file_name)
|
||||
# if local_file_size < file_size_separation_value:
|
||||
if False:
|
||||
# 小文件上传
|
||||
upload_uri = self.build_uri(path=object_name,
|
||||
operate="/content")
|
||||
if DEBUG:
|
||||
print("Upload uri:")
|
||||
print(upload_uri)
|
||||
headers = self.get_authorized_header()
|
||||
# headers.update({
|
||||
# "Content-Type": "application/octet-stream"
|
||||
# })
|
||||
# files = {"file": (object_name, open(local_file_name, "rb"))}
|
||||
file_data = open(local_file_name, "rb")
|
||||
response = requests.put(upload_uri,
|
||||
headers=headers,
|
||||
data=file_data)
|
||||
if DEBUG:
|
||||
print("status code:")
|
||||
print(response.status_code)
|
||||
# print(response.text)
|
||||
if response.status_code in [201, 200]:
|
||||
if DEBUG:
|
||||
print("文件上传成功!")
|
||||
return True
|
||||
else:
|
||||
# 大文件上传
|
||||
|
||||
# 1. 创建上传session
|
||||
create_session_uri = self.build_uri(
|
||||
path=object_name,
|
||||
operate="createUploadSession")
|
||||
headers = self.get_authorized_header()
|
||||
response = requests.post(create_session_uri, headers=headers)
|
||||
if response.status_code == 200:
|
||||
response_data = response.json()
|
||||
upload_url = response_data["uploadUrl"]
|
||||
expiration_date_time = response_data["expirationDateTime"]
|
||||
|
||||
if DEBUG:
|
||||
print("上传session已建立。")
|
||||
print("Upload url: {}".format(upload_url))
|
||||
print("Expiration datetime: {}".format(
|
||||
expiration_date_time))
|
||||
|
||||
# 2. 分片上传文件
|
||||
requests.adapters.DEFAULT_RETRIES = 1
|
||||
session = requests.session()
|
||||
session.keep_alive = False
|
||||
|
||||
# 开始分片上传
|
||||
import math
|
||||
parts = int(math.ceil(local_file_size / part_size))
|
||||
for i in range(parts):
|
||||
if DEBUG:
|
||||
if i == parts - 1:
|
||||
num = "最后"
|
||||
else:
|
||||
num = "第{}".format(i + 1)
|
||||
print("正在上传{}部分...".format(num))
|
||||
|
||||
upload_range_start = i * part_size
|
||||
upload_range_end = min(upload_range_start + part_size,
|
||||
local_file_size)
|
||||
content_length = upload_range_end - upload_range_start
|
||||
|
||||
headers = {
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) '
|
||||
'AppleWebKit/537.36 (KHTML, like Gecko) '
|
||||
'Chrome/67.0.3396.99 Safari/537.36'
|
||||
}
|
||||
# 开发记录
|
||||
# Content-Range和标准的http请求头中的Range作用有所不同
|
||||
# Content-Range是OneDrive自定义的分片上传标识,格式也不一样
|
||||
headers.update({
|
||||
"Content-Length": repr(content_length),
|
||||
"Content-Range": "bytes {}-{}/{}".format(
|
||||
upload_range_start,
|
||||
upload_range_end - 1,
|
||||
local_file_size),
|
||||
"Content-Type": "application/octet-stream"
|
||||
})
|
||||
|
||||
if DEBUG:
|
||||
print("Headers:")
|
||||
print(headers)
|
||||
|
||||
'''# TODO 优化read的读取占用内存'''
|
||||
f = io.open(local_file_name, "rb")
|
||||
f.seek(upload_range_start)
|
||||
upload_data = f.read(content_length)
|
||||
sub_response = session.put(upload_url,
|
||||
headers=headers,
|
||||
data=upload_data)
|
||||
|
||||
expected_status_code = [200, 201, 202]
|
||||
if sub_response.status_code in expected_status_code:
|
||||
if DEBUG:
|
||||
print("Response status code: {}, "
|
||||
"bytes {}-{} 已上传成功。".format(
|
||||
sub_response.status_code,
|
||||
upload_range_start,
|
||||
upload_range_end - 1)
|
||||
)
|
||||
print(sub_response.text)
|
||||
if sub_response.status_code in [200, 201]:
|
||||
if DEBUG:
|
||||
print("文件 {} 上传成功。".format(object_name))
|
||||
return True
|
||||
else:
|
||||
print(sub_response.status_code)
|
||||
print(sub_response.text)
|
||||
_error_msg = "Bytes {}-{} 分片上传失败。".format(
|
||||
upload_range_start,
|
||||
upload_range_end
|
||||
)
|
||||
if self.error_msg:
|
||||
self.error_msg += r"\n"
|
||||
self.error_msg += _error_msg
|
||||
raise RuntimeError(_error_msg)
|
||||
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
raise RuntimeError("session创建失败。")
|
||||
|
||||
except UnauthorizedError as e:
|
||||
_error_msg = str(e)
|
||||
if self.error_msg:
|
||||
self.error_msg += r"\n"
|
||||
self.error_msg += _error_msg
|
||||
print(_error_msg)
|
||||
return False
|
||||
except Exception as e:
|
||||
print("文件上传出现错误:")
|
||||
print(e)
|
||||
|
||||
if self.error_msg:
|
||||
self.error_msg += r"\n"
|
||||
self.error_msg += "文件{}上传出现错误:{}".format(object_name, str(e))
|
||||
|
||||
try:
|
||||
if upload_url:
|
||||
if DEBUG:
|
||||
print("正在清理上传session.")
|
||||
session.delete(upload_url)
|
||||
except:
|
||||
pass
|
||||
finally:
|
||||
try:
|
||||
f.close()
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
session.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
# 重试断点续传
|
||||
if retries > 0:
|
||||
print("重试上传文件....")
|
||||
return self.resumable_upload(
|
||||
local_file_name,
|
||||
object_name=object_name,
|
||||
store_dir=store_dir,
|
||||
part_size=part_size,
|
||||
multipart_threshold=multipart_threshold,
|
||||
progress_callback=progress_callback,
|
||||
progress_file_name=progress_file_name,
|
||||
retries=retries - 1,
|
||||
)
|
||||
else:
|
||||
if self.error_msg:
|
||||
self.error_msg += r"\n"
|
||||
self.error_msg += "文件{}上传失败。".format(object_name)
|
||||
return False
|
||||
|
||||
def upload_abs_file(self, file_name, remote_dir, *args, **kwargs):
|
||||
"""按照数据类型上传文件
|
||||
|
||||
:param file_name: 上传文件名称
|
||||
:param data_type: 数据类型 site/database/path
|
||||
:return: True/False
|
||||
"""
|
||||
try:
|
||||
import re
|
||||
# 根据数据类型提取子分类名称
|
||||
# 比如data_type=database,子分类名称是数据库的名称。
|
||||
# 提取方式是从file_name中利用正则规则去提取。
|
||||
self.error_msg = ""
|
||||
|
||||
file_name = os.path.abspath(file_name)
|
||||
temp_name = os.path.split(file_name)[1]
|
||||
object_name = 'backup/' + temp_name
|
||||
|
||||
print(file_name)
|
||||
print(object_name)
|
||||
|
||||
return self.resumable_upload(file_name,
|
||||
object_name=object_name,
|
||||
*args,
|
||||
**kwargs)
|
||||
except Exception as e:
|
||||
if self.error_msg:
|
||||
self.error_msg += r"\n"
|
||||
self.error_msg += "文件上传出现错误:{}".format(str(e))
|
||||
return False
|
||||
|
||||
def upload_file(self, file_name, data_type, *args, **kwargs):
|
||||
"""按照数据类型上传文件
|
||||
|
||||
:param file_name: 上传文件名称
|
||||
:param data_type: 数据类型 site/database/path
|
||||
:return: True/False
|
||||
"""
|
||||
try:
|
||||
import re
|
||||
# 根据数据类型提取子分类名称
|
||||
# 比如data_type=database,子分类名称是数据库的名称。
|
||||
# 提取方式是从file_name中利用正则规则去提取。
|
||||
self.error_msg = ""
|
||||
|
||||
if not file_name or not data_type:
|
||||
_error_msg = "文件参数错误。"
|
||||
print(_error_msg)
|
||||
self.error_msg = _error_msg
|
||||
return False
|
||||
|
||||
file_name = os.path.abspath(file_name)
|
||||
temp_name = os.path.split(file_name)[1]
|
||||
object_name = self.build_object_name(data_type, temp_name)
|
||||
|
||||
# dir_name = os.path.dirname(object_name)
|
||||
# self.create_dir(dir_name)
|
||||
if DEBUG:
|
||||
print(file_name)
|
||||
print(object_name)
|
||||
print(dir_name)
|
||||
|
||||
return self.resumable_upload(file_name,
|
||||
object_name=object_name,
|
||||
*args,
|
||||
**kwargs)
|
||||
except Exception as e:
|
||||
if self.error_msg:
|
||||
self.error_msg += r"\n"
|
||||
self.error_msg += "文件上传出现错误:{}".format(str(e))
|
||||
return False
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"onedrive-international": {
|
||||
"client_id": "08125e6b-6502-4ac9-9548-ad682f00848d",
|
||||
"client_secret": "0WA8Q~sZkZFZKv50ryP4ux~.fpVtbHw7BuTZmbQB",
|
||||
"authority": "https://login.microsoftonline.com/common",
|
||||
"token_endpoint": "/oauth2/v2.0/token",
|
||||
"authorize_endpoint": "/oauth2/v2.0/authorize",
|
||||
"scopes": "offline_access Files.ReadWrite.All User.Read",
|
||||
"redirect_uri": "http://localhost",
|
||||
"api_uri": "https://graph.microsoft.com/v1.0"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,310 @@
|
||||
<style>
|
||||
.upyunCon {
|
||||
height: 428px;
|
||||
}
|
||||
|
||||
.up-place {
|
||||
height: 62px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.up-place .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.up-place .place-input {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
overflow: hidden;
|
||||
margin: 1px 0 0 -1px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
.place-input ul {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.place-input ul li {
|
||||
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.place-input ul li a {
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upyunlist {
|
||||
height: 516px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.up-bottom {
|
||||
background-color: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.up-use {
|
||||
line-height: 50px
|
||||
}
|
||||
|
||||
.list-list .cursor span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.btn-title {
|
||||
margin-top: 1px
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 10px;
|
||||
font-style: oblique;
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<div class="upyunCon">
|
||||
<div class="up-place pd15">
|
||||
<button id="backBtn" class="btn btn-default btn-sm glyphicon glyphicon-arrow-left pull-left" title="后退"></button>
|
||||
<input id="myPath" style="display:none;" type="text" value="">
|
||||
<div class="place-input pull-left">
|
||||
<div style="width:1400px;height:28px"><ul></ul></div>
|
||||
</div>
|
||||
<button class="refreshBtn btn btn-default btn-sm glyphicon glyphicon-refresh pull-left mr20" title="刷新" style="margin-left:-1px;"></button>
|
||||
<button class="btn btn-default btn-sm pull-right btn-title" onclick="authApi()">授权</button>
|
||||
<button class="btn btn-default btn-sm pull-right mr20 btn-title" onclick="createDir()">新建文件夹</button>
|
||||
</div>
|
||||
|
||||
<div class="upyunlist pd15">
|
||||
<div class="divtable" style="margin-bottom:15px">
|
||||
<table class="table table-hover">
|
||||
<thead><tr><th>名称</th><th>大小</th><th>更新时间</th><th class="text-right">操作</th></tr></thead>
|
||||
<tbody class="list-list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style type="text/css">
|
||||
.check_api {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.up-place {
|
||||
height: 62px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.up-place .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.up-place .place-input {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
overflow: hidden;
|
||||
margin: 1px 0 0 -1px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
.place-input ul {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.place-input ul li {
|
||||
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.place-input ul li a {
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upyunlist {
|
||||
height: 546px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.up-bottom {
|
||||
background-color: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.up-use {
|
||||
line-height: 50px
|
||||
}
|
||||
|
||||
.list-list .cursor span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.btn-title {
|
||||
margin-top: 1px
|
||||
}
|
||||
|
||||
.step_item{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.step_item .serial_box{
|
||||
display: inline-block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.step_item .serial{
|
||||
width: 70px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
.step_item .serial span{
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 28px;
|
||||
font-size: 11px;
|
||||
border-radius: 50%;
|
||||
color: #20a53a;
|
||||
border: 2px solid #20a53a;
|
||||
}
|
||||
.step_item .serial_title{
|
||||
margin-bottom: 10px;
|
||||
font-size: 15px;
|
||||
line-height: 30px;
|
||||
color: #666;
|
||||
}
|
||||
.step_two_url{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
width: 380px;
|
||||
/*text-overflow: ellipsis;*/
|
||||
white-space: nowrap;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
margin-right: 15px;
|
||||
border-radius: 2px;
|
||||
padding: 0 10px;
|
||||
float: left;
|
||||
width:360px;
|
||||
padding-right: 35px;
|
||||
}
|
||||
.btn_btlink{
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
border: 1px solid #20a53a;
|
||||
color: #fff;
|
||||
background-color: #20a53a;
|
||||
margin-right:10px;
|
||||
}
|
||||
.btn_btlink:hover{
|
||||
color: #fff;
|
||||
background-color: #10952a;
|
||||
border-color: #398439;
|
||||
}
|
||||
.btn_btlink a:visited{
|
||||
color: #fff;
|
||||
background-color: #10952a;
|
||||
border-color: #398439;
|
||||
}
|
||||
.view_video{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.view_video ul li{
|
||||
line-height: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.setp_one i{
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 25px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.OneDrive{
|
||||
width:465px;
|
||||
height:100px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/html" id="check_api">
|
||||
<div class="check_api">
|
||||
<div class="step_two">
|
||||
<div class="step_item">
|
||||
<div class="serial"><span>1</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">阅读简易操作教程:如何获取Microsoft OneDrive授权?</div>
|
||||
<div class="serial_conter">
|
||||
<div class="view_video">
|
||||
<ul>
|
||||
<li>1. 点击下面第<div class="serial" style="float: none;width: 45px;"><span>2</span></div>步中的 打开授权链接。<li>
|
||||
<li>2. 在新窗口页面上登录Microsoft账号。阅读授权权限,并同意。<li>
|
||||
<li>3. 页面跳转后,将浏览器的地址栏地址复制到第<div class="serial" style="float: none;width: 45px;"><span>3</span></div>步的文本框中。<li>
|
||||
<li>4. 点击 获取授权,随即完成授权。<li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step_item pb15">
|
||||
<div class="serial"><span>2</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">操作1:👇打开授权链接,根据网页提示对插件进行授权。</div>
|
||||
<div class="serial_conter step_two" style="width: 500px;">
|
||||
<input class="bt-input-text mr5 step_two_url" type="text" disabled>
|
||||
<span class="ico-copy mr10" data-copy="" style="vertical-align: middle;cursor: pointer;margin-left: -37px;margin-right: 20px;"></span>
|
||||
<a href="" class="btn_btlink open_btlink" target="_blank" style="padding: 7px 10px;">打开授权链接</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="step_item">
|
||||
<div class="serial"><span>3</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">操作2:复制回浏览器跳转后的地址:</div>
|
||||
<div class="serial_conter">
|
||||
<textarea row="3" placeholder="验证URL地址" class="bt-input-text OneDrive" style="resize: none;"/></br>
|
||||
<button type="button" class="btn btn-success btn-sm set_auth_btn">获取授权</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<!-- <script type="text/javascript" src="/plugins/file?name=msonedrive&f=js/msonedrive.js"></script> -->
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=msonedrive&f=js/msonedrive.js", function(){
|
||||
odList('/');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,351 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
# print(sys.platform)
|
||||
if sys.platform != "darwin":
|
||||
os.chdir("/www/server/mdserver-web")
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
import db
|
||||
|
||||
_ver = sys.version_info
|
||||
is_py2 = (_ver[0] == 2)
|
||||
is_py3 = (_ver[0] == 3)
|
||||
|
||||
DEBUG = False
|
||||
|
||||
if is_py2:
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'msonedrive'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def in_array(name, arr=[]):
|
||||
for x in arr:
|
||||
if name == x:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
sys.path.append(getPluginDir() + "/class")
|
||||
from msodclient import msodclient
|
||||
|
||||
|
||||
msodc = msodclient(getPluginDir(), getServerDir())
|
||||
msodc.setDebug(False)
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
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(':', 1)
|
||||
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 isAuthApi():
|
||||
cfg = getServerDir() + "/user.conf"
|
||||
if os.path.exists(cfg):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getConf():
|
||||
if not isAuthApi():
|
||||
sign_in_url, state = msodc.get_sign_in_url()
|
||||
return mw.returnJson(False, "未授权!", {'auth_url': sign_in_url})
|
||||
return mw.returnJson(True, "OK")
|
||||
|
||||
|
||||
def setAuthUrl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['url'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
url = args['url']
|
||||
|
||||
try:
|
||||
if url.startswith("http://"):
|
||||
url = url.replace("http://", "https://")
|
||||
token = msodc.get_token_from_authorized_url(authorized_url=url)
|
||||
msodc.store_token(token)
|
||||
msodc.store_user()
|
||||
return mw.returnJson(True, "授权成功!")
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "授权失败2!:" + str(e))
|
||||
return mw.returnJson(False, "授权失败!:" + str(e))
|
||||
|
||||
|
||||
def clearAuth():
|
||||
cfg = getServerDir() + "/user.conf"
|
||||
if os.path.exists(cfg):
|
||||
os.remove(cfg)
|
||||
|
||||
token = getServerDir() + "/token.pickle"
|
||||
if os.path.exists(token):
|
||||
os.remove(token)
|
||||
|
||||
return mw.returnJson(True, "清空授权成功!")
|
||||
|
||||
|
||||
def getList():
|
||||
cfg = getServerDir() + "/user.conf"
|
||||
if not os.path.exists(cfg):
|
||||
return mw.returnJson(False, "未配置,请点击`授权`", [])
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['path'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
try:
|
||||
flist = msodc.get_list(args['path'])
|
||||
return mw.returnJson(True, "ok", flist)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, str(e), [])
|
||||
|
||||
|
||||
def createDir():
|
||||
cfg = getServerDir() + "/user.conf"
|
||||
if not os.path.exists(cfg):
|
||||
return mw.returnJson(False, "未配置OneDrive,请点击`授权`", [])
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['path', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['path'] + "/" + args['name']
|
||||
isok = msodc.create_dir(file)
|
||||
if isok:
|
||||
return mw.returnJson(True, "创建成功")
|
||||
return mw.returnJson(False, "创建失败")
|
||||
|
||||
|
||||
def deleteDir():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['dir_name', 'path'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['path'] + "/" + args['dir_name']
|
||||
file = file.strip('/')
|
||||
isok = msodc.delete_object(file)
|
||||
if isok:
|
||||
return mw.returnJson(True, "删除成功")
|
||||
return mw.returnJson(False, "文件不为空,删除失败!")
|
||||
|
||||
|
||||
def deleteFile():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['path', 'filename'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['path'] + "/" + args['filename']
|
||||
file = file.strip('/')
|
||||
isok = msodc.delete_object(file)
|
||||
if isok:
|
||||
return mw.returnJson(True, "删除成功")
|
||||
return mw.returnJson(False, "删除失败")
|
||||
|
||||
|
||||
def findPathName(path, filename):
|
||||
f = os.scandir(path)
|
||||
l = []
|
||||
for ff in f:
|
||||
t = {}
|
||||
if ff.name.find(filename) > -1:
|
||||
t['filename'] = path + '/' + ff.name
|
||||
l.append(t)
|
||||
return l
|
||||
|
||||
|
||||
def backupAllFunc(stype):
|
||||
if not isAuthApi():
|
||||
mw.echoInfo("未授权API,无法使用!!!")
|
||||
return ''
|
||||
|
||||
os.chdir(mw.getRunDir())
|
||||
backup_dir = mw.getBackupDir()
|
||||
run_dir = mw.getRunDir()
|
||||
|
||||
stype = sys.argv[1]
|
||||
name = sys.argv[2]
|
||||
num = sys.argv[3]
|
||||
|
||||
prefix_dict = {
|
||||
"site": "web",
|
||||
"database": "db",
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
backups = []
|
||||
sql = db.Sql()
|
||||
|
||||
# print("stype:", stype)
|
||||
# 提前获取-清理多余备份
|
||||
if stype == 'site':
|
||||
pid = sql.table('sites').where('name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('0', pid)).field('id,filename').select()
|
||||
if stype == 'database':
|
||||
db_path = mw.getServerDir() + '/mysql'
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
if stype == 'path':
|
||||
backup_path = backup_dir + '/path'
|
||||
_name = 'path_{}'.format(os.path.basename(name))
|
||||
backups = findPathName(backup_path, _name)
|
||||
|
||||
# 其他类型关系性数据库(mysql类的)
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
db_path = mw.getServerDir() + '/' + plugin_name
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
|
||||
args = stype + " " + name + " " + num
|
||||
cmd = 'python3 ' + run_dir + '/scripts/backup.py ' + args
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
args = "database " + name + " " + num
|
||||
cmd = 'python3 ' + run_dir + '/plugins/' + \
|
||||
plugin_name + '/scripts/backup.py ' + args
|
||||
|
||||
if stype == 'path':
|
||||
name = os.path.basename(name)
|
||||
|
||||
# print("cmd:", cmd)
|
||||
os.system(cmd)
|
||||
|
||||
# 开始执行上传信息.
|
||||
if stype.find('database_') > -1:
|
||||
bk_name = 'database'
|
||||
plugin_name = stype.replace('database_', '')
|
||||
bk_prefix = plugin_name + '/db'
|
||||
stype = 'database'
|
||||
else:
|
||||
bk_prefix = prefix_dict[stype]
|
||||
bk_name = stype
|
||||
|
||||
find_path = backup_dir + '/' + bk_name + '/' + bk_prefix + '_' + name
|
||||
find_new_file = "ls " + find_path + \
|
||||
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
|
||||
|
||||
# print(find_new_file)
|
||||
|
||||
filename = mw.execShell(find_new_file)[0].strip()
|
||||
if filename == "":
|
||||
mw.echoInfo("not find upload file!")
|
||||
return False
|
||||
|
||||
mw.echoInfo("准备上传文件 {}".format(filename))
|
||||
mw.echoStart('开始上传')
|
||||
msodc.upload_file(filename, stype)
|
||||
mw.echoEnd('上传成功')
|
||||
|
||||
# print(backups)
|
||||
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
|
||||
mw.echoStart('开始删除远程备份')
|
||||
num = int(num)
|
||||
sep = len(backups) - num
|
||||
if sep > -1:
|
||||
for backup in backups:
|
||||
fn = os.path.basename(backup['filename'])
|
||||
msodc.delete_file(fn, stype)
|
||||
mw.echoInfo("---已清理远程过期备份文件:" + fn)
|
||||
sep -= 1
|
||||
if sep < 0:
|
||||
break
|
||||
mw.echoEnd('结束删除远程备份')
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def installPreInspection():
|
||||
return 'ok'
|
||||
|
||||
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())
|
||||
elif func == 'install_pre_inspection':
|
||||
print(installPreInspection())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'set_auth_url':
|
||||
print(setAuthUrl())
|
||||
elif func == 'clear_auth':
|
||||
print(clearAuth())
|
||||
elif func == "get_list":
|
||||
print(getList())
|
||||
elif func == "create_dir":
|
||||
print(createDir())
|
||||
elif func == "delete_dir":
|
||||
print(deleteDir())
|
||||
elif func == 'delete_file':
|
||||
print(deleteFile())
|
||||
elif in_array(func, ['site', 'database', 'path']) or func.find('database_') > -1:
|
||||
print(backupAllFunc(func))
|
||||
else:
|
||||
print('error')
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"hook":["backup"],
|
||||
"title": "OneDrive",
|
||||
"tip": "lib",
|
||||
"name": "msonedrive",
|
||||
"type": "sort",
|
||||
"ps": "微软家的云网盘服务。",
|
||||
"versions": "1.0",
|
||||
"shell": "install.sh",
|
||||
"checks": "server/msonedrive",
|
||||
"author": "midoks",
|
||||
"date": "2023-8-18",
|
||||
"pid": "4"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
PATH=/www/server/panel/pyenv/bin:/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")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=$2
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
Install_App()
|
||||
{
|
||||
pip install requests-oauthlib==1.3.0
|
||||
mkdir -p $serverPath/msonedrive
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
echo "${VERSION}" > $serverPath/msonedrive/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
|
||||
echo "Successify"
|
||||
}
|
||||
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/msonedrive
|
||||
}
|
||||
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
elif [ "${1}" == 'uninstall' ];then
|
||||
Uninstall_App
|
||||
else
|
||||
echo 'Error!';
|
||||
fi
|
||||
@@ -0,0 +1,258 @@
|
||||
|
||||
function msodPost(method,args,callback){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'msonedrive', func:method, args:_args}, 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 createDir(){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: "400px",
|
||||
title: "创建目录",
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
btn: ['确定','取消'],
|
||||
content:'<div class="bingfa bt-form c6" style="padding-bottom: 10px;">\
|
||||
<p>\
|
||||
<span class="span_tit">目录名称:</span>\
|
||||
<input style="width: 200px;" type="text" name="newPath" value="">\
|
||||
</p>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("input[name='newPath']").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(index,layero){
|
||||
var name = $("input[name='newPath']").val();
|
||||
if(name == ''){
|
||||
layer.msg('目录名称不能为空!',{icon:2});
|
||||
return;
|
||||
}
|
||||
var path = $("#myPath").val();
|
||||
var dirname = name;
|
||||
var loadT = layer.msg('正在创建目录['+dirname+']...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
msodPost('create_dir', {path:path,name:dirname}, function(data){
|
||||
layer.close(loadT);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if(rdata.status) {
|
||||
showMsg(rdata.msg, function(){
|
||||
layer.close(index);
|
||||
odList(path);
|
||||
} ,{icon:1}, 2000);
|
||||
} else{
|
||||
layer.msg(rdata.msg,{icon:2});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//设置API
|
||||
function authApi(){
|
||||
|
||||
msodPost('conf', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
|
||||
// console.log(rdata);
|
||||
// console.log(rdata.data.auth_url);
|
||||
var apicon = '';
|
||||
if (rdata.status){
|
||||
|
||||
var html = '';
|
||||
html += '<button id="clear_auth" onclick="clearAuth();" class="btn btn-default btn-sm">清空配置</button>';
|
||||
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '已授权',
|
||||
area: '240px',
|
||||
content:'<div class="change-default pd20">'+html+'</div>',
|
||||
success: function(){
|
||||
$('#clear_auth').click(function(){
|
||||
msodPost('clear_auth', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(loadOpen);
|
||||
odList('/');
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
||||
} else{
|
||||
apicon = '<div class="new_form">'+$("#check_api").html()+'</div>';
|
||||
}
|
||||
|
||||
var layer_auth = layer.open({
|
||||
type: 1,
|
||||
area: "620px",
|
||||
title: "OneDrive授权",
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:apicon,
|
||||
success:function(layero,index){
|
||||
// console.log(layero,index);
|
||||
if (!rdata.status){
|
||||
$('.check_api .step_two_url').val(rdata.data['auth_url']);
|
||||
$('.check_api .open_btlink').attr('href',rdata.data['auth_url']);
|
||||
|
||||
$('.check_api .ico-copy').click(function(){
|
||||
copyPass(rdata.data['auth_url']);
|
||||
});
|
||||
|
||||
$('.check_api .set_auth_btn').click(function(){
|
||||
|
||||
var url = $('.check_api .OneDrive').val();
|
||||
if ( url == ''){
|
||||
layer.msg("验证URL不能为空",{icon:2});
|
||||
return;
|
||||
}
|
||||
// console.log(url);
|
||||
msodPost('set_auth_url', {url:url}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
var show_time = 2000;
|
||||
if (!rdata.status){
|
||||
show_time = 10000;
|
||||
}
|
||||
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(layer_auth);
|
||||
odList('/');
|
||||
}
|
||||
},{icon:rdata.status?1:2},show_time);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//计算当前目录偏移
|
||||
function upPathLeft(){
|
||||
var UlWidth = $(".place-input ul").width();
|
||||
var SpanPathWidth = $(".place-input").width() - 20;
|
||||
var Ml = UlWidth - SpanPathWidth;
|
||||
if(UlWidth > SpanPathWidth ){
|
||||
$(".place-input ul").css("left",-Ml)
|
||||
}
|
||||
else{
|
||||
$(".place-input ul").css("left",0)
|
||||
}
|
||||
}
|
||||
|
||||
function odList(path){
|
||||
msodPost('get_list', {path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
if(rdata.status === false){
|
||||
showMsg(rdata.msg,function(){
|
||||
authApi();
|
||||
},{icon:2},2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var mlist = rdata.data;
|
||||
var listBody = ''
|
||||
var listFiles = ''
|
||||
for(var i=0;i<mlist.list.length;i++){
|
||||
if(mlist.list[i].type == null){
|
||||
listBody += '<tr><td class="cursor" onclick="odList(\''+(path+'/'+mlist.list[i].name).replace('//','/')+'\')"><span class="ico ico-folder"></span>\<span>'+mlist.list[i].name+'</span></td>\
|
||||
<td>-</td>\
|
||||
<td>-</td>\
|
||||
<td class="text-right"><a class="btlink" onclick="deleteFile(\''+mlist.list[i].name+'\', true)">删除</a></td></tr>'
|
||||
}else{
|
||||
listFiles += '<tr><td class="cursor"><span class="ico ico-file"></span>\<span>'+mlist.list[i].name+'</span></td>\
|
||||
<td>'+toSize(mlist.list[i].size)+'</td>\
|
||||
<td>'+getLocalTime(mlist.list[i].time)+'</td>\
|
||||
<td class="text-right"><a target="_blank" href="'+mlist.list[i].download+'" class="btlink">下载</a> | <a class="btlink" onclick="deleteFile(\''+mlist.list[i].name+'\', false)">删除</a></td></tr>'
|
||||
}
|
||||
}
|
||||
listBody += listFiles;
|
||||
|
||||
var pathLi='';
|
||||
var tmp = path.split('/')
|
||||
var pathname = '';
|
||||
var n = 0;
|
||||
for(var i=0;i<tmp.length;i++){
|
||||
if(n > 0 && tmp[i] == '') continue;
|
||||
var dirname = tmp[i];
|
||||
if(dirname == '') {
|
||||
dirname = '根目录';
|
||||
n++;
|
||||
}
|
||||
pathname += '/' + tmp[i];
|
||||
pathname = pathname.replace('//','/');
|
||||
pathLi += '<li><a title="'+pathname+'" onclick="odList(\''+pathname+'\')">'+dirname+'</a></li>';
|
||||
}
|
||||
var um = 1;
|
||||
if(tmp[tmp.length-1] == '') um = 2;
|
||||
var backPath = tmp.slice(0,tmp.length-um).join('/') || '/';
|
||||
$('#myPath').val(path);
|
||||
$(".upyunCon .place-input ul").html(pathLi);
|
||||
$(".upyunlist .list-list").html(listBody);
|
||||
|
||||
upPathLeft();
|
||||
|
||||
$('#backBtn').unbind().click(function() {
|
||||
odList(backPath);
|
||||
});
|
||||
|
||||
$('.upyunCon .refreshBtn').unbind().click(function(){
|
||||
odList(path);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//删除文件
|
||||
function deleteFile(name, is_dir){
|
||||
if (is_dir === false){
|
||||
safeMessage('删除文件','删除后将无法恢复,真的要删除['+name+']吗?',function(){
|
||||
var path = $("#myPath").val();
|
||||
var filename = name;
|
||||
msodPost('delete_file', {filename:filename,path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
odList(path);
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
safeMessage('删除文件夹','删除后将无法恢复,真的要删除['+name+']吗?',function(){
|
||||
var path = $("#myPath").val();
|
||||
msodPost('delete_dir', {dir_name:name,path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
odList(path);
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
# python3 plugins/msonedrive/t/test.py
|
||||
|
||||
|
||||
# https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/08125e6b-6502-4ac9-9548-ad682f00848d/objectId/62b1d655-9828-47ed-be99-65eb18c3a929/isMSAApp~/false/defaultBlade/Overview/appSignInAudience/AzureADandPersonalMicrosoftAccount/servicePrincipalCreated~/true
|
||||
|
||||
# 0WA8Q~sZkZFZKv50ryP4ux~.fpVtbHw7BuTZmbQB
|
||||
# client_id:d9878fac-8526-4ff6-8036-e1c92dd9dd80
|
||||
|
||||
# 08125e6b-6502-4ac9-9548-ad682f00848d
|
||||
|
||||
|
||||
# https://login.microsoftonline.com/common/oauth2/v2.0/authorize?response_type=code&client_id=d9878fac-8526-4ff6-8036-e1c92dd9dd80&redirect_uri=http://localhost&scope=offline_access+Files.ReadWrite.All+User.Read&state=cwopMdHiPIkze4MvgFL6WfSl8LdYAl&prompt=login
|
||||
|
||||
|
||||
# http://localhost/?code=M.C106_BAY.2.3e12c859-6107-0c5b-9ef4-14b3fb8269ba&state=JzHdzHXmA7x6zl7Be6cJ6uOlf9Bg69
|
||||
|
||||
|
||||
# python3 /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/msonedrive/index.py site t1.cn 3
|
||||
# python3 /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/msonedrive/index.py database t1 3
|
||||
# python3
|
||||
# /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/msonedrive/index.py
|
||||
# path /Users/midoks/Desktop/dev/python 3
|
||||
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
from requests_oauthlib import OAuth2Session
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'msonedrive'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
sys.path.append(getPluginDir() + "/class")
|
||||
from msodclient import msodclient
|
||||
|
||||
msodclient.setDebug(True)
|
||||
msodc = msodclient(getPluginDir(), getServerDir())
|
||||
|
||||
|
||||
# sign_in_url, state = msodc.get_sign_in_url()
|
||||
# print(sign_in_url)
|
||||
|
||||
|
||||
def set_auth_url(url):
|
||||
try:
|
||||
if url.startswith("http://"):
|
||||
url = url.replace("http://", "https://")
|
||||
token = msodc.get_token_from_authorized_url(
|
||||
authorized_url=url)
|
||||
msodc.store_token(token)
|
||||
msodc.store_user()
|
||||
return mw.returnJson(True, "授权成功!")
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return mw.returnJson(False, "授权失败2!:" + str(e))
|
||||
return mw.returnJson(False, "授权失败!:" + str(e))
|
||||
|
||||
# url = 'http://localhost/?code=M.C106_BAY.2.310112f3-a158-c400-9667-d158cbd1de6c&state=jEJz0ucR9bpZYD9PGxp2GgRDotrzO6'
|
||||
# token = set_auth_url(url)
|
||||
# print(token)
|
||||
|
||||
# token = msodc.get_token()
|
||||
# print("token:", token)
|
||||
|
||||
# t = msodc.get_list('/backup')
|
||||
# print(t)
|
||||
|
||||
# t = msodc.create_dir('backup')
|
||||
# print(t)
|
||||
|
||||
# t = msodc.delete_object('backup')
|
||||
# print(t)
|
||||
|
||||
|
||||
t = msodc.upload_file('web_t1.cn_20230830_134549.tar.gz', 'site')
|
||||
print(t)
|
||||
# print(msodc.error_msg)
|
||||
|
||||
# /Users/midoks/Desktop/mwdev/server/mdserver-web/paramiko.log
|
||||
# backup/site/paramiko.log
|
||||
# |-正在上传到 backup/site/paramiko.log...
|
||||
# True
|
||||
|
||||
|
||||
# t = msodc.upload_abs_file(
|
||||
# 'web_t1.cn_20230830_134549.tar.gz', 'site')
|
||||
# print(t)
|
||||
# print(msodc.error_msg)
|
||||
@@ -14,6 +14,9 @@ port = 33206
|
||||
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
|
||||
language={$SERVER_APP_PATH}/bin/usr/share/mysql/english
|
||||
|
||||
@@ -45,7 +48,6 @@ skip-ssl
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
@@ -65,12 +67,15 @@ binlog-ignore-db = performance_schema
|
||||
#slave
|
||||
log-slave-updates
|
||||
#replicate-do-db
|
||||
slave_skip_errors=1062
|
||||
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
|
||||
|
||||
@@ -16,6 +16,9 @@ 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
|
||||
@@ -43,7 +46,6 @@ max_allowed_packet = 128M
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
@@ -62,12 +64,15 @@ binlog-ignore-db = performance_schema
|
||||
#slave
|
||||
log_replica_updates
|
||||
#replicate-do-db
|
||||
slave_skip_errors=1062
|
||||
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
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="bt-w-con pd15" style="height:555px;overflow: auto;">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+245
-179
@@ -28,6 +28,10 @@ def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getSPluginDir():
|
||||
return '/www/server/mdserver-web/plugins/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
@@ -51,19 +55,20 @@ def is_number(s):
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
t = t.split(':')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
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(':')
|
||||
t = args[i].split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
|
||||
return tmp
|
||||
|
||||
|
||||
@@ -116,6 +121,10 @@ def contentReplace(content):
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$SERVER_APP_PATH}',
|
||||
service_path + '/' + getPluginName())
|
||||
|
||||
server_id = int(time.time())
|
||||
content = content.replace('{$SERVER_ID}', str(server_id))
|
||||
|
||||
return content
|
||||
|
||||
|
||||
@@ -161,6 +170,10 @@ def pMysqlDb():
|
||||
|
||||
def initDreplace(version=''):
|
||||
|
||||
t = getServerDir()
|
||||
if not os.path.exists(t):
|
||||
return
|
||||
|
||||
conf_dir = getServerDir() + '/etc'
|
||||
mode_dir = conf_dir + '/mode'
|
||||
|
||||
@@ -654,15 +667,15 @@ def isSqlError(mysqlMsg):
|
||||
return mw.returnJson(False, "Can't connect to MySQL server on '127.0.0.1' (61)")
|
||||
if "using password:" in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库密码错误,在管理列表-点击【修复】!')
|
||||
if "1045" in mysqlMsg:
|
||||
if "1045," in mysqlMsg:
|
||||
return mw.returnJson(False, '连接错误!')
|
||||
if "SQL syntax" in mysqlMsg:
|
||||
return mw.returnJson(False, 'SQL语法错误!')
|
||||
if "Connection refused" in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库连接失败,请检查数据库服务是否启动!')
|
||||
if "1133" in mysqlMsg:
|
||||
if "1133," in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库用户不存在!')
|
||||
if "1007" in mysqlMsg:
|
||||
if "1007," in mysqlMsg:
|
||||
return mw.returnJson(False, '数据库已经存在!')
|
||||
return None
|
||||
|
||||
@@ -1583,6 +1596,15 @@ def setDbMasterAccess():
|
||||
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=''):
|
||||
try:
|
||||
args = getArgs()
|
||||
@@ -1885,27 +1907,34 @@ def getMasterRepSlaveUserCmd(version):
|
||||
|
||||
mode = recognizeDbMode()
|
||||
|
||||
sid = getDbServerId()
|
||||
channel_name = ""
|
||||
if sid != '':
|
||||
channel_name = " for channel 'r{}';".format(sid)
|
||||
|
||||
if mode == "gtid":
|
||||
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
||||
clist[0]['password'] + "', MASTER_AUTO_POSITION=1"
|
||||
clist[0]['password'] + "', MASTER_AUTO_POSITION=1" + channel_name
|
||||
if version == '8.0':
|
||||
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
|
||||
clist[0]['username'] + "', SOURCE_PASSWORD='" + \
|
||||
clist[0]['password'] + "', MASTER_AUTO_POSITION=1"
|
||||
clist[0]['password'] + \
|
||||
"', MASTER_AUTO_POSITION=1" + channel_name
|
||||
else:
|
||||
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
|
||||
clist[0]['username'] + "', MASTER_PASSWORD='" + \
|
||||
clist[0]['password'] + \
|
||||
"', MASTER_LOG_FILE='" + mstatus[0]["File"] + \
|
||||
"',MASTER_LOG_POS=" + str(mstatus[0]["Position"])
|
||||
"',MASTER_LOG_POS=" + str(mstatus[0]["Position"]) + channel_name
|
||||
|
||||
if version == "8.0":
|
||||
sql = "CHANGE REPLICATION SOURCE TO SOURCE_HOST='" + ip + "', SOURCE_PORT=" + port + ", SOURCE_USER='" + \
|
||||
clist[0]['username'] + "', SOURCE_PASSWORD='" + \
|
||||
clist[0]['password'] + \
|
||||
"', SOURCE_LOG_FILE='" + mstatus[0]["File"] + \
|
||||
"',SOURCE_LOG_POS=" + str(mstatus[0]["Position"])
|
||||
"',SOURCE_LOG_POS=" + \
|
||||
str(mstatus[0]["Position"]) + channel_name
|
||||
|
||||
data = {}
|
||||
data['cmd'] = sql
|
||||
@@ -2176,40 +2205,10 @@ def updateSlaveSSH(version=''):
|
||||
|
||||
|
||||
def getSlaveList(version=''):
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
ret = []
|
||||
for x in range(0, len(dlist)):
|
||||
tmp = {}
|
||||
tmp['Master_User'] = dlist[x]["Master_User"]
|
||||
tmp['Master_Host'] = dlist[x]["Master_Host"]
|
||||
tmp['Master_Port'] = dlist[x]["Master_Port"]
|
||||
tmp['Master_Log_File'] = dlist[x]["Master_Log_File"]
|
||||
tmp['Slave_IO_Running'] = dlist[x]["Slave_IO_Running"]
|
||||
tmp['Slave_SQL_Running'] = dlist[x]["Slave_SQL_Running"]
|
||||
tmp['Last_Error'] = dlist[x]["Last_Error"]
|
||||
tmp['Last_IO_Error'] = dlist[x]["Last_IO_Error"]
|
||||
tmp['Last_SQL_Error'] = dlist[x]["Last_SQL_Error"]
|
||||
tmp['Slave_SQL_Running_State'] = dlist[x]["Slave_SQL_Running_State"]
|
||||
|
||||
tmp['Error'] = ''
|
||||
if tmp['Last_Error'] != '':
|
||||
tmp['Error'] = tmp['Last_Error']
|
||||
|
||||
if tmp['Last_IO_Error'] != '':
|
||||
tmp['Error'] = tmp['Last_IO_Error']
|
||||
|
||||
if tmp['Last_SQL_Error'] != '':
|
||||
tmp['Error'] = tmp['Last_SQL_Error']
|
||||
|
||||
if tmp['Error'] == '':
|
||||
tmp['Error'] = tmp['Slave_SQL_Running_State']
|
||||
|
||||
ret.append(tmp)
|
||||
data = {}
|
||||
data['data'] = ret
|
||||
|
||||
data['data'] = dlist
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
@@ -2217,7 +2216,7 @@ def getSlaveSyncCmd(version=''):
|
||||
|
||||
root = mw.getRunDir()
|
||||
cmd = 'cd ' + root + ' && python3 ' + root + \
|
||||
'/plugins/mysql/index.py do_full_sync {"db":"all"}'
|
||||
'/plugins/mysql/index.py do_full_sync {"db":"all","sign":""}'
|
||||
return mw.returnJson(True, 'ok', cmd)
|
||||
|
||||
|
||||
@@ -2233,100 +2232,151 @@ def initSlaveStatus(version=''):
|
||||
return initSlaveStatusSyncUser(version)
|
||||
|
||||
|
||||
def parseSlaveSyncCmd(cmd):
|
||||
a = {}
|
||||
if cmd.lower().find('for') > 0:
|
||||
cmd_tmp = cmd.split('for')
|
||||
cmd = cmd_tmp[0].strip()
|
||||
|
||||
pattern_c = r"channel \'(.*)\';"
|
||||
match_val = re.match(pattern_c, cmd_tmp[1].strip(), re.I)
|
||||
if match_val:
|
||||
m_groups = match_val.groups()
|
||||
a['channel'] = m_groups[0]
|
||||
vlist = cmd.split(',')
|
||||
for i in vlist:
|
||||
tmp = i.strip()
|
||||
tmp_a = tmp.split(" ")
|
||||
real_tmp = tmp_a[len(tmp_a) - 1]
|
||||
kv = real_tmp.split("=")
|
||||
a[kv[0]] = kv[1].replace("'", '').replace("'", '').replace(";", '')
|
||||
return a
|
||||
|
||||
|
||||
def initSlaveStatusSyncUser(version=''):
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
if len(data) < 1:
|
||||
slave_data = conn.field('ip,port,user,pass,mode,cmd').select()
|
||||
if len(slave_data) < 1:
|
||||
return mw.returnJson(False, '需要先添加同步用户配置!')
|
||||
|
||||
# print(data)
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) > 0:
|
||||
return mw.returnJson(False, '已经初始化好了zz...')
|
||||
|
||||
u = data
|
||||
|
||||
mode_name = 'classic'
|
||||
if u['mode'] == '1':
|
||||
mode_name = 'gtid'
|
||||
pdb = pMysqlDb()
|
||||
if len(slave_data) == 1:
|
||||
dlist = pdb.query('show slave status')
|
||||
if len(dlist) > 0:
|
||||
return mw.returnJson(False, '已经初始化好了zz...')
|
||||
|
||||
msg = ''
|
||||
local_mode = recognizeDbMode()
|
||||
if local_mode != mode_name:
|
||||
return mw.returnJson(False, '同步模式不一致!')
|
||||
for x in range(len(slave_data)):
|
||||
slave_t = slave_data[x]
|
||||
mode_name = 'classic'
|
||||
base_t = 'IP:' + slave_t['ip'] + ",PORT:" + \
|
||||
slave_t['port'] + ",USER:" + slave_t['user']
|
||||
|
||||
t = db.query(u['cmd'])
|
||||
# print(t)
|
||||
db.query("start slave user='{}' password='{}';".format(
|
||||
u['user'], u['pass']))
|
||||
return mw.returnJson(True, '初始化成功!')
|
||||
if slave_t['mode'] == '1':
|
||||
mode_name = 'gtid'
|
||||
|
||||
if local_mode != mode_name:
|
||||
msg += base_t + '->同步模式不一致'
|
||||
continue
|
||||
|
||||
cmd_sql = slave_t['cmd']
|
||||
if cmd_sql == '':
|
||||
msg += base_t + '->同步命令不能为空'
|
||||
continue
|
||||
|
||||
try:
|
||||
pinfo = parseSlaveSyncCmd(cmd_sql)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, base_t + '->CMD同步命令不合规范!')
|
||||
t = pdb.query(cmd_sql)
|
||||
isError = isSqlError(t)
|
||||
if isError:
|
||||
return isError
|
||||
|
||||
# pdb.query("start slave user='{}' password='{}';".format(
|
||||
# u['user'], u['pass']))
|
||||
|
||||
pdb.query("start slave")
|
||||
pdb.query("start all slaves")
|
||||
|
||||
if msg == '':
|
||||
msg = '初始化成功!'
|
||||
return mw.returnJson(True, msg)
|
||||
|
||||
|
||||
def initSlaveStatusSSH(version=''):
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) > 0:
|
||||
return mw.returnJson(False, '已经初始化好了zz...')
|
||||
|
||||
conn = pSqliteDb('slave_id_rsa')
|
||||
data = conn.field('ip,port,id_rsa').find()
|
||||
ssh_list = conn.field('ip,port,id_rsa,db_user').select()
|
||||
|
||||
if len(data) < 1:
|
||||
if len(ssh_list) < 1:
|
||||
return mw.returnJson(False, '需要先配置【[主]SSH配置】!')
|
||||
|
||||
SSH_PRIVATE_KEY = "/tmp/t_ssh.txt"
|
||||
ip = data['ip']
|
||||
master_port = data['port']
|
||||
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
|
||||
local_mode = recognizeDbMode()
|
||||
|
||||
import paramiko
|
||||
paramiko.util.log_to_file('paramiko.log')
|
||||
ssh = paramiko.SSHClient()
|
||||
|
||||
try:
|
||||
|
||||
db.query('stop slave')
|
||||
db.query('reset slave all')
|
||||
for data in ssh_list:
|
||||
ip = data['ip']
|
||||
SSH_PRIVATE_KEY = "/tmp/t_ssh_" + ip + ".txt"
|
||||
master_port = data['port']
|
||||
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
|
||||
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
|
||||
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=ip, port=int(master_port),
|
||||
username='root', pkey=key)
|
||||
try:
|
||||
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
ssh.connect(hostname=ip, port=int(master_port),
|
||||
username='root', pkey=key)
|
||||
|
||||
cmd = 'cd /www/server/mdserver-web && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"","db":""}'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
result = result.decode('utf-8')
|
||||
cmd_data = json.loads(result)
|
||||
db_user = data['db_user']
|
||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 ' + \
|
||||
getSPluginDir() + \
|
||||
'/index.py get_master_rep_slave_user_cmd {"username":"' + \
|
||||
db_user + '","db":""}'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
result = result.decode('utf-8')
|
||||
if result.strip() == "":
|
||||
return mw.returnJson(False, '[主][' + ip + ']:获取同步命令失败!')
|
||||
|
||||
if not cmd_data['status']:
|
||||
return mw.returnJson(False, '[主]:' + cmd_data['msg'])
|
||||
cmd_data = json.loads(result)
|
||||
if not cmd_data['status']:
|
||||
return mw.returnJson(False, '[主][' + ip + ']:' + cmd_data['msg'])
|
||||
|
||||
local_mode = recognizeDbMode()
|
||||
if local_mode != cmd_data['data']['mode']:
|
||||
return mw.returnJson(False, '主【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
|
||||
if local_mode != cmd_data['data']['mode']:
|
||||
return mw.returnJson(False, '[主][' + ip + ']:【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
|
||||
|
||||
u = cmd_data['data']['info']
|
||||
ps = u['username'] + "|" + u['password']
|
||||
conn.where('ip=?', (ip,)).setField('ps', ps)
|
||||
db.query('stop slave')
|
||||
u = cmd_data['data']['info']
|
||||
|
||||
# 保证同步IP一致
|
||||
cmd = cmd_data['data']['cmd']
|
||||
if cmd.find('SOURCE_HOST') > -1:
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*)'",
|
||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
ps = u['username'] + "|" + u['password']
|
||||
print(ps)
|
||||
conn.where('ip=?', (ip,)).setField('ps', ps)
|
||||
db.query('stop slave')
|
||||
|
||||
if cmd.find('MASTER_HOST') > -1:
|
||||
cmd = re.sub(r"MASTER_HOST='(.*)'",
|
||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||
db.query(cmd)
|
||||
db.query("start slave user='{}' password='{}';".format(
|
||||
u['username'], u['password']))
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, 'SSH认证配置连接失败!' + str(e))
|
||||
# 保证同步IP一致
|
||||
cmd = cmd_data['data']['cmd']
|
||||
if cmd.find('SOURCE_HOST') > -1:
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
|
||||
ssh.close()
|
||||
time.sleep(1)
|
||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||
if cmd.find('MASTER_HOST') > -1:
|
||||
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||
db.query(cmd)
|
||||
ssh.close()
|
||||
if os.path.exists(SSH_PRIVATE_KEY):
|
||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '[主][' + ip + ']:SSH认证配置连接失败!' + str(e))
|
||||
db.query('start slave')
|
||||
return mw.returnJson(True, '初始化成功!')
|
||||
|
||||
|
||||
@@ -2336,60 +2386,37 @@ def setSlaveStatus(version=''):
|
||||
return mw.returnJson(False, '需要先设置同步配置')
|
||||
|
||||
mode = mw.readFile(mode_file)
|
||||
if mode == 'ssh':
|
||||
return setSlaveStatusSSH(version)
|
||||
if mode == 'sync-user':
|
||||
return setSlaveStatusSyncUser(version)
|
||||
|
||||
|
||||
def setSlaveStatusSyncUser(version=''):
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
pdb = pMysqlDb()
|
||||
dlist = pdb.query('show slave status')
|
||||
if len(dlist) == 0:
|
||||
return mw.returnJson(False, '需要手动添加同步账户或者执行初始化!')
|
||||
|
||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
||||
db.query('stop slave')
|
||||
else:
|
||||
ip = dlist[0]['Master_Host']
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
if len(data) == 0:
|
||||
return mw.returnJson(False, '没有数据无法重启!')
|
||||
user = data['user']
|
||||
apass = data['pass']
|
||||
for v in dlist:
|
||||
connection_name = ''
|
||||
cmd = "slave"
|
||||
if 'Channel_Name' in v:
|
||||
ch_name = v['Channel_Name']
|
||||
cmd = "slave for channel '{}'".format(ch_name)
|
||||
|
||||
db.query("start slave")
|
||||
# db.query("start slave user='{}' password='{}';".format(user, apass))
|
||||
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def setSlaveStatusSSH(version=''):
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
if len(dlist) == 0:
|
||||
return mw.returnJson(False, '需要手动添加主服务命令或者执行[初始化]!')
|
||||
|
||||
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
|
||||
db.query('stop slave')
|
||||
else:
|
||||
ip = dlist[0]['Master_Host']
|
||||
conn = pSqliteDb('slave_id_rsa')
|
||||
data = conn.field('ip,ps').where("ip=?", (ip,)).find()
|
||||
if len(data) == 0:
|
||||
return mw.returnJson(False, '没有数据无法重启!')
|
||||
u = data['ps'].split("|")
|
||||
db.query("start slave user='{}' password='{}';".format(u[0], u[1]))
|
||||
if (v["Slave_IO_Running"] == 'Yes' or v["Slave_SQL_Running"] == 'Yes'):
|
||||
pdb.query("stop {}".format(cmd))
|
||||
else:
|
||||
pdb.query("start {}".format(cmd))
|
||||
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def deleteSlave(version=''):
|
||||
args = getArgs()
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('stop slave')
|
||||
dlist = db.query('reset slave all')
|
||||
if 'sign' in args:
|
||||
sign = args['sign']
|
||||
db.query("stop slave for channel '{}'".format(sign))
|
||||
db.query("reset slave all for channel '{}'".format(sign))
|
||||
else:
|
||||
db.query('stop slave')
|
||||
db.query('reset slave all')
|
||||
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
|
||||
|
||||
@@ -2425,11 +2452,13 @@ def dumpMysqlData(version=''):
|
||||
|
||||
############### --- 重要 同步---- ###########
|
||||
|
||||
def asyncTmpfile():
|
||||
path = '/tmp/mysql_apt_async_status.txt'
|
||||
return path
|
||||
|
||||
|
||||
def writeDbSyncStatus(data):
|
||||
path = '/tmp/db_async_status.txt'
|
||||
# status_data['code'] = 1
|
||||
# status_data['msg'] = '主服务器备份完成...'
|
||||
# status_data['progress'] = 30
|
||||
path = asyncTmpfile()
|
||||
mw.writeFile(path, json.dumps(data))
|
||||
|
||||
|
||||
@@ -2447,16 +2476,32 @@ def doFullSync(version=''):
|
||||
|
||||
def doFullSyncUser(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['db'])
|
||||
data = checkArgs(args, ['db', 'sign'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
sync_db = args['db']
|
||||
sync_db_import = args['db']
|
||||
|
||||
if sync_db.lower() == 'all':
|
||||
sync_db_import = ''
|
||||
dbs = findBinlogSlaveDoDb()
|
||||
dbs_str = ''
|
||||
for x in dbs:
|
||||
dbs_str += ' ' + x
|
||||
sync_db = "--databases " + dbs_str.strip()
|
||||
|
||||
sync_sign = args['sign']
|
||||
|
||||
db = pMysqlDb()
|
||||
|
||||
conn = pSqliteDb('slave_sync_user')
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
if sync_sign != '':
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').where(
|
||||
'ip=?', (sync_sign,)).find()
|
||||
else:
|
||||
data = conn.field('ip,port,user,pass,mode,cmd').find()
|
||||
|
||||
user = data['user']
|
||||
apass = data['pass']
|
||||
port = data['port']
|
||||
@@ -2473,17 +2518,18 @@ def doFullSyncUser(version=''):
|
||||
writeDbSyncStatus({'code': 1, '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
|
||||
dump_sql_data = getServerDir() + "/bin/usr/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)
|
||||
mw.execShell(dump_sql_data)
|
||||
|
||||
writeDbSyncStatus({'code': 2, '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 + ' < ' + bak_file
|
||||
my_import_cmd = getServerDir() + '/bin/usr/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
|
||||
' ' + sync_db_import + ' < ' + bak_file
|
||||
mw.execShell(my_import_cmd)
|
||||
|
||||
if version == '8.0':
|
||||
@@ -2492,21 +2538,30 @@ def doFullSyncUser(version=''):
|
||||
db.query("start slave")
|
||||
|
||||
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
||||
os.system("rm -rf " + bak_file)
|
||||
|
||||
if os.path.exists(bak_file):
|
||||
os.system("rm -rf " + bak_file)
|
||||
return True
|
||||
|
||||
|
||||
def doFullSyncSSH(version=''):
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['db'])
|
||||
data = checkArgs(args, ['db', 'sign'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
sync_db = args['db']
|
||||
sync_sign = args['sign']
|
||||
|
||||
db = pMysqlDb()
|
||||
|
||||
id_rsa_conn = pSqliteDb('slave_id_rsa')
|
||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
|
||||
if sync_sign != '':
|
||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').where(
|
||||
'ip=?', (sync_sign,)).find()
|
||||
else:
|
||||
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
|
||||
|
||||
SSH_PRIVATE_KEY = "/tmp/mysql_sync_id_rsa.txt"
|
||||
id_rsa = data['id_rsa'].replace('\\n', '\n')
|
||||
@@ -2548,7 +2603,8 @@ def doFullSyncSSH(version=''):
|
||||
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
|
||||
|
||||
dbname = args['db']
|
||||
cmd = "cd /www/server/mdserver-web && python3 plugins/mysql/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 " + \
|
||||
getSPluginDir() + "/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||
print(cmd)
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
@@ -2571,7 +2627,10 @@ def doFullSyncSSH(version=''):
|
||||
if copy_status == None:
|
||||
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
|
||||
|
||||
cmd = 'cd /www/server/mdserver-web && python3 plugins/mysql/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
|
||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 ' + \
|
||||
getSPluginDir() + \
|
||||
'/index.py get_master_rep_slave_user_cmd {"username":"' + \
|
||||
db_user + '","db":""}'
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
result = result.decode('utf-8')
|
||||
@@ -2583,10 +2642,12 @@ def doFullSyncSSH(version=''):
|
||||
cmd = cmd_data['data']['cmd']
|
||||
# 保证同步IP一致
|
||||
if cmd.find('SOURCE_HOST') > -1:
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*)'", "SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
|
||||
if cmd.find('MASTER_HOST') > -1:
|
||||
cmd = re.sub(r"MASTER_HOST='(.*)'", "SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||
|
||||
db.query(cmd)
|
||||
uinfo = cmd_data['data']['info']
|
||||
@@ -2598,8 +2659,10 @@ def doFullSyncSSH(version=''):
|
||||
root_dir = getServerDir()
|
||||
msock = root_dir + "/mysql.sock"
|
||||
mw.execShell("cd /tmp && gzip -d dump.sql.gz")
|
||||
cmd = root_dir + "/bin/mysql -S " + msock + \
|
||||
cmd = root_dir + "/bin/usr/bin/mysql -S " + msock + \
|
||||
" -uroot -p" + pwd + " < /tmp/dump.sql"
|
||||
|
||||
print(cmd)
|
||||
import_data = mw.execShell(cmd)
|
||||
if import_data[0] == '':
|
||||
print(import_data[1])
|
||||
@@ -2609,8 +2672,9 @@ def doFullSyncSSH(version=''):
|
||||
writeDbSyncStatus({'code': 5, 'msg': '导入数据失败...', 'progress': 100})
|
||||
return 'fail'
|
||||
|
||||
db.query("start slave user='{}' password='{}';".format(
|
||||
uinfo['username'], uinfo['password']))
|
||||
# "start slave user='{}' password='{}';".format(uinfo['username'], uinfo['password'])
|
||||
|
||||
db.query("start slave")
|
||||
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
|
||||
|
||||
os.system("rm -rf " + SSH_PRIVATE_KEY)
|
||||
@@ -2624,12 +2688,12 @@ def fullSync(version=''):
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
status_file = '/tmp/db_async_status.txt'
|
||||
status_file = asyncTmpfile()
|
||||
if args['begin'] == '1':
|
||||
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
|
||||
getPluginDir() + \
|
||||
'/index.py do_full_sync {"db":"' + args['db'] + '"} &'
|
||||
print(cmd)
|
||||
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + getPluginDir() + \
|
||||
'/index.py do_full_sync {"db":"' + \
|
||||
args['db'] + '","sign":"' + sign + '"} &'
|
||||
# print(cmd)
|
||||
mw.execShell(cmd)
|
||||
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
|
||||
|
||||
@@ -2667,8 +2731,8 @@ def installPreInspection(version):
|
||||
if not sysName in ('debian', 'ubuntu'):
|
||||
return '仅支持debian,ubuntu'
|
||||
|
||||
if (sysName == 'debian' and not sysId in('11', '10')):
|
||||
return 'debian支持10,11'
|
||||
if (sysName == 'debian' and not sysId in('12', '11', '10')):
|
||||
return 'debian支持10,11,12'
|
||||
|
||||
if (sysName == 'ubuntu' and version == '5.7' and not sysId in ('18.04')):
|
||||
return "Ubuntu Apt MySQL[" + version + "] 仅支持18.04"
|
||||
@@ -2795,6 +2859,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':
|
||||
|
||||
@@ -48,7 +48,11 @@ fi
|
||||
sh -x $curPath/versions/$2/install.sh $1
|
||||
|
||||
if [ "${action}" == "install" ];then
|
||||
# #初始化
|
||||
#初始化
|
||||
|
||||
if [ "$?" != "0" ];then
|
||||
exit $?
|
||||
fi
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-apt/index.py start ${type}
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-apt/index.py initd_install ${type}
|
||||
fi
|
||||
|
||||
@@ -162,34 +162,6 @@ function myPort(){
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//数据库存储信置
|
||||
function changeMySQLDataPath(act) {
|
||||
if (act != undefined) {
|
||||
layer.confirm(lan.soft.mysql_to_msg, { closeBtn: 2, icon: 3 }, function() {
|
||||
var datadir = $("#datadir").val();
|
||||
var data = 'datadir=' + datadir;
|
||||
var loadT = layer.msg(lan.soft.mysql_to_msg1, { icon: 16, time: 0, shade: [0.3, '#000'] });
|
||||
$.post('/database?action=SetDataDir', data, function(rdata) {
|
||||
layer.close(loadT)
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 5 });
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
$.post('/database?action=GetMySQLInfo', '', function(rdata) {
|
||||
var LimitCon = '<p class="conf_p">\
|
||||
<input id="datadir" class="phpUploadLimit bt-input-text mr5" style="width:350px;" type="text" value="' + rdata.datadir + '" name="datadir">\
|
||||
<span onclick="ChangePath(\'datadir\')" class="glyphicon glyphicon-folder-open cursor mr20" style="width:auto"></span><button class="btn btn-success btn-sm" onclick="changeMySQLDataPath(1)">' + lan.soft.mysql_to + '</button>\
|
||||
</p>';
|
||||
$(".soft-man-con").html(LimitCon);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//数据库配置状态
|
||||
function myPerfOpt() {
|
||||
//获取MySQL配置
|
||||
@@ -1629,6 +1601,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'){
|
||||
@@ -1691,12 +1671,12 @@ function getMasterRepSlaveListPage(){
|
||||
}
|
||||
|
||||
|
||||
function deleteSlave(){
|
||||
myPost('delete_slave', {}, function(data){
|
||||
function deleteSlave(sign){
|
||||
myPost('delete_slave', {sign:sign}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata['msg'], function(){
|
||||
masterOrSlaveConf();
|
||||
},{},3000);
|
||||
},{icon:rdata.status?1:2,time:3000},3000);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1704,28 +1684,73 @@ function deleteSlave(){
|
||||
function getFullSyncStatus(db){
|
||||
var timeId = null;
|
||||
|
||||
var btn = '<div class="table_toolbar" style="left:0px;"><span data-status="init" class="sync btn btn-default btn-sm" id="begin_full_sync" title="">开始</span></div>';
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '全量同步['+db+']',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<span id='full_msg'></span>\
|
||||
<div class='progress'>\
|
||||
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
"+btn+"\
|
||||
</div>",
|
||||
cancel: function(){
|
||||
clearInterval(timeId);
|
||||
myPost('get_slave_list', {page:1,page_size:100}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var rsource = rdata.data;
|
||||
|
||||
if (db == 'ALL' && rsource.length>1){
|
||||
layer.msg("多主不支持该模式!",{icon:2});
|
||||
return;
|
||||
}
|
||||
|
||||
var dataSource = '';
|
||||
if (rsource.length>1){
|
||||
var sourceList = '';
|
||||
for (var i = 0; i < rsource.length; i++) {
|
||||
if ('Channel_Name' in rsource[i]){
|
||||
sourceList += '<option val="'+rsource[i]['Master_Host']+'">'+rsource[i]['Master_Host']+'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
dataSource = "<p class='line' style='text-align:center;'>\
|
||||
<span>同步数据源:</span>\
|
||||
<select class='bt-input-text' name='data_source' style='width:200px;'>" + sourceList + "</select>\
|
||||
</p>";
|
||||
}
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '全量同步['+db+']',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd15'>\
|
||||
<div class='divtable mtb10'>\
|
||||
"+dataSource+"\
|
||||
<span id='full_msg'></span>\
|
||||
<div class='progress'>\
|
||||
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class='table_toolbar' style='left:0px;'>\
|
||||
<span data-status='init' class='sync btn btn-default btn-sm' id='begin_full_sync'>开始</span>\
|
||||
</div>\
|
||||
</div>",
|
||||
cancel: function(){
|
||||
clearInterval(timeId);
|
||||
},
|
||||
success:function(){
|
||||
$('#begin_full_sync').click(function(){
|
||||
var val = $(this).data('status');
|
||||
var sign = '';
|
||||
if (dataSource !=''){
|
||||
sign = $('select[name="data_source"]').val();
|
||||
}
|
||||
if (val == 'init'){
|
||||
fullSync(db, sign, 1);
|
||||
timeId = setInterval(function(){
|
||||
fullSync(db,sign,0);
|
||||
}, 1000);
|
||||
$(this).data('status','starting');
|
||||
} else {
|
||||
layer.msg("正在同步中..",{icon:0});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function fullSync(db,begin){
|
||||
function fullSync(db,sign,begin){
|
||||
|
||||
myPostN('full_sync', {db:db,begin:begin}, function(data){
|
||||
myPostN('full_sync', {db:db,sign:sign,begin:begin}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
$('#full_msg').text(rdata['msg']);
|
||||
$('.progress-bar').css('width',rdata['progress']+'%');
|
||||
@@ -1734,23 +1759,10 @@ function getFullSyncStatus(db){
|
||||
if (rdata['code']==6 ||rdata['code']<0){
|
||||
layer.msg(rdata['msg']);
|
||||
clearInterval(timeId);
|
||||
$("#begin_full_sync").attr('data-status','init');
|
||||
$("#begin_full_sync").data('data','init');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#begin_full_sync').click(function(){
|
||||
var val = $(this).attr('data-status');
|
||||
if (val == 'init'){
|
||||
fullSync(db,1);
|
||||
timeId = setInterval(function(){
|
||||
fullSync(db,0);
|
||||
}, 1000);
|
||||
$(this).attr('data-status','starting');
|
||||
} else {
|
||||
layer.msg("正在同步中..");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addSlaveSSH(ip=''){
|
||||
@@ -1920,18 +1932,29 @@ function addSlaveSyncUser(ip=''){
|
||||
<div class='line'><span class='tname'>同步账户</span><div class='info-r'><input name='user' class='bt-input-text mr5' type='text' style='width:330px;' value='"+user+"'></div></div>\
|
||||
<div class='line'><span class='tname'>同步密码</span><div class='info-r'><input name='pass' class='bt-input-text mr5' type='text' style='width:330px;' value='"+pass+"'></div></div>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>CMD[最好填好]</span>\
|
||||
<span class='tname'>CMD[必须填写]</span>\
|
||||
<div class='info-r'><textarea class='bt-input-text mr5' row='20' cols='30' name='cmd' style='width:330px;height:150px;'></textarea></div>\
|
||||
</div>\
|
||||
<input type='hidden' name='mode' value='"+mode+"' />\
|
||||
</form>",
|
||||
success:function(){
|
||||
$('textarea[name="cmd"]').html(cmd);
|
||||
|
||||
$('textarea[name="cmd"]').change(function(){
|
||||
var val = $(this).val();
|
||||
var vlist = val.split(',');
|
||||
var a = {};
|
||||
if (val.toLowerCase().indexOf('for')>0){
|
||||
cmd_tmp = val.split('for');
|
||||
val = cmd_tmp[0].trim();
|
||||
|
||||
const channel_str = cmd_tmp[1].trim();
|
||||
const ch_reg = /channel \'(.*)\';/;
|
||||
var match_val = channel_str.match(ch_reg);
|
||||
if (match_val.length>1){
|
||||
a['channel'] = match_val[1];
|
||||
}
|
||||
}
|
||||
|
||||
var vlist = val.split(',');
|
||||
for (var i in vlist) {
|
||||
var tmp = toTrim(vlist[i]);
|
||||
var tmp_a = tmp.split(" ");
|
||||
@@ -2098,7 +2121,7 @@ function getSlaveUserList(){
|
||||
layerId = layer.open({
|
||||
type: 1,
|
||||
title: '同步账户列表',
|
||||
area: '500px',
|
||||
area: '600px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div><table class='table table-hover get-slave-ssh-list'>\
|
||||
@@ -2122,7 +2145,7 @@ function getSlaveSSHList(page=1){
|
||||
layerId = layer.open({
|
||||
type: 1,
|
||||
title: 'SSH列表',
|
||||
area: '500px',
|
||||
area: '600px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div class='divtable mtb10'>\
|
||||
<div><table class='table table-hover get-slave-ssh-list'>\
|
||||
@@ -2230,10 +2253,16 @@ function masterOrSlaveConf(version=''){
|
||||
myPost('get_slave_list', _data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var list = '';
|
||||
|
||||
var isHasSign = false;
|
||||
for(i in rdata.data){
|
||||
|
||||
var v = rdata.data[i];
|
||||
var status = "<a class='btlink db_error'>异常</>";
|
||||
if ('Channel_Name' in v){
|
||||
isHasSign = true;
|
||||
}
|
||||
|
||||
var status = "<a data-id="+i+" class='btlink db_error'>异常</>";
|
||||
if (v['Slave_SQL_Running'] == 'Yes' && v['Slave_IO_Running'] == 'Yes'){
|
||||
status = "正常";
|
||||
}
|
||||
@@ -2245,13 +2274,23 @@ function masterOrSlaveConf(version=''){
|
||||
list += '<td>' + rdata.data[i]['Master_Log_File'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Slave_IO_Running'] +'</td>';
|
||||
list += '<td>' + rdata.data[i]['Slave_SQL_Running'] +'</td>';
|
||||
|
||||
if (isHasSign){
|
||||
list += '<td>' + v['Channel_Name'] +'</td>';
|
||||
}
|
||||
|
||||
list += '<td>' + status +'</td>';
|
||||
list += '<td style="text-align:right">' +
|
||||
'<a href="javascript:;" class="btlink" onclick="deleteSlave()" title="删除">删除</a>' +
|
||||
'<a data-id="'+i+'" href="javascript:;" class="btlink btn_delete_slave" title="删除">删除</a>' +
|
||||
'</td>';
|
||||
list += '</tr>';
|
||||
}
|
||||
|
||||
var signThead_th = '';
|
||||
if (isHasSign){
|
||||
var signThead_th = '<th>标识</th>';
|
||||
}
|
||||
|
||||
var con = '<div class="divtable mtb10">\
|
||||
<div class="tablescroll">\
|
||||
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
|
||||
@@ -2262,6 +2301,7 @@ function masterOrSlaveConf(version=''){
|
||||
<th>日志</th>\
|
||||
<th>IO</th>\
|
||||
<th>SQL</th>\
|
||||
'+signThead_th+'\
|
||||
<th>状态</th>\
|
||||
<th style="text-align:right;">操作</th></tr></thead>\
|
||||
<tbody>\
|
||||
@@ -2276,22 +2316,74 @@ function masterOrSlaveConf(version=''){
|
||||
// </div>
|
||||
$(".table_slave_status_list").html(con);
|
||||
|
||||
$('.db_error').click(function(){
|
||||
$(".btn_delete_slave").click(function(){
|
||||
var id = $(this).data('id');
|
||||
var v = rdata.data[id];
|
||||
if ('Channel_Name' in v){
|
||||
deleteSlave(v['Channel_Name']);
|
||||
} else{
|
||||
deleteSlave();
|
||||
}
|
||||
});
|
||||
|
||||
$('.db_error').click(function(){
|
||||
var id = $(this).data('id');
|
||||
var info = rdata.data[id];
|
||||
|
||||
var err_line = "";
|
||||
err_line +="<tr>\
|
||||
<td>IO错误</td>\
|
||||
<td>"+ (info['Last_IO_Error'] == '' ? '无':info['Last_IO_Error'])+"</td>\
|
||||
</tr>";
|
||||
err_line +="<tr>\
|
||||
<td>SQL错误</td>\
|
||||
<td>"+(info['Last_SQL_Error'] == '' ? '无':info['Last_SQL_Error'])+"</td>\
|
||||
</tr>";
|
||||
|
||||
err_line +="<tr>\
|
||||
<td>状态</td>\
|
||||
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
|
||||
</tr>";
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '同步异常信息',
|
||||
area: '500px',
|
||||
content:"<form class='bt-form pd20 pb70'>\
|
||||
<div class='line'>"+v['Error']+"</div>\
|
||||
<div class='bt-form-submit-btn'>\
|
||||
<button type='button' class='btn btn-success btn-sm btn-title class-copy-db-err'>复制</button>\
|
||||
area: ['600px','300px'],
|
||||
btn:['复制错误',"取消"],
|
||||
content:"<form class='bt-form pd15'>\
|
||||
<div 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 style='width:80px;'>类型</th>\
|
||||
<th>内容</th>\
|
||||
</tr></thead>\
|
||||
<tbody>"+ err_line +"</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</form>",
|
||||
</form>",
|
||||
success:function(){
|
||||
copyText(v['Error']);
|
||||
$('.class-copy-db-err').click(function(){
|
||||
copyText(v['Error']);
|
||||
});
|
||||
// copyText(v['Error']);
|
||||
// $('.class-copy-db-err').click(function(){
|
||||
// copyText(v['Error']);
|
||||
// });
|
||||
},
|
||||
yes:function(){
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2362,6 +2454,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 -->\
|
||||
|
||||
@@ -35,7 +35,22 @@ if [ "$OSNAME" == "ubuntu" ];then
|
||||
VERSION_ID="18.04"
|
||||
fi
|
||||
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_amd64
|
||||
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 0
|
||||
fi
|
||||
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_${ARCH}
|
||||
|
||||
APT_INSTALL()
|
||||
{
|
||||
|
||||
@@ -22,8 +22,25 @@ VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/mysql-apt && bash install.sh install 8.0
|
||||
|
||||
|
||||
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.0.30
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_amd64
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_${ARCH}
|
||||
|
||||
|
||||
# /lib/systemd/system/mysql.service
|
||||
@@ -81,7 +98,6 @@ Install_mysql()
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_INSTALL
|
||||
|
||||
@@ -14,6 +14,9 @@ port = 33206
|
||||
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
|
||||
language={$SERVER_APP_PATH}/bin/usr/share/mysql/english
|
||||
|
||||
@@ -46,7 +49,6 @@ skip-ssl
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
@@ -66,12 +68,15 @@ binlog-ignore-db = performance_schema
|
||||
#slave
|
||||
log-slave-updates
|
||||
#replicate-do-db
|
||||
slave_skip_errors=1062
|
||||
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
|
||||
|
||||
@@ -16,6 +16,9 @@ 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
|
||||
@@ -43,7 +46,6 @@ max_allowed_packet = 128M
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
@@ -62,12 +64,15 @@ binlog-ignore-db = performance_schema
|
||||
#slave
|
||||
log_replica_updates
|
||||
#replicate-do-db
|
||||
slave_skip_errors=1062
|
||||
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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user