mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 03:59:25 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2861f7f995 | ||
|
|
10d6fa2d47 | ||
|
|
16e5b4ae73 | ||
|
|
aca89d7d5e | ||
|
|
ffefe96f1f | ||
|
|
e1e1e81a90 | ||
|
|
502295125a | ||
|
|
85258dd80b | ||
|
|
ff0cb6eb31 | ||
|
|
e4e1945ea5 | ||
|
|
e7f74a482f | ||
|
|
dd27af9ede | ||
|
|
4aeffd2aa6 | ||
|
|
8924957e7f | ||
|
|
c013db9d41 | ||
|
|
e492abf354 | ||
|
|
f84cab9e98 | ||
|
|
eb5be2842d | ||
|
|
06e99096cf | ||
|
|
93f1129c0f | ||
|
|
46bc94946c | ||
|
|
0857c6aed7 | ||
|
|
fdcdd27f8e | ||
|
|
d1810606db | ||
|
|
68f5f4c6cb | ||
|
|
d40665c0f8 | ||
|
|
9d1ebba509 | ||
|
|
d0113840a3 | ||
|
|
43c287132b | ||
|
|
deb3a40fb7 | ||
|
|
88196175f4 | ||
|
|
217ba2d14e | ||
|
|
7af7e2321a | ||
|
|
20b39cbb70 | ||
|
|
66ff690bae | ||
|
|
99e8e63917 | ||
|
|
a4dfe26254 | ||
|
|
15c0ef390e | ||
|
|
a2b9658b2e | ||
|
|
5bcb0fb739 | ||
|
|
6278c9588b | ||
|
|
19d4456e2e | ||
|
|
807cb8fe98 | ||
|
|
ba2df01084 | ||
|
|
d82b0dbe9f | ||
|
|
acc18cf571 | ||
|
|
f69dd139c0 | ||
|
|
ab6f860bde | ||
|
|
febe56f430 | ||
|
|
0962e5aab8 | ||
|
|
5ea062862f | ||
|
|
cce5598f2f | ||
|
|
d88962eb56 | ||
|
|
b44e24df0d | ||
|
|
f36e540a59 | ||
|
|
992e7445f6 | ||
|
|
066729e8d9 | ||
|
|
be3e57a905 | ||
|
|
bc7a569ae9 | ||
|
|
1bc24b12fc | ||
|
|
b2fdc8212f | ||
|
|
ab763f444b | ||
|
|
c0738ff1bd | ||
|
|
82dd2553e6 | ||
|
|
ae371be91a | ||
|
|
48e1ecaec6 | ||
|
|
5a21c4dac8 | ||
|
|
7e014dfa94 | ||
|
|
93785a2472 | ||
|
|
cd0f5fd8a0 | ||
|
|
d12524debd | ||
|
|
297fb60fcb | ||
|
|
d3781edad0 | ||
|
|
78667460e6 | ||
|
|
decc579c2d | ||
|
|
34a64eafa2 | ||
|
|
38b263e689 | ||
|
|
0ad3e8d42c | ||
|
|
5243f6f4c3 | ||
|
|
976c8c3271 | ||
|
|
b627b222bc | ||
|
|
8df8365eaa | ||
|
|
d735d857a4 | ||
|
|
211764060f | ||
|
|
b07be2d004 | ||
|
|
c6edd2221c | ||
|
|
be8dd153a3 | ||
|
|
e4aef4592e | ||
|
|
4f5b25a680 | ||
|
|
abc4486311 | ||
|
|
baeb788148 | ||
|
|
e30dcf1fbe | ||
|
|
e7347c4a4c | ||
|
|
044cad1e64 | ||
|
|
c0d0efb756 | ||
|
|
49d1579782 | ||
|
|
b6f7ec11c2 | ||
|
|
0860ffc713 | ||
|
|
cd3f7603e8 | ||
|
|
bc0e7764b2 | ||
|
|
cfe185b105 | ||
|
|
3094a0af32 | ||
|
|
7f010caa6e | ||
|
|
2b6d287cf1 | ||
|
|
e525323a7d | ||
|
|
69670aa1f6 | ||
|
|
d741677b66 | ||
|
|
7fd4ea28c1 | ||
|
|
41294a23a2 | ||
|
|
86edf89474 | ||
|
|
e2f4043569 | ||
|
|
6ebcb8e005 | ||
|
|
088b7425d7 | ||
|
|
f854eed924 | ||
|
|
ba706e070e | ||
|
|
2cdaa36744 | ||
|
|
7937189935 | ||
|
|
1b7f1e2f13 | ||
|
|
a88483e2ba | ||
|
|
b76fad0b5c | ||
|
|
f357dfbd1a | ||
|
|
ea56cd93c2 | ||
|
|
cfd06d7721 | ||
|
|
e3f5ddccef | ||
|
|
cca3a5a899 | ||
|
|
908a1f660a | ||
|
|
dfc3030900 | ||
|
|
0ab8800813 | ||
|
|
1d66f9c355 | ||
|
|
84a8e755a8 | ||
|
|
f17d4c5bef | ||
|
|
704960f7cb | ||
|
|
38e13d086c | ||
|
|
56ff442a8d | ||
|
|
6cddfa4010 | ||
|
|
2f4eb172a3 | ||
|
|
6b282ce287 | ||
|
|
a597d95940 | ||
|
|
1c471abd09 | ||
|
|
495cdfeb7c | ||
|
|
798c7888b6 | ||
|
|
efc6a3dd83 | ||
|
|
724ccf507c | ||
|
|
cef92e76a6 | ||
|
|
3f5c01ac85 | ||
|
|
3dec4cd54d | ||
|
|
2a0dc74d3a | ||
|
|
4f514b09c5 | ||
|
|
5e1fe6cff8 | ||
|
|
4e59c6fb5c | ||
|
|
248cb43c61 | ||
|
|
23cb934e0c | ||
|
|
36b837bb29 | ||
|
|
478a3eb7f2 | ||
|
|
d08c5bd511 | ||
|
|
fd2f838712 | ||
|
|
5bd57b3c8b | ||
|
|
bfe6429bc2 | ||
|
|
2979def4dc | ||
|
|
1e603d27d2 | ||
|
|
f09cdcc83a | ||
|
|
b46b3346d1 | ||
|
|
b18c78b38a | ||
|
|
ac5a86b14e | ||
|
|
af9ce2372f | ||
|
|
8bec7ccf84 | ||
|
|
3256e8dc95 | ||
|
|
6e4f671628 | ||
|
|
a646cbacb5 | ||
|
|
11a4d3acf8 | ||
|
|
1e324aa695 | ||
|
|
48b57108d7 | ||
|
|
0543c0847f | ||
|
|
c47758a977 | ||
|
|
4010eaceb0 | ||
|
|
b988e09d33 | ||
|
|
1bfa8e0ac0 | ||
|
|
d442324466 | ||
|
|
e5ae0ecc7c | ||
|
|
642bb61a25 | ||
|
|
b8de9e3d01 | ||
|
|
4cd456a76c | ||
|
|
36952614d4 | ||
|
|
0cb03f92a5 | ||
|
|
453c17d248 | ||
|
|
46ec61d915 | ||
|
|
7577776214 | ||
|
|
376ad46fb9 | ||
|
|
11c40cf490 | ||
|
|
9fd85009ae | ||
|
|
f456ae2a14 | ||
|
|
578fa62c84 | ||
|
|
6ef897addd | ||
|
|
690d30b73c | ||
|
|
bdc1fb75b4 | ||
|
|
440fa1c535 | ||
|
|
7fd59222a9 | ||
|
|
690d959898 | ||
|
|
93cbbd6e80 | ||
|
|
4f6991aefc | ||
|
|
6f2012eb7b | ||
|
|
bb8e43610e | ||
|
|
7ad77f8338 | ||
|
|
c117d8e253 | ||
|
|
d754f6f0cd | ||
|
|
00f421a56a | ||
|
|
b74902c1b6 | ||
|
|
452210fdb2 | ||
|
|
b39e2e2a8c | ||
|
|
b61e08b2d9 | ||
|
|
2d85633d86 | ||
|
|
747c2a92ef | ||
|
|
bf39b04622 | ||
|
|
d6856498f8 | ||
|
|
99f7cf9181 | ||
|
|
d5977fd9b9 | ||
|
|
d8fd671eee | ||
|
|
abd8fecbf2 | ||
|
|
60b25cd35b | ||
|
|
240d915913 | ||
|
|
f13290c7e8 | ||
|
|
f6136932f4 | ||
|
|
6df4bbdb68 | ||
|
|
dfad621845 | ||
|
|
b677b1a73b | ||
|
|
39c350942e | ||
|
|
631475bd43 | ||
|
|
1f9e273ee0 | ||
|
|
66eb3b8825 | ||
|
|
29540da79c | ||
|
|
864c77359f | ||
|
|
1a0a02e1a6 | ||
|
|
61b3223bb4 | ||
|
|
4b794bed26 | ||
|
|
96e903596a | ||
|
|
eb33f376c7 | ||
|
|
724c3ae02a | ||
|
|
bb6f7f4e3a | ||
|
|
91e7f9917b | ||
|
|
4ea0dfe063 | ||
|
|
ec5266f750 | ||
|
|
f152184808 | ||
|
|
1ca051a496 | ||
|
|
70a5ca1048 | ||
|
|
c853cc66ad | ||
|
|
58d2881c8e | ||
|
|
a0cdb4c8c2 | ||
|
|
3e3af5f11a | ||
|
|
b2b36208a2 | ||
|
|
0fcdd3b841 | ||
|
|
3c0844d26c | ||
|
|
40d4a3e963 | ||
|
|
a61179164c | ||
|
|
c21c8d9322 | ||
|
|
3adb59188a | ||
|
|
806e554607 | ||
|
|
1a0a1e5ead | ||
|
|
7f6ba0cbed | ||
|
|
f4ac70a415 | ||
|
|
7203c31f9b | ||
|
|
e6ea4ff580 | ||
|
|
dc4a4688c4 | ||
|
|
d9c547cce5 | ||
|
|
0517d606c8 | ||
|
|
7fc4a7f899 | ||
|
|
9a0739b9d2 | ||
|
|
1f16cae6c5 | ||
|
|
adb8789a4f | ||
|
|
0cb320cb23 | ||
|
|
a5861ce04e | ||
|
|
d4c9e9cae1 | ||
|
|
4713f13c10 | ||
|
|
595b6f9d28 | ||
|
|
dbca385d90 | ||
|
|
5c56dc7b24 | ||
|
|
524db0d9f5 | ||
|
|
b1dbdc3000 | ||
|
|
0f0d54dd9e | ||
|
|
7c1c2fc4c2 | ||
|
|
fcb8db8e75 | ||
|
|
024d0a3a52 | ||
|
|
c1d3e09c67 | ||
|
|
9d556f9991 | ||
|
|
cc744c4ccb | ||
|
|
6ad12f08cf | ||
|
|
aef9c526a6 | ||
|
|
669eb83893 | ||
|
|
0a8831e766 | ||
|
|
f094179c70 | ||
|
|
0b74018e61 | ||
|
|
3fa7332646 | ||
|
|
5d2580ae01 | ||
|
|
2b02663ea4 | ||
|
|
db29c0162f | ||
|
|
07f6636a54 | ||
|
|
b06afe619a | ||
|
|
7aa69aab0d | ||
|
|
16bbe53c6e | ||
|
|
cb3226c184 | ||
|
|
66187beabc | ||
|
|
82fd78080c | ||
|
|
a8cf8975d4 | ||
|
|
b09c83b502 | ||
|
|
48be4ac07c | ||
|
|
d2ebf6d038 | ||
|
|
6801ea2eea | ||
|
|
9a9d97d482 | ||
|
|
25083e7dd2 | ||
|
|
519dc4f491 | ||
|
|
bfabe34f9c | ||
|
|
23cf28133a | ||
|
|
b231c321e3 | ||
|
|
f71c43d057 | ||
|
|
0ca010245d | ||
|
|
d1cef12341 | ||
|
|
da31ad7dbe | ||
|
|
ec16720858 | ||
|
|
217b42eae3 | ||
|
|
e33bf94a17 | ||
|
|
6d112e9d3d | ||
|
|
605a6f1245 | ||
|
|
eb1213d55c | ||
|
|
43ee847814 | ||
|
|
03bfc3a637 | ||
|
|
a229b322d2 | ||
|
|
15b3d44a1d | ||
|
|
520da4fabc | ||
|
|
1458d67d93 | ||
|
|
85077a5d2f | ||
|
|
1004056347 | ||
|
|
6efffdfa4f | ||
|
|
26f4d0b37b | ||
|
|
5f8b08f100 | ||
|
|
fd3fc13710 | ||
|
|
d55b370bb0 | ||
|
|
3424135409 | ||
|
|
0057c495da | ||
|
|
4073d863d0 | ||
|
|
07a8096a15 | ||
|
|
8fd7c9eda6 | ||
|
|
fd1260c71f | ||
|
|
e364d2e972 | ||
|
|
ca10fbc3b5 | ||
|
|
5a660d72b7 | ||
|
|
b5a710791d | ||
|
|
74357fa5ee | ||
|
|
c5193178a3 | ||
|
|
49cdc7e73e | ||
|
|
08ac9abb65 | ||
|
|
af7ffe2b26 | ||
|
|
95f7dc0d3a | ||
|
|
d749c80884 | ||
|
|
8a36c2ee15 | ||
|
|
f9330720d6 | ||
|
|
e1b68eed0a | ||
|
|
cf3e530fad | ||
|
|
282c1a3e70 | ||
|
|
0ab9b25483 | ||
|
|
6d98a704a4 | ||
|
|
99afb3f5e1 | ||
|
|
081998f0de | ||
|
|
4bee6c54be | ||
|
|
5db32760cf | ||
|
|
42e5eff80f | ||
|
|
94f00fe948 | ||
|
|
1c31f2b481 | ||
|
|
ff56bedbc6 | ||
|
|
68798453c4 | ||
|
|
280b3de46c | ||
|
|
101806826c | ||
|
|
adb10c9f3f | ||
|
|
5c547b60f6 | ||
|
|
2431f22420 | ||
|
|
47009b42af | ||
|
|
b8afbc65fb | ||
|
|
5f9a3dcf21 | ||
|
|
0082b1fb76 | ||
|
|
4848f9b8f6 | ||
|
|
1eb7f71567 | ||
|
|
041c62edac | ||
|
|
c351f5e896 | ||
|
|
cf24cb38ff | ||
|
|
e85c88d9fd | ||
|
|
68c1acfb3e | ||
|
|
6bbc3ea73b | ||
|
|
d2ca9b57b9 | ||
|
|
3a70c92c2b | ||
|
|
015869494c | ||
|
|
f500d882cc | ||
|
|
3cf1204dde | ||
|
|
6d8e5403c8 | ||
|
|
ece7d43950 | ||
|
|
ecd72b98db | ||
|
|
e13e2c172a | ||
|
|
a8fa93574a | ||
|
|
54cd9fa007 | ||
|
|
d5615ae88f | ||
|
|
7ca758b2bb | ||
|
|
9be9c2a4f3 | ||
|
|
5c0717d9c3 | ||
|
|
dd2bf1cb52 | ||
|
|
4dbadb2d5f | ||
|
|
9bc68eccf5 | ||
|
|
6272c1a879 | ||
|
|
49ebca2ef2 | ||
|
|
4bd6b0d770 | ||
|
|
fdf140ea7d | ||
|
|
2bac521c56 | ||
|
|
2d067b2df6 | ||
|
|
80560f3763 | ||
|
|
efb148db2e | ||
|
|
7d244e0acc | ||
|
|
a9a0e61729 | ||
|
|
445a1f3c43 | ||
|
|
8f50e0365b | ||
|
|
af74b1e5f7 | ||
|
|
5ebb1c3f9b | ||
|
|
38f4b2c2b5 | ||
|
|
ed4c62d620 | ||
|
|
be02344c4e | ||
|
|
9234d452b5 | ||
|
|
8142722652 | ||
|
|
0decd938e4 | ||
|
|
e55163f244 | ||
|
|
d103fb1879 | ||
|
|
c37f1021d9 | ||
|
|
080be8368f | ||
|
|
f7d565f33e | ||
|
|
2de31b28b2 | ||
|
|
0f72c80abf | ||
|
|
9091a26778 | ||
|
|
a99920a651 | ||
|
|
6b89763075 | ||
|
|
715441b972 | ||
|
|
102f0cadff | ||
|
|
4a2cb35865 | ||
|
|
81929adba5 | ||
|
|
ef13161bc7 | ||
|
|
93a323add5 | ||
|
|
3573517f7c | ||
|
|
e337f0ffd7 | ||
|
|
0a84cbec9c | ||
|
|
fabc73be28 | ||
|
|
b7cc254407 | ||
|
|
4f59d07416 | ||
|
|
9abe3ec166 | ||
|
|
b2546d71a5 | ||
|
|
da56e5caff | ||
|
|
04b35c832a | ||
|
|
06780dadb2 | ||
|
|
bfba24c66d | ||
|
|
8a518e70d5 | ||
|
|
050c5efe4f | ||
|
|
b0534f57c8 | ||
|
|
b9b4c055dd | ||
|
|
6a37640efb | ||
|
|
4ee232a689 | ||
|
|
66e5e1596d | ||
|
|
0d48f3973a | ||
|
|
453528e8e7 | ||
|
|
71890ca8de | ||
|
|
289bca248d | ||
|
|
3f22209e62 | ||
|
|
3893e24619 | ||
|
|
cacbca5053 | ||
|
|
c17f5b35d7 | ||
|
|
d68f61de30 | ||
|
|
7caef5e104 | ||
|
|
9de12c1b01 | ||
|
|
50917e4eef | ||
|
|
18b9a799b3 | ||
|
|
5fbae06c00 | ||
|
|
a5775b16b5 | ||
|
|
d377286de3 | ||
|
|
c35ee90068 | ||
|
|
d9042d7c37 | ||
|
|
6975e9adb7 | ||
|
|
3caebe4399 | ||
|
|
27c5b9044b | ||
|
|
8f85955717 | ||
|
|
87b0d087d4 | ||
|
|
e25eed0f97 | ||
|
|
786df5911e | ||
|
|
a6c5c843db | ||
|
|
3f993ffa61 | ||
|
|
eae5729e35 | ||
|
|
38dce0d70a | ||
|
|
f6178c3ac2 | ||
|
|
798f413d6e | ||
|
|
5a7b2512ac | ||
|
|
c177b6f7b7 | ||
|
|
84f2c20f2a | ||
|
|
ab338dc8a7 | ||
|
|
e00fe09851 | ||
|
|
20416e46b6 | ||
|
|
1dbf9a21f9 | ||
|
|
37e852b411 | ||
|
|
deb44571ef | ||
|
|
1dd39b569e | ||
|
|
0531c484ab | ||
|
|
2dd6a25890 | ||
|
|
d1a55ffa52 | ||
|
|
467692f586 | ||
|
|
284552c02d | ||
|
|
6c4f69e2c7 | ||
|
|
22af57840e | ||
|
|
212e537334 | ||
|
|
49ae49b501 | ||
|
|
48777a5924 | ||
|
|
eafe6b9762 | ||
|
|
3eedc949a1 | ||
|
|
4e53ce3a1c | ||
|
|
994d2feeed | ||
|
|
4b34049c5f | ||
|
|
dad3c295d4 | ||
|
|
b91d680d25 | ||
|
|
942ed2b79f | ||
|
|
0dd72160f5 | ||
|
|
7fd4e7177b | ||
|
|
6fe9302108 | ||
|
|
50020056ca | ||
|
|
aaf5ed2cf4 | ||
|
|
c629a7e682 | ||
|
|
13d5d1f2be | ||
|
|
aa7ce151a9 | ||
|
|
2603d1673c | ||
|
|
2eab126986 | ||
|
|
fc58c5265c | ||
|
|
d9cfc41574 | ||
|
|
e009615454 | ||
|
|
f435919179 | ||
|
|
e9a4aeacc9 | ||
|
|
3771e0f429 | ||
|
|
4bed9cb7b6 | ||
|
|
759e8dce7d | ||
|
|
20ea48c0f5 | ||
|
|
99f2fad1f3 | ||
|
|
4cb20ad907 | ||
|
|
5e1f316898 | ||
|
|
c99cb8c859 | ||
|
|
89f2746da0 | ||
|
|
eb52435ce7 | ||
|
|
099971f768 | ||
|
|
2f8d808c8f | ||
|
|
faa8c05690 | ||
|
|
b3dc35abca | ||
|
|
3880d443b4 | ||
|
|
671b174034 | ||
|
|
667b3c9724 | ||
|
|
20e7c7ae9a | ||
|
|
1a9dfb8302 | ||
|
|
5bcff64aa6 | ||
|
|
924c1aa077 | ||
|
|
384bef1dce | ||
|
|
dd81275439 | ||
|
|
e033e783ac | ||
|
|
f965a8760f | ||
|
|
4ff7d0c02c | ||
|
|
45e797024a | ||
|
|
b26d8a6224 | ||
|
|
86e88d88d0 | ||
|
|
db12d96793 | ||
|
|
e1e785299d | ||
|
|
37fd032ed8 | ||
|
|
85f2eb63da | ||
|
|
b2af6dbce0 | ||
|
|
25de758943 | ||
|
|
2b587d952e | ||
|
|
4c6dcb7c0a | ||
|
|
f9a3ac5cec | ||
|
|
5f40286bff | ||
|
|
bcde85d24e | ||
|
|
73c8d85f88 | ||
|
|
3cfbf554e1 | ||
|
|
5a635fcbba | ||
|
|
c573449524 | ||
|
|
b0536b37ec | ||
|
|
02f73e6487 | ||
|
|
6ca64a07be | ||
|
|
9d1e934f9a | ||
|
|
77e154d567 | ||
|
|
b2d78d53d1 | ||
|
|
4ca234b41f | ||
|
|
309d8291aa | ||
|
|
5ddacf9b20 | ||
|
|
d647c124e6 | ||
|
|
9c99a55a4f | ||
|
|
24a4640940 | ||
|
|
b3f0358814 | ||
|
|
e3fcb14efc | ||
|
|
1f643d0657 | ||
|
|
d68e505ba2 | ||
|
|
3e593bb652 | ||
|
|
a917598d80 | ||
|
|
49028a1ffd | ||
|
|
c399e73800 | ||
|
|
b2a18e6816 | ||
|
|
1438715c94 | ||
|
|
4e7165a248 | ||
|
|
35c9ca7e4e | ||
|
|
985106d3cf | ||
|
|
b7e90f81e2 | ||
|
|
21e2b2b31b | ||
|
|
79700aa561 | ||
|
|
598909d6c8 | ||
|
|
d36db9d5b7 | ||
|
|
77d22c459e | ||
|
|
4cdb791ab4 | ||
|
|
e7673bb428 | ||
|
|
77f98ac663 | ||
|
|
a1831e3cd6 | ||
|
|
65a364ef33 | ||
|
|
3b9d874678 | ||
|
|
375e657030 | ||
|
|
774154784d | ||
|
|
656c453f4f | ||
|
|
e4e41bced3 | ||
|
|
e5f63d876b | ||
|
|
96f8622ac1 | ||
|
|
166d462224 | ||
|
|
502e5a1877 | ||
|
|
eb8ff69598 | ||
|
|
2c9d9dd19c | ||
|
|
f117b2098d | ||
|
|
66274be102 | ||
|
|
19b4fe375e | ||
|
|
c330a357a2 | ||
|
|
ed02d8a10b | ||
|
|
c583f83448 | ||
|
|
4c459c8676 | ||
|
|
47bb1a98d4 | ||
|
|
8e29d117c0 | ||
|
|
806ac7c032 | ||
|
|
07fece751b | ||
|
|
ac65efde61 | ||
|
|
0b0773851a | ||
|
|
53e6307693 | ||
|
|
89540b6256 | ||
|
|
834b0ea80a | ||
|
|
630fba02be | ||
|
|
77657233c9 | ||
|
|
26224a37c8 | ||
|
|
70998c0d04 | ||
|
|
94dce5c01c | ||
|
|
fc344fe89a | ||
|
|
cba594447a | ||
|
|
8d09ceef27 | ||
|
|
b32fcd43f6 | ||
|
|
78f3151c3d | ||
|
|
31815c489b | ||
|
|
a7f73e10ae | ||
|
|
3dccb2620d | ||
|
|
248d8ad27e | ||
|
|
c3be68c3fb | ||
|
|
d7f8510284 | ||
|
|
6f30354c38 | ||
|
|
48b9023e67 | ||
|
|
7fa7ee6770 | ||
|
|
d810165ed4 | ||
|
|
3909a584c1 | ||
|
|
74d0db13d4 | ||
|
|
c78cb88774 | ||
|
|
816cd89dd1 | ||
|
|
caaa930eaa | ||
|
|
0622346852 | ||
|
|
18f320bf25 | ||
|
|
309c4cc9f4 | ||
|
|
984615a9f7 | ||
|
|
b512a7fa85 | ||
|
|
d72d4c8d99 | ||
|
|
238b46ebfd | ||
|
|
98773983da | ||
|
|
7c390e4af6 | ||
|
|
046f77d6c2 | ||
|
|
983aecdf9f | ||
|
|
cc074a7c8f | ||
|
|
076ae674ad | ||
|
|
f3da1c6ce9 | ||
|
|
f5d2fa8238 | ||
|
|
60e9f8e143 | ||
|
|
aefd77876a | ||
|
|
25cdacc98f | ||
|
|
4393605832 | ||
|
|
4d88e79202 | ||
|
|
d9e615d265 | ||
|
|
c3b77ee645 | ||
|
|
891a311be2 | ||
|
|
dd5d070bb8 | ||
|
|
1574b3a010 | ||
|
|
2d15a3fed5 | ||
|
|
8c11cfb14a | ||
|
|
a7b9522afa | ||
|
|
d0e4e5fcae | ||
|
|
bcbaf1d26d | ||
|
|
fd6160e30f | ||
|
|
8bdd24daa1 | ||
|
|
ee93d2fc21 | ||
|
|
410cb7d277 | ||
|
|
140561ba74 | ||
|
|
c6bd1298ea | ||
|
|
8058cb0068 | ||
|
|
16e29821cc | ||
|
|
116e4e0efc | ||
|
|
cd5e6e1ec7 | ||
|
|
4fad0b9270 | ||
|
|
67d931b581 | ||
|
|
996f13c5f5 | ||
|
|
f89afe5a91 | ||
|
|
f3061fd084 | ||
|
|
c72092f5af | ||
|
|
f0ed396701 | ||
|
|
902e8a91ee | ||
|
|
fb2ae13465 | ||
|
|
9da7470b4e | ||
|
|
d036f23f4a | ||
|
|
64223402c4 | ||
|
|
fecdf0660f | ||
|
|
f6d1610234 | ||
|
|
ffaed6706c | ||
|
|
d50e4196cb | ||
|
|
c77382f082 | ||
|
|
8cafb1c86e | ||
|
|
a0d69fc68a | ||
|
|
10db90764f | ||
|
|
5a690702cf | ||
|
|
032d4f9b57 | ||
|
|
8753f45bcb | ||
|
|
1d02896349 | ||
|
|
d4fb0be60b | ||
|
|
a233d440ef | ||
|
|
e2962146cf | ||
|
|
ab2f55282d | ||
|
|
098f0ffdd2 | ||
|
|
8e544fee93 | ||
|
|
ea20cc6e89 | ||
|
|
176112b332 | ||
|
|
53332e9b6b | ||
|
|
600cd80676 | ||
|
|
6cd3a09584 | ||
|
|
0d3a533c11 | ||
|
|
63f9b577aa | ||
|
|
57786cb95a | ||
|
|
5b9bd6e0bf | ||
|
|
96c9bc38ca | ||
|
|
141fd8fb34 | ||
|
|
063f13ef69 | ||
|
|
1054fd1400 | ||
|
|
d795242fdd | ||
|
|
8ed36c1781 | ||
|
|
b17bfb0da6 | ||
|
|
105f12cba6 | ||
|
|
00b978dd70 | ||
|
|
fd23a4c572 | ||
|
|
421c9a673c | ||
|
|
9295455628 | ||
|
|
93f79a7e69 | ||
|
|
7e627856d7 | ||
|
|
f068bf1292 | ||
|
|
2d495e498e | ||
|
|
496ef3cc36 | ||
|
|
008bb49365 | ||
|
|
2f94f9b856 | ||
|
|
a2e6073858 | ||
|
|
4580f10ba7 | ||
|
|
d2974c0d79 | ||
|
|
ee255086ac | ||
|
|
7f1643720a | ||
|
|
0b3ddd22a5 | ||
|
|
4db3650b59 | ||
|
|
a86588ee01 | ||
|
|
72af570958 | ||
|
|
df0d980d24 | ||
|
|
b06308c842 | ||
|
|
e0f1a74f74 | ||
|
|
4a5f6fef6b | ||
|
|
9eaabab738 | ||
|
|
1615e7c580 | ||
|
|
b2d0c4815e | ||
|
|
2ac903be9b | ||
|
|
c3979d5f55 | ||
|
|
0d618b1b68 | ||
|
|
d0e6954680 | ||
|
|
57be5fd61c | ||
|
|
59987eb502 | ||
|
|
04fe781241 | ||
|
|
31fcd80877 | ||
|
|
a13c366813 | ||
|
|
6e978b668e | ||
|
|
bf09f29f48 | ||
|
|
e035330eac | ||
|
|
668f135b71 | ||
|
|
e9296fbecb | ||
|
|
c8feecfb2a | ||
|
|
02bc554afb | ||
|
|
9f3c7e0479 | ||
|
|
ad315cf37c | ||
|
|
3d807cd0c8 | ||
|
|
e0ca9b4654 | ||
|
|
a852cdeead | ||
|
|
6b3c40baea | ||
|
|
852f236bb5 | ||
|
|
9ad2bf8bf0 | ||
|
|
1284ddd1af | ||
|
|
412ff74f0c | ||
|
|
2eceff82e8 | ||
|
|
6b164c58e9 | ||
|
|
e9802040d9 | ||
|
|
5dd84c12f3 | ||
|
|
b1a8c5c02f | ||
|
|
3ed0ceed70 | ||
|
|
6948d503c0 | ||
|
|
39bca95e62 | ||
|
|
063bc092e6 | ||
|
|
aa97982f6f | ||
|
|
af73ce7af8 | ||
|
|
e46ed828d9 | ||
|
|
f5ec3bba3d | ||
|
|
2f7ec60e89 | ||
|
|
5df4b9ee57 | ||
|
|
71dbfbf5d8 | ||
|
|
93fcdd2e27 | ||
|
|
a725220577 | ||
|
|
783c4ebc60 | ||
|
|
a06db0e8c3 | ||
|
|
d7c4dcda66 | ||
|
|
2866e1a602 | ||
|
|
77e4ee1053 | ||
|
|
7589c14f81 | ||
|
|
4344d774c1 | ||
|
|
4859792096 | ||
|
|
e55c40e973 | ||
|
|
103beb62a4 | ||
|
|
76a34578ad | ||
|
|
f82fdbf939 | ||
|
|
4eaf9eb36c | ||
|
|
9c9f9fc42c | ||
|
|
8301ad6f62 | ||
|
|
d42fb48749 | ||
|
|
fa49a3dbeb | ||
|
|
dd1147c891 | ||
|
|
67b015a50b | ||
|
|
57831168a3 | ||
|
|
f6f7cabddc | ||
|
|
dfec241c3f | ||
|
|
8a78dff571 | ||
|
|
a9486d4fbe | ||
|
|
78d3a091cd | ||
|
|
314005e478 | ||
|
|
55fa911485 | ||
|
|
a72046462c | ||
|
|
0b8fe15b65 | ||
|
|
34f5d12ad9 | ||
|
|
e88544d290 | ||
|
|
a211746de7 | ||
|
|
c417b02844 | ||
|
|
034aaedf48 | ||
|
|
af0ec79072 | ||
|
|
195ccf409e | ||
|
|
7cec26b8a3 | ||
|
|
aacb816b11 | ||
|
|
0cf35955d8 |
@@ -1,9 +1,3 @@
|
||||
### 合并描述
|
||||
|
||||
对pull请求的内容进行清晰、简洁的描述,即应该解决什么问题?
|
||||
|
||||
问题链接:<!--将问题链接粘贴到此处,如果不适用,请填写“不适用”->
|
||||
|
||||
### 清单
|
||||
|
||||
- [ ] 我添加了测试用例来覆盖新代码。
|
||||
- 我添加了测试用例来覆盖新代码。
|
||||
|
||||
+9
-2
@@ -107,7 +107,6 @@ venv.bak/
|
||||
tmp/*
|
||||
*.swp
|
||||
*.zip
|
||||
scripts/init.d/mw
|
||||
logs/*
|
||||
data/*.db
|
||||
data/control.conf
|
||||
@@ -132,7 +131,9 @@ include
|
||||
share
|
||||
pip-selfcheck.json
|
||||
|
||||
scripts/init.d/mw
|
||||
scripts/mdserver-web
|
||||
|
||||
data/api_login.txt
|
||||
data/sessions
|
||||
data/ssl.pl
|
||||
@@ -145,6 +146,10 @@ data/osname.pl
|
||||
data/only_netio_counters.pl
|
||||
data/system.db-journal
|
||||
data/hook_*.json
|
||||
data/letsencrypt.json
|
||||
data/basic_auth.json
|
||||
data/api.json
|
||||
data/bind_domain.pl
|
||||
|
||||
plugins/l2tp
|
||||
plugins/openlitespeed
|
||||
@@ -153,7 +158,9 @@ plugins/mtproxy
|
||||
plugins/zimg
|
||||
plugins/bk_demo
|
||||
plugins/mail
|
||||
plugins/fastdfs
|
||||
plugins/v2ray
|
||||
plugins/frp
|
||||
debug.out
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
### 主要插件介绍
|
||||
|
||||
* OpenResty - 轻量级,占有内存少,并发能力强。
|
||||
* PHP[52-81] - PHP是世界上最好的编程语言。
|
||||
* PHP[53-82] - PHP是世界上最好的编程语言。
|
||||
* MySQL - 一种关系数据库管理系统。
|
||||
* MariaDB - 是MySQL的一个重要分支。
|
||||
* MongoDB - 一种非关系NOSQL数据库管理系统。
|
||||
@@ -65,13 +65,12 @@ phpMyAdmin[5.2.0]支持MySQL[8.0]
|
||||
|
||||
PHP[53-72]支持phpMyAdmin[4.4.15]
|
||||
PHP[72-81]支持phpMyAdmin[5.2.0]
|
||||
|
||||
|
||||
```
|
||||
|
||||
# 特别赞助
|
||||
|
||||
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.la/)
|
||||
- [奈飞丝 - 奈飞中国 Netflix MOD首发](https://naifeis.com/index.php#/register?code=k7P7V6Ur)
|
||||
|
||||
# AD - VPS推荐 - 🙏
|
||||
|
||||
@@ -79,8 +78,7 @@ PHP[72-81]支持phpMyAdmin[5.2.0]
|
||||
|
||||
| 服务商 | LOGO | 推广地址 | 优惠码 |
|
||||
| ------------- |----------|-----------|-------|
|
||||
| digitalvirt |[](https://digitalvirt.com/aff.php?aff=154) | https://digitalvirt.com/aff.php?aff=154 | 9SYDY7UH0U |
|
||||
| 搬瓦工 |[](https://bwh81.net/aff.php?aff=54161) | https://bwh81.net/aff.php?aff=54161 | BWH3HYATVBJW |
|
||||
| digitalvirt |[](https://digitalvirt.com/aff.php?aff=154) | https://digitalvirt.com/aff.php?aff=154 | mdserver-web |
|
||||
|
||||
# Docker
|
||||
|
||||
@@ -92,14 +90,15 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.10.0
|
||||
### 版本更新 0.11.2
|
||||
|
||||
* OP防火墙优化。
|
||||
* OP防火墙-添加URL白名单功能。
|
||||
* redis安全强化。
|
||||
* 添加php命令行设置。
|
||||
* 域名绑定。
|
||||
* Gitea优化。
|
||||
* 网站统计优化。
|
||||
* 添加`FTP存储空间`插件。
|
||||
* 初始安装IPv6安装。
|
||||
* phpMyAdmin优化。
|
||||
* centos9下php-gd安装优化。
|
||||
* php82rc7测试版。
|
||||
|
||||
|
||||
### JSDelivr安装地址
|
||||
@@ -116,6 +115,12 @@ curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/instal
|
||||
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/update.sh | bash
|
||||
```
|
||||
|
||||
- 卸载脚本
|
||||
|
||||
```
|
||||
wget -O uninstall.sh https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/uninstall.sh && bash uninstall.sh
|
||||
```
|
||||
|
||||
### 备用地址
|
||||
|
||||
- 初始安装
|
||||
@@ -131,6 +136,12 @@ curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts
|
||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
|
||||
```
|
||||
|
||||
- 卸载脚本
|
||||
|
||||
```
|
||||
wget -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/uninstall.sh && bash uninstall.sh
|
||||
```
|
||||
|
||||
|
||||
### 通用软件安装[命令行安装]
|
||||
|
||||
@@ -147,9 +158,10 @@ curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/qu
|
||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
|
||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
|
||||
|
||||
wget -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/uninstall.sh && bash uninstall.sh
|
||||
|
||||
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/install_dev.sh | bash
|
||||
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/update_dev.sh | bash
|
||||
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/dev/scripts/update_dev.sh | bash
|
||||
```
|
||||
|
||||
### 捐赠地址 USDT(TRC20)
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 入口文件
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
# pip install profiler_online
|
||||
# 性能测试
|
||||
# from profiler_online import run_profiler
|
||||
# run_profiler()
|
||||
|
||||
from gevent import monkey
|
||||
monkey.patch_all()
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
@@ -17,6 +26,9 @@ from route import app, socketio
|
||||
from gevent.pywsgi import WSGIServer
|
||||
from geventwebsocket.handler import WebSocketHandler
|
||||
|
||||
from gevent import monkey
|
||||
monkey.patch_all()
|
||||
|
||||
try:
|
||||
if __name__ == "__main__":
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+41
-7
@@ -1,5 +1,17 @@
|
||||
# coding: utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 公共操作
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
@@ -23,6 +35,7 @@ def init():
|
||||
initDB()
|
||||
initUserInfo()
|
||||
initInitD()
|
||||
initInitTask()
|
||||
|
||||
|
||||
def local():
|
||||
@@ -58,16 +71,19 @@ def doContentReplace(src, dst):
|
||||
def initInitD():
|
||||
|
||||
# systemctl
|
||||
# 有问题
|
||||
# if os.path.exists('/lib/systemd/system'):
|
||||
# systemd_mw = '/lib/systemd/system/mw.service'
|
||||
# systemd_mw_task = '/lib/systemd/system/mw-task.service'
|
||||
# sysCfgDir = mw.systemdCfgDir()
|
||||
# if os.path.exists(sysCfgDir) and mw.getOsName() == 'centos' and mw.getOsID() == '9':
|
||||
# systemd_mw = sysCfgDir + '/mw.service'
|
||||
# systemd_mw_task = sysCfgDir + '/mw-task.service'
|
||||
|
||||
# systemd_mw_tpl = mw.getRunDir() + '/scripts/init.d/mw.service.tpl'
|
||||
# systemd_mw_task_tpl = mw.getRunDir() + '/scripts/init.d/mw-task.service.tpl'
|
||||
|
||||
# os.remove(systemd_mw)
|
||||
# os.remove(systemd_mw_task)
|
||||
# if os.path.exists(systemd_mw):
|
||||
# os.remove(systemd_mw)
|
||||
# if os.path.exists(systemd_mw_task):
|
||||
# os.remove(systemd_mw_task)
|
||||
|
||||
# doContentReplace(systemd_mw_tpl, systemd_mw)
|
||||
# doContentReplace(systemd_mw_task_tpl, systemd_mw_task)
|
||||
|
||||
@@ -81,10 +97,22 @@ def initInitD():
|
||||
mw.execShell('chmod +x ' + script_bin)
|
||||
|
||||
# 在linux系统中,确保/etc/init.d存在
|
||||
if not mw.isAppleSystem() and not os.path.exists("/etc/rc.d/init.d"):
|
||||
mw.execShell('mkdir -p /etc/rc.d/init.d')
|
||||
|
||||
if not mw.isAppleSystem() and not os.path.exists("/etc/init.d"):
|
||||
mw.execShell('mkdir -p /etc/init.d')
|
||||
|
||||
# initd
|
||||
if os.path.exists('/etc/rc.d/init.d'):
|
||||
initd_bin = '/etc/rc.d/init.d/mw'
|
||||
if not os.path.exists(initd_bin):
|
||||
import shutil
|
||||
shutil.copyfile(script_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
# 加入自启动
|
||||
mw.execShell('which chkconfig && chkconfig --add mw')
|
||||
|
||||
if os.path.exists('/etc/init.d'):
|
||||
initd_bin = '/etc/init.d/mw'
|
||||
if not os.path.exists(initd_bin):
|
||||
@@ -92,13 +120,19 @@ def initInitD():
|
||||
shutil.copyfile(script_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
# 加入自启动
|
||||
mw.execShell('which chkconfig && chkconfig --add mw')
|
||||
mw.execShell('which update-rc.d && update-rc.d -f mw defaults')
|
||||
|
||||
# 获取系统IPV4
|
||||
mw.setHostAddr(mw.getLocalIp())
|
||||
|
||||
|
||||
def initInitTask():
|
||||
# 创建证书同步命令
|
||||
import cert_api
|
||||
api = cert_api.cert_api()
|
||||
api.createCertCron()
|
||||
|
||||
|
||||
def initUserInfo():
|
||||
|
||||
data = mw.M('users').where('id=?', (1,)).getField('password')
|
||||
|
||||
+321
-17
@@ -1,5 +1,17 @@
|
||||
# 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
|
||||
@@ -15,11 +27,15 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.10.0'
|
||||
__version = '0.11.2'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getVersion(self):
|
||||
return self.__version
|
||||
|
||||
##### ----- start ----- ###
|
||||
|
||||
# 取面板列表
|
||||
@@ -73,6 +89,21 @@ class config_api:
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
return mw.returnJson(False, '修改失败!')
|
||||
|
||||
def setPanelDomainApi(self):
|
||||
domain = request.form.get('domain', '')
|
||||
|
||||
cfg_domain = 'data/bind_domain.pl'
|
||||
if domain == '':
|
||||
os.remove(cfg_domain)
|
||||
return mw.returnJson(True, '清空域名成功!')
|
||||
|
||||
reg = r"^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
|
||||
if not re.match(reg, domain):
|
||||
return mw.returnJson(False, '主域名格式不正确')
|
||||
|
||||
mw.writeFile(cfg_domain, domain)
|
||||
return mw.returnJson(True, '设置域名成功!')
|
||||
|
||||
def syncDateApi(self):
|
||||
if mw.isAppleSystem():
|
||||
return mw.returnJson(True, '开发系统不必同步时间!')
|
||||
@@ -107,6 +138,96 @@ class config_api:
|
||||
session['username'] = name1
|
||||
return mw.returnJson(True, '用户修改成功!')
|
||||
|
||||
def setWebnameApi(self):
|
||||
webname = request.form.get('webname', '')
|
||||
if webname != mw.getConfig('title'):
|
||||
mw.setConfig('title', webname)
|
||||
return mw.returnJson(True, '面板别名保存成功!')
|
||||
|
||||
def setPortApi(self):
|
||||
port = request.form.get('port', '')
|
||||
if port != mw.getHostPort():
|
||||
import system_api
|
||||
import firewall_api
|
||||
|
||||
if os.path.exists("/lib/systemd/system/firewalld.service"):
|
||||
if not firewall_api.firewall_api().getFwStatus():
|
||||
return mw.returnJson(False, 'firewalld必须先启动!')
|
||||
|
||||
mw.setHostPort(port)
|
||||
|
||||
msg = mw.getInfo('放行端口[{1}]成功', (port,))
|
||||
mw.writeLog("防火墙管理", msg)
|
||||
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
mw.M('firewall').add('port,ps,addtime', (port, "配置修改", addtime))
|
||||
|
||||
firewall_api.firewall_api().addAcceptPort(port)
|
||||
firewall_api.firewall_api().firewallReload()
|
||||
|
||||
system_api.system_api().restartMw()
|
||||
|
||||
return mw.returnJson(True, '端口保存成功!')
|
||||
|
||||
def setIpApi(self):
|
||||
host_ip = request.form.get('host_ip', '')
|
||||
if host_ip != mw.getHostAddr():
|
||||
mw.setHostAddr(host_ip)
|
||||
return mw.returnJson(True, 'IP保存成功!')
|
||||
|
||||
def setWwwDirApi(self):
|
||||
sites_path = request.form.get('sites_path', '')
|
||||
if sites_path != mw.getWwwDir():
|
||||
mw.setWwwDir(sites_path)
|
||||
return mw.returnJson(True, '修改默认建站目录成功!')
|
||||
|
||||
def setBackupDirApi(self):
|
||||
backup_path = request.form.get('backup_path', '')
|
||||
if backup_path != mw.getBackupDir():
|
||||
mw.setBackupDir(backup_path)
|
||||
return mw.returnJson(True, '修改默认备份目录成功!')
|
||||
|
||||
def setBasicAuthApi(self):
|
||||
basic_user = request.form.get('basic_user', '').strip()
|
||||
basic_pwd = request.form.get('basic_pwd', '').strip()
|
||||
basic_open = request.form.get('is_open', '').strip()
|
||||
|
||||
salt = '_md_salt'
|
||||
path = 'data/basic_auth.json'
|
||||
is_open = True
|
||||
|
||||
if basic_open == 'false':
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
return mw.returnJson(True, '删除BasicAuth成功!')
|
||||
|
||||
if basic_user == '' or basic_pwd == '':
|
||||
return mw.returnJson(True, '用户和密码不能为空!')
|
||||
|
||||
ba_conf = None
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
ba_conf = json.loads(public.readFile(path))
|
||||
except:
|
||||
os.remove(path)
|
||||
|
||||
if not ba_conf:
|
||||
ba_conf = {
|
||||
"basic_user": mw.md5(basic_user + salt),
|
||||
"basic_pwd": mw.md5(basic_pwd + salt),
|
||||
"open": is_open
|
||||
}
|
||||
else:
|
||||
ba_conf['basic_user'] = mw.md5(basic_user + salt)
|
||||
ba_conf['basic_pwd'] = mw.md5(basic_pwd + salt)
|
||||
ba_conf['open'] = is_open
|
||||
|
||||
mw.writeFile(path, json.dumps(ba_conf))
|
||||
os.chmod(path, 384)
|
||||
mw.writeLog('面板设置', '设置BasicAuth状态为: %s' % is_open)
|
||||
|
||||
mw.restartMw()
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
def setApi(self):
|
||||
webname = request.form.get('webname', '')
|
||||
port = request.form.get('port', '')
|
||||
@@ -164,10 +285,12 @@ class config_api:
|
||||
|
||||
def setAdminPathApi(self):
|
||||
admin_path = request.form.get('admin_path', '').strip()
|
||||
admin_path_checks = ['/', '/close', '/login', '/do_login', '/site',
|
||||
'/sites', '/download_file', '/control', '/crontab',
|
||||
'/firewall', '/files', 'config', '/soft', '/system',
|
||||
'/code', '/ssl', '/plugins']
|
||||
admin_path_checks = ['/', '/close', '/login',
|
||||
'/do_login', '/site', '/sites',
|
||||
'/download_file', '/control', '/crontab',
|
||||
'/firewall', '/files', 'config',
|
||||
'/soft', '/system', '/code',
|
||||
'/ssl', '/plugins', '/hook']
|
||||
if admin_path == '':
|
||||
admin_path = '/'
|
||||
if admin_path != '/':
|
||||
@@ -176,16 +299,18 @@ class config_api:
|
||||
if admin_path in admin_path_checks:
|
||||
return mw.returnJson(False, '该入口已被面板占用,请使用其它入口!')
|
||||
if not re.match("^/[\w\./-_]+$", admin_path):
|
||||
return mw.returnJson(False, '入口地址格式不正确,示例: /my_panel')
|
||||
else:
|
||||
domain = mw.readFile('data/domain.conf')
|
||||
if not domain:
|
||||
domain = ''
|
||||
limitip = mw.readFile('data/limitip.conf')
|
||||
if not limitip:
|
||||
limitip = ''
|
||||
if not domain.strip() and not limitip.strip():
|
||||
return mw.returnJson(False, '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:<a style="color:red;"><br>1、绑定访问域名<br>2、绑定授权IP</a>')
|
||||
return mw.returnJson(False, '入口地址格式不正确,示例: /mw_rand')
|
||||
# else:
|
||||
# domain = mw.readFile('data/bind_domain.pl')
|
||||
# if not domain:
|
||||
# domain = ''
|
||||
# limitip = mw.readFile('data/bind_limitip.pl')
|
||||
# if not limitip:
|
||||
# limitip = ''
|
||||
# if not domain.strip() and not limitip.strip():
|
||||
# return mw.returnJson(False,
|
||||
# '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:<a
|
||||
# style="color:red;"><br>1、绑定访问域名<br>2、绑定授权IP</a>')
|
||||
|
||||
admin_path_file = 'data/admin_path.pl'
|
||||
admin_path_old = '/'
|
||||
@@ -302,8 +427,162 @@ class config_api:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getVersion(self):
|
||||
return self.__version
|
||||
# 获取临时登录列表
|
||||
def getTempLoginApi(self):
|
||||
if 'tmp_login_expire' in session:
|
||||
return mw.returnJson(False, '没有权限')
|
||||
limit = request.form.get('limit', '10').strip()
|
||||
p = request.form.get('p', '1').strip()
|
||||
tojs = request.form.get('tojs', '').strip()
|
||||
|
||||
tempLoginM = mw.M('temp_login')
|
||||
tempLoginM.where('state=? and expire<?',
|
||||
(0, int(time.time()))).setField('state', -1)
|
||||
|
||||
start = (int(p) - 1) * (int(limit))
|
||||
vlist = tempLoginM.limit(str(start) + ',' + str(limit)).order('id desc').field(
|
||||
'id,addtime,expire,login_time,login_addr,state').select()
|
||||
|
||||
data = {}
|
||||
data['data'] = vlist
|
||||
|
||||
count = tempLoginM.count()
|
||||
page_args = {}
|
||||
page_args['count'] = count
|
||||
page_args['tojs'] = 'get_temp_login'
|
||||
page_args['p'] = p
|
||||
page_args['row'] = limit
|
||||
|
||||
data['page'] = mw.getPage(page_args)
|
||||
return mw.getJson(data)
|
||||
|
||||
# 删除临时登录
|
||||
def removeTempLoginApi(self):
|
||||
if 'tmp_login_expire' in session:
|
||||
return mw.returnJson(False, '没有权限')
|
||||
sid = request.form.get('id', '10').strip()
|
||||
if mw.M('temp_login').where('id=?', (sid,)).delete():
|
||||
mw.writeLog('面板设置', '删除临时登录连接')
|
||||
return mw.returnJson(True, '删除成功')
|
||||
return mw.returnJson(False, '删除失败')
|
||||
|
||||
def setTempLoginApi(self):
|
||||
if 'tmp_login_expire' in session:
|
||||
return mw.returnJson(False, '没有权限')
|
||||
s_time = int(time.time())
|
||||
mw.M('temp_login').where(
|
||||
'state=? and expire>?', (0, s_time)).delete()
|
||||
token = mw.getRandomString(48)
|
||||
salt = mw.getRandomString(12)
|
||||
|
||||
pdata = {
|
||||
'token': mw.md5(token + salt),
|
||||
'salt': salt,
|
||||
'state': 0,
|
||||
'login_time': 0,
|
||||
'login_addr': '',
|
||||
'expire': s_time + 3600,
|
||||
'addtime': s_time
|
||||
}
|
||||
|
||||
if not mw.M('temp_login').count():
|
||||
pdata['id'] = 101
|
||||
|
||||
if mw.M('temp_login').insert(pdata):
|
||||
mw.writeLog('面板设置', '生成临时连接,过期时间:{}'.format(
|
||||
mw.formatDate(times=pdata['expire'])))
|
||||
return mw.getJson({'status': True, 'msg': "临时连接已生成", 'token': token, 'expire': pdata['expire']})
|
||||
return mw.returnJson(False, '连接生成失败')
|
||||
|
||||
def getTempLoginLogsApi(self):
|
||||
if 'tmp_login_expire' in session:
|
||||
return mw.returnJson(False, '没有权限')
|
||||
|
||||
logs_id = request.form.get('id', '').strip()
|
||||
logs_id = int(logs_id)
|
||||
data = mw.M('logs').where(
|
||||
'uid=?', (logs_id,)).order('id desc').field(
|
||||
'id,type,uid,log,addtime').select()
|
||||
return mw.returnJson(False, 'ok', data)
|
||||
|
||||
def checkPanelToken(self):
|
||||
api_file = self.__api_addr
|
||||
if not os.path.exists(api_file):
|
||||
return False, ''
|
||||
|
||||
tmp = mw.readFile(api_file)
|
||||
data = json.loads(tmp)
|
||||
if data['open']:
|
||||
return True, data
|
||||
else:
|
||||
return False, ''
|
||||
|
||||
def getPanelTokenApi(self):
|
||||
api_file = self.__api_addr
|
||||
|
||||
tmp = mw.readFile(api_file)
|
||||
if not os.path.exists(api_file):
|
||||
ready_data = {"open": False, "token": "", "limit_addr": []}
|
||||
mw.writeFile(api_file, json.dumps(ready_data))
|
||||
mw.execShell("chmod 600 " + api_file)
|
||||
tmp = mw.readFile(api_file)
|
||||
data = json.loads(tmp)
|
||||
|
||||
if not 'key' in data:
|
||||
data['key'] = mw.getRandomString(16)
|
||||
mw.writeFile(api_file, json.dumps(data))
|
||||
|
||||
if 'token_crypt' in data:
|
||||
data['token'] = mw.deCrypt(data['token'], data['token_crypt'])
|
||||
else:
|
||||
token = mw.getRandomString(32)
|
||||
data['token'] = mw.md5(token)
|
||||
data['token_crypt'] = mw.enCrypt(
|
||||
data['token'], token).decode('utf-8')
|
||||
mw.writeFile(api_file, json.dumps(data))
|
||||
data['token'] = "***********************************"
|
||||
|
||||
data['limit_addr'] = '\n'.join(data['limit_addr'])
|
||||
|
||||
del(data['key'])
|
||||
return mw.returnJson(True, 'ok', data)
|
||||
|
||||
def setPanelTokenApi(self):
|
||||
op_type = request.form.get('op_type', '').strip()
|
||||
|
||||
api_file = self.__api_addr
|
||||
tmp = mw.readFile(api_file)
|
||||
data = json.loads(tmp)
|
||||
|
||||
if op_type == '1':
|
||||
token = mw.getRandomString(32)
|
||||
data['token'] = mw.md5(token)
|
||||
data['token_crypt'] = mw.enCrypt(
|
||||
data['token'], token).decode('utf-8')
|
||||
mw.writeLog('API配置', '重新生成API-Token')
|
||||
mw.writeFile(api_file, json.dumps(data))
|
||||
return mw.returnJson(True, 'ok', token)
|
||||
|
||||
elif op_type == '2':
|
||||
data['open'] = not data['open']
|
||||
stats = {True: '开启', False: '关闭'}
|
||||
if not 'token_crypt' in data:
|
||||
token = mw.getRandomString(32)
|
||||
data['token'] = mw.md5(token)
|
||||
data['token_crypt'] = mw.enCrypt(
|
||||
data['token'], token).decode('utf-8')
|
||||
|
||||
token = stats[data['open']] + '成功!'
|
||||
mw.writeLog('API配置', '%sAPI接口' % stats[data['open']])
|
||||
mw.writeFile(api_file, json.dumps(data))
|
||||
return mw.returnJson(not not data['open'], token)
|
||||
|
||||
elif op_type == '3':
|
||||
limit_addr = request.form.get('limit_addr', '').strip()
|
||||
data['limit_addr'] = limit_addr.split('\n')
|
||||
mw.writeLog('API配置', '变更IP限制为[%s]' % limit_addr)
|
||||
mw.writeFile(api_file, json.dumps(data))
|
||||
return mw.returnJson(True, '保存成功!')
|
||||
|
||||
def get(self):
|
||||
|
||||
@@ -341,6 +620,31 @@ class config_api:
|
||||
else:
|
||||
data['ssl'] = ''
|
||||
|
||||
basic_auth = 'data/basic_auth.json'
|
||||
if os.path.exists(basic_auth):
|
||||
bac = mw.readFile(basic_auth)
|
||||
bac = json.loads(bac)
|
||||
if bac['open']:
|
||||
data['basic_auth'] = 'checked'
|
||||
else:
|
||||
data['basic_auth'] = ''
|
||||
|
||||
cfg_domain = 'data/bind_domain.pl'
|
||||
if os.path.exists(cfg_domain):
|
||||
domain = mw.readFile(cfg_domain)
|
||||
data['bind_domain'] = domain.strip()
|
||||
else:
|
||||
data['bind_domain'] = ''
|
||||
|
||||
api_token = self.__api_addr
|
||||
if os.path.exists(api_token):
|
||||
bac = mw.readFile(api_token)
|
||||
bac = json.loads(bac)
|
||||
if bac['open']:
|
||||
data['api_token'] = 'checked'
|
||||
else:
|
||||
data['api_token'] = ''
|
||||
|
||||
data['site_count'] = mw.M('sites').count()
|
||||
|
||||
data['username'] = mw.M('users').where(
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# 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
|
||||
@@ -115,6 +128,56 @@ class crontab_api:
|
||||
'id=?', (sid,)).field(self.field).find()
|
||||
return mw.getJson(data)
|
||||
|
||||
# 参数校验
|
||||
def cronCheck(self, params):
|
||||
|
||||
if params['stype'] == 'site' or params['stype'] == 'database' or params['stype'] == 'logs':
|
||||
if params['save'] == '':
|
||||
return False, '保留份数不能为空!'
|
||||
|
||||
if params['type'] == 'day':
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'day-n':
|
||||
if params['where1'] == '':
|
||||
return False, '天不能为空!'
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
if params['type'] == 'hour':
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'hour-n':
|
||||
if params['where1'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'minute-n':
|
||||
if params['where1'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'week':
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
if params['type'] == 'month':
|
||||
if params['where1'] == '':
|
||||
return False, '日不能为空!'
|
||||
if params['hour'] == '':
|
||||
return False, '小时不能为空!'
|
||||
if params['minute'] == '':
|
||||
return False, '分钟不能为空!'
|
||||
|
||||
return True, 'OK'
|
||||
|
||||
def modifyCrondApi(self):
|
||||
sid = request.form.get('id', '')
|
||||
iname = request.form.get('name', '')
|
||||
@@ -147,6 +210,11 @@ class crontab_api:
|
||||
'sbody': sbody,
|
||||
'urladdress': urladdress,
|
||||
}
|
||||
|
||||
is_check_pass, msg = self.cronCheck(params)
|
||||
if not is_check_pass:
|
||||
return mw.returnJson(is_check_pass, msg)
|
||||
|
||||
cuonConfig, get, name = self.getCrondCycle(params)
|
||||
cronInfo = mw.M('crontab').where(
|
||||
'id=?', (sid,)).field(self.field).find()
|
||||
@@ -210,6 +278,10 @@ class crontab_api:
|
||||
'urladdress': urladdress,
|
||||
}
|
||||
|
||||
is_check_pass, msg = self.cronCheck(params)
|
||||
if not is_check_pass:
|
||||
return mw.returnJson(is_check_pass, msg)
|
||||
|
||||
addData = self.add(params)
|
||||
if addData > 0:
|
||||
return mw.returnJson(True, '添加成功')
|
||||
@@ -419,6 +491,7 @@ class crontab_api:
|
||||
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
|
||||
|
||||
source_bin_activate = '''
|
||||
export LANG=en_US.UTF-8
|
||||
MW_PATH=%s/bin/activate
|
||||
if [ -f $MW_PATH ];then
|
||||
source $MW_PATH
|
||||
|
||||
+49
-12
@@ -1,5 +1,17 @@
|
||||
# coding: utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# sqlite3操作
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
import sqlite3
|
||||
import os
|
||||
@@ -23,7 +35,7 @@ class Sql():
|
||||
def __init__(self):
|
||||
self.__DB_FILE = 'data/default.db'
|
||||
|
||||
def __GetConn(self):
|
||||
def __getConn(self):
|
||||
# 取数据库对象
|
||||
try:
|
||||
if self.__DB_CONN == None:
|
||||
@@ -100,10 +112,11 @@ class Sql():
|
||||
|
||||
def select(self):
|
||||
# 查询数据集
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
||||
self.__OPT_WHERE + self.__OPT_GROUP + self.__OPT_ORDER + self.__OPT_LIMIT
|
||||
# print(sql)
|
||||
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
|
||||
data = result.fetchall()
|
||||
# 构造字曲系列
|
||||
@@ -133,7 +146,7 @@ class Sql():
|
||||
def inquiry(self, input_field=''):
|
||||
# 查询数据集
|
||||
# 不清空查询参数
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
||||
self.__OPT_WHERE + self.__OPT_GROUP + self.__OPT_ORDER + self.__OPT_LIMIT
|
||||
@@ -171,6 +184,7 @@ class Sql():
|
||||
def getField(self, keyName):
|
||||
# 取回指定字段
|
||||
result = self.field(keyName).select()
|
||||
# print(result)
|
||||
if len(result) == 1:
|
||||
return result[0][keyName]
|
||||
return result
|
||||
@@ -197,7 +211,7 @@ class Sql():
|
||||
|
||||
def add(self, keys, param):
|
||||
# 插入数据
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
values = ""
|
||||
for key in keys.split(','):
|
||||
@@ -213,6 +227,29 @@ class Sql():
|
||||
except Exception as ex:
|
||||
return "error: " + str(ex)
|
||||
|
||||
# 插入数据
|
||||
def insert(self, pdata):
|
||||
if not pdata:
|
||||
return False
|
||||
keys, param = self.__format_pdata(pdata)
|
||||
return self.add(keys, param)
|
||||
|
||||
# 更新数据
|
||||
def update(self, pdata):
|
||||
if not pdata:
|
||||
return False
|
||||
keys, param = self.__format_pdata(pdata)
|
||||
return self.save(keys, param)
|
||||
|
||||
# 构造数据
|
||||
def __format_pdata(self, pdata):
|
||||
keys = pdata.keys()
|
||||
keys_str = ','.join(keys)
|
||||
param = []
|
||||
for k in keys:
|
||||
param.append(pdata[k])
|
||||
return keys_str, tuple(param)
|
||||
|
||||
def checkInput(self, data):
|
||||
if not data:
|
||||
return data
|
||||
@@ -233,7 +270,7 @@ class Sql():
|
||||
|
||||
def addAll(self, keys, param):
|
||||
# 插入数据
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
values = ""
|
||||
for key in keys.split(','):
|
||||
@@ -252,7 +289,7 @@ class Sql():
|
||||
|
||||
def save(self, keys, param):
|
||||
# 更新数据
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
opt = ""
|
||||
for key in keys.split(','):
|
||||
@@ -277,7 +314,7 @@ class Sql():
|
||||
|
||||
def delete(self, id=None):
|
||||
# 删除数据
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
if id:
|
||||
self.__OPT_WHERE = " WHERE id=?"
|
||||
@@ -291,7 +328,7 @@ class Sql():
|
||||
return "error: " + str(ex)
|
||||
|
||||
def originExecute(self, sql, param=()):
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
result = self.__DB_CONN.execute(sql, param)
|
||||
self.__DB_CONN.commit()
|
||||
@@ -301,7 +338,7 @@ class Sql():
|
||||
|
||||
def execute(self, sql, param=()):
|
||||
# 执行SQL语句返回受影响行
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
# print sql, param
|
||||
try:
|
||||
result = self.__DB_CONN.execute(sql, param)
|
||||
@@ -312,7 +349,7 @@ class Sql():
|
||||
|
||||
def query(self, sql, param):
|
||||
# 执行SQL语句返回数据集
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
try:
|
||||
result = self.__DB_CONN.execute(sql, param)
|
||||
# 将元组转换成列表
|
||||
@@ -323,7 +360,7 @@ class Sql():
|
||||
|
||||
def create(self, name):
|
||||
# 创建数据表
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
import mw
|
||||
script = mw.readFile('data/' + name + '.sql')
|
||||
result = self.__DB_CONN.executescript(script)
|
||||
@@ -332,7 +369,7 @@ class Sql():
|
||||
|
||||
def fofile(self, filename):
|
||||
# 执行脚本
|
||||
self.__GetConn()
|
||||
self.__getConn()
|
||||
import mw
|
||||
script = mw.readFile(filename)
|
||||
result = self.__DB_CONN.executescript(script)
|
||||
|
||||
+35
-17
@@ -1,5 +1,18 @@
|
||||
# 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
|
||||
@@ -39,7 +52,7 @@ class files_api:
|
||||
data = mw.getLastLine(path, int(line))
|
||||
return mw.returnJson(True, 'OK', data)
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, u'无法正确读取文件!' + str(ex))
|
||||
return mw.returnJson(False, '无法正确读取文件!' + str(ex))
|
||||
|
||||
def saveBodyApi(self):
|
||||
path = request.form.get('path', '')
|
||||
@@ -324,7 +337,7 @@ class files_api:
|
||||
if not self.checkDir(path):
|
||||
return mw.returnJson(False, '敏感目录,请不要花样作死!')
|
||||
|
||||
os.system('which chattr && chattr -R -i ' + rPath + path)
|
||||
mw.execShell('which chattr && chattr -R -i ' + rPath + path)
|
||||
if os.path.isdir(rPath + path):
|
||||
import shutil
|
||||
shutil.rmtree(rPath + path)
|
||||
@@ -343,7 +356,7 @@ class files_api:
|
||||
|
||||
def closeRecycleBinApi(self):
|
||||
rPath = self.rPath
|
||||
os.system('which chattr && chattr -R -i ' + rPath)
|
||||
mw.execShell('which chattr && chattr -R -i ' + rPath)
|
||||
rlist = os.listdir(rPath)
|
||||
i = 0
|
||||
l = len(rlist)
|
||||
@@ -626,6 +639,7 @@ class files_api:
|
||||
user = mw.execShell(
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
auth = user + ':staff'
|
||||
|
||||
os.system('chown -R ' + auth + ' ' + filename)
|
||||
os.system('chmod -R 755 ' + filename)
|
||||
|
||||
@@ -652,7 +666,7 @@ class files_api:
|
||||
return mw.returnJson(False, '文件不存在', (path,))
|
||||
|
||||
if os.path.getsize(path) > 2097152:
|
||||
return mw.returnJson(False, u'不能在线编辑大于2MB的文件!')
|
||||
return mw.returnJson(False, '不能在线编辑大于2MB的文件!')
|
||||
|
||||
fp = open(path, 'rb')
|
||||
data = {}
|
||||
@@ -676,8 +690,10 @@ class files_api:
|
||||
data['encoding'] = 'utf-8'
|
||||
if char['encoding'] == 'Big5':
|
||||
data['encoding'] = 'BIG5'
|
||||
if not char['encoding'] in ['GBK', 'utf-8', 'BIG5']:
|
||||
|
||||
if not data['encoding'] in ['GBK', 'utf-8', 'BIG5']:
|
||||
data['encoding'] = 'utf-8'
|
||||
|
||||
try:
|
||||
if sys.version_info[0] == 2:
|
||||
data['data'] = srcBody.decode(
|
||||
@@ -691,16 +707,17 @@ class files_api:
|
||||
data['encoding']).encode('utf-8', errors='ignore')
|
||||
else:
|
||||
data['data'] = srcBody.decode(data['encoding'])
|
||||
return mw.returnJson(True, 'OK', data)
|
||||
else:
|
||||
if sys.version_info[0] == 2:
|
||||
data['data'] = srcBody.decode('utf-8').encode('utf-8')
|
||||
else:
|
||||
data['data'] = srcBody.decode('utf-8')
|
||||
data['encoding'] = u'utf-8'
|
||||
data['encoding'] = 'utf-8'
|
||||
|
||||
return mw.returnJson(True, 'OK', data)
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, u'文件编码不被兼容,无法正确读取文件!' + str(ex))
|
||||
return mw.returnJson(False, '文件编码不被兼容,无法正确读取文件!' + str(ex))
|
||||
|
||||
def saveBody(self, path, data, encoding='utf-8'):
|
||||
if not os.path.exists(path):
|
||||
@@ -724,7 +741,7 @@ class files_api:
|
||||
mw.writeLog('文件管理', '文件保存成功', (path,))
|
||||
return mw.returnJson(True, '文件保存成功')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, 'FILE_SAVE_ERR:' + str(ex))
|
||||
return mw.returnJson(False, '文件保存错误:' + str(ex))
|
||||
|
||||
def zip(self, sfile, dfile, stype, path):
|
||||
if sfile.find(',') == -1:
|
||||
@@ -734,16 +751,16 @@ class files_api:
|
||||
try:
|
||||
tmps = mw.getRunDir() + '/tmp/panelExec.log'
|
||||
if stype == 'zip':
|
||||
os.system("cd '" + path + "' && zip '" + dfile +
|
||||
"' -r '" + sfile + "' > " + tmps + " 2>&1")
|
||||
mw.execShell("cd '" + path + "' && zip '" + dfile +
|
||||
"' -r '" + sfile + "' > " + tmps + " 2>&1")
|
||||
else:
|
||||
sfiles = ''
|
||||
for sfile in sfile.split(','):
|
||||
if not sfile:
|
||||
continue
|
||||
sfiles += " '" + sfile + "'"
|
||||
os.system("cd '" + path + "' && tar -zcvf '" +
|
||||
dfile + "' " + sfiles + " > " + tmps + " 2>&1")
|
||||
mw.execShell("cd '" + path + "' && tar -zcvf '" +
|
||||
dfile + "' " + sfiles + " > " + tmps + " 2>&1")
|
||||
self.setFileAccept(dfile)
|
||||
mw.writeLog("文件管理", '文件压缩成功!', (sfile, dfile))
|
||||
return mw.returnJson(True, '文件压缩成功!')
|
||||
@@ -758,16 +775,17 @@ class files_api:
|
||||
try:
|
||||
tmps = mw.getRunDir() + '/tmp/panelExec.log'
|
||||
if stype == 'zip':
|
||||
os.system("cd " + path + " && unzip -d '" + dfile +
|
||||
"' '" + sfile + "' > " + tmps + " 2>&1 &")
|
||||
mw.execShell("cd " + path + " && unzip -o -d '" + dfile +
|
||||
"' '" + sfile + "' > " + tmps + " 2>&1 &")
|
||||
else:
|
||||
sfiles = ''
|
||||
for sfile in sfile.split(','):
|
||||
if not sfile:
|
||||
continue
|
||||
sfiles += " '" + sfile + "'"
|
||||
os.system("cd " + path + " && tar -zxvf " + sfiles +
|
||||
" -C " + dfile + " > " + tmps + " 2>&1 &")
|
||||
mw.execShell("cd " + path + " && tar -zxvf " + sfiles +
|
||||
" -C " + dfile + " > " + tmps + " 2>&1 &")
|
||||
|
||||
self.setFileAccept(dfile)
|
||||
mw.writeLog("文件管理", '文件解压成功!', (sfile, dfile))
|
||||
return mw.returnJson(True, '文件解压成功!')
|
||||
@@ -781,7 +799,7 @@ class files_api:
|
||||
|
||||
# 检查是否为.user.ini
|
||||
if path.find('.user.ini') >= 0:
|
||||
os.system("which chattr && chattr -i '" + path + "'")
|
||||
mw.execShell("which chattr && chattr -i '" + path + "'")
|
||||
|
||||
try:
|
||||
if os.path.exists('data/recycle_bin.pl'):
|
||||
|
||||
+77
-35
@@ -1,5 +1,18 @@
|
||||
# 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
|
||||
@@ -165,6 +178,8 @@ class firewall_api:
|
||||
return self.getLogList(int(p), int(limit), search)
|
||||
|
||||
def getSshInfoApi(self):
|
||||
data = {}
|
||||
|
||||
file = '/etc/ssh/sshd_config'
|
||||
conf = mw.readFile(file)
|
||||
rep = "#*Port\s+([0-9]+)\s*\n"
|
||||
@@ -176,39 +191,40 @@ class firewall_api:
|
||||
isPing = True
|
||||
else:
|
||||
file = '/etc/sysctl.conf'
|
||||
conf = mw.readFile(file)
|
||||
sys_conf = mw.readFile(file)
|
||||
rep = "#*net\.ipv4\.icmp_echo_ignore_all\s*=\s*([0-9]+)"
|
||||
tmp = re.search(rep, conf).groups(0)[0]
|
||||
tmp = re.search(rep, sys_conf).groups(0)[0]
|
||||
if tmp == '1':
|
||||
isPing = False
|
||||
except:
|
||||
isPing = True
|
||||
|
||||
import system_api
|
||||
panelsys = system_api.system_api()
|
||||
version = panelsys.getSystemVersion()
|
||||
if os.path.exists('/usr/bin/apt-get'):
|
||||
if os.path.exists('/etc/init.d/sshd'):
|
||||
cmd = "service sshd status | grep -P '(dead|stop)'|grep -v grep"
|
||||
status = mw.execShell(cmd)
|
||||
else:
|
||||
cmd = "service ssh status | grep -P '(dead|stop)'|grep -v grep"
|
||||
status = mw.execShell(cmd)
|
||||
else:
|
||||
if version.find(' 7.') != -1:
|
||||
cmd = "systemctl status sshd.service | grep 'dead'|grep -v grep"
|
||||
status = mw.execShell(cmd)
|
||||
else:
|
||||
cmd = "/etc/init.d/sshd status | grep -e 'stopped' -e '已停'|grep -v grep"
|
||||
status = mw.execShell(cmd)
|
||||
if len(status[0]) > 3:
|
||||
# sshd 检测
|
||||
status = True
|
||||
cmd = "service sshd status | grep -P '(dead|stop)'|grep -v grep"
|
||||
ssh_status = mw.execShell(cmd)
|
||||
if ssh_status[0] != '':
|
||||
status = False
|
||||
else:
|
||||
status = True
|
||||
|
||||
data = {}
|
||||
cmd = "systemctl status sshd.service | grep 'dead'|grep -v grep"
|
||||
ssh_status = mw.execShell(cmd)
|
||||
if ssh_status[0] != '':
|
||||
status = False
|
||||
|
||||
data['pass_prohibit_status'] = False
|
||||
# 密码登陆配置检查
|
||||
pass_rep = "#PasswordAuthentication\s+(\w*)\s*\n"
|
||||
pass_status = re.search(pass_rep, conf)
|
||||
if pass_status:
|
||||
data['pass_prohibit_status'] = True
|
||||
|
||||
if not data['pass_prohibit_status']:
|
||||
pass_rep = "PasswordAuthentication\s+(\w*)\s*\n"
|
||||
pass_status = re.search(pass_rep, conf)
|
||||
if pass_status and pass_status.groups(0)[0].strip() == 'no':
|
||||
data['pass_prohibit_status'] = True
|
||||
|
||||
data['port'] = port
|
||||
|
||||
data['status'] = status
|
||||
data['ping'] = isPing
|
||||
if mw.isAppleSystem():
|
||||
@@ -222,7 +238,7 @@ class firewall_api:
|
||||
if int(port) < 22 or int(port) > 65535:
|
||||
return mw.returnJson(False, '端口范围必需在22-65535之间!')
|
||||
|
||||
ports = ['21', '25', '80', '443', '7200', '8080', '888', '8888']
|
||||
ports = ['21', '25', '80', '443', '888']
|
||||
if port in ports:
|
||||
return mw.returnJson(False, '(' + port + ')' + '特殊端口不可设置!')
|
||||
|
||||
@@ -249,7 +265,7 @@ class firewall_api:
|
||||
self.firewallReload()
|
||||
# mw.M('firewall').where(
|
||||
# "ps=?", ('SSH远程管理服务',)).setField('port', port)
|
||||
msg = mw.getInfo('改SSH端口为[{1}]成功!', port)
|
||||
msg = "改SSH端口为[{}]成功!".format(port)
|
||||
mw.writeLog("防火墙管理", msg)
|
||||
return mw.returnJson(True, '修改成功!')
|
||||
|
||||
@@ -258,24 +274,50 @@ class firewall_api:
|
||||
return mw.returnJson(True, '开发机不能操作!')
|
||||
|
||||
status = request.form.get('status', '1').strip()
|
||||
version = mw.readFile('/etc/redhat-release')
|
||||
if int(status) == 1:
|
||||
msg = 'SSH服务已启用'
|
||||
act = 'start'
|
||||
if status == "1":
|
||||
msg = 'SSH服务已停用'
|
||||
act = 'stop'
|
||||
else:
|
||||
msg = 'SSH服务已启用'
|
||||
act = 'start'
|
||||
|
||||
if not os.path.exists('/etc/redhat-release'):
|
||||
mw.execShell('service ssh ' + act)
|
||||
elif version.find(' 7.') != -1:
|
||||
ssh_service = mw.systemdCfgDir() + '/sshd.service'
|
||||
if os.path.exists(ssh_service):
|
||||
mw.execShell("systemctl " + act + " sshd.service")
|
||||
else:
|
||||
mw.execShell("/etc/init.d/sshd " + act)
|
||||
mw.execShell('service sshd ' + act)
|
||||
|
||||
if os.path.exists('/etc/init.d/sshd'):
|
||||
mw.execShell('/etc/init.d/sshd ' + act)
|
||||
|
||||
mw.writeLog("防火墙管理", msg)
|
||||
return mw.returnJson(True, '操作成功!')
|
||||
|
||||
def setSshPassStatusApi(self):
|
||||
if mw.isAppleSystem():
|
||||
return mw.returnJson(True, '开发机不能操作!')
|
||||
|
||||
status = request.form.get('status', '1').strip()
|
||||
msg = '禁止密码登陆成功'
|
||||
if status == "1":
|
||||
msg = '开启密码登陆成功'
|
||||
|
||||
file = '/etc/ssh/sshd_config'
|
||||
if not os.path.exists(file):
|
||||
return mw.returnJson(False, '无法设置!')
|
||||
|
||||
conf = mw.readFile(file)
|
||||
|
||||
if status == '1':
|
||||
rep = "(#)?PasswordAuthentication\s+(\w*)\s*\n"
|
||||
conf = re.sub(rep, "PasswordAuthentication yes\n", conf)
|
||||
else:
|
||||
rep = "(#)?PasswordAuthentication\s+(\w*)\s*\n"
|
||||
conf = re.sub(rep, "PasswordAuthentication no\n", conf)
|
||||
mw.writeFile(file, conf)
|
||||
mw.execShell("systemctl restart sshd.service")
|
||||
mw.writeLog("SSH管理", msg)
|
||||
return mw.returnJson(True, msg)
|
||||
|
||||
def setPingApi(self):
|
||||
if mw.isAppleSystem():
|
||||
return mw.returnJson(True, '开发机不能操作!')
|
||||
|
||||
+266
-22
@@ -1,4 +1,17 @@
|
||||
# coding: utf-8
|
||||
# coding:utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 核心方法库
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
@@ -45,6 +58,12 @@ def execShell(cmdstring, cwd=None, timeout=None, shell=True):
|
||||
return (t1, t2)
|
||||
|
||||
|
||||
def getTracebackInfo():
|
||||
import traceback
|
||||
errorMsg = traceback.format_exc()
|
||||
return errorMsg
|
||||
|
||||
|
||||
def getRunDir():
|
||||
return os.getcwd()
|
||||
|
||||
@@ -69,10 +88,6 @@ def getLogsDir():
|
||||
return getRootDir() + '/wwwlogs'
|
||||
|
||||
|
||||
def getBackupDir():
|
||||
return getRootDir() + '/backup'
|
||||
|
||||
|
||||
def getWwwDir():
|
||||
file = getRunDir() + '/data/site.pl'
|
||||
if os.path.exists(file):
|
||||
@@ -85,11 +100,29 @@ def setWwwDir(wdir):
|
||||
return writeFile(file, wdir)
|
||||
|
||||
|
||||
def getBackupDir():
|
||||
file = getRunDir() + '/data/backup.pl'
|
||||
if os.path.exists(file):
|
||||
return readFile(file).strip()
|
||||
return getRootDir() + '/backup'
|
||||
|
||||
|
||||
def setBackupDir(bdir):
|
||||
file = getRunDir() + '/data/backup.pl'
|
||||
return writeFile(file, bdir)
|
||||
|
||||
|
||||
def getAcmeDir():
|
||||
acme = '/root/.acme.sh'
|
||||
if isAppleSystem():
|
||||
cmd = "who | sed -n '2, 1p' |awk '{print $1}'"
|
||||
user = execShell(cmd)[0].strip()
|
||||
acme = '/Users/' + user + '/.acme.sh'
|
||||
if not os.path.exists(acme):
|
||||
acme = '/.acme.sh'
|
||||
return acme
|
||||
|
||||
|
||||
def triggerTask():
|
||||
isTask = getRunDir() + '/tmp/panelTask.pl'
|
||||
writeFile(isTask, 'True')
|
||||
@@ -110,10 +143,36 @@ def systemdCfgDir():
|
||||
return "/tmp"
|
||||
|
||||
|
||||
def getSslCrt():
|
||||
if os.path.exists('/etc/ssl/certs/ca-certificates.crt'):
|
||||
return '/etc/ssl/certs/ca-certificates.crt'
|
||||
if os.path.exists('/etc/pki/tls/certs/ca-bundle.crt'):
|
||||
return '/etc/pki/tls/certs/ca-bundle.crt'
|
||||
return ''
|
||||
|
||||
|
||||
def getOs():
|
||||
return sys.platform
|
||||
|
||||
|
||||
def getOsName():
|
||||
cmd = "cat /etc/*-release | grep PRETTY_NAME |awk -F = '{print $2}' | awk -F '\"' '{print $2}'| awk '{print $1}'"
|
||||
data = execShell(cmd)
|
||||
return data[0].strip().lower()
|
||||
|
||||
|
||||
def getOsID():
|
||||
cmd = "cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F '\"' '{print $2}'"
|
||||
data = execShell(cmd)
|
||||
return data[0].strip()
|
||||
|
||||
|
||||
def getFileSuffix(file):
|
||||
tmp = file.split('.')
|
||||
ext = tmp[len(tmp) - 1]
|
||||
return ext
|
||||
|
||||
|
||||
def isAppleSystem():
|
||||
if getOs() == 'darwin':
|
||||
return True
|
||||
@@ -194,7 +253,7 @@ def checkWebConfig():
|
||||
cmd = "ulimit -n 10240 && " + op_dir + \
|
||||
"/sbin/nginx -t -c " + op_dir + "/conf/nginx.conf"
|
||||
result = execShell(cmd)
|
||||
searchStr = 'successful'
|
||||
searchStr = 'test is successful'
|
||||
if result[1].find(searchStr) == -1:
|
||||
msg = getInfo('配置文件错误: {1}', (result[1],))
|
||||
writeLog("软件管理", msg)
|
||||
@@ -238,11 +297,11 @@ def getPageObject(args, result='1,2,3,4,5,8'):
|
||||
return (page.GetPage(info, result), page)
|
||||
|
||||
|
||||
def md5(str):
|
||||
def md5(content):
|
||||
# 生成MD5
|
||||
try:
|
||||
m = hashlib.md5()
|
||||
m.update(str.encode("utf-8"))
|
||||
m.update(content.encode("utf-8"))
|
||||
return m.hexdigest()
|
||||
except Exception as ex:
|
||||
return False
|
||||
@@ -386,32 +445,38 @@ def getDate():
|
||||
return time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
|
||||
|
||||
def writeLog(type, logMsg, args=()):
|
||||
def writeLog(stype, msg, args=()):
|
||||
# 写日志
|
||||
try:
|
||||
import time
|
||||
import db
|
||||
import json
|
||||
from flask import session
|
||||
uid = 1
|
||||
if 'uid' in session:
|
||||
uid = session['uid']
|
||||
sql = db.Sql()
|
||||
mDate = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
data = (type, logMsg, mDate)
|
||||
result = sql.table('logs').add('type,log,addtime', data)
|
||||
mdate = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
wmsg = getInfo(msg, args)
|
||||
data = (stype, wmsg, uid, mdate)
|
||||
result = sql.table('logs').add('type,log,uid,addtime', data)
|
||||
return True
|
||||
except Exception as e:
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def writeFile(filename, str):
|
||||
def writeFile(filename, content, mode='w+'):
|
||||
# 写文件内容
|
||||
try:
|
||||
fp = open(filename, 'w+')
|
||||
fp.write(str)
|
||||
fp = open(filename, mode)
|
||||
fp.write(content)
|
||||
fp.close()
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
|
||||
def backFile(self, file, act=None):
|
||||
def backFile(file, act=None):
|
||||
"""
|
||||
@name 备份配置文件
|
||||
@param file 需要备份的文件
|
||||
@@ -420,10 +485,12 @@ def backFile(self, file, act=None):
|
||||
file_type = "_bak"
|
||||
if act:
|
||||
file_type = "_def"
|
||||
execShell("/usr/bin/cp -p {0} {1}".format(file, file + file_type))
|
||||
|
||||
# print("cp -p {0} {1}".format(file, file + file_type))
|
||||
execShell("cp -p {0} {1}".format(file, file + file_type))
|
||||
|
||||
|
||||
def restoreFile(self, file, act=None):
|
||||
def restoreFile(file, act=None):
|
||||
"""
|
||||
@name 还原配置文件
|
||||
@param file 需要还原的文件
|
||||
@@ -432,7 +499,90 @@ def restoreFile(self, file, act=None):
|
||||
file_type = "_bak"
|
||||
if act:
|
||||
file_type = "_def"
|
||||
execShell("/usr/bin/cp -p {1} {0}".format(file, file + file_type))
|
||||
execShell("cp -p {1} {0}".format(file, file + file_type))
|
||||
|
||||
|
||||
def enPunycode(domain):
|
||||
if sys.version_info[0] == 2:
|
||||
domain = domain.encode('utf8')
|
||||
tmp = domain.split('.')
|
||||
newdomain = ''
|
||||
for dkey in tmp:
|
||||
if dkey == '*':
|
||||
continue
|
||||
# 匹配非ascii字符
|
||||
match = re.search(u"[\x80-\xff]+", dkey)
|
||||
if not match:
|
||||
match = re.search(u"[\u4e00-\u9fa5]+", dkey)
|
||||
if not match:
|
||||
newdomain += dkey + '.'
|
||||
else:
|
||||
if sys.version_info[0] == 2:
|
||||
newdomain += 'xn--' + \
|
||||
dkey.decode('utf-8').encode('punycode') + '.'
|
||||
else:
|
||||
newdomain += 'xn--' + \
|
||||
dkey.encode('punycode').decode('utf-8') + '.'
|
||||
if tmp[0] == '*':
|
||||
newdomain = "*." + newdomain
|
||||
return newdomain[0:-1]
|
||||
|
||||
|
||||
def dePunycode(domain):
|
||||
# punycode 转中文
|
||||
tmp = domain.split('.')
|
||||
newdomain = ''
|
||||
for dkey in tmp:
|
||||
if dkey.find('xn--') >= 0:
|
||||
newdomain += dkey.replace('xn--',
|
||||
'').encode('utf-8').decode('punycode') + '.'
|
||||
else:
|
||||
newdomain += dkey + '.'
|
||||
return newdomain[0:-1]
|
||||
|
||||
|
||||
def enCrypt(key, strings):
|
||||
# 加密字符串
|
||||
try:
|
||||
if type(strings) != bytes:
|
||||
strings = strings.encode('utf-8')
|
||||
from cryptography.fernet import Fernet
|
||||
f = Fernet(key)
|
||||
result = f.encrypt(strings)
|
||||
return result.decode('utf-8')
|
||||
except:
|
||||
# print(get_error_info())
|
||||
return strings
|
||||
|
||||
|
||||
def deCrypt(key, strings):
|
||||
# 解密字符串
|
||||
try:
|
||||
if type(strings) != bytes:
|
||||
strings = strings.decode('utf-8')
|
||||
from cryptography.fernet import Fernet
|
||||
f = Fernet(key)
|
||||
result = f.decrypt(strings).decode('utf-8')
|
||||
return result
|
||||
except:
|
||||
# print(get_error_info())
|
||||
return strings
|
||||
|
||||
|
||||
def buildSoftLink(src, dst, force=False):
|
||||
'''
|
||||
建立软连接
|
||||
'''
|
||||
if not os.path.exists(src):
|
||||
return False
|
||||
|
||||
if os.path.exists(dst) and force:
|
||||
os.remove(dst)
|
||||
|
||||
if not os.path.exists(dst):
|
||||
execShell('ln -sf "' + src + '" "' + dst + '"')
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def HttpGet(url, timeout=10):
|
||||
@@ -478,6 +628,11 @@ def HttpGet2(url, timeout):
|
||||
import urllib.request
|
||||
|
||||
try:
|
||||
import ssl
|
||||
try:
|
||||
ssl._create_default_https_context = ssl._create_unverified_context
|
||||
except:
|
||||
pass
|
||||
req = urllib.request.urlopen(url, timeout=timeout)
|
||||
result = req.read().decode('utf-8')
|
||||
return result
|
||||
@@ -676,6 +831,11 @@ def getLocalIpBack():
|
||||
return '127.0.0.1'
|
||||
|
||||
|
||||
def getClientIp():
|
||||
from flask import request
|
||||
return request.remote_addr.replace('::ffff:', '')
|
||||
|
||||
|
||||
def getLocalIp():
|
||||
filename = 'data/iplist.txt'
|
||||
try:
|
||||
@@ -711,6 +871,14 @@ def inArray(arrays, searchStr):
|
||||
return False
|
||||
|
||||
|
||||
def formatDate(format="%Y-%m-%d %H:%M:%S", times=None):
|
||||
# 格式化指定时间戳
|
||||
if not times:
|
||||
times = int(time.time())
|
||||
time_local = time.localtime(times)
|
||||
return time.strftime(format, time_local)
|
||||
|
||||
|
||||
def checkIp(ip):
|
||||
# 检查是否为IPv4地址
|
||||
import re
|
||||
@@ -722,9 +890,85 @@ def checkIp(ip):
|
||||
return False
|
||||
|
||||
|
||||
def getHost(port=False):
|
||||
from flask import request
|
||||
host_tmp = request.headers.get('host')
|
||||
if not host_tmp:
|
||||
if request.url_root:
|
||||
tmp = re.findall(r"(https|http)://([\w:\.-]+)", request.url_root)
|
||||
if tmp:
|
||||
host_tmp = tmp[0][1]
|
||||
if not host_tmp:
|
||||
host_tmp = getLocalIp() + ':' + readFile('data/port.pl').strip()
|
||||
try:
|
||||
if host_tmp.find(':') == -1:
|
||||
host_tmp += ':80'
|
||||
except:
|
||||
host_tmp = "127.0.0.1:8888"
|
||||
h = host_tmp.split(':')
|
||||
if port:
|
||||
return h[-1]
|
||||
return ':'.join(h[0:-1])
|
||||
|
||||
|
||||
def getClientIp():
|
||||
from flask import request
|
||||
return request.remote_addr.replace('::ffff:', '')
|
||||
|
||||
|
||||
def checkDomainPanel():
|
||||
tmp = getHost()
|
||||
domain = readFile('data/bind_domain.pl')
|
||||
port = readFile('data/port.pl').strip()
|
||||
if domain:
|
||||
client_ip = getClientIp()
|
||||
if client_ip in ['127.0.0.1', 'localhost', '::1']:
|
||||
return False
|
||||
if tmp.strip().lower() != domain.strip().lower():
|
||||
from flask import Flask, redirect, request, url_for
|
||||
to = "http://" + domain + ":" + port
|
||||
return redirect(to, code=302)
|
||||
return False
|
||||
|
||||
|
||||
def createLinuxUser(user, group):
|
||||
execShell("groupadd {}".format(group))
|
||||
execShell('useradd -s /sbin/nologin -g {} {}'.format(user, group))
|
||||
return True
|
||||
|
||||
|
||||
def setOwn(filename, user, group=None):
|
||||
if isAppleSystem():
|
||||
return True
|
||||
|
||||
# 设置用户组
|
||||
if not os.path.exists(filename):
|
||||
return False
|
||||
from pwd import getpwnam
|
||||
try:
|
||||
user_info = getpwnam(user)
|
||||
user = user_info.pw_uid
|
||||
if group:
|
||||
user_info = getpwnam(group)
|
||||
group = user_info.pw_gid
|
||||
except:
|
||||
if user == 'www':
|
||||
createLinuxUser(user)
|
||||
# 如果指定用户或组不存在,则使用www
|
||||
try:
|
||||
user_info = getpwnam('www')
|
||||
except:
|
||||
createLinuxUser(user)
|
||||
user_info = getpwnam('www')
|
||||
user = user_info.pw_uid
|
||||
group = user_info.pw_gid
|
||||
os.chown(filename, user, group)
|
||||
return True
|
||||
|
||||
|
||||
def checkPort(port):
|
||||
# 检查端口是否合法
|
||||
ports = ['21', '25', '443', '888']
|
||||
ports = ['21', '443', '888']
|
||||
if port in ports:
|
||||
return False
|
||||
intport = int(port)
|
||||
@@ -807,7 +1051,7 @@ def makeConf():
|
||||
file = getRunDir() + '/data/json/config.json'
|
||||
if not os.path.exists(file):
|
||||
c = {}
|
||||
c['title'] = 'mdserver-web | linux面板'
|
||||
c['title'] = '猫王面板'
|
||||
c['home'] = 'http://github/midoks/mdserver-web'
|
||||
c['recycle_bin'] = True
|
||||
c['template'] = 'default'
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# coding: utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 分页库操作
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
import math
|
||||
import string
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# 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
|
||||
@@ -91,6 +104,63 @@ class plugins_api:
|
||||
return mw.returnJson(True, '成功!')
|
||||
return mw.returnJson(False, '失败!')
|
||||
|
||||
def initApi(self):
|
||||
|
||||
plugin_names = {
|
||||
'openresty': '1.21.4.1',
|
||||
'php': '56',
|
||||
'swap': '1.1',
|
||||
'mysql': '5.7',
|
||||
'phpmyadmin': '4.4.15',
|
||||
}
|
||||
|
||||
pn_dir = mw.getPluginDir()
|
||||
pn_server_dir = mw.getServerDir()
|
||||
pn_list = []
|
||||
for pn in plugin_names:
|
||||
info = {}
|
||||
pn_json = pn_dir + '/' + pn + '/info.json'
|
||||
pn_server = pn_server_dir + '/' + pn
|
||||
if not os.path.exists(pn_server):
|
||||
|
||||
tmp = mw.readFile(pn_json)
|
||||
tmp = json.loads(tmp)
|
||||
|
||||
info['title'] = tmp['title']
|
||||
info['name'] = tmp['name']
|
||||
info['versions'] = tmp['versions']
|
||||
info['default_ver'] = plugin_names[pn]
|
||||
pn_list.append(info)
|
||||
else:
|
||||
return mw.returnJson(False, 'ok')
|
||||
|
||||
return mw.returnJson(True, 'ok', pn_list)
|
||||
|
||||
def initInstallApi(self):
|
||||
pn_list = request.form.get('list', '')
|
||||
try:
|
||||
pn_list = json.loads(pn_list)
|
||||
|
||||
for pn in pn_list:
|
||||
name = pn['name']
|
||||
version = pn['version']
|
||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
||||
pluginInfo = json.loads(mw.readFile(infoJsonPos))
|
||||
self.hookInstall(pluginInfo)
|
||||
execstr = 'cd ' + mw.getPluginDir() + '/' + name + ' && bash ' + \
|
||||
pluginInfo['shell'] + ' install ' + version
|
||||
|
||||
taskAdd = ('安装[' + name + '-' + version + ']',
|
||||
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
|
||||
|
||||
mw.M('tasks').add('name,type,status,addtime, execstr', taskAdd)
|
||||
os.mkdir(mw.getServerDir() + '/php')
|
||||
# 任务执行相关
|
||||
mw.triggerTask()
|
||||
return mw.returnJson(True, '添加成功')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, mw.getTracebackInfo())
|
||||
|
||||
def installApi(self):
|
||||
rundir = mw.getRunDir()
|
||||
name = request.form.get('name', '')
|
||||
@@ -116,17 +186,16 @@ class plugins_api:
|
||||
pluginInfo = json.loads(mw.readFile(infoJsonPos))
|
||||
self.hookInstall(pluginInfo)
|
||||
|
||||
execstr = "cd " + os.getcwd() + "/plugins/" + \
|
||||
name + " && /bin/bash " + pluginInfo["shell"] \
|
||||
+ " install " + version
|
||||
execstr = 'cd ' + mw.getPluginDir() + '/' + name + ' && bash ' + \
|
||||
pluginInfo['shell'] + ' install ' + version
|
||||
|
||||
if mw.isAppleSystem():
|
||||
print(execstr)
|
||||
|
||||
taskAdd = (None, mmsg + '[' + name + '-' + version + ']',
|
||||
taskAdd = (mmsg + '[' + name + '-' + version + ']',
|
||||
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
|
||||
|
||||
mw.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
|
||||
mw.M('tasks').add('name,type,status,addtime, execstr', taskAdd)
|
||||
|
||||
# 任务执行相关
|
||||
mw.triggerTask()
|
||||
|
||||
+558
-222
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,18 @@
|
||||
# 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
|
||||
@@ -442,7 +455,7 @@ class system_api:
|
||||
else:
|
||||
os.remove(filename)
|
||||
count += 1
|
||||
mw.serviceReload()
|
||||
mw.restartWeb()
|
||||
os.system('echo > /tmp/panelBoot.pl')
|
||||
return total, count
|
||||
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# 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
|
||||
|
||||
+12
-1
@@ -1,6 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# coding: utf-8
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# MW-Linux面板
|
||||
# ---------------------------------------------------------------------------------
|
||||
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
|
||||
# ---------------------------------------------------------------------------------
|
||||
# Author: midoks <midoks@163.com>
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------------
|
||||
# 验证码操作
|
||||
# ---------------------------------------------------------------------------------
|
||||
|
||||
|
||||
import random
|
||||
import math
|
||||
|
||||
@@ -56,8 +56,10 @@ CREATE TABLE IF NOT EXISTS `logs` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`type` TEXT,
|
||||
`log` TEXT,
|
||||
`uid` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
ALTER TABLE `logs` ADD COLUMN `uid` INTEGER DEFAULT '1';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `sites` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -109,6 +111,18 @@ CREATE TABLE IF NOT EXISTS `tasks` (
|
||||
`execstr` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `temp_login` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`token` REAL,
|
||||
`salt` REAL,
|
||||
`state` INTEGER,
|
||||
`login_time` INTEGER,
|
||||
`login_addr` REAL,
|
||||
`logout_time` INTEGER,
|
||||
`expire` INTEGER,
|
||||
`addtime` INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `panel` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`title` TEXT,
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
server
|
||||
{
|
||||
listen {$PORT};
|
||||
listen [::]:{$PORT};
|
||||
server_name {$SERVER_NAME};
|
||||
index index.php index.html index.htm default.php default.htm default.html;
|
||||
root {$ROOT_DIR};
|
||||
@@ -14,8 +15,8 @@ server
|
||||
#PROXY-START
|
||||
|
||||
#ERROR-PAGE-START
|
||||
error_page 404 /404.html;
|
||||
error_page 502 /502.html;
|
||||
#error_page 404 /404.html;
|
||||
#error_page 502 /502.html;
|
||||
#ERROR-PAGE-END
|
||||
|
||||
#PHP-INFO-START
|
||||
|
||||
@@ -12,8 +12,8 @@ server
|
||||
#SSL-END
|
||||
|
||||
#ERROR-PAGE-START
|
||||
error_page 404 /404.html;
|
||||
error_page 502 /502.html;
|
||||
#error_page 404 /404.html;
|
||||
#error_page 502 /502.html;
|
||||
#ERROR-PAGE-END
|
||||
|
||||
#PHP-INFO-START
|
||||
|
||||
@@ -187,7 +187,7 @@ class FtpPSClient:
|
||||
}
|
||||
mw.writeFile(pg_file, json.dumps(progress_info))
|
||||
else:
|
||||
progress_info = json.loads(public.readFile(pg_file))
|
||||
progress_info = json.loads(mw.readFile(pg_file))
|
||||
if total_bytes == progress_info.get("total_bytes"):
|
||||
# 取远程文件大小
|
||||
_max_loop = 10
|
||||
@@ -352,7 +352,7 @@ class FtpPSClient:
|
||||
ftp.rmd(dir_name)
|
||||
return True
|
||||
except ftplib.error_perm as e:
|
||||
print(str(e) + ":" + dir_name)
|
||||
print("deleteDir:" + str(e) + ":" + dir_name)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
@@ -7,6 +7,11 @@ 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
|
||||
|
||||
@@ -192,10 +197,12 @@ def backupAllFunc(stype):
|
||||
prefix_dict[stype] + '_' + name
|
||||
|
||||
find_new_file = "ls " + find_path + \
|
||||
"_* | grep tar.gz | cut -d \ -f 1 | awk 'END {print}'"
|
||||
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
|
||||
|
||||
filename = mw.execShell(find_new_file)[0].strip()
|
||||
# print("filename:", filename)
|
||||
if filename == "":
|
||||
print("not find upload file!")
|
||||
return False
|
||||
|
||||
ftp = FtpPSClient()
|
||||
ftp.uploadFile(filename, stype)
|
||||
|
||||
@@ -17,7 +17,7 @@ pluginService('clean');
|
||||
|
||||
function pRead(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>启动后,假如到计划中[2:30]执行。</li>';
|
||||
readme += '<li>启动后,加入到计划中[2:30]执行。</li>';
|
||||
readme += '<li>【*】代表要删除。</li>';
|
||||
readme += '<li>添加/删除清除日志,可在`配置修改`中添加/删除。</li>';
|
||||
readme += '<li>如果是目录,会寻找【.log】后缀的文件清空。</li>';
|
||||
|
||||
@@ -74,6 +74,7 @@ def initConf():
|
||||
content = ""
|
||||
|
||||
clog = [
|
||||
"/var/spool/clientmqueue/*",
|
||||
"/var/log/cron-*",
|
||||
"/var/log/maillog-*",
|
||||
"/var/log/secure-*",
|
||||
|
||||
@@ -10,6 +10,7 @@ GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
|
||||
|
||||
|
||||
git config --global credential.helper store
|
||||
git config --global pull.rebase false
|
||||
|
||||
# echo $GIT_PROJECT_DIR
|
||||
if [ ! -d $GIT_PROJECT_DIR ];then
|
||||
@@ -18,6 +19,7 @@ if [ ! -d $GIT_PROJECT_DIR ];then
|
||||
fi
|
||||
|
||||
unset GIT_DIR
|
||||
|
||||
cd $GIT_PROJECT_DIR && git pull
|
||||
|
||||
# func 2
|
||||
@@ -26,9 +28,13 @@ cd $GIT_PROJECT_DIR && git pull
|
||||
|
||||
#更新的目的地址
|
||||
WEB_PATH={$WEB_ROOT}/{$USERNAME}/{$PROJECT}
|
||||
mkdir -p $WEB_PATH
|
||||
|
||||
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
if [ ! -d $WEB_PATH ];then
|
||||
mkdir -p $WEB_PATH
|
||||
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
else
|
||||
rsync -vauP --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
fi
|
||||
|
||||
sysName=`uname`
|
||||
if [ $sysName == 'Darwin' ]; then
|
||||
|
||||
@@ -15,6 +15,8 @@ if [ ! -d $GIT_PROJECT_DIR ];then
|
||||
fi
|
||||
|
||||
unset GIT_DIR
|
||||
git config pull.rebase false
|
||||
|
||||
cd $GIT_PROJECT_DIR && git pull
|
||||
|
||||
# func 2
|
||||
|
||||
+24
-6
@@ -101,7 +101,7 @@ def getHomeDir():
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
return '/Users/' + user
|
||||
else:
|
||||
return 'git'
|
||||
return 'www'
|
||||
|
||||
|
||||
def getRunUser():
|
||||
@@ -110,7 +110,7 @@ def getRunUser():
|
||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
||||
return user
|
||||
else:
|
||||
return 'git'
|
||||
return 'www'
|
||||
|
||||
__SR = '''#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
@@ -135,6 +135,10 @@ def initDreplace():
|
||||
file_tpl = getInitdConfTpl()
|
||||
service_path = mw.getServerDir()
|
||||
|
||||
git_dir = mw.getServerDir() + '/git'
|
||||
if not os.path.exists(git_dir):
|
||||
mw.execShell('mkdir -p ' + git_dir)
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
@@ -445,7 +449,7 @@ def submitGogsConf():
|
||||
val = g + ' = ' + args[g]
|
||||
conf = re.sub(rep, val, conf)
|
||||
mw.writeFile(filename, conf)
|
||||
reload()
|
||||
restart()
|
||||
return mw.returnJson(True, '设置成功')
|
||||
|
||||
|
||||
@@ -515,7 +519,7 @@ def checkProjectListIsHasScript(user, data):
|
||||
path = getRootPath() + '/' + user
|
||||
for x in range(len(data)):
|
||||
name = data[x]['name'] + '.git'
|
||||
path_tmp = path + '/' + name + '/custom_hooks/post-receive'
|
||||
path_tmp = path + '/' + name + '/hooks/post-receive.d/post-receive'
|
||||
if os.path.exists(path_tmp):
|
||||
data[x]['has_hook'] = True
|
||||
else:
|
||||
@@ -593,15 +597,17 @@ def projectScriptLoad():
|
||||
|
||||
path = getRootPath() + '/' + user + '/' + name
|
||||
post_receive_tpl = getPluginDir() + '/hook/post-receive.tpl'
|
||||
post_receive = path + '/custom_hooks/post-receive'
|
||||
post_receive = path + '/hooks/post-receive.d/post-receive'
|
||||
|
||||
if not os.path.exists(path + '/custom_hooks'):
|
||||
mw.execShell('mkdir -p ' + path + '/custom_hooks')
|
||||
mw.execShell('chown -R www:www ' + path + '/custom_hooks')
|
||||
|
||||
pct_content = mw.readFile(post_receive_tpl)
|
||||
pct_content = pct_content.replace('{$PATH}', path + '/custom_hooks')
|
||||
mw.writeFile(post_receive, pct_content)
|
||||
mw.execShell('chmod 777 ' + post_receive)
|
||||
mw.execShell('chown -R www:www ' + post_receive)
|
||||
|
||||
commit_tpl = getPluginDir() + '/hook/commit.tpl'
|
||||
commit = path + '/custom_hooks/commit'
|
||||
@@ -618,6 +624,7 @@ def projectScriptLoad():
|
||||
cc_content = cc_content.replace('{$WEB_ROOT}', mw.getWwwDir())
|
||||
mw.writeFile(commit, cc_content)
|
||||
mw.execShell('chmod 777 ' + commit)
|
||||
mw.execShell('chown -R www:www ' + commit)
|
||||
|
||||
return 'ok'
|
||||
|
||||
@@ -632,7 +639,7 @@ def projectScriptUnload():
|
||||
name = args['name'] + '.git'
|
||||
|
||||
post_receive = getRootPath() + '/' + user + '/' + name + \
|
||||
'/custom_hooks/post-receive'
|
||||
'/hooks/post-receive.d/post-receive'
|
||||
mw.execShell('rm -f ' + post_receive)
|
||||
|
||||
commit = getRootPath() + '/' + user + '/' + name + \
|
||||
@@ -697,6 +704,15 @@ def getTotalStatistics():
|
||||
return mw.returnJson(False, 'fail', data)
|
||||
|
||||
|
||||
def uninstallPreInspection():
|
||||
repo_dir = getServerDir() + "/data/gitea-repositories"
|
||||
if not os.path.exists(repo_dir):
|
||||
return 'ok'
|
||||
dir_list = os.listdir(repo_dir)
|
||||
if len(dir_list) > 0:
|
||||
return "有项目数据!请手动删除Gitea<br/> rm -rf {}".format(getServerDir())
|
||||
return 'ok'
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
@@ -715,6 +731,8 @@ if __name__ == "__main__":
|
||||
print(initdInstall())
|
||||
elif func == 'initd_uninstall':
|
||||
print(initdUinstall())
|
||||
elif func == 'uninstall_pre_inspection':
|
||||
print(uninstallPreInspection())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'post_receive_log':
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
"title": "Gitea",
|
||||
"versions": ["1.17.2"],
|
||||
"tip": "soft",
|
||||
"install_pre_inspection":false,
|
||||
"uninstall_pre_inspection":true,
|
||||
"checks": "server/gitea",
|
||||
"path":"server/gitea",
|
||||
"author": "gitea",
|
||||
|
||||
@@ -6,12 +6,12 @@ After=network.target
|
||||
[Service]
|
||||
RestartSec=2s
|
||||
Type=simple
|
||||
User=git
|
||||
Group=git
|
||||
User=www
|
||||
Group=www
|
||||
WorkingDirectory={$SERVER_PATH}/gitea
|
||||
ExecStart={$SERVER_PATH}/gitea/gitea web
|
||||
Restart=always
|
||||
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
|
||||
Environment=USER=www HOME=/home/www GITEA_WORK_DIR={$SERVER_PATH}/gitea
|
||||
RemainAfterExit=yes
|
||||
#AmbientCapabilities=CAP_NET_BIND_SERVICE
|
||||
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
|
||||
|
||||
+36
-19
@@ -16,42 +16,59 @@ fi
|
||||
|
||||
URL_DOWNLOAD=https://dl.gitea.io/
|
||||
|
||||
getOs(){
|
||||
os=`uname`
|
||||
if [ "Darwin" == "$os" ];then
|
||||
echo 'darwin'
|
||||
else
|
||||
echo 'linux'
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
|
||||
getBit(){
|
||||
echo `getconf LONG_BIT`
|
||||
}
|
||||
|
||||
Install_Rsync(){
|
||||
if [ "$OSNAME" == "debian" ] || [ "$OSNAME" == "ubuntu" ];then
|
||||
apt install -y rsync
|
||||
elif [[ "$OSNAME" == "arch" ]]; then
|
||||
echo y | pacman -Sy rsync
|
||||
elif [[ "$OSNAME" == "macos" ]]; then
|
||||
# brew install rsync
|
||||
# brew install lsyncd
|
||||
echo "ok"
|
||||
else
|
||||
yum install -y rsync
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
Install_App()
|
||||
{
|
||||
Install_Rsync
|
||||
|
||||
mkdir -p $serverPath/source/gitea
|
||||
|
||||
|
||||
if id git &> /dev/null ;then
|
||||
echo "git UID is `id -u git`"
|
||||
echo "git Shell is `grep "^git:" /etc/passwd |cut -d':' -f7 `"
|
||||
if id www &> /dev/null ;then
|
||||
echo "www uid is `id -u www`"
|
||||
echo "www shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd git
|
||||
useradd -g git git
|
||||
groupadd www
|
||||
useradd -g www www
|
||||
fi
|
||||
|
||||
if [ "macos" != "$OSNAME" ];then
|
||||
if [ ! -d /home/www ];then
|
||||
mkdir -p /home/www
|
||||
chown -R www:www /home/www
|
||||
fi
|
||||
fi
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
version=$1
|
||||
os=`getOs`
|
||||
|
||||
|
||||
git config --global push.default simple
|
||||
|
||||
if [ "darwin" == "$os" ];then
|
||||
if [ "macos" == "$OSNAME" ];then
|
||||
file=gitea-${version}-darwin-10.12-amd64
|
||||
else
|
||||
file=gitea-${version}-linux-amd64
|
||||
@@ -60,7 +77,7 @@ Install_App()
|
||||
file_xz="${file}.xz"
|
||||
echo "wget -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}"
|
||||
if [ ! -f $serverPath/source/gitea/$file_xz ];then
|
||||
wget -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}
|
||||
wget --no-check-certificate -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}
|
||||
fi
|
||||
|
||||
cd $serverPath/source/gitea && xz -k -d $file_xz
|
||||
@@ -69,7 +86,7 @@ Install_App()
|
||||
mv $serverPath/source/gitea/$file $serverPath/gitea/gitea
|
||||
chmod +x $serverPath/gitea/gitea
|
||||
|
||||
chown -R git:git $serverPath/gitea
|
||||
chown -R www:www $serverPath/gitea
|
||||
fi
|
||||
|
||||
|
||||
|
||||
+64
-48
@@ -1,19 +1,9 @@
|
||||
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function gogsPost(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -186,6 +176,28 @@ function giteaUserList(page, search) {
|
||||
}
|
||||
|
||||
function userProjectList(user, search){
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '用户('+user+')项目列表',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div>\
|
||||
<div id='gitea_table' class='divtable' style='margin-top:5px;'>\
|
||||
<table class='table table-hover'>\
|
||||
<thead><tr><th>项目</th><th>操作</th></tr></thead>\
|
||||
<tbody></tbody>\
|
||||
</table>\
|
||||
<div class='dataTables_paginate paging_bootstrap pagination' style='margin-top:0px;'><ul id='gitea_page' class='page'></ul></div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>",
|
||||
success:function(){
|
||||
userProjectListPost(user,search);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function userProjectListPost(user, search){
|
||||
var req = {};
|
||||
if (!isNaN(user)){
|
||||
req['page'] = user;
|
||||
@@ -202,7 +214,6 @@ function userProjectList(user, search){
|
||||
req['search'] = search;
|
||||
}
|
||||
|
||||
$('.layui-layer-close1').click();
|
||||
gogsPost('user_project_list', req, function(data){
|
||||
var rdata = [];
|
||||
try {
|
||||
@@ -227,24 +238,10 @@ function userProjectList(user, search){
|
||||
</tr>';
|
||||
}
|
||||
|
||||
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
|
||||
page += rdata['data']['list'];
|
||||
page += '</div></ul></div>';
|
||||
$('#gitea_table tbody').html(list);
|
||||
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '用户('+user+')项目列表',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div>\
|
||||
<div class='divtable' style='margin-top:5px;'>\
|
||||
<table class='table table-hover'>\
|
||||
<thead><tr><th>项目</th><th>操作</th></tr></thead>\
|
||||
<tbody>" + list + "</tbody>\
|
||||
</table>" +
|
||||
page +
|
||||
"</div></div></div>"
|
||||
});
|
||||
var page = rdata['data']['list'];
|
||||
$('#gitea_table .gitea_page').html(page);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -253,23 +250,41 @@ function projectScript(user, name,has_hook){
|
||||
// console.log(user,name,has_hook);
|
||||
var html = '';
|
||||
if (has_hook){
|
||||
html += '<button onclick="projectScriptEdit(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">手动编辑</button>';
|
||||
html += '<button onclick="projectScriptDebug(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">调试日志</button>';
|
||||
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">重新加载</button>';
|
||||
html += '<button onclick="projectScriptUnload(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">卸载脚本</button>';
|
||||
html += '<button class="btn btn-default btn-sm hook_edit">手动编辑</button>';
|
||||
html += '<button class="btn btn-default btn-sm hook_log">调试日志</button>';
|
||||
html += '<button class="btn btn-default btn-sm hook_load">重新加载</button>';
|
||||
html += '<button class="btn btn-default btn-sm hook_unload">卸载脚本</button>';
|
||||
} else {
|
||||
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">加载脚本</button>';
|
||||
html += '<button class="btn btn-default btn-sm hook_load">加载脚本</button>';
|
||||
}
|
||||
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '['+user+']['+name+']脚本设置',
|
||||
area: '240px',
|
||||
content:'<div class="change-default pd20">'+html+'</div>'
|
||||
content:'<div class="change-default pd20">'+html+'</div>',
|
||||
success:function(layero,index) {
|
||||
|
||||
$('.hook_edit').click(function(){
|
||||
projectScriptEdit(user,name,index);
|
||||
});
|
||||
|
||||
$('.hook_log').click(function(){
|
||||
projectScriptDebug(user,name,index);
|
||||
});
|
||||
|
||||
$('.hook_load').click(function(){
|
||||
projectScriptLoad(user,name,index);
|
||||
});
|
||||
|
||||
$('.hook_unload').click(function(){
|
||||
projectScriptUnload(user,name,index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptEdit(user,name){
|
||||
function projectScriptEdit(user,name,index){
|
||||
gogsPost('project_script_edit', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (rdata['status']){
|
||||
@@ -280,41 +295,42 @@ function projectScriptEdit(user,name){
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptLoad(user,name){
|
||||
function projectScriptLoad(user,name,index){
|
||||
gogsPost('project_script_load', {'user':user,'name':name}, function(data){
|
||||
if (data.data != 'ok'){
|
||||
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
layer.msg('加载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){
|
||||
userProjectList(1);
|
||||
}, 2000);
|
||||
showMsg('加载成功!',function(){
|
||||
layer.close(index);
|
||||
userProjectListPost(1);
|
||||
},{icon:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptUnload(user,name){
|
||||
function projectScriptUnload(user,name,index){
|
||||
gogsPost('project_script_unload', {'user':user,'name':name}, function(data){
|
||||
if (data.data != 'ok'){
|
||||
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
layer.msg('卸载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){
|
||||
userProjectList(1);
|
||||
}, 2000);
|
||||
showMsg('卸载成功!',function(){
|
||||
layer.close(index);
|
||||
userProjectListPost(1);
|
||||
},{icon:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptDebug(user,name){
|
||||
function projectScriptDebug(user,name,index){
|
||||
gogsPost('project_script_debug', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (rdata['status']){
|
||||
onlineEditFile(0, rdata['path']);
|
||||
} else {
|
||||
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
showMsg(rdata.msg,function(){
|
||||
},{icon:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ Install_gogs()
|
||||
fi
|
||||
|
||||
if [ ! -f $serverPath/source/gogs/$file ];then
|
||||
wget -O $serverPath/source/gogs/$file ${GOGS_DOWNLOAD}/${version}/${file}
|
||||
wget --no-check-certificate -O $serverPath/source/gogs/$file ${GOGS_DOWNLOAD}/${version}/${file}
|
||||
fi
|
||||
|
||||
cd $serverPath/source/gogs && unzip -o $file -d gogs_${version}
|
||||
|
||||
@@ -29,7 +29,7 @@ Install_App()
|
||||
|
||||
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
|
||||
if [ $sysName == 'Darwin' ]; then
|
||||
wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
|
||||
else
|
||||
curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"name": "imail",
|
||||
"title": "邮件服务",
|
||||
"shell": "install.sh",
|
||||
"versions":["0.0.17"],
|
||||
"updates":["0.0.17"],
|
||||
"versions":["0.0.19"],
|
||||
"updates":["0.0.19"],
|
||||
"tip": "soft",
|
||||
"checks": "server/imail",
|
||||
"path": "server/imail",
|
||||
|
||||
@@ -8,7 +8,7 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
VERSION=0.0.17
|
||||
VERSION=0.0.19
|
||||
|
||||
# bash install.sh install 0.0.16
|
||||
## cd /www/server/mdserver-web/plugins/imail && bash install.sh install 0.0.16
|
||||
@@ -29,9 +29,11 @@ read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=1
|
||||
query_cache_size = 4M
|
||||
tmp_table_size = 8M
|
||||
|
||||
query_cache_type = 1
|
||||
query_cache_size = 4M
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 65535
|
||||
|
||||
+175
-33
@@ -335,6 +335,10 @@ def initMysqlData():
|
||||
data = mw.execShell(cmd)
|
||||
# print(data[0])
|
||||
# print(data[1])
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
mw.execShell('chown -R mysql:mysql ' + serverdir + '/data')
|
||||
mw.execShell('chmod -R 755 ' + serverdir + '/data')
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -359,6 +363,11 @@ def initMariaDbPwd():
|
||||
print("init mariadb password fail:" + data[1])
|
||||
exit(1)
|
||||
|
||||
# 删除空账户
|
||||
drop_empty_user = serverdir + '/bin/mysql ' + db_option + '-uroot -p' + \
|
||||
pwd + ' -e "use mysql;delete from user where USER=\'\'"'
|
||||
mw.execShell(drop_empty_user)
|
||||
|
||||
# 删除测试数据库
|
||||
drop_test_db = serverdir + '/bin/mysql ' + db_option + ' -uroot -p' + \
|
||||
pwd + ' -e "drop database test";'
|
||||
@@ -366,13 +375,14 @@ def initMariaDbPwd():
|
||||
|
||||
# 删除冗余账户
|
||||
hostname = mw.execShell('hostname')[0].strip()
|
||||
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
if hostname != 'localhost':
|
||||
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
|
||||
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
return True
|
||||
@@ -541,13 +551,17 @@ def setMyPort():
|
||||
return mw.returnJson(True, '编辑成功!')
|
||||
|
||||
|
||||
def runInfo():
|
||||
def runInfo(version):
|
||||
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动', [])
|
||||
|
||||
db = pMysqlDb()
|
||||
data = db.query('show global status')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
return isError
|
||||
|
||||
gets = ['Max_used_connections', 'Com_commit', 'Com_rollback', 'Questions', 'Innodb_buffer_pool_reads', 'Innodb_buffer_pool_read_requests', 'Key_reads', 'Key_read_requests', 'Key_writes',
|
||||
'Key_write_requests', 'Qcache_hits', 'Qcache_inserts', 'Bytes_received', 'Bytes_sent', 'Aborted_clients', 'Aborted_connects',
|
||||
'Created_tmp_disk_tables', 'Created_tmp_tables', 'Innodb_buffer_pool_pages_dirty', 'Opened_files', 'Open_tables', 'Opened_tables', 'Select_full_join',
|
||||
@@ -628,7 +642,7 @@ def isSqlError(mysqlMsg):
|
||||
if "2003," in 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, '数据库管理密码错误!')
|
||||
return mw.returnJson(False, '数据库密码错误,在管理列表-点击【修复】!')
|
||||
if "1045" in mysqlMsg:
|
||||
return mw.returnJson(False, '连接错误!')
|
||||
if "SQL syntax" in mysqlMsg:
|
||||
@@ -712,15 +726,82 @@ def importDbBackup():
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
def deleteDbBackup():
|
||||
def importDbExternal():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['filename'])
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
bkDir = mw.getRootDir() + '/backup/database'
|
||||
file = args['file']
|
||||
name = args['name']
|
||||
|
||||
os.remove(bkDir + '/' + args['filename'])
|
||||
import_dir = mw.getRootDir() + '/backup/import/'
|
||||
|
||||
file_path = import_dir + file
|
||||
if not os.path.exists(file_path):
|
||||
return mw.returnJson(False, '文件突然消失?')
|
||||
|
||||
exts = ['sql', 'gz', 'zip']
|
||||
tmp = file.split('.')
|
||||
ext = tmp[len(tmp) - 1]
|
||||
if ext not in exts:
|
||||
return mw.returnJson(False, '导入数据库格式不对!')
|
||||
|
||||
tmp = file.split('/')
|
||||
tmpFile = tmp[len(tmp) - 1]
|
||||
tmpFile = tmpFile.replace('.sql.' + ext, '.sql')
|
||||
tmpFile = tmpFile.replace('.' + ext, '.sql')
|
||||
tmpFile = tmpFile.replace('tar.', '')
|
||||
|
||||
# print(tmpFile)
|
||||
import_sql = ""
|
||||
if file.find("sql.gz") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && gzip -dc ' + \
|
||||
file + " > " + import_dir + tmpFile
|
||||
info = mw.execShell(cmd)
|
||||
if info[1] == "":
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find(".zip") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && unzip -o ' + file
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find("tar.gz") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && tar -zxvf ' + file
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if import_sql == "":
|
||||
return mw.returnJson(False, '未找SQL文件')
|
||||
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
|
||||
os.environ["MYSQL_PWD"] = pwd
|
||||
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + \
|
||||
pwd + ' ' + name + ' < ' + import_sql
|
||||
|
||||
# print(mysql_cmd)
|
||||
os.system(mysql_cmd)
|
||||
os.remove(import_sql)
|
||||
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
def deleteDbBackup():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['filename', 'path'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = args['path']
|
||||
full_file = ""
|
||||
bkDir = mw.getRootDir() + '/backup/database'
|
||||
full_file = bkDir + '/' + args['filename']
|
||||
if path != "":
|
||||
full_file = path + "/" + args['filename']
|
||||
os.remove(full_file)
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
@@ -752,6 +833,39 @@ def getDbBackupList():
|
||||
return mw.returnJson(True, 'ok', rr)
|
||||
|
||||
|
||||
def getDbBackupImportList():
|
||||
|
||||
bkImportDir = mw.getRootDir() + '/backup/import'
|
||||
if not os.path.exists(bkImportDir):
|
||||
os.mkdir(bkImportDir)
|
||||
|
||||
blist = os.listdir(bkImportDir)
|
||||
|
||||
rr = []
|
||||
for x in range(0, len(blist)):
|
||||
name = blist[x]
|
||||
p = bkImportDir + '/' + name
|
||||
data = {}
|
||||
data['name'] = name
|
||||
|
||||
rsize = os.path.getsize(p)
|
||||
data['size'] = mw.toSize(rsize)
|
||||
|
||||
t = os.path.getctime(p)
|
||||
t = time.localtime(t)
|
||||
|
||||
data['time'] = time.strftime('%Y-%m-%d %H:%M:%S', t)
|
||||
rr.append(data)
|
||||
|
||||
data['file'] = p
|
||||
|
||||
rdata = {
|
||||
"list": rr,
|
||||
"upload_dir": bkImportDir,
|
||||
}
|
||||
return mw.returnJson(True, 'ok', rdata)
|
||||
|
||||
|
||||
def getDbList():
|
||||
args = getArgs()
|
||||
page = 1
|
||||
@@ -1083,6 +1197,10 @@ def getDbAccess():
|
||||
users = pdb.query("select Host from user where User='" +
|
||||
username + "' AND Host!='localhost'")
|
||||
|
||||
isError = isSqlError(users)
|
||||
if isError != None:
|
||||
return isError
|
||||
|
||||
if len(users) < 1:
|
||||
return mw.returnJson(True, "127.0.0.1")
|
||||
accs = []
|
||||
@@ -1122,6 +1240,22 @@ def setDbAccess():
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def fixDbAccess(version):
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
psdb = pSqliteDb('databases')
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
appCMD(version, 'stop')
|
||||
mw.execShell("rm -rf " + getServerDir() + "/data")
|
||||
appCMD(version, 'start')
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '修复失败请重试!')
|
||||
|
||||
|
||||
def setDbRw(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['username', 'id', 'rw'])
|
||||
@@ -1532,30 +1666,32 @@ def setDbSlave(version):
|
||||
|
||||
|
||||
def getMasterStatus(version=''):
|
||||
try:
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动,或正在启动中...!', [])
|
||||
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动,或正在启动中...!', [])
|
||||
conf = getConf()
|
||||
content = mw.readFile(conf)
|
||||
master_status = False
|
||||
if content.find('#log-bin') == -1 and content.find('log-bin') > 1:
|
||||
dodb = findBinlogDoDb()
|
||||
if len(dodb) > 0:
|
||||
master_status = True
|
||||
|
||||
conf = getConf()
|
||||
content = mw.readFile(conf)
|
||||
master_status = False
|
||||
if content.find('#log-bin') == -1 and content.find('log-bin') > 1:
|
||||
dodb = findBinlogDoDb()
|
||||
if len(dodb) > 0:
|
||||
master_status = True
|
||||
data = {}
|
||||
data['mode'] = recognizeDbMode()
|
||||
data['status'] = master_status
|
||||
|
||||
data = {}
|
||||
data['mode'] = recognizeDbMode()
|
||||
data['status'] = master_status
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave 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
|
||||
|
||||
# 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
|
||||
|
||||
return mw.returnJson(master_status, '设置成功', data)
|
||||
return mw.returnJson(master_status, '设置成功', data)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "数据库密码错误,在管理列表-点击【修复】!", 'pwd')
|
||||
|
||||
|
||||
def setMasterStatus(version=''):
|
||||
@@ -2200,7 +2336,7 @@ def uninstallPreInspection(version):
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
|
||||
version = "5.6"
|
||||
version = "10.6"
|
||||
version_pl = getServerDir() + "/version.pl"
|
||||
if os.path.exists(version_pl):
|
||||
version = mw.readFile(version_pl).strip()
|
||||
@@ -2226,7 +2362,7 @@ if __name__ == "__main__":
|
||||
elif func == 'uninstall_pre_inspection':
|
||||
print(uninstallPreInspection(version))
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
print(runInfo(version))
|
||||
elif func == 'db_status':
|
||||
print(myDbStatus())
|
||||
elif func == 'set_db_status':
|
||||
@@ -2257,10 +2393,14 @@ if __name__ == "__main__":
|
||||
print(setDbBackup())
|
||||
elif func == 'import_db_backup':
|
||||
print(importDbBackup())
|
||||
elif func == 'import_db_external':
|
||||
print(importDbExternal())
|
||||
elif func == 'delete_db_backup':
|
||||
print(deleteDbBackup())
|
||||
elif func == 'get_db_backup_list':
|
||||
print(getDbBackupList())
|
||||
elif func == 'get_db_backup_import_list':
|
||||
print(getDbBackupImportList())
|
||||
elif func == 'add_db':
|
||||
print(addDb())
|
||||
elif func == 'del_db':
|
||||
@@ -2277,6 +2417,8 @@ if __name__ == "__main__":
|
||||
print(getDbAccess())
|
||||
elif func == 'set_db_access':
|
||||
print(setDbAccess())
|
||||
elif func == 'fix_db_access':
|
||||
print(fixDbAccess(version))
|
||||
elif func == 'get_db_rw':
|
||||
print(setDbRw(version))
|
||||
elif func == 'set_db_ps':
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"uninstall_pre_inspection":true,
|
||||
"checks": "server/mariadb",
|
||||
"path": "server/mariadb",
|
||||
"versions":["10.6","10.7","10.8"],
|
||||
"versions":["10.6","10.7","10.8","10.9"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/mariadb",
|
||||
"path":"server/mariadb",
|
||||
|
||||
+244
-107
@@ -1,18 +1,8 @@
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function myPost(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -40,7 +30,7 @@ function myPostN(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -59,7 +49,7 @@ function myPostN(method,args,callback, title){
|
||||
function myAsyncPost(method,args){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -184,6 +174,11 @@ function myPerfOpt() {
|
||||
//获取MySQL配置
|
||||
myPost('db_status','',function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if ( typeof(rdata.status) != 'undefined' && !rdata.status){
|
||||
layer.msg(rdata.msg, {icon:2});
|
||||
return;
|
||||
}
|
||||
|
||||
// console.log(rdata);
|
||||
var key_buffer_size = toSizeM(rdata.mem.key_buffer_size);
|
||||
var query_cache_size = toSizeM(rdata.mem.query_cache_size);
|
||||
@@ -586,7 +581,7 @@ function setDbAccess(username){
|
||||
yes:function(index){
|
||||
var data = $("#set_db_access").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['access']){
|
||||
dataObj['access'] = dataObj['dataAccess'];
|
||||
if ( dataObj['dataAccess'] == 'ip'){
|
||||
@@ -611,6 +606,15 @@ function setDbAccess(username){
|
||||
});
|
||||
}
|
||||
|
||||
function fixDbAccess(username){
|
||||
myPost('fix_db_access', '', function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
}
|
||||
|
||||
function setDbPass(id, username, password){
|
||||
|
||||
var index = layer.open({
|
||||
@@ -651,33 +655,15 @@ function setDbPass(id, username, password){
|
||||
}
|
||||
|
||||
function addDatabase(type){
|
||||
if (type==1){
|
||||
var data = $("#add_db").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
if(!dataObj['address']){
|
||||
dataObj['address'] = dataObj['dataAccess'];
|
||||
}
|
||||
myPost('add_db', dataObj, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
dbList();
|
||||
}
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2},600);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var index = layer.open({
|
||||
layer.open({
|
||||
type: 1,
|
||||
skin: 'demo-class',
|
||||
area: '500px',
|
||||
title: '添加数据库',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: true,
|
||||
content: "<form class='bt-form pd20 pb70' id='add_db'>\
|
||||
btn:["提交","关闭"],
|
||||
content: "<form class='bt-form pd20' id='add_db'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>数据库名</span>\
|
||||
<div class='info-r'><input name='name' class='bt-input-text mr5' placeholder='新的数据库名称' type='text' style='width:65%' value=''>\
|
||||
@@ -705,28 +691,39 @@ function addDatabase(type){
|
||||
</div>\
|
||||
</div>\
|
||||
<input type='hidden' name='ps' value='' />\
|
||||
<div class='bt-form-submit-btn'>\
|
||||
<button id='my_mod_close' type='button' class='btn btn-danger btn-sm btn-title'>关闭</button>\
|
||||
<button type='button' class='btn btn-success btn-sm btn-title' onclick=\"addDatabase(1)\" >提交</button>\
|
||||
</div>\
|
||||
</form>",
|
||||
});
|
||||
success:function(){
|
||||
$("input[name='name']").keyup(function(){
|
||||
var v = $(this).val();
|
||||
$("input[name='db_user']").val(v);
|
||||
$("input[name='ps']").val(v);
|
||||
});
|
||||
|
||||
$("input[name='name']").keyup(function(){
|
||||
var v = $(this).val();
|
||||
$("input[name='db_user']").val(v);
|
||||
$("input[name='ps']").val(v);
|
||||
});
|
||||
|
||||
$('#my_mod_close').click(function(){
|
||||
$('.layui-layer-close1').click();
|
||||
});
|
||||
$('select[name="dataAccess"]').change(function(){
|
||||
var v = $(this).val();
|
||||
if (v == 'ip'){
|
||||
$(this).after("<input id='dataAccess_subid' class='bt-input-text mr5' type='text' name='address' placeholder='多个IP使用逗号(,)分隔' style='width: 230px; display: inline-block;'>");
|
||||
} else {
|
||||
$('#dataAccess_subid').remove();
|
||||
$('select[name="dataAccess"]').change(function(){
|
||||
var v = $(this).val();
|
||||
if (v == 'ip'){
|
||||
$(this).after("<input id='dataAccess_subid' class='bt-input-text mr5' type='text' name='address' placeholder='多个IP使用逗号(,)分隔' style='width: 230px; display: inline-block;'>");
|
||||
} else {
|
||||
$('#dataAccess_subid').remove();
|
||||
}
|
||||
});
|
||||
},
|
||||
yes:function(index) {
|
||||
var data = $("#add_db").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['address']){
|
||||
dataObj['address'] = dataObj['dataAccess'];
|
||||
}
|
||||
myPost('add_db', dataObj, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
dbList();
|
||||
}
|
||||
},{icon: rdata.status ? 1 : 2},600);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -738,7 +735,6 @@ function delDb(id, name){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
@@ -860,12 +856,14 @@ function openPhpmyadmin(name,username,password){
|
||||
}
|
||||
}
|
||||
|
||||
function delBackup(filename,name){
|
||||
myPost('delete_db_backup',{filename:filename},function(){
|
||||
function delBackup(filename, name, path){
|
||||
if(typeof(path) == "undefined"){
|
||||
path = "";
|
||||
}
|
||||
myPost('delete_db_backup',{filename:filename,path:path},function(){
|
||||
layer.msg('执行成功!');
|
||||
setTimeout(function(){
|
||||
$('.layui-layer-close2').click();
|
||||
setBackup(name);
|
||||
setBackupReq(name);
|
||||
},2000);
|
||||
});
|
||||
}
|
||||
@@ -881,9 +879,180 @@ function importBackup(file,name){
|
||||
});
|
||||
}
|
||||
|
||||
function setBackup(db_name,obj){
|
||||
myPost('get_db_backup_list', {name:db_name}, function(data){
|
||||
|
||||
function importDbExternal(file,name){
|
||||
myPost('import_db_external',{file:file,name:name}, function(data){
|
||||
layer.msg('执行成功!');
|
||||
});
|
||||
}
|
||||
|
||||
function setLocalImport(db_name){
|
||||
|
||||
//上传文件
|
||||
function uploadDbFiles(upload_dir){
|
||||
var up_db = layer.open({
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
title:"上传导入文件["+upload_dir+']',
|
||||
area: ['500px','300px'],
|
||||
shadeClose:false,
|
||||
content:'<div class="fileUploadDiv">\
|
||||
<input type="hidden" id="input-val" value="'+upload_dir+'" />\
|
||||
<input type="file" id="file_input" multiple="true" autocomplete="off" />\
|
||||
<button type="button" id="opt" autocomplete="off">添加文件</button>\
|
||||
<button type="button" id="up" autocomplete="off" >开始上传</button>\
|
||||
<span id="totalProgress" style="position: absolute;top: 7px;right: 147px;"></span>\
|
||||
<span style="float:right;margin-top: 9px;">\
|
||||
<font>文件编码:</font>\
|
||||
<select id="fileCodeing" >\
|
||||
<option value="byte">二进制</option>\
|
||||
<option value="utf-8">UTF-8</option>\
|
||||
<option value="gb18030">GB2312</option>\
|
||||
</select>\
|
||||
</span>\
|
||||
<button type="button" id="filesClose" autocomplete="off">关闭</button>\
|
||||
<ul id="up_box"></ul>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$('#filesClose').click(function(){
|
||||
layer.close(up_db);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
uploadStart(function(){
|
||||
getList();
|
||||
layer.close(up_db);
|
||||
});
|
||||
}
|
||||
|
||||
function getList(){
|
||||
myPost('get_db_backup_import_list',{}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
var file_list = rdata.data.list;
|
||||
var upload_dir = rdata.data.upload_dir;
|
||||
|
||||
var tbody = '';
|
||||
for (var i = 0; i < file_list.length; i++) {
|
||||
tbody += '<tr>\
|
||||
<td><span> ' + file_list[i]['name'] + '</span></td>\
|
||||
<td><span> ' + file_list[i]['size'] + '</span></td>\
|
||||
<td><span> ' + file_list[i]['time'] + '</span></td>\
|
||||
<td style="text-align: right;">\
|
||||
<a class="btlink" onclick="importDbExternal(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
|
||||
<a class="btlink del" index="'+i+'">删除</a>\
|
||||
</td>\
|
||||
</tr>';
|
||||
}
|
||||
|
||||
$('#import_db_file_list').html(tbody);
|
||||
$('input[name="upload_dir"]').val(upload_dir);
|
||||
|
||||
$("#import_db_file_list .del").on('click',function(){
|
||||
var index = $(this).attr('index');
|
||||
var filename = file_list[index]["name"];
|
||||
myPost('delete_db_backup',{filename:filename,path:upload_dir},function(){
|
||||
showMsg('执行成功!', function(){
|
||||
getList();
|
||||
},{icon:1},2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var layerIndex = layer.open({
|
||||
type: 1,
|
||||
title: "从文件导入数据",
|
||||
area: ['600px', '380px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<button id="btn_file_upload" class="btn btn-success btn-sm" type="button">从本地上传</button>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<input type="hidden" name="upload_dir" value=""> \
|
||||
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>文件大小</th>\
|
||||
<th>备份时间</th>\
|
||||
<th style="text-align: right;">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="import_db_file_list" class="gztr"></tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
<ul class="help-info-text c7">\
|
||||
<li>仅支持sql、zip、sql.gz、(tar.gz|gz|tgz)</li>\
|
||||
<li>zip、tar.gz压缩包结构:test.zip或test.tar.gz压缩包内,必需包含test.sql</li>\
|
||||
<li>若文件过大,您还可以使用SFTP工具,将数据库文件上传到/www/backup/import</li>\
|
||||
</ul>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(index){
|
||||
$('#btn_file_upload').click(function(){
|
||||
var upload_dir = $('input[name="upload_dir"]').val();
|
||||
uploadDbFiles(upload_dir);
|
||||
});
|
||||
getList();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function setBackup(db_name){
|
||||
var layerIndex = layer.open({
|
||||
type: 1,
|
||||
title: "数据库备份详情",
|
||||
area: ['600px', '280px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
|
||||
<button id="btn_local_import" class="btn btn-success btn-sm" type="button">外部导入</button>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table id="database_table" class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>文件大小</th>\
|
||||
<th>备份时间</th>\
|
||||
<th style="text-align: right;">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody class="list"></tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(index){
|
||||
$('#btn_backup').click(function(){
|
||||
myPost('set_db_backup',{name:db_name}, function(data){
|
||||
showMsg('执行成功!', function(){
|
||||
setBackupReq(db_name);
|
||||
}, {icon:1}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#btn_local_import').click(function(){
|
||||
setLocalImport(db_name);
|
||||
});
|
||||
|
||||
setBackupReq(db_name);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function setBackupReq(db_name, obj){
|
||||
myPost('get_db_backup_list', {name:db_name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var tbody = '';
|
||||
for (var i = 0; i < rdata.data.length; i++) {
|
||||
@@ -898,45 +1067,7 @@ function setBackup(db_name,obj){
|
||||
</td>\
|
||||
</tr> ';
|
||||
}
|
||||
|
||||
var s = layer.open({
|
||||
type: 1,
|
||||
title: "数据库备份详情",
|
||||
area: ['600px', '280px'],
|
||||
closeBtn: 2,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>文件大小</th>\
|
||||
<th>备份时间</th>\
|
||||
<th style="text-align: right;">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody class="gztr">' + tbody + '</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>'
|
||||
});
|
||||
|
||||
$('#btn_backup').click(function(){
|
||||
myPost('set_db_backup',{name:db_name}, function(data){
|
||||
layer.msg('执行成功!');
|
||||
|
||||
setTimeout(function(){
|
||||
layer.close(s);
|
||||
setBackup(db_name,obj);
|
||||
},2000);
|
||||
});
|
||||
});
|
||||
$('#database_table tbody').html(tbody);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -970,7 +1101,7 @@ function dbList(page, search){
|
||||
list += '<td><span class="c9 input-edit" onclick="setDbPs(\''+rdata.data[i]['id']+'\',\''+rdata.data[i]['name']+'\',this)" style="display: inline-block;">'+rdata.data[i]['ps']+'</span></td>';
|
||||
list += '<td style="text-align:right">';
|
||||
|
||||
list += '<a href="javascript:;" class="btlink" class="btlink" onclick="setBackup(\''+rdata.data[i]['name']+'\',this)" title="数据库备份">'+(rdata.data[i]['is_backup']?'备份':'未备份') +'</a> | ';
|
||||
list += '<a href="javascript:;" class="btlink" class="btlink" onclick="setBackup(\''+rdata.data[i]['name']+'\')" title="数据库备份">'+(rdata.data[i]['is_backup']?'备份':'未备份') +'</a> | ';
|
||||
|
||||
var rw = '';
|
||||
var rw_change = 'all';
|
||||
@@ -1006,6 +1137,7 @@ function dbList(page, search){
|
||||
<button onclick="setRootPwd(0,\''+rdata.info['root_pwd']+'\')" title="设置MySQL管理员密码" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">root密码</button>\
|
||||
<button onclick="openPhpmyadmin(\'\',\'root\',\''+rdata.info['root_pwd']+'\')" title="打开phpMyadmin" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">phpMyAdmin</button>\
|
||||
<button onclick="setDbAccess(\'root\')" title="ROOT权限" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">ROOT权限</button>\
|
||||
<button onclick="fixDbAccess(\'root\')" title="修复" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">修复</button>\
|
||||
<span style="float:right"> \
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" onclick="delDbBatch();" title="删除选中项" class="btn btn-default btn-sm">删除选中</button>\
|
||||
</span>\
|
||||
@@ -1311,7 +1443,7 @@ function addMasterRepSlaveUser(){
|
||||
yes:function(index){
|
||||
var data = $("#add_master").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['address']){
|
||||
dataObj['address'] = dataObj['dataAccess'];
|
||||
}
|
||||
@@ -1356,7 +1488,7 @@ function updateMasterRepSlaveUser(username){
|
||||
$('#submit_update_master').click(function(){
|
||||
var data = $("#update_master").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
myPost('update_master_rep_slave_user', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
@@ -1467,7 +1599,7 @@ function setDbMasterAccess(username){
|
||||
yes:function(index){
|
||||
var data = $("#set_db_access").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['access']){
|
||||
dataObj['access'] = dataObj['dataAccess'];
|
||||
if ( dataObj['dataAccess'] == 'ip'){
|
||||
@@ -1940,9 +2072,14 @@ function masterOrSlaveConf(version=''){
|
||||
|
||||
|
||||
function getMasterStatus(){
|
||||
myPost('get_master_status', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
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});
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = rdata.data;
|
||||
var limitCon = '\
|
||||
<p class="conf_p">\
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
os.chdir('/www/server/mdserver-web')
|
||||
@@ -19,13 +21,13 @@ sys.path.append(chdir + '/class/core')
|
||||
|
||||
import mw
|
||||
import db
|
||||
import time
|
||||
|
||||
|
||||
class backupTools:
|
||||
|
||||
def backupDatabase(self, name, count):
|
||||
db_path = mw.getServerDir() + '/mariadb'
|
||||
db_sock = mw.getServerDir() + '/mariadb/'
|
||||
db_name = 'mysql'
|
||||
name = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('name')
|
||||
@@ -45,26 +47,27 @@ class backupTools:
|
||||
filename = backup_path + "/db_" + name + "_" + \
|
||||
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
|
||||
|
||||
import re
|
||||
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
|
||||
"id=?", (1,)).getField('mysql_root')
|
||||
|
||||
mycnf = mw.readFile(db_path + '/etc/my.cnf')
|
||||
my_conf_path = db_path + '/etc/my.cnf'
|
||||
content = mw.readFile(my_conf_path)
|
||||
rep = "\[mysqldump\]\nuser=root"
|
||||
sea = "[mysqldump]\n"
|
||||
subStr = sea + "user=root\npassword=" + mysql_root + "\n"
|
||||
mycnf = mycnf.replace(sea, subStr)
|
||||
if len(mycnf) > 100:
|
||||
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
|
||||
content = content.replace(sea, subStr)
|
||||
if len(content) > 100:
|
||||
mw.writeFile(my_conf_path, content)
|
||||
|
||||
# mw.execShell(db_path + "/bin/mysqldump --opt --default-character-set=utf8 " +
|
||||
# mw.execShell(db_path + "/bin/mysqldump --defaults-file=" + my_conf_path + " --opt --default-character-set=utf8 " +
|
||||
# name + " | gzip > " + filename)
|
||||
|
||||
# mw.execShell(db_path + "/bin/mysqldump --skip-lock-tables --default-character-set=utf8 " +
|
||||
# mw.execShell(db_path + "/bin/mysqldump --defaults-file=" + my_conf_path + " --skip-lock-tables --default-character-set=utf8 " +
|
||||
# name + " | gzip > " + filename)
|
||||
|
||||
mw.execShell(db_path + "/bin/mysqldump --single-transaction --quick --default-character-set=utf8 " +
|
||||
name + " | gzip > " + filename)
|
||||
cmd = db_path + "/bin/mysqldump --defaults-file=" + my_conf_path + " --single-transaction --quick --default-character-set=utf8 " + \
|
||||
name + " | gzip > " + filename
|
||||
mw.execShell(cmd)
|
||||
|
||||
if not os.path.exists(filename):
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
#https://dev.mysql.com/downloads/file/?id=480541
|
||||
# https://mariadb.org/download/?t=mariadb
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
@@ -22,8 +21,8 @@ Install_app()
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql UID is `id -u www`"
|
||||
echo "mysql Shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
echo "mysql uid is `id -u www`"
|
||||
echo "mysql shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
@@ -52,20 +51,22 @@ Install_app()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
# https://mirrors.aliyun.com/mariadb/mariadb-10.8.3/source/mariadb-10.8.3.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
|
||||
fi
|
||||
# fi
|
||||
|
||||
# https://downloads.mariadb.org/interstitial/mariadb-10.6.8/source/mariadb-10.6.8.tar.gz
|
||||
if [ "$?" != "0" ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
@@ -106,12 +107,14 @@ Install_app()
|
||||
echo '10.6' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
echo '安装失败' > $install_tmp
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.7.5
|
||||
MY_VER=10.7.4
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -22,8 +22,8 @@ Install_app()
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql UID is `id -u www`"
|
||||
echo "mysql Shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
echo "mysql uid is `id -u www`"
|
||||
echo "mysql shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
@@ -52,17 +52,20 @@ Install_app()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# fi
|
||||
|
||||
if [ "$?" != "0" ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# https://downloads.mariadb.org/interstitial/mariadb-10.7.4/source/mariadb-10.7.4.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
@@ -91,12 +94,14 @@ Install_app()
|
||||
echo '10.7' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
echo '安装失败' > $install_tmp
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.8.4
|
||||
MY_VER=10.8.5
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -22,8 +22,8 @@ Install_app()
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql UID is `id -u www`"
|
||||
echo "mysql Shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
echo "mysql uid is `id -u www`"
|
||||
echo "mysql shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
@@ -52,17 +52,19 @@ Install_app()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# fi
|
||||
|
||||
if [ "$?" != "0" ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
@@ -92,12 +94,14 @@ Install_app()
|
||||
echo '10.8' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
echo '安装失败' > $install_tmp
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
#https://dev.mysql.com/downloads/file/?id=480541
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=10.9.2
|
||||
|
||||
Install_app()
|
||||
{
|
||||
mkdir -p ${mariadbDir}
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u www`"
|
||||
echo "mysql shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
if [ "$sysName" != "Darwin" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ -f /proc/cpuinfo ];then
|
||||
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
|
||||
fi
|
||||
|
||||
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
|
||||
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
|
||||
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
|
||||
cpuCore="${MEM_INFO}"
|
||||
fi
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
# if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
# wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
# fi
|
||||
|
||||
# https://downloads.mariadb.org/interstitial/mariadb-10.9.1/source/mariadb-10.9.1.tar.gz
|
||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://archive.mariadb.org/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
||||
-DMYSQL_USER=mysql \
|
||||
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
|
||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
||||
-DENABLED_LOCAL_INFILE=1 \
|
||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
||||
-DEXTRA_CHARSETS=all \
|
||||
-DDEFAULT_CHARSET=utf8mb4 \
|
||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
||||
-DCMAKE_C_COMPILER=/usr/bin/gcc \
|
||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
||||
make -j${cpuCore} && make install && make clean
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.9' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
@@ -1,242 +0,0 @@
|
||||
# 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 'memcached'
|
||||
|
||||
|
||||
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 getConf():
|
||||
path = getServerDir() + "/init.d/memcached"
|
||||
return path
|
||||
|
||||
|
||||
def getConfTpl():
|
||||
path = getPluginDir() + "/init.d/memcached.tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getMemPort():
|
||||
path = getConf()
|
||||
content = mw.readFile(path)
|
||||
rep = 'PORT\s*=\s*(\d*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0]
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
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
|
||||
|
||||
|
||||
def status():
|
||||
data = mw.execShell(
|
||||
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getConfTpl()
|
||||
service_path = mw.getServerDir()
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/memcached'
|
||||
|
||||
if not os.path.exists(file_bin):
|
||||
content = mw.readFile(file_tpl)
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
mw.writeFile(file_bin, content)
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def memOp(method):
|
||||
file = initDreplace()
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def start():
|
||||
return memOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return memOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
return memOp('restart')
|
||||
|
||||
|
||||
def reload():
|
||||
return memOp('reload')
|
||||
|
||||
|
||||
def runInfo():
|
||||
# 获取memcached状态
|
||||
import telnetlib
|
||||
import re
|
||||
port = getMemPort()
|
||||
try:
|
||||
tn = telnetlib.Telnet('127.0.0.1', int(port))
|
||||
tn.write(b"stats\n")
|
||||
tn.write(b"quit\n")
|
||||
data = tn.read_all()
|
||||
if type(data) == bytes:
|
||||
data = data.decode('utf-8')
|
||||
data = data.replace('STAT', '').replace('END', '').split("\n")
|
||||
result = {}
|
||||
res = ['cmd_get', 'get_hits', 'get_misses', 'limit_maxbytes', 'curr_items', 'bytes',
|
||||
'evictions', 'limit_maxbytes', 'bytes_written', 'bytes_read', 'curr_connections']
|
||||
for d in data:
|
||||
if len(d) < 3:
|
||||
continue
|
||||
t = d.split()
|
||||
if not t[0] in res:
|
||||
continue
|
||||
result[t[0]] = int(t[1])
|
||||
result['hit'] = 1
|
||||
if result['get_hits'] > 0 and result['cmd_get'] > 0:
|
||||
result['hit'] = float(result['get_hits']) / \
|
||||
float(result['cmd_get']) * 100
|
||||
|
||||
conf = mw.readFile(getConf())
|
||||
result['bind'] = re.search('IP=(.+)', conf).groups()[0]
|
||||
result['port'] = int(re.search('PORT=(\d+)', conf).groups()[0])
|
||||
result['maxconn'] = int(re.search('MAXCONN=(\d+)', conf).groups()[0])
|
||||
result['cachesize'] = int(
|
||||
re.search('CACHESIZE=(\d+)', conf).groups()[0])
|
||||
return mw.getJson(result)
|
||||
except Exception as e:
|
||||
return mw.getJson({})
|
||||
|
||||
|
||||
def saveConf():
|
||||
# 设置memcached缓存大小
|
||||
import re
|
||||
confFile = getConf()
|
||||
# print confFile
|
||||
try:
|
||||
args = getArgs()
|
||||
content = mw.readFile(confFile)
|
||||
content = re.sub('IP=.+', 'IP=' + args['ip'], content)
|
||||
content = re.sub('PORT=\d+', 'PORT=' + args['port'], content)
|
||||
content = re.sub('MAXCONN=\d+', 'MAXCONN=' + args['maxconn'], content)
|
||||
content = re.sub('CACHESIZE=\d+', 'CACHESIZE=' +
|
||||
args['cachesize'], content)
|
||||
mw.writeFile(confFile, content)
|
||||
restart()
|
||||
return 'save ok'
|
||||
except Exception as e:
|
||||
pass
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdStatus():
|
||||
if not app_debug:
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
return 'fail'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
import shutil
|
||||
if not app_debug:
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mem_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(mem_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
mw.execShell('chkconfig --add ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
if not app_debug:
|
||||
if mw.isAppleSystem():
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('chkconfig --del ' + getPluginName())
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
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 == '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 == 'conf_tpl':
|
||||
print(getConfTpl())
|
||||
elif func == 'save_conf':
|
||||
print(saveConf())
|
||||
else:
|
||||
print('fail')
|
||||
@@ -18,7 +18,7 @@ Install_mem(){
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
if [ ! -f $serverPath/source/memcached.tar.gz ];then
|
||||
wget -O $serverPath/source/memcached.tar.gz http://www.memcached.org/files/memcached-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O $serverPath/source/memcached.tar.gz http://www.memcached.org/files/memcached-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
cd $serverPath/source && tar -zxvf memcached.tar.gz
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[mysqld]
|
||||
# SHOW GLOBAL VARIABLES LIKE '%gtid%'
|
||||
gtid_mode=ON
|
||||
enforce_gtid_consistency=ON
|
||||
@@ -0,0 +1,101 @@
|
||||
[client]
|
||||
user = root
|
||||
#password = your_password
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
default-character-set = UTF8MB4
|
||||
|
||||
[mysqld]
|
||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
||||
|
||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
||||
user = mysql
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
default_storage_engine = InnoDB
|
||||
language={$SERVER_APP_PATH}/bin/usr/share/mysql/english
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
net_buffer_length = 4K
|
||||
read_buffer_size = 128K
|
||||
read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=0
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
query_cache_type = 1
|
||||
query_cache_size = 64M
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
max_allowed_packet = 128M
|
||||
|
||||
#skip-external-locking
|
||||
#skip-grant-tables
|
||||
#loose-skip-innodb
|
||||
#skip-networking
|
||||
#skip-name-resolve
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
expire_logs_days=30
|
||||
#log_queries_not_using_indexes=on
|
||||
|
||||
relay-log=mdserver
|
||||
relay-log-index=mdserver
|
||||
|
||||
#master
|
||||
#binlog-do-db
|
||||
binlog-ignore-db = test
|
||||
binlog-ignore-db = mysql
|
||||
binlog-ignore-db = information_schema
|
||||
binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log-slave-updates
|
||||
#replicate-do-db
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_buffer_pool_size = 16M
|
||||
innodb_log_file_size = 5M
|
||||
innodb_log_buffer_size = 8M
|
||||
innodb_flush_log_at_trx_commit = 1
|
||||
innodb_lock_wait_timeout = 120
|
||||
innodb_max_dirty_pages_pct = 90
|
||||
innodb_read_io_threads = 1
|
||||
innodb_write_io_threads = 1
|
||||
innodb_file_per_table=1
|
||||
|
||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[myisamchk]
|
||||
key_buffer_size = 20M
|
||||
sort_buffer_size = 20M
|
||||
read_buffer = 2M
|
||||
write_buffer = 2M
|
||||
|
||||
[mysqlhotcopy]
|
||||
interactive-timeout
|
||||
@@ -0,0 +1,100 @@
|
||||
[client]
|
||||
user = root
|
||||
#password = your_password
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
default-character-set = UTF8MB4
|
||||
|
||||
[mysqld]
|
||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
||||
|
||||
authentication_policy=mysql_native_password
|
||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
||||
user = mysql
|
||||
port = 33206
|
||||
mysqlx_port = 33260
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
default_storage_engine = InnoDB
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
net_buffer_length = 4K
|
||||
read_buffer_size = 128K
|
||||
read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=1
|
||||
tmp_table_size = 8M
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
max_allowed_packet = 128M
|
||||
|
||||
#skip-external-locking
|
||||
#skip-grant-tables
|
||||
#loose-skip-innodb
|
||||
#skip-networking
|
||||
#skip-name-resolve
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
#log_queries_not_using_indexes=on
|
||||
|
||||
relay-log=mdserver
|
||||
relay-log-index=mdserver
|
||||
|
||||
#master
|
||||
#binlog-do-db
|
||||
binlog-ignore-db = test
|
||||
binlog-ignore-db = mysql
|
||||
binlog-ignore-db = information_schema
|
||||
binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log_replica_updates
|
||||
#replicate-do-db
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_buffer_pool_size = 16M
|
||||
innodb_redo_log_capacity=10485760
|
||||
innodb_log_buffer_size = 8M
|
||||
innodb_flush_log_at_trx_commit = 1
|
||||
innodb_lock_wait_timeout = 120
|
||||
innodb_max_dirty_pages_pct = 90
|
||||
innodb_read_io_threads = 1
|
||||
innodb_write_io_threads = 1
|
||||
innodb_file_per_table=1
|
||||
binlog_expire_logs_seconds=2592000
|
||||
|
||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[myisamchk]
|
||||
key_buffer_size = 20M
|
||||
sort_buffer_size = 20M
|
||||
read_buffer = 2M
|
||||
write_buffer = 2M
|
||||
|
||||
[mysqlhotcopy]
|
||||
interactive-timeout
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
CREATE TABLE IF NOT EXISTS `config` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`mysql_root` TEXT
|
||||
);
|
||||
|
||||
INSERT INTO `config` (`id`, `mysql_root`) VALUES (1, 'admin');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `databases` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`pid` INTEGER,
|
||||
`name` TEXT,
|
||||
`username` TEXT,
|
||||
`password` TEXT,
|
||||
`accept` TEXT,
|
||||
`rw` TEXT DEFAULT 'rw',
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
-- ALTER TABLE `databases` ADD COLUMN `rw` TEXT DEFAULT 'rw';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `master_replication_user` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`username` TEXT,
|
||||
`password` TEXT,
|
||||
`accept` TEXT,
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
-- 从库配置主库的[ssh private key]
|
||||
-- drop table `slave_id_rsa`;
|
||||
CREATE TABLE IF NOT EXISTS `slave_id_rsa` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`ip` TEXT,
|
||||
`port` TEXT,
|
||||
`user` TEXT,
|
||||
`db_user` TEXT,
|
||||
`id_rsa` TEXT,
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Executable
+57
@@ -0,0 +1,57 @@
|
||||
<div class="bt-form">
|
||||
<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>
|
||||
<p class="bgw" onclick="pluginService('mysql-apt', $('.plugin_version').attr('version'));">服务</p>
|
||||
<p onclick="pluginInitD('mysql-apt', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="pluginConfig('mysql-apt', $('.plugin_version').attr('version'));">配置文件</p>
|
||||
<p onclick="myDbPos();">存储位置</p>
|
||||
<p onclick="myPort();">端口</p>
|
||||
<p onclick="runInfo();">当前状态</p>
|
||||
<p onclick="myPerfOpt();">性能优化</p>
|
||||
<p onclick="myLogs();">日志</p>
|
||||
<p onclick="pluginLogs('mysql-apt',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
.db_list{
|
||||
padding: 0px 0 10px 0;
|
||||
font-size: 13px;
|
||||
line-height: 35px;
|
||||
height: 45px;
|
||||
}
|
||||
.db_list a{
|
||||
margin-right: 15px;
|
||||
color: #555;
|
||||
font-weight: 600;
|
||||
}
|
||||
.db_list span:nth-child(1){
|
||||
display: block;
|
||||
float: left;
|
||||
padding-left: 15px;
|
||||
background: #ececec;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#db_tools button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
#db_tools button:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(800);
|
||||
$.getScript( "/plugins/file?name=mysql-apt&f=js/mysql-apt.js", function(){
|
||||
pluginService('mysql-apt',$('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+2522
File diff suppressed because it is too large
Load Diff
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"title":"MySQL[APT]",
|
||||
"tip":"soft",
|
||||
"name":"mysql-apt",
|
||||
"type":"运行环境",
|
||||
"ps":"[<b style='color:red;'>潜龙勿用</b>]一种关系数据库管理系统[debian,ubuntu](极速安装)",
|
||||
"todo_versions":["5.7","8.0"],
|
||||
"versions":["5.7","8.0"],
|
||||
"shell":"install.sh",
|
||||
"install_pre_inspection":true,
|
||||
"checks":"server/mysql-apt",
|
||||
"path":"server/mysql-apt",
|
||||
"author":"mysql",
|
||||
"home":"https://dev.mysql.com/downloads/mysql",
|
||||
"date":"2022-06-29",
|
||||
"pid": "6"
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# Copyright (c) 2015, 2022, Oracle and/or its affiliates.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License, version 2.0,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is also distributed with certain software (including
|
||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
||||
# as designated in a particular file or component or in included license
|
||||
# documentation. The authors of MySQL hereby grant you an additional
|
||||
# permission to link the program and your derivative works with the
|
||||
# separately licensed software that they have included with MySQL.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License, version 2.0, for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# MySQL systemd service file
|
||||
|
||||
[Unit]
|
||||
Description=MySQL Community Server
|
||||
After=network.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
User=mysql
|
||||
Group=mysql
|
||||
Type=forking
|
||||
PermissionsStartOnly=true
|
||||
#ExecStartPre=/usr/share/mysql/mysql-systemd-start pre
|
||||
ExecStart={$SERVER_PATH}/mysql-apt/bin/usr/sbin/mysqld --defaults-file={$SERVER_PATH}/mysql-apt/etc/my.cnf --daemonize
|
||||
TimeoutSec=600
|
||||
LimitNOFILE = 5000
|
||||
Restart=on-failure
|
||||
RestartPreventExitStatus=1
|
||||
RuntimeDirectory=mysqld
|
||||
RuntimeDirectoryMode=755
|
||||
@@ -0,0 +1,50 @@
|
||||
# Copyright (c) 2015, 2022, Oracle and/or its affiliates.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License, version 2.0,
|
||||
# as published by the Free Software Foundation.
|
||||
#
|
||||
# This program is also distributed with certain software (including
|
||||
# but not limited to OpenSSL) that is licensed under separate terms,
|
||||
# as designated in a particular file or component or in included license
|
||||
# documentation. The authors of MySQL hereby grant you an additional
|
||||
# permission to link the program and your derivative works with the
|
||||
# separately licensed software that they have included with MySQL.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License, version 2.0, for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
# MySQL systemd service file
|
||||
|
||||
[Unit]
|
||||
Description=MySQL Community Server
|
||||
Documentation=man:mysqld(8)
|
||||
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
|
||||
After=network.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
User=mysql
|
||||
Group=mysql
|
||||
Type=notify
|
||||
#ExecStartPre=+/usr/share/mysql-8.0/mysql-systemd-start pre
|
||||
ExecStart={$SERVER_PATH}/mysql-apt/bin/usr/sbin/mysqld --defaults-file={$SERVER_PATH}/mysql-apt/etc/my.cnf
|
||||
TimeoutSec=0
|
||||
LimitNOFILE = 10000
|
||||
Restart=on-failure
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
# Always restart when mysqld exits with exit code of 16. This special exit code
|
||||
# is used by mysqld for RESTART SQL.
|
||||
RestartForceExitStatus=16
|
||||
|
||||
# Set enviroment variable MYSQLD_PARENT_PID. This is required for restart.
|
||||
Environment=MYSQLD_PARENT_PID=1
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/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")
|
||||
|
||||
# https://downloads.mysql.com/archives/community/
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/mysql-apt && bash install.sh install 8.0
|
||||
# cd /www/server/mdserver-web/plugins/mysql-apt && bash install.sh uninstall 8.0
|
||||
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mysql-apt/index.py start 8.0
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
action=$1
|
||||
type=$2
|
||||
|
||||
|
||||
if [ "${2}" == "" ];then
|
||||
echo '缺少安装脚本...' > $install_tmp
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d $curPath/versions/$2 ];then
|
||||
echo '缺少安装脚本2...' > $install_tmp
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${action}" == "uninstall" ];then
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-apt/index.py stop ${type}
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-apt/index.py initd_uninstall ${type}
|
||||
cd $curPath
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mysql-apt.service ] || [ -f /lib/systemd/system/mysql-apt.service ];then
|
||||
systemctl stop mysql-apt
|
||||
systemctl disable mysql-apt
|
||||
rm -rf /usr/lib/systemd/system/mysql-apt.service
|
||||
rm -rf /lib/systemd/system/mysql-apt.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
fi
|
||||
|
||||
sh -x $curPath/versions/$2/install.sh $1
|
||||
|
||||
if [ "${action}" == "install" ];then
|
||||
# #初始化
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-apt/index.py start ${type}
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-apt/index.py initd_install ${type}
|
||||
fi
|
||||
Executable
+2207
File diff suppressed because it is too large
Load Diff
Executable
+126
@@ -0,0 +1,126 @@
|
||||
# coding: utf-8
|
||||
#-----------------------------
|
||||
# 网站备份工具
|
||||
#-----------------------------
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
os.chdir('/www/server/mdserver-web')
|
||||
|
||||
|
||||
chdir = os.getcwd()
|
||||
sys.path.append(chdir + '/class/core')
|
||||
|
||||
# reload(sys)
|
||||
# sys.setdefaultencoding('utf-8')
|
||||
|
||||
|
||||
import mw
|
||||
import db
|
||||
import time
|
||||
import re
|
||||
|
||||
'''
|
||||
DEBUG:
|
||||
python3 /www/server/mdserver-web/plugins/mysql-apt/scripts/backup.py database admin 3
|
||||
'''
|
||||
|
||||
|
||||
class backupTools:
|
||||
|
||||
def backupDatabase(self, name, count):
|
||||
db_path = mw.getServerDir() + '/mysql-apt'
|
||||
db_name = 'mysql'
|
||||
find_name = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('name')
|
||||
startTime = time.time()
|
||||
if not find_name:
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
log = "数据库[" + name + "]不存在!"
|
||||
print("★[" + endDate + "] " + log)
|
||||
print(
|
||||
"----------------------------------------------------------------------------")
|
||||
return
|
||||
|
||||
backup_path = mw.getRootDir() + '/backup/database'
|
||||
if not os.path.exists(backup_path):
|
||||
mw.execShell("mkdir -p " + backup_path)
|
||||
|
||||
filename = backup_path + "/db_" + name + "_" + \
|
||||
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
|
||||
|
||||
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
|
||||
"id=?", (1,)).getField('mysql_root')
|
||||
|
||||
my_conf_path = db_path + '/etc/my.cnf'
|
||||
mycnf = mw.readFile(my_conf_path)
|
||||
rep = "\[mysqldump\]\nuser=root"
|
||||
sea = "[mysqldump]\n"
|
||||
subStr = sea + "user=root\npassword=" + mysql_root + "\n"
|
||||
mycnf = mycnf.replace(sea, subStr)
|
||||
if len(mycnf) > 100:
|
||||
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
|
||||
|
||||
cmd = db_path + "/bin/usr/bin/mysqldump --defaults-file=" + my_conf_path + " --single-transaction --quick --default-character-set=utf8 " + \
|
||||
name + " | gzip > " + filename
|
||||
mw.execShell(cmd)
|
||||
|
||||
if not os.path.exists(filename):
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
log = "数据库[" + name + "]备份失败!"
|
||||
print("★[" + endDate + "] " + log)
|
||||
print(
|
||||
"----------------------------------------------------------------------------")
|
||||
return
|
||||
|
||||
mycnf = mw.readFile(db_path + '/etc/my.cnf')
|
||||
mycnf = mycnf.replace(subStr, sea)
|
||||
if len(mycnf) > 100:
|
||||
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
|
||||
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
outTime = time.time() - startTime
|
||||
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(
|
||||
filename), pid, filename, endDate, os.path.getsize(filename)))
|
||||
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
|
||||
mw.writeLog('计划任务', log)
|
||||
print("★[" + endDate + "] " + log)
|
||||
print("|---保留最新的[" + count + "]份备份")
|
||||
print("|---文件名:" + filename)
|
||||
|
||||
# 清理多余备份
|
||||
backups = mw.M('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
|
||||
num = len(backups) - int(count)
|
||||
if num > 0:
|
||||
for backup in backups:
|
||||
mw.execShell("rm -f " + backup['filename'])
|
||||
mw.M('backup').where('id=?', (backup['id'],)).delete()
|
||||
num -= 1
|
||||
print("|---已清理过期备份文件:" + backup['filename'])
|
||||
if num < 1:
|
||||
break
|
||||
|
||||
def backupDatabaseAll(self, save):
|
||||
db_path = mw.getServerDir() + '/mysql-apt'
|
||||
db_name = 'mysql'
|
||||
databases = mw.M('databases').dbPos(
|
||||
db_path, db_name).field('name').select()
|
||||
for database in databases:
|
||||
self.backupDatabase(database['name'], save)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
backup = backupTools()
|
||||
type = sys.argv[1]
|
||||
if type == 'database':
|
||||
if sys.argv[2] == 'ALL':
|
||||
backup.backupDatabaseAll(sys.argv[3])
|
||||
else:
|
||||
backup.backupDatabase(sys.argv[2], sys.argv[3])
|
||||
Executable
+123
@@ -0,0 +1,123 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# https://downloads.mysql.com/archives/community/
|
||||
|
||||
# debug
|
||||
# cd /www/server/mdserver-web/plugins/mysql-apt && bash install.sh install 8.0
|
||||
# /www/server/mysql-apt/bin/usr/sbin/mysqld --defaults-file=/www/server/mysql-apt/etc/my.cnf --daemonize
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
myDir=${serverPath}/source/mysql-apt
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
MYSQL_VER=5.7.39
|
||||
if [ "$OSNAME" == "debian" ];then
|
||||
# mysql5.7现在仅有10的编译版
|
||||
VERSION_ID="10"
|
||||
fi
|
||||
|
||||
if [ "$OSNAME" == "ubuntu" ];then
|
||||
# mysql5.7现在仅有18.04的编译版
|
||||
VERSION_ID="18.04"
|
||||
fi
|
||||
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_amd64
|
||||
|
||||
APT_INSTALL()
|
||||
{
|
||||
########
|
||||
mkdir -p $myDir
|
||||
mkdir -p $serverPath/mysql-apt/bin
|
||||
|
||||
wget --no-check-certificate -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-5.7/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
chmod +x ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
cd ${myDir} && tar vxf ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
|
||||
apt update -y
|
||||
apt install -y libnuma1 libaio1 libmecab2
|
||||
|
||||
# 安装
|
||||
dpkg -X mysql-common_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
|
||||
dpkg -X mysql-community-client-plugins_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-community-client-core_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-community-client_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-client_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
dpkg -X mysql-community-server-core_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
dpkg -X mysql-community-server_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-server_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
# rm -rf $myDir
|
||||
#######
|
||||
}
|
||||
|
||||
APT_UNINSTALL()
|
||||
{
|
||||
###
|
||||
rm -rf $myDir
|
||||
# apt remove -y mysql-server
|
||||
###
|
||||
}
|
||||
|
||||
|
||||
Install_mysql()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u mysql`"
|
||||
echo "mysql shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_INSTALL
|
||||
fi
|
||||
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/mysql-apt
|
||||
echo '5.7' > $serverPath/mysql-apt/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo "暂时不支持该系统" > $install_tmp
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_UNINSTALL
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/mysql-apt
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_mysql
|
||||
else
|
||||
Uninstall_mysql
|
||||
fi
|
||||
Executable
+116
@@ -0,0 +1,116 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# https://downloads.mysql.com/archives/community/
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
myDir=${serverPath}/source/mysql-apt
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/mysql-apt && bash install.sh install 8.0
|
||||
|
||||
MYSQL_VER=8.0.30
|
||||
SUFFIX_NAME=${MYSQL_VER}-1${OSNAME}${VERSION_ID}_amd64
|
||||
|
||||
|
||||
# /lib/systemd/system/mysql.service
|
||||
# /etc/mysql/my.cnf
|
||||
|
||||
APT_INSTALL()
|
||||
{
|
||||
########
|
||||
mkdir -p $myDir
|
||||
mkdir -p $serverPath/mysql-apt/bin
|
||||
|
||||
wget --no-check-certificate -O ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar https://cdn.mysql.com/archives/mysql-8.0/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
chmod +x ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
cd ${myDir} && tar vxf ${myDir}/mysql-server_${SUFFIX_NAME}.deb-bundle.tar
|
||||
|
||||
apt update -y
|
||||
apt install -y libnuma1 libaio1 libmecab2
|
||||
|
||||
# 安装
|
||||
dpkg -X mysql-common_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
|
||||
|
||||
dpkg -X mysql-community-client-plugins_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-community-client-core_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-community-client_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-client_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
dpkg -X mysql-community-server-core_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
dpkg -X mysql-community-server_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
dpkg -X mysql-server_${SUFFIX_NAME}.deb $serverPath/mysql-apt/bin
|
||||
|
||||
# rm -rf $myDir
|
||||
#######
|
||||
}
|
||||
|
||||
APT_UNINSTALL()
|
||||
{
|
||||
###
|
||||
rm -rf $myDir
|
||||
# apt remove -y mysql-server
|
||||
###
|
||||
}
|
||||
|
||||
|
||||
Install_mysql()
|
||||
{
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u mysql`"
|
||||
echo "mysql shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_INSTALL
|
||||
fi
|
||||
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/mysql-apt
|
||||
echo '8.0' > $serverPath/mysql-apt/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo "暂时不支持该系统" > $install_tmp
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
|
||||
isApt=`which apt`
|
||||
if [ "$isApt" != "" ];then
|
||||
APT_UNINSTALL
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/mysql-apt
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_mysql
|
||||
else
|
||||
Uninstall_mysql
|
||||
fi
|
||||
@@ -0,0 +1,4 @@
|
||||
[mysqld]
|
||||
# SHOW GLOBAL VARIABLES LIKE '%gtid%'
|
||||
gtid_mode=ON
|
||||
enforce_gtid_consistency=ON
|
||||
@@ -0,0 +1,102 @@
|
||||
[client]
|
||||
user = root
|
||||
#password = your_password
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
default-character-set = UTF8MB4
|
||||
|
||||
[mysqld]
|
||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
||||
|
||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
||||
user = mysql
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
default_storage_engine = InnoDB
|
||||
language={$SERVER_APP_PATH}/bin/usr/share/mysql/english
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
net_buffer_length = 4K
|
||||
read_buffer_size = 128K
|
||||
read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=0
|
||||
tmp_table_size = 8M
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
query_cache_type = 1
|
||||
query_cache_size = 64M
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
max_allowed_packet = 128M
|
||||
|
||||
#skip-external-locking
|
||||
#skip-grant-tables
|
||||
#loose-skip-innodb
|
||||
#skip-networking
|
||||
#skip-name-resolve
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
expire_logs_days=30
|
||||
#log_queries_not_using_indexes=on
|
||||
|
||||
relay-log=mdserver
|
||||
relay-log-index=mdserver
|
||||
|
||||
#master
|
||||
#binlog-do-db
|
||||
binlog-ignore-db = test
|
||||
binlog-ignore-db = mysql
|
||||
binlog-ignore-db = information_schema
|
||||
binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log-slave-updates
|
||||
#replicate-do-db
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_buffer_pool_size = 16M
|
||||
innodb_log_file_size = 5M
|
||||
innodb_log_buffer_size = 8M
|
||||
innodb_flush_log_at_trx_commit = 1
|
||||
innodb_lock_wait_timeout = 120
|
||||
innodb_max_dirty_pages_pct = 90
|
||||
innodb_read_io_threads = 1
|
||||
innodb_write_io_threads = 1
|
||||
innodb_file_per_table=1
|
||||
|
||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[myisamchk]
|
||||
key_buffer_size = 20M
|
||||
sort_buffer_size = 20M
|
||||
read_buffer = 2M
|
||||
write_buffer = 2M
|
||||
|
||||
[mysqlhotcopy]
|
||||
interactive-timeout
|
||||
@@ -0,0 +1,100 @@
|
||||
[client]
|
||||
user = root
|
||||
#password = your_password
|
||||
port = 33206
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
default-character-set = UTF8MB4
|
||||
|
||||
[mysqld]
|
||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
||||
|
||||
authentication_policy=mysql_native_password
|
||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
||||
user = mysql
|
||||
port = 33206
|
||||
mysqlx_port = 33260
|
||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
||||
datadir = {$SERVER_APP_PATH}/data
|
||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
||||
default_storage_engine = InnoDB
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
net_buffer_length = 4K
|
||||
read_buffer_size = 128K
|
||||
read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=1
|
||||
tmp_table_size = 8M
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
max_allowed_packet = 128M
|
||||
|
||||
#skip-external-locking
|
||||
#skip-grant-tables
|
||||
#loose-skip-innodb
|
||||
#skip-networking
|
||||
#skip-name-resolve
|
||||
|
||||
log-bin=mysql-bin
|
||||
binlog_format=mixed
|
||||
server-id = 1
|
||||
slow_query_log=1
|
||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
||||
long_query_time=3
|
||||
#log_queries_not_using_indexes=on
|
||||
|
||||
relay-log=mdserver
|
||||
relay-log-index=mdserver
|
||||
|
||||
#master
|
||||
#binlog-do-db
|
||||
binlog-ignore-db = test
|
||||
binlog-ignore-db = mysql
|
||||
binlog-ignore-db = information_schema
|
||||
binlog-ignore-db = performance_schema
|
||||
|
||||
#slave
|
||||
log_replica_updates
|
||||
#replicate-do-db
|
||||
replicate-ignore-db = information_schema
|
||||
replicate-ignore-db = performance_schema
|
||||
replicate-ignore-db = mysql
|
||||
replicate-ignore-db = test
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_data_file_path = ibdata1:10M:autoextend
|
||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
||||
innodb_buffer_pool_size = 16M
|
||||
innodb_redo_log_capacity=10485760
|
||||
innodb_log_buffer_size = 8M
|
||||
innodb_flush_log_at_trx_commit = 1
|
||||
innodb_lock_wait_timeout = 120
|
||||
innodb_max_dirty_pages_pct = 90
|
||||
innodb_read_io_threads = 1
|
||||
innodb_write_io_threads = 1
|
||||
innodb_file_per_table=1
|
||||
binlog_expire_logs_seconds=2592000
|
||||
|
||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
||||
|
||||
[mysqldump]
|
||||
quick
|
||||
|
||||
[mysql]
|
||||
no-auto-rehash
|
||||
|
||||
[myisamchk]
|
||||
key_buffer_size = 20M
|
||||
sort_buffer_size = 20M
|
||||
read_buffer = 2M
|
||||
write_buffer = 2M
|
||||
|
||||
[mysqlhotcopy]
|
||||
interactive-timeout
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
CREATE TABLE IF NOT EXISTS `config` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`mysql_root` TEXT
|
||||
);
|
||||
|
||||
INSERT INTO `config` (`id`, `mysql_root`) VALUES (1, 'admin');
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `databases` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`pid` INTEGER,
|
||||
`name` TEXT,
|
||||
`username` TEXT,
|
||||
`password` TEXT,
|
||||
`accept` TEXT,
|
||||
`rw` TEXT DEFAULT 'rw',
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
-- ALTER TABLE `databases` ADD COLUMN `rw` TEXT DEFAULT 'rw';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `master_replication_user` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`username` TEXT,
|
||||
`password` TEXT,
|
||||
`accept` TEXT,
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
-- 从库配置主库的[ssh private key]
|
||||
-- drop table `slave_id_rsa`;
|
||||
CREATE TABLE IF NOT EXISTS `slave_id_rsa` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`ip` TEXT,
|
||||
`port` TEXT,
|
||||
`user` TEXT,
|
||||
`db_user` TEXT,
|
||||
`id_rsa` TEXT,
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Executable
+57
@@ -0,0 +1,57 @@
|
||||
<div class="bt-form">
|
||||
<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> -->
|
||||
<p class="bgw" onclick="pluginService('mysql-yum', $('.plugin_version').attr('version'));">服务</p>
|
||||
<p onclick="pluginInitD('mysql-yum', $('.plugin_version').attr('version'));">自启动</p>
|
||||
<p onclick="pluginConfig('mysql-yum', $('.plugin_version').attr('version'));">配置文件</p>
|
||||
<p onclick="myDbPos();">存储位置</p>
|
||||
<p onclick="myPort();">端口</p>
|
||||
<p onclick="runInfo();">当前状态</p>
|
||||
<p onclick="myPerfOpt();">性能优化</p>
|
||||
<p onclick="myLogs();">日志</p>
|
||||
<p onclick="pluginLogs('mysql-yum',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
|
||||
<p onclick="dbList()">管理列表</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<style type="text/css">
|
||||
.db_list{
|
||||
padding: 0px 0 10px 0;
|
||||
font-size: 13px;
|
||||
line-height: 35px;
|
||||
height: 45px;
|
||||
}
|
||||
.db_list a{
|
||||
margin-right: 15px;
|
||||
color: #555;
|
||||
font-weight: 600;
|
||||
}
|
||||
.db_list span:nth-child(1){
|
||||
display: block;
|
||||
float: left;
|
||||
padding-left: 15px;
|
||||
background: #ececec;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#db_tools button {
|
||||
margin-right: 10px;
|
||||
}
|
||||
#db_tools button:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinWidth(800);
|
||||
$.getScript( "/plugins/file?name=mysql-yum&f=js/mysql-yum.js", function(){
|
||||
pluginService('mysql-yum',$('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+2495
File diff suppressed because it is too large
Load Diff
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"title":"MySQL[YUM]",
|
||||
"tip":"soft",
|
||||
"name":"mysql-yum",
|
||||
"type":"运行环境",
|
||||
"ps":"[<b style='color:red;'>潜龙勿用</b>]一种关系数据库管理系统[centos](极速安装)",
|
||||
"todo_versions":["5.7","8.0"],
|
||||
"versions":["5.7","8.0"],
|
||||
"shell":"install.sh",
|
||||
"install_pre_inspection":true,
|
||||
"checks":"server/mysql-yum",
|
||||
"path":"server/mysql-yum",
|
||||
"author":"mysql",
|
||||
"home":"https://dev.mysql.com/downloads/mysql",
|
||||
"date":"2022-06-29",
|
||||
"pid": "6"
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
# It's not recommended to modify this file in-place, because it will be
|
||||
# overwritten during package upgrades. If you want to customize, the
|
||||
# best way is to use systemctl edit:
|
||||
#
|
||||
# $ systemctl edit mysqld.service
|
||||
#
|
||||
# this will create file
|
||||
#
|
||||
# /etc/systemd/system/mysqld.service.d/override.conf
|
||||
#
|
||||
# which be parsed after the file mysqld.service itself is parsed.
|
||||
#
|
||||
# For example, if you want to increase mysql's open-files-limit to 20000
|
||||
# add following when editing with command above:
|
||||
#
|
||||
# [Service]
|
||||
# LimitNOFILE=20000
|
||||
#
|
||||
# Or if you require to execute pre and post scripts in the unit file as root, set
|
||||
# PermissionsStartOnly=true
|
||||
#
|
||||
# For more info about custom unit files, see systemd.unit(5) or
|
||||
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
|
||||
#
|
||||
# Don't forget to reload systemd daemon after you change unit configuration:
|
||||
# root> systemctl --system daemon-reload
|
||||
|
||||
[Unit]
|
||||
Description=MySQL 5.7 database server
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
User=mysql
|
||||
Group=mysql
|
||||
|
||||
#ExecStartPre=/usr/libexec/mysql-check-socket
|
||||
#ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
|
||||
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
|
||||
# per bug #547485
|
||||
ExecStart={$SERVER_PATH}/mysql-yum/bin/usr/sbin/mysqld --defaults-file={$SERVER_PATH}/mysql-yum/etc/my.cnf --basedir={$SERVER_PATH}/mysql-yum/bin/usr --daemonize
|
||||
#ExecStartPost=/usr/libexec/mysql-check-upgrade
|
||||
#ExecStopPost=/usr/libexec/mysql-wait-stop
|
||||
|
||||
# Give a reasonable amount of time for the server to start up/shut down
|
||||
TimeoutSec=300
|
||||
|
||||
# Place temp files in a secure directory, not /tmp
|
||||
PrivateTmp=false
|
||||
|
||||
Restart=on-failure
|
||||
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
# Sets open_files_limit
|
||||
LimitNOFILE = 10000
|
||||
|
||||
# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.
|
||||
Environment=MYSQLD_PARENT_PID=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,63 @@
|
||||
# It's not recommended to modify this file in-place, because it will be
|
||||
# overwritten during package upgrades. If you want to customize, the
|
||||
# best way is to use systemctl edit:
|
||||
#
|
||||
# $ systemctl edit mysqld.service
|
||||
#
|
||||
# this will create file
|
||||
#
|
||||
# /etc/systemd/system/mysqld.service.d/override.conf
|
||||
#
|
||||
# which be parsed after the file mysqld.service itself is parsed.
|
||||
#
|
||||
# For example, if you want to increase mysql's open-files-limit to 20000
|
||||
# add following when editing with command above:
|
||||
#
|
||||
# [Service]
|
||||
# LimitNOFILE=20000
|
||||
#
|
||||
# Or if you require to execute pre and post scripts in the unit file as root, set
|
||||
# PermissionsStartOnly=true
|
||||
#
|
||||
# For more info about custom unit files, see systemd.unit(5) or
|
||||
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
|
||||
#
|
||||
# Don't forget to reload systemd daemon after you change unit configuration:
|
||||
# root> systemctl --system daemon-reload
|
||||
|
||||
[Unit]
|
||||
Description=MySQL 8.0 database server
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
User=mysql
|
||||
Group=mysql
|
||||
|
||||
#ExecStartPre=/usr/libexec/mysql-check-socket
|
||||
#ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
|
||||
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
|
||||
# per bug #547485
|
||||
ExecStart={$SERVER_PATH}/mysql-yum/bin/usr/sbin/mysqld --defaults-file={$SERVER_PATH}/mysql-yum/etc/my.cnf --basedir={$SERVER_PATH}/mysql-yum/bin/usr --user=mysql
|
||||
#ExecStartPost=/usr/libexec/mysql-check-upgrade
|
||||
#ExecStopPost=/usr/libexec/mysql-wait-stop
|
||||
|
||||
# Give a reasonable amount of time for the server to start up/shut down
|
||||
TimeoutSec=300
|
||||
|
||||
# Place temp files in a secure directory, not /tmp
|
||||
PrivateTmp=false
|
||||
|
||||
Restart=on-failure
|
||||
|
||||
RestartPreventExitStatus=1
|
||||
|
||||
# Sets open_files_limit
|
||||
LimitNOFILE = 10000
|
||||
|
||||
# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.
|
||||
Environment=MYSQLD_PARENT_PID=1
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/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/mysql-yum && bash install.sh install 8.0
|
||||
# cd /www/server/mdserver-web/plugins/mysql-yum && bash install.sh uninstall 8.0
|
||||
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mysql-yum/index.py start 8.0
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
|
||||
action=$1
|
||||
type=$2
|
||||
|
||||
|
||||
|
||||
if [ "${2}" == "" ];then
|
||||
echo '缺少安装脚本...' > $install_tmp
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d $curPath/versions/$2 ];then
|
||||
echo '缺少安装脚本2...' > $install_tmp
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${action}" == "uninstall" ];then
|
||||
|
||||
cd ${rootPath} && python3 plugins/mysql-yum/index.py stop ${type}
|
||||
cd ${rootPath} && python3 plugins/mysql-yum/index.py initd_uninstall ${type}
|
||||
cd $curPath
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mysql-yum.service ] || [ -f /lib/systemd/system/mysql-yum.service ];then
|
||||
systemctl stop mysql-yum
|
||||
systemctl disable mysql-yum
|
||||
rm -rf /usr/lib/systemd/system/mysql-yum.service
|
||||
rm -rf /lib/systemd/system/mysql-yum.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
fi
|
||||
|
||||
sh -x $curPath/versions/$2/install.sh $1
|
||||
|
||||
if [ "${action}" == "install" ];then
|
||||
# #初始化
|
||||
cd ${rootPath} && python3 plugins/mysql-yum/index.py start ${type}
|
||||
cd ${rootPath} && python3 plugins/mysql-yum/index.py initd_install ${type}
|
||||
fi
|
||||
Executable
+2207
File diff suppressed because it is too large
Load Diff
Executable
+124
@@ -0,0 +1,124 @@
|
||||
# coding: utf-8
|
||||
#-----------------------------
|
||||
# 网站备份工具
|
||||
#-----------------------------
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
if sys.platform != 'darwin':
|
||||
os.chdir('/www/server/mdserver-web')
|
||||
|
||||
|
||||
chdir = os.getcwd()
|
||||
sys.path.append(chdir + '/class/core')
|
||||
|
||||
# reload(sys)
|
||||
# sys.setdefaultencoding('utf-8')
|
||||
|
||||
|
||||
import mw
|
||||
import db
|
||||
import time
|
||||
import re
|
||||
|
||||
'''
|
||||
DEBUG:
|
||||
python3 /www/server/mdserver-web/plugins/mysql-yum/scripts/backup.py database admin 3
|
||||
'''
|
||||
|
||||
|
||||
class backupTools:
|
||||
|
||||
def backupDatabase(self, name, count):
|
||||
db_path = mw.getServerDir() + '/mysql-yum'
|
||||
db_name = 'mysql'
|
||||
find_name = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('name')
|
||||
startTime = time.time()
|
||||
if not find_name:
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
log = "数据库[" + name + "]不存在!"
|
||||
print("★[" + endDate + "] " + log)
|
||||
print(
|
||||
"----------------------------------------------------------------------------")
|
||||
return
|
||||
|
||||
backup_path = mw.getRootDir() + '/backup/database'
|
||||
if not os.path.exists(backup_path):
|
||||
mw.execShell("mkdir -p " + backup_path)
|
||||
|
||||
filename = backup_path + "/db_" + name + "_" + \
|
||||
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
|
||||
|
||||
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
|
||||
"id=?", (1,)).getField('mysql_root')
|
||||
|
||||
my_cnf = db_path + '/etc/my.cnf'
|
||||
|
||||
mw.backFile(my_cnf)
|
||||
content = mw.readFile(my_cnf)
|
||||
rep = "\[mysqldump\]\nuser=root"
|
||||
sea = "[mysqldump]\n"
|
||||
subStr = sea + "user=root\npassword=" + mysql_root + "\n"
|
||||
content = content.replace(sea, subStr)
|
||||
if len(content) > 100:
|
||||
mw.writeFile(my_cnf, content)
|
||||
|
||||
cmd = db_path + "/bin/usr/bin/mysqldump --defaults-file=" + my_cnf + " --single-transaction --quick --default-character-set=utf8 " + \
|
||||
name + " | gzip > " + filename
|
||||
mw.execShell(cmd)
|
||||
|
||||
mw.restoreFile(my_cnf)
|
||||
if not os.path.exists(filename):
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
log = "数据库[" + name + "]备份失败!"
|
||||
print("★[" + endDate + "] " + log)
|
||||
print(
|
||||
"----------------------------------------------------------------------------")
|
||||
return
|
||||
|
||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
||||
outTime = time.time() - startTime
|
||||
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(
|
||||
filename), pid, filename, endDate, os.path.getsize(filename)))
|
||||
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
|
||||
mw.writeLog('计划任务', log)
|
||||
print("★[" + endDate + "] " + log)
|
||||
print("|---保留最新的[" + count + "]份备份")
|
||||
print("|---文件名:" + filename)
|
||||
|
||||
# 清理多余备份
|
||||
backups = mw.M('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
|
||||
num = len(backups) - int(count)
|
||||
if num > 0:
|
||||
for backup in backups:
|
||||
mw.execShell("rm -f " + backup['filename'])
|
||||
mw.M('backup').where('id=?', (backup['id'],)).delete()
|
||||
num -= 1
|
||||
print("|---已清理过期备份文件:" + backup['filename'])
|
||||
if num < 1:
|
||||
break
|
||||
|
||||
def backupDatabaseAll(self, save):
|
||||
db_path = mw.getServerDir() + '/mysql-yum'
|
||||
db_name = 'mysql'
|
||||
databases = mw.M('databases').dbPos(
|
||||
db_path, db_name).field('name').select()
|
||||
for database in databases:
|
||||
self.backupDatabase(database['name'], save)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
backup = backupTools()
|
||||
stype = sys.argv[1]
|
||||
if stype == 'database':
|
||||
if sys.argv[2] == 'ALL':
|
||||
backup.backupDatabaseAll(sys.argv[3])
|
||||
else:
|
||||
backup.backupDatabase(sys.argv[2], sys.argv[3])
|
||||
Executable
+121
@@ -0,0 +1,121 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# https://downloads.mysql.com/archives/community/
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
myDir=${serverPath}/source/mysql-yum
|
||||
|
||||
ARCH=`uname -m`
|
||||
ARCH_NAME=''
|
||||
case $(uname -m) in
|
||||
i386) ARCH_NAME="386" ;;
|
||||
i686) ARCH_NAME="386" ;;
|
||||
x86_64) ARCH_NAME="amd64" ;;
|
||||
arm) ARCH_NAME="arm64" ;;
|
||||
esac
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
echo "VERSION_ID:${VERSION_ID}"
|
||||
|
||||
if [ "$OSNAME" == "centos" ] && [ "$VERSION_ID" -gt "7" ]; then
|
||||
VERSION_ID=7
|
||||
fi
|
||||
|
||||
OS_SIGN=1.el9
|
||||
if [ "$OSNAME" == "centos" ];then
|
||||
OS_SIGN=1.el${VERSION_ID}
|
||||
elif [ "$OSNAME" == "fedora" ]; then
|
||||
OS_SIGN=10.fc${VERSION_ID}
|
||||
elif [ "$OSNAME" == "suse" ]; then
|
||||
OS_SIGN=1.sl${VERSION_ID}
|
||||
fi
|
||||
|
||||
MYSQL_VER=5.7.39
|
||||
SUFFIX_NAME=${MYSQL_VER}-${OS_SIGN}.${ARCH}
|
||||
|
||||
YUM_INSTALL()
|
||||
{
|
||||
|
||||
#######
|
||||
mkdir -p $myDir
|
||||
|
||||
wget --no-check-certificate -O $myDir/mysql-${SUFFIX_NAME}.rpm-bundle.tar https://cdn.mysql.com/archives/mysql-5.7/mysql-${SUFFIX_NAME}.rpm-bundle.tar
|
||||
cd ${myDir} && tar vxf mysql-${SUFFIX_NAME}.rpm-bundle.tar
|
||||
|
||||
mkdir -p ${serverPath}/mysql-yum/bin && cd ${serverPath}/mysql-yum/bin
|
||||
|
||||
rpm2cpio ${myDir}/mysql-community-client-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-common-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-devel-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-embedded-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-embedded-compat-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-embedded-devel-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-libs-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-libs-compat-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-server-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-test-${SUFFIX_NAME}.rpm | cpio -div
|
||||
|
||||
#######
|
||||
}
|
||||
|
||||
YUM_UNINSTALL()
|
||||
{
|
||||
### YUM卸载 START ########
|
||||
# yum -y remove mysql-server
|
||||
rm -rf ${myDir}
|
||||
### YUM卸载 END ########
|
||||
}
|
||||
|
||||
|
||||
Install_mysql()
|
||||
{
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u mysql`"
|
||||
echo "mysql shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
isYum=`which yum`
|
||||
if [ "$isYum" != "" ];then
|
||||
YUM_INSTALL
|
||||
fi
|
||||
|
||||
|
||||
mkdir -p $serverPath/mysql-yum
|
||||
echo '5.7' > $serverPath/mysql-yum/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
isYum=`which yum`
|
||||
if [ "$isYum" != "" ];then
|
||||
YUM_UNINSTALL
|
||||
fi
|
||||
rm -rf $serverPath/mysql-yum
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_mysql
|
||||
else
|
||||
Uninstall_mysql
|
||||
fi
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# https://downloads.mysql.com/archives/community/
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
sysName=`uname`
|
||||
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
myDir=${serverPath}/source/mysql-yum
|
||||
|
||||
ARCH=`uname -m`
|
||||
ARCH_NAME=''
|
||||
case $(uname -m) in
|
||||
i386) ARCH_NAME="386" ;;
|
||||
i686) ARCH_NAME="386" ;;
|
||||
x86_64) ARCH_NAME="amd64" ;;
|
||||
arm) ARCH_NAME="arm64" ;;
|
||||
esac
|
||||
|
||||
bash ${rootPath}/scripts/getos.sh
|
||||
OSNAME=`cat ${rootPath}/data/osname.pl`
|
||||
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
|
||||
echo "VERSION_ID:${VERSION_ID}"
|
||||
|
||||
OS_SIGN=1.el9
|
||||
if [ "$OSNAME" == "centos" ];then
|
||||
OS_SIGN=1.el${VERSION_ID}
|
||||
elif [ "$OSNAME" == "fedora" ]; then
|
||||
OS_SIGN=10.fc${VERSION_ID}
|
||||
elif [ "$OSNAME" == "suse" ]; then
|
||||
OS_SIGN=1.sl${VERSION_ID}
|
||||
fi
|
||||
|
||||
MYSQL_VER=8.0.30
|
||||
SUFFIX_NAME=${MYSQL_VER}-${OS_SIGN}.${ARCH}
|
||||
|
||||
YUM_INSTALL()
|
||||
{
|
||||
|
||||
#######
|
||||
mkdir -p $myDir
|
||||
|
||||
wget --no-check-certificate -O $myDir/mysql-${SUFFIX_NAME}.rpm-bundle.tar https://cdn.mysql.com/archives/mysql-8.0/mysql-${SUFFIX_NAME}.rpm-bundle.tar
|
||||
cd ${myDir} && tar vxf mysql-${SUFFIX_NAME}.rpm-bundle.tar
|
||||
|
||||
mkdir -p ${serverPath}/mysql-yum/bin && cd ${serverPath}/mysql-yum/bin
|
||||
|
||||
rpm2cpio ${myDir}/mysql-community-client-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-client-${SUFFIX_NAME}.x86_64.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-common-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-debuginfo-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-devel-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-embedded-compat-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-icu-data-files-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-libs-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-libs-compat-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-server-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-server-debug-${SUFFIX_NAME}.rpm | cpio -div
|
||||
rpm2cpio ${myDir}/mysql-community-test-${SUFFIX_NAME}.rpm | cpio -div
|
||||
|
||||
#######
|
||||
}
|
||||
|
||||
YUM_UNINSTALL()
|
||||
{
|
||||
### YUM卸载 START ########
|
||||
# yum -y remove mysql-server
|
||||
rm -rf ${myDir}
|
||||
### YUM卸载 END ########
|
||||
}
|
||||
|
||||
|
||||
Install_mysql()
|
||||
{
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
if id mysql &> /dev/null ;then
|
||||
echo "mysql uid is `id -u mysql`"
|
||||
echo "mysql shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd mysql
|
||||
useradd -g mysql mysql
|
||||
fi
|
||||
|
||||
isYum=`which yum`
|
||||
if [ "$isYum" != "" ];then
|
||||
YUM_INSTALL
|
||||
fi
|
||||
|
||||
|
||||
|
||||
mkdir -p $serverPath/mysql-yum
|
||||
echo '8.0' > $serverPath/mysql-yum/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
Uninstall_mysql()
|
||||
{
|
||||
isYum=`which yum`
|
||||
if [ "$isYum" != "" ];then
|
||||
YUM_UNINSTALL
|
||||
fi
|
||||
rm -rf $serverPath/mysql-yum
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_mysql
|
||||
else
|
||||
Uninstall_mysql
|
||||
fi
|
||||
@@ -29,9 +29,12 @@ read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=0
|
||||
query_cache_size = 4M
|
||||
tmp_table_size = 8M
|
||||
|
||||
|
||||
query_cache_type = 1
|
||||
query_cache_size = 64M
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 65535
|
||||
|
||||
@@ -32,9 +32,11 @@ read_rnd_buffer_size = 256K
|
||||
myisam_sort_buffer_size = 4M
|
||||
thread_cache_size = 4
|
||||
lower_case_table_names=0
|
||||
query_cache_size = 4M
|
||||
tmp_table_size = 8M
|
||||
|
||||
query_cache_type = 1
|
||||
query_cache_size = 64M
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 65535
|
||||
|
||||
@@ -22,6 +22,7 @@ server-id = {$SERVER_ID}
|
||||
|
||||
default_storage_engine = InnoDB
|
||||
|
||||
|
||||
key_buffer_size = 8M
|
||||
table_open_cache = 32
|
||||
sort_buffer_size = 256K
|
||||
@@ -34,6 +35,9 @@ lower_case_table_names=0
|
||||
tmp_table_size = 8M
|
||||
character-set-server = UTF8MB4
|
||||
|
||||
query_cache_type = 1
|
||||
query_cache_size = 64M
|
||||
|
||||
max_connections = 500
|
||||
max_connect_errors = 100
|
||||
open_files_limit = 2560
|
||||
|
||||
+261
-109
@@ -92,6 +92,14 @@ def getSocketFile():
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getErrorLogsFile():
|
||||
file = getConf()
|
||||
content = mw.readFile(file)
|
||||
rep = 'log-error\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0].strip()
|
||||
|
||||
|
||||
def getInitdTpl(version=''):
|
||||
path = getPluginDir() + '/init.d/mysql' + version + '.tpl'
|
||||
if not os.path.exists(path):
|
||||
@@ -319,15 +327,7 @@ def setSkipGrantTables(v):
|
||||
|
||||
def getErrorLog():
|
||||
args = getArgs()
|
||||
path = getDataDir()
|
||||
filename = ''
|
||||
for n in os.listdir(path):
|
||||
if len(n) < 5:
|
||||
continue
|
||||
if n == 'error.log':
|
||||
filename = path + '/' + n
|
||||
break
|
||||
# print filename
|
||||
filename = getErrorLogsFile()
|
||||
if not os.path.exists(filename):
|
||||
return mw.returnJson(False, '指定文件不存在!')
|
||||
if 'close' in args:
|
||||
@@ -406,22 +406,21 @@ def initMysqlPwd():
|
||||
serverdir = getServerDir()
|
||||
myconf = serverdir + "/etc/my.cnf"
|
||||
pwd = mw.getRandomString(16)
|
||||
# cmd_pass = serverdir + '/bin/mysqladmin -uroot password ' + pwd
|
||||
|
||||
# cmd_pass = "insert into mysql.user(Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,Event_priv,Trigger_priv,Create_tablespace_priv,User,Password,host)values('Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','root',password('" + pwd + "'),'127.0.0.1')"
|
||||
# cmd_pass = cmd_pass + \
|
||||
# "insert into mysql.user(Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,Event_priv,Trigger_priv,Create_tablespace_priv,User,Password,host)values('Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','root',password('" + pwd + "'),'localhost')"
|
||||
# cmd_pass = cmd_pass + \
|
||||
# "UPDATE mysql.user SET password=PASSWORD('" + \
|
||||
# pwd + "') WHERE user='root'"
|
||||
cmd_pass = serverdir + '/bin/mysql -uroot -e'
|
||||
cmd_pass = cmd_pass + "\"UPDATE mysql.user SET password=PASSWORD('" + \
|
||||
cmd_pass = serverdir + '/bin/mysql --defaults-file=' + myconf + ' -uroot -e'
|
||||
cmd_pass = cmd_pass + \
|
||||
'"UPDATE mysql.user SET password=PASSWORD(\'' + \
|
||||
pwd + "') WHERE user='root';"
|
||||
cmd_pass = cmd_pass + "flush privileges;\""
|
||||
cmd_pass = cmd_pass + 'flush privileges;"'
|
||||
data = mw.execShell(cmd_pass)
|
||||
# print(cmd_pass)
|
||||
# print(data)
|
||||
|
||||
# 删除空账户
|
||||
drop_empty_user = serverdir + '/bin/mysql -uroot -p' + \
|
||||
pwd + ' -e "use mysql;delete from user where USER=\'\'"'
|
||||
mw.execShell(drop_empty_user)
|
||||
|
||||
# 删除测试数据库
|
||||
drop_test_db = serverdir + '/bin/mysql -uroot -p' + \
|
||||
pwd + ' -e "drop database test";'
|
||||
@@ -429,14 +428,14 @@ def initMysqlPwd():
|
||||
|
||||
# 删除冗余账户
|
||||
hostname = mw.execShell('hostname')[0].strip()
|
||||
if hostname != 'localhost':
|
||||
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
|
||||
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_hostname)
|
||||
|
||||
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
|
||||
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
|
||||
mw.execShell(drop_root_hostname)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
return True
|
||||
@@ -681,14 +680,18 @@ def setMyPort():
|
||||
return mw.returnJson(True, '编辑成功!')
|
||||
|
||||
|
||||
def runInfo():
|
||||
def runInfo(version):
|
||||
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动', [])
|
||||
|
||||
db = pMysqlDb()
|
||||
data = db.query('show global status')
|
||||
gets = ['Max_used_connections', 'Com_commit', 'Com_rollback', 'Questions', 'Innodb_buffer_pool_reads', 'Innodb_buffer_pool_read_requests', 'Key_reads', 'Key_read_requests', 'Key_writes',
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
return isError
|
||||
|
||||
gets = ['Max_used_connections', 'Com_commit', 'Com_select', 'Com_rollback', 'Questions', 'Innodb_buffer_pool_reads', 'Innodb_buffer_pool_read_requests', 'Key_reads', 'Key_read_requests', 'Key_writes',
|
||||
'Key_write_requests', 'Qcache_hits', 'Qcache_inserts', 'Bytes_received', 'Bytes_sent', 'Aborted_clients', 'Aborted_connects',
|
||||
'Created_tmp_disk_tables', 'Created_tmp_tables', 'Innodb_buffer_pool_pages_dirty', 'Opened_files', 'Open_tables', 'Opened_tables', 'Select_full_join',
|
||||
'Select_range_check', 'Sort_merge_passes', 'Table_locks_waited', 'Threads_cached', 'Threads_connected', 'Threads_created', 'Threads_running', 'Connections', 'Uptime']
|
||||
@@ -713,7 +716,7 @@ def runInfo():
|
||||
return mw.getJson(result)
|
||||
|
||||
|
||||
def myDbStatus():
|
||||
def myDbStatus(version):
|
||||
result = {}
|
||||
db = pMysqlDb()
|
||||
data = db.query('show variables')
|
||||
@@ -723,6 +726,10 @@ def myDbStatus():
|
||||
|
||||
gets = ['table_open_cache', 'thread_cache_size', 'key_buffer_size', 'tmp_table_size', 'max_heap_table_size', 'innodb_buffer_pool_size',
|
||||
'innodb_additional_mem_pool_size', 'innodb_log_buffer_size', 'max_connections', 'sort_buffer_size', 'read_buffer_size', 'read_rnd_buffer_size', 'join_buffer_size', 'thread_stack', 'binlog_cache_size']
|
||||
|
||||
if version != "8.0":
|
||||
gets.append('query_cache_size')
|
||||
|
||||
result['mem'] = {}
|
||||
for d in data:
|
||||
vname = d['Variable_name']
|
||||
@@ -733,9 +740,16 @@ def myDbStatus():
|
||||
return mw.getJson(result)
|
||||
|
||||
|
||||
def setDbStatus():
|
||||
def setDbStatus(version):
|
||||
gets = ['key_buffer_size', 'tmp_table_size', 'max_heap_table_size', 'innodb_buffer_pool_size', 'innodb_log_buffer_size', 'max_connections',
|
||||
'table_open_cache', 'thread_cache_size', 'sort_buffer_size', 'read_buffer_size', 'read_rnd_buffer_size', 'join_buffer_size', 'thread_stack', 'binlog_cache_size']
|
||||
|
||||
if version != "8.0":
|
||||
# gets.append('query_cache_size')
|
||||
gets = ['key_buffer_size', 'query_cache_size', 'tmp_table_size', 'max_heap_table_size', 'innodb_buffer_pool_size', 'innodb_log_buffer_size', 'max_connections',
|
||||
'table_open_cache', 'thread_cache_size', 'sort_buffer_size', 'read_buffer_size', 'read_rnd_buffer_size', 'join_buffer_size', 'thread_stack', 'binlog_cache_size']
|
||||
|
||||
# print(gets)
|
||||
emptys = ['max_connections', 'thread_cache_size', 'table_open_cache']
|
||||
args = getArgs()
|
||||
conFile = getConf()
|
||||
@@ -768,7 +782,7 @@ def isSqlError(mysqlMsg):
|
||||
if "2003," in 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, '数据库管理密码错误!')
|
||||
return mw.returnJson(False, '数据库密码错误,在管理列表-点击【修复】!')
|
||||
if "1045" in mysqlMsg:
|
||||
return mw.returnJson(False, '连接错误!')
|
||||
if "SQL syntax" in mysqlMsg:
|
||||
@@ -822,11 +836,77 @@ def setDbBackup():
|
||||
|
||||
scDir = mw.getRunDir() + '/scripts/backup.py'
|
||||
|
||||
cmd = 'python ' + scDir + ' database ' + args['name'] + ' 3'
|
||||
cmd = 'python3 ' + scDir + ' database ' + args['name'] + ' 3'
|
||||
os.system(cmd)
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
def importDbExternal():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
file = args['file']
|
||||
name = args['name']
|
||||
|
||||
import_dir = mw.getRootDir() + '/backup/import/'
|
||||
|
||||
file_path = import_dir + file
|
||||
if not os.path.exists(file_path):
|
||||
return mw.returnJson(False, '文件突然消失?')
|
||||
|
||||
exts = ['sql', 'gz', 'zip']
|
||||
ext = mw.getFileSuffix(file)
|
||||
if ext not in exts:
|
||||
return mw.returnJson(False, '导入数据库格式不对!')
|
||||
|
||||
tmp = file.split('/')
|
||||
tmpFile = tmp[len(tmp) - 1]
|
||||
tmpFile = tmpFile.replace('.sql.' + ext, '.sql')
|
||||
tmpFile = tmpFile.replace('.' + ext, '.sql')
|
||||
tmpFile = tmpFile.replace('tar.', '')
|
||||
|
||||
# print(tmpFile)
|
||||
import_sql = ""
|
||||
if file.find("sql.gz") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && gzip -dc ' + \
|
||||
file + " > " + import_dir + tmpFile
|
||||
info = mw.execShell(cmd)
|
||||
if info[1] == "":
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find(".zip") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && unzip -o ' + file
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find("tar.gz") > -1:
|
||||
cmd = 'cd ' + import_dir + ' && tar -zxvf ' + file
|
||||
mw.execShell(cmd)
|
||||
import_sql = import_dir + tmpFile
|
||||
|
||||
if file.find(".sql") > -1 and file.find(".sql.gz") == -1:
|
||||
import_sql = import_dir + file
|
||||
|
||||
if import_sql == "":
|
||||
return mw.returnJson(False, '未找SQL文件')
|
||||
|
||||
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
|
||||
sock = getSocketFile()
|
||||
|
||||
os.environ["MYSQL_PWD"] = pwd
|
||||
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + \
|
||||
pwd + ' ' + name + ' < ' + import_sql
|
||||
|
||||
# print(mysql_cmd)
|
||||
os.system(mysql_cmd)
|
||||
if ext != 'sql':
|
||||
os.remove(import_sql)
|
||||
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
def importDbBackup():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
@@ -855,13 +935,17 @@ def importDbBackup():
|
||||
|
||||
def deleteDbBackup():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['filename'])
|
||||
data = checkArgs(args, ['filename', 'path'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
path = args['path']
|
||||
full_file = ""
|
||||
bkDir = mw.getRootDir() + '/backup/database'
|
||||
|
||||
os.remove(bkDir + '/' + args['filename'])
|
||||
full_file = bkDir + '/' + args['filename']
|
||||
if path != "":
|
||||
full_file = path + "/" + args['filename']
|
||||
os.remove(full_file)
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
@@ -893,6 +977,39 @@ def getDbBackupList():
|
||||
return mw.returnJson(True, 'ok', rr)
|
||||
|
||||
|
||||
def getDbBackupImportList():
|
||||
|
||||
bkImportDir = mw.getRootDir() + '/backup/import'
|
||||
if not os.path.exists(bkImportDir):
|
||||
os.mkdir(bkImportDir)
|
||||
|
||||
blist = os.listdir(bkImportDir)
|
||||
|
||||
rr = []
|
||||
for x in range(0, len(blist)):
|
||||
name = blist[x]
|
||||
p = bkImportDir + '/' + name
|
||||
data = {}
|
||||
data['name'] = name
|
||||
|
||||
rsize = os.path.getsize(p)
|
||||
data['size'] = mw.toSize(rsize)
|
||||
|
||||
t = os.path.getctime(p)
|
||||
t = time.localtime(t)
|
||||
|
||||
data['time'] = time.strftime('%Y-%m-%d %H:%M:%S', t)
|
||||
rr.append(data)
|
||||
|
||||
data['file'] = p
|
||||
|
||||
rdata = {
|
||||
"list": rr,
|
||||
"upload_dir": bkImportDir,
|
||||
}
|
||||
return mw.returnJson(True, 'ok', rdata)
|
||||
|
||||
|
||||
def getDbList():
|
||||
args = getArgs()
|
||||
page = 1
|
||||
@@ -1194,11 +1311,11 @@ def delDb():
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
try:
|
||||
id = args['id']
|
||||
sid = args['id']
|
||||
name = args['name']
|
||||
psdb = pSqliteDb('databases')
|
||||
pdb = pMysqlDb()
|
||||
find = psdb.where("id=?", (id,)).field(
|
||||
find = psdb.where("id=?", (sid,)).field(
|
||||
'id,pid,name,username,password,accept,ps,addtime').find()
|
||||
accept = find['accept']
|
||||
username = find['username']
|
||||
@@ -1214,7 +1331,7 @@ def delDb():
|
||||
pdb.execute("flush privileges")
|
||||
|
||||
# 删除SQLITE
|
||||
psdb.where("id=?", (id,)).delete()
|
||||
psdb.where("id=?", (sid,)).delete()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '删除失败!' + str(ex))
|
||||
@@ -1231,6 +1348,10 @@ def getDbAccess():
|
||||
users = pdb.query("select Host from mysql.user where User='" +
|
||||
username + "' AND Host!='localhost'")
|
||||
|
||||
isError = isSqlError(users)
|
||||
if isError != None:
|
||||
return isError
|
||||
|
||||
if len(users) < 1:
|
||||
return mw.returnJson(True, "127.0.0.1")
|
||||
accs = []
|
||||
@@ -1270,6 +1391,21 @@ def setDbAccess():
|
||||
return mw.returnJson(True, '设置成功!')
|
||||
|
||||
|
||||
def fixDbAccess(version):
|
||||
try:
|
||||
pdb = pMysqlDb()
|
||||
data = pdb.query('show databases')
|
||||
isError = isSqlError(data)
|
||||
if isError != None:
|
||||
appCMD(version, 'stop')
|
||||
mw.execShell("rm -rf " + getServerDir() + "/data")
|
||||
appCMD(version, 'start')
|
||||
return mw.returnJson(True, '修复成功!')
|
||||
return mw.returnJson(True, '正常无需修复!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '修复失败请重试!')
|
||||
|
||||
|
||||
def setDbRw(version=''):
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['username', 'id', 'rw'])
|
||||
@@ -1567,55 +1703,57 @@ def setDbMasterAccess():
|
||||
|
||||
|
||||
def getMasterDbList(version=''):
|
||||
args = getArgs()
|
||||
page = 1
|
||||
page_size = 10
|
||||
search = ''
|
||||
data = {}
|
||||
if 'page' in args:
|
||||
page = int(args['page'])
|
||||
try:
|
||||
args = getArgs()
|
||||
page = 1
|
||||
page_size = 10
|
||||
search = ''
|
||||
data = {}
|
||||
if 'page' in args:
|
||||
page = int(args['page'])
|
||||
|
||||
if 'page_size' in args:
|
||||
page_size = int(args['page_size'])
|
||||
if 'page_size' in args:
|
||||
page_size = int(args['page_size'])
|
||||
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
|
||||
conn = pSqliteDb('databases')
|
||||
limit = str((page - 1) * page_size) + ',' + str(page_size)
|
||||
condition = ''
|
||||
dodb = findBinlogDoDb()
|
||||
data['dodb'] = dodb
|
||||
conn = pSqliteDb('databases')
|
||||
limit = str((page - 1) * page_size) + ',' + str(page_size)
|
||||
condition = ''
|
||||
dodb = findBinlogDoDb()
|
||||
data['dodb'] = dodb
|
||||
|
||||
slave_dodb = findBinlogSlaveDoDb()
|
||||
slave_dodb = findBinlogSlaveDoDb()
|
||||
|
||||
if not search == '':
|
||||
condition = "name like '%" + search + "%'"
|
||||
field = 'id,pid,name,username,password,accept,ps,addtime'
|
||||
clist = conn.where(condition, ()).field(
|
||||
field).limit(limit).order('id desc').select()
|
||||
count = conn.where(condition, ()).count()
|
||||
if not search == '':
|
||||
condition = "name like '%" + search + "%'"
|
||||
field = 'id,pid,name,username,password,accept,ps,addtime'
|
||||
clist = conn.where(condition, ()).field(
|
||||
field).limit(limit).order('id desc').select()
|
||||
count = conn.where(condition, ()).count()
|
||||
|
||||
for x in range(0, len(clist)):
|
||||
if clist[x]['name'] in dodb:
|
||||
clist[x]['master'] = 1
|
||||
else:
|
||||
clist[x]['master'] = 0
|
||||
for x in range(0, len(clist)):
|
||||
if clist[x]['name'] in dodb:
|
||||
clist[x]['master'] = 1
|
||||
else:
|
||||
clist[x]['master'] = 0
|
||||
|
||||
if clist[x]['name'] in slave_dodb:
|
||||
clist[x]['slave'] = 1
|
||||
else:
|
||||
clist[x]['slave'] = 0
|
||||
if clist[x]['name'] in slave_dodb:
|
||||
clist[x]['slave'] = 1
|
||||
else:
|
||||
clist[x]['slave'] = 0
|
||||
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['p'] = page
|
||||
_page['row'] = page_size
|
||||
_page['tojs'] = 'dbList'
|
||||
data['page'] = mw.getPage(_page)
|
||||
data['data'] = clist
|
||||
|
||||
return mw.getJson(data)
|
||||
_page = {}
|
||||
_page['count'] = count
|
||||
_page['p'] = page
|
||||
_page['row'] = page_size
|
||||
_page['tojs'] = 'dbList'
|
||||
data['page'] = mw.getPage(_page)
|
||||
data['data'] = clist
|
||||
return mw.getJson(data)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "数据库密码错误,在管理列表-点击【修复】!")
|
||||
|
||||
|
||||
def setDbMaster(version):
|
||||
@@ -1681,29 +1819,32 @@ def setDbSlave(version):
|
||||
|
||||
def getMasterStatus(version=''):
|
||||
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动,或正在启动中...!', [])
|
||||
try:
|
||||
if status(version) == 'stop':
|
||||
return mw.returnJson(False, 'MySQL未启动,或正在启动中...!', [])
|
||||
|
||||
conf = getConf()
|
||||
content = mw.readFile(conf)
|
||||
master_status = False
|
||||
if content.find('#log-bin') == -1 and content.find('log-bin') > 1:
|
||||
dodb = findBinlogDoDb()
|
||||
if len(dodb) > 0:
|
||||
master_status = True
|
||||
conf = getConf()
|
||||
content = mw.readFile(conf)
|
||||
master_status = False
|
||||
if content.find('#log-bin') == -1 and content.find('log-bin') > 1:
|
||||
dodb = findBinlogDoDb()
|
||||
if len(dodb) > 0:
|
||||
master_status = True
|
||||
|
||||
data = {}
|
||||
data['mode'] = recognizeDbMode()
|
||||
data['status'] = master_status
|
||||
data = {}
|
||||
data['mode'] = recognizeDbMode()
|
||||
data['status'] = master_status
|
||||
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave status')
|
||||
db = pMysqlDb()
|
||||
dlist = db.query('show slave 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
|
||||
# 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
|
||||
|
||||
return mw.returnJson(master_status, '设置成功', data)
|
||||
return mw.returnJson(master_status, '设置成功', data)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "数据库密码错误,在管理列表-点击【修复】!", 'pwd')
|
||||
|
||||
|
||||
def setMasterStatus(version=''):
|
||||
@@ -2092,7 +2233,7 @@ def initSlaveStatus(version=''):
|
||||
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":""}'
|
||||
cmd = 'cd /www/server/mdserver-web && source bin/activate && 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')
|
||||
@@ -2113,11 +2254,11 @@ def initSlaveStatus(version=''):
|
||||
# 保证同步IP一致
|
||||
cmd = cmd_data['data']['cmd']
|
||||
if cmd.find('SOURCE_HOST') > -1:
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*)'",
|
||||
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
|
||||
"SOURCE_HOST='" + ip + "'", cmd, 1)
|
||||
|
||||
if cmd.find('MASTER_HOST') > -1:
|
||||
cmd = re.sub(r"MASTER_HOST='(.*)'",
|
||||
cmd = re.sub(r"MASTER_HOST='(.*?)'",
|
||||
"MASTER_HOST='" + ip + "'", cmd, 1)
|
||||
db.query(cmd)
|
||||
db.query("start slave user='{}' password='{}';".format(
|
||||
@@ -2177,11 +2318,12 @@ def dumpMysqlData(version=''):
|
||||
if args['db'].lower() == 'all':
|
||||
dlist = findBinlogDoDb()
|
||||
cmd = mysql_dir + "/bin/mysqldump --defaults-file=" + myconf + " " + option + " -uroot -p" + \
|
||||
pwd + " --databases " + \
|
||||
pwd + " --force --databases " + \
|
||||
' '.join(dlist) + " | gzip > /tmp/dump.sql.gz"
|
||||
else:
|
||||
cmd = mysql_dir + "/bin/mysqldump --defaults-file=" + myconf + " " + option + " -uroot -p" + \
|
||||
pwd + " --databases " + args['db'] + " | gzip > /tmp/dump.sql.gz"
|
||||
pwd + " --force --databases " + \
|
||||
args['db'] + " | gzip > /tmp/dump.sql.gz"
|
||||
|
||||
ret = mw.execShell(cmd)
|
||||
if ret[0] == '':
|
||||
@@ -2251,7 +2393,7 @@ def doFullSync(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 plugins/mysql/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
|
||||
print(cmd)
|
||||
stdin, stdout, stderr = ssh.exec_command(cmd)
|
||||
result = stdout.read()
|
||||
@@ -2274,7 +2416,7 @@ def doFullSync(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 plugins/mysql/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')
|
||||
@@ -2286,10 +2428,12 @@ def doFullSync(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']
|
||||
@@ -2303,6 +2447,8 @@ def doFullSync(version=''):
|
||||
mw.execShell("cd /tmp && gzip -d dump.sql.gz")
|
||||
cmd = root_dir + "/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])
|
||||
@@ -2396,11 +2542,11 @@ if __name__ == "__main__":
|
||||
elif func == 'uninstall_pre_inspection':
|
||||
print(uninstallPreInspection(version))
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
print(runInfo(version))
|
||||
elif func == 'db_status':
|
||||
print(myDbStatus())
|
||||
print(myDbStatus(version))
|
||||
elif func == 'set_db_status':
|
||||
print(setDbStatus())
|
||||
print(setDbStatus(version))
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'bin_log':
|
||||
@@ -2427,10 +2573,14 @@ if __name__ == "__main__":
|
||||
print(setDbBackup())
|
||||
elif func == 'import_db_backup':
|
||||
print(importDbBackup())
|
||||
elif func == 'import_db_external':
|
||||
print(importDbExternal())
|
||||
elif func == 'delete_db_backup':
|
||||
print(deleteDbBackup())
|
||||
elif func == 'get_db_backup_list':
|
||||
print(getDbBackupList())
|
||||
elif func == 'get_db_backup_import_list':
|
||||
print(getDbBackupImportList())
|
||||
elif func == 'add_db':
|
||||
print(addDb())
|
||||
elif func == 'del_db':
|
||||
@@ -2447,6 +2597,8 @@ if __name__ == "__main__":
|
||||
print(getDbAccess())
|
||||
elif func == 'set_db_access':
|
||||
print(setDbAccess())
|
||||
elif func == 'fix_db_access':
|
||||
print(fixDbAccess(version))
|
||||
elif func == 'set_db_rw':
|
||||
print(setDbRw(version))
|
||||
elif func == 'set_db_ps':
|
||||
|
||||
@@ -24,6 +24,10 @@ if [ ! -d $curPath/versions/$2 ];then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/mysql ];then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${action}" == "uninstall" ];then
|
||||
|
||||
if [ -f /usr/lib/systemd/system/mysql.service ] || [ -f /lib/systemd/system/mysql.service ];then
|
||||
|
||||
+253
-114
@@ -1,18 +1,9 @@
|
||||
function str2Obj(str){
|
||||
var data = {};
|
||||
kv = str.split('&');
|
||||
for(i in kv){
|
||||
v = kv[i].split('=');
|
||||
data[v[0]] = v[1];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function myPost(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -40,7 +31,7 @@ function myPostN(method,args,callback, title){
|
||||
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -59,7 +50,7 @@ function myPostN(method,args,callback, title){
|
||||
function myAsyncPost(method,args){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(str2Obj(args));
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
@@ -69,8 +60,7 @@ function myAsyncPost(method,args){
|
||||
}
|
||||
|
||||
function vaildPhpmyadmin(url,username,password){
|
||||
|
||||
console.log("Authorization: Basic " + btoa(username + ":" + password));
|
||||
// console.log("Authorization: Basic " + btoa(username + ":" + password));
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: url,
|
||||
@@ -97,6 +87,7 @@ function runInfo(){
|
||||
return;
|
||||
}
|
||||
|
||||
// Com_select , Qcache_inserts
|
||||
var cache_size = ((parseInt(rdata.Qcache_hits) / (parseInt(rdata.Qcache_hits) + parseInt(rdata.Qcache_inserts))) * 100).toFixed(2) + '%';
|
||||
if (cache_size == 'NaN%') cache_size = 'OFF';
|
||||
var Con = '<div class="divtable"><table class="table table-hover table-bordered" style="margin-bottom:10px;background-color:#fafafa">\
|
||||
@@ -204,6 +195,12 @@ function myPerfOpt() {
|
||||
//获取MySQL配置
|
||||
myPost('db_status','',function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if ( typeof(rdata.status) != 'undefined' && !rdata.status){
|
||||
layer.msg(rdata.msg, {icon:2});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// console.log(rdata);
|
||||
var key_buffer_size = toSizeM(rdata.mem.key_buffer_size);
|
||||
var query_cache_size = toSizeM(rdata.mem.query_cache_size);
|
||||
@@ -606,7 +603,7 @@ function setDbAccess(username){
|
||||
yes:function(index){
|
||||
var data = $("#set_db_access").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['access']){
|
||||
dataObj['access'] = dataObj['dataAccess'];
|
||||
if ( dataObj['dataAccess'] == 'ip'){
|
||||
@@ -631,9 +628,17 @@ function setDbAccess(username){
|
||||
});
|
||||
}
|
||||
|
||||
function setDbPass(id, username, password){
|
||||
function fixDbAccess(username){
|
||||
myPost('fix_db_access', '', function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
},{icon: rdata.status ? 1 : 2});
|
||||
});
|
||||
}
|
||||
|
||||
var index = layer.open({
|
||||
function setDbPass(id, username, password){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: '500px',
|
||||
title: '修改数据库密码',
|
||||
@@ -672,39 +677,21 @@ function setDbPass(id, username, password){
|
||||
}
|
||||
|
||||
function addDatabase(type){
|
||||
if (type==1){
|
||||
var data = $("#add_db").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
if(!dataObj['address']){
|
||||
dataObj['address'] = dataObj['dataAccess'];
|
||||
}
|
||||
myPost('add_db', dataObj, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
dbList();
|
||||
}
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2},600);
|
||||
});
|
||||
return;
|
||||
}
|
||||
var index = layer.open({
|
||||
layer.open({
|
||||
type: 1,
|
||||
skin: 'demo-class',
|
||||
area: '500px',
|
||||
title: '添加数据库',
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: true,
|
||||
content: "<form class='bt-form pd20 pb70' id='add_db'>\
|
||||
btn:["提交","关闭"],
|
||||
content: "<form class='bt-form pd20' id='add_db'>\
|
||||
<div class='line'>\
|
||||
<span class='tname'>数据库名</span>\
|
||||
<div class='info-r'><input name='name' class='bt-input-text mr5' placeholder='新的数据库名称' type='text' style='width:65%' value=''>\
|
||||
<select class='bt-input-text mr5 codeing_a5nGsm' name='codeing' style='width:27%'>\
|
||||
<option value='utf8'>utf-8</option>\
|
||||
<option value='utf8mb4'>utf8mb4</option>\
|
||||
<option value='utf8'>utf-8</option>\
|
||||
<option value='gbk'>gbk</option>\
|
||||
<option value='big5'>big5</option>\
|
||||
</select>\
|
||||
@@ -726,28 +713,39 @@ function addDatabase(type){
|
||||
</div>\
|
||||
</div>\
|
||||
<input type='hidden' name='ps' value='' />\
|
||||
<div class='bt-form-submit-btn'>\
|
||||
<button id='my_mod_close' type='button' class='btn btn-danger btn-sm btn-title'>关闭</button>\
|
||||
<button type='button' class='btn btn-success btn-sm btn-title' onclick=\"addDatabase(1)\" >提交</button>\
|
||||
</div>\
|
||||
</form>",
|
||||
});
|
||||
success:function(){
|
||||
$("input[name='name']").keyup(function(){
|
||||
var v = $(this).val();
|
||||
$("input[name='db_user']").val(v);
|
||||
$("input[name='ps']").val(v);
|
||||
});
|
||||
|
||||
$("input[name='name']").keyup(function(){
|
||||
var v = $(this).val();
|
||||
$("input[name='db_user']").val(v);
|
||||
$("input[name='ps']").val(v);
|
||||
});
|
||||
|
||||
$('#my_mod_close').click(function(){
|
||||
$('.layui-layer-close1').click();
|
||||
});
|
||||
$('select[name="dataAccess"]').change(function(){
|
||||
var v = $(this).val();
|
||||
if (v == 'ip'){
|
||||
$(this).after("<input id='dataAccess_subid' class='bt-input-text mr5' type='text' name='address' placeholder='多个IP使用逗号(,)分隔' style='width: 230px; display: inline-block;'>");
|
||||
} else {
|
||||
$('#dataAccess_subid').remove();
|
||||
$('select[name="dataAccess"]').change(function(){
|
||||
var v = $(this).val();
|
||||
if (v == 'ip'){
|
||||
$(this).after("<input id='dataAccess_subid' class='bt-input-text mr5' type='text' name='address' placeholder='多个IP使用逗号(,)分隔' style='width: 230px; display: inline-block;'>");
|
||||
} else {
|
||||
$('#dataAccess_subid').remove();
|
||||
}
|
||||
});
|
||||
},
|
||||
yes:function(index) {
|
||||
var data = $("#add_db").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['address']){
|
||||
dataObj['address'] = dataObj['dataAccess'];
|
||||
}
|
||||
myPost('add_db', dataObj, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(index);
|
||||
dbList();
|
||||
}
|
||||
},{icon: rdata.status ? 1 : 2},600);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -759,7 +757,6 @@ function delDb(id, name){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
dbList();
|
||||
$('.layui-layer-close1').click();
|
||||
},{icon: rdata.status ? 1 : 2}, 600);
|
||||
});
|
||||
});
|
||||
@@ -834,8 +831,8 @@ function openPhpmyadmin(name,username,password){
|
||||
|
||||
data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'get_cfg'});
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (rdata.choose == 'mariadb'){
|
||||
layer.msg('当前为[mariadb]模式,若要使用请切换模式.',{icon:2,shade: [0.3, '#000']});
|
||||
if (rdata.choose != 'mysql'){
|
||||
layer.msg('当前为['+rdata.choose+']模式,若要使用请切换模式.',{icon:2,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -881,12 +878,14 @@ function openPhpmyadmin(name,username,password){
|
||||
}
|
||||
}
|
||||
|
||||
function delBackup(filename,name){
|
||||
myPost('delete_db_backup',{filename:filename},function(){
|
||||
function delBackup(filename, name, path){
|
||||
if(typeof(path) == "undefined"){
|
||||
path = "";
|
||||
}
|
||||
myPost('delete_db_backup',{filename:filename,path:path},function(){
|
||||
layer.msg('执行成功!');
|
||||
setTimeout(function(){
|
||||
$('.layui-layer-close2').click();
|
||||
setBackup(name);
|
||||
setBackupReq(name);
|
||||
},2000);
|
||||
});
|
||||
}
|
||||
@@ -902,9 +901,182 @@ function importBackup(file,name){
|
||||
});
|
||||
}
|
||||
|
||||
function setBackup(db_name,obj){
|
||||
myPost('get_db_backup_list', {name:db_name}, function(data){
|
||||
|
||||
function importDbExternal(file,name){
|
||||
myPost('import_db_external',{file:file,name:name}, function(data){
|
||||
layer.msg('执行成功!');
|
||||
});
|
||||
}
|
||||
|
||||
function setLocalImport(db_name){
|
||||
|
||||
//上传文件
|
||||
function uploadDbFiles(upload_dir){
|
||||
var up_db = layer.open({
|
||||
type:1,
|
||||
closeBtn: 1,
|
||||
title:"上传导入文件["+upload_dir+']',
|
||||
area: ['500px','300px'],
|
||||
shadeClose:false,
|
||||
content:'<div class="fileUploadDiv">\
|
||||
<input type="hidden" id="input-val" value="'+upload_dir+'" />\
|
||||
<input type="file" id="file_input" multiple="true" autocomplete="off" />\
|
||||
<button type="button" id="opt" autocomplete="off">添加文件</button>\
|
||||
<button type="button" id="up" autocomplete="off" >开始上传</button>\
|
||||
<span id="totalProgress" style="position: absolute;top: 7px;right: 147px;"></span>\
|
||||
<span style="float:right;margin-top: 9px;">\
|
||||
<font>文件编码:</font>\
|
||||
<select id="fileCodeing" >\
|
||||
<option value="byte">二进制</option>\
|
||||
<option value="utf-8">UTF-8</option>\
|
||||
<option value="gb18030">GB2312</option>\
|
||||
</select>\
|
||||
</span>\
|
||||
<button type="button" id="filesClose" autocomplete="off">关闭</button>\
|
||||
<ul id="up_box"></ul>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$('#filesClose').click(function(){
|
||||
layer.close(up_db);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
uploadStart(function(){
|
||||
getList();
|
||||
layer.close(up_db);
|
||||
});
|
||||
}
|
||||
|
||||
function getList(){
|
||||
myPost('get_db_backup_import_list',{}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
var file_list = rdata.data.list;
|
||||
var upload_dir = rdata.data.upload_dir;
|
||||
|
||||
var tbody = '';
|
||||
for (var i = 0; i < file_list.length; i++) {
|
||||
tbody += '<tr>\
|
||||
<td><span> ' + file_list[i]['name'] + '</span></td>\
|
||||
<td><span> ' + file_list[i]['size'] + '</span></td>\
|
||||
<td><span> ' + file_list[i]['time'] + '</span></td>\
|
||||
<td style="text-align: right;">\
|
||||
<a class="btlink" onclick="importDbExternal(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
|
||||
<a class="btlink del" index="'+i+'">删除</a>\
|
||||
</td>\
|
||||
</tr>';
|
||||
}
|
||||
|
||||
$('#import_db_file_list').html(tbody);
|
||||
$('input[name="upload_dir"]').val(upload_dir);
|
||||
|
||||
$("#import_db_file_list .del").on('click',function(){
|
||||
var index = $(this).attr('index');
|
||||
var filename = file_list[index]["name"];
|
||||
myPost('delete_db_backup',{filename:filename,path:upload_dir},function(){
|
||||
showMsg('执行成功!', function(){
|
||||
getList();
|
||||
},{icon:1},2000);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
var layerIndex = layer.open({
|
||||
type: 1,
|
||||
title: "从文件导入数据",
|
||||
area: ['600px', '380px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<button id="btn_file_upload" class="btn btn-success btn-sm" type="button">从本地上传</button>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<input type="hidden" name="upload_dir" value=""> \
|
||||
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>文件大小</th>\
|
||||
<th>备份时间</th>\
|
||||
<th style="text-align: right;">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody id="import_db_file_list" class="gztr"></tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
<ul class="help-info-text c7">\
|
||||
<li>仅支持sql、zip、sql.gz、(tar.gz|gz|tgz)</li>\
|
||||
<li>zip、tar.gz压缩包结构:test.zip或test.tar.gz压缩包内,必需包含test.sql</li>\
|
||||
<li>若文件过大,您还可以使用SFTP工具,将数据库文件上传到/www/backup/import</li>\
|
||||
</ul>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(index){
|
||||
$('#btn_file_upload').click(function(){
|
||||
var upload_dir = $('input[name="upload_dir"]').val();
|
||||
uploadDbFiles(upload_dir);
|
||||
});
|
||||
|
||||
getList();
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
function setBackup(db_name){
|
||||
var layerIndex = layer.open({
|
||||
type: 1,
|
||||
title: "数据库备份详情",
|
||||
area: ['600px', '280px'],
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
|
||||
<button id="btn_local_import" class="btn btn-success btn-sm" type="button">外部导入</button>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table id="database_table" class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>文件大小</th>\
|
||||
<th>备份时间</th>\
|
||||
<th style="text-align: right;">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody class="list"></tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(index){
|
||||
$('#btn_backup').click(function(){
|
||||
myPost('set_db_backup',{name:db_name}, function(data){
|
||||
showMsg('执行成功!', function(){
|
||||
setBackupReq(db_name);
|
||||
}, {icon:1}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#btn_local_import').click(function(){
|
||||
setLocalImport(db_name);
|
||||
});
|
||||
|
||||
setBackupReq(db_name);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function setBackupReq(db_name, obj){
|
||||
myPost('get_db_backup_list', {name:db_name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var tbody = '';
|
||||
for (var i = 0; i < rdata.data.length; i++) {
|
||||
@@ -919,49 +1091,10 @@ function setBackup(db_name,obj){
|
||||
</td>\
|
||||
</tr> ';
|
||||
}
|
||||
|
||||
var s = layer.open({
|
||||
type: 1,
|
||||
title: "数据库备份详情",
|
||||
area: ['600px', '280px'],
|
||||
closeBtn: 2,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
|
||||
</div >\
|
||||
<div class="divtable">\
|
||||
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
|
||||
<table class="table table-hover "style="border:none">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>文件名称</th>\
|
||||
<th>文件大小</th>\
|
||||
<th>备份时间</th>\
|
||||
<th style="text-align: right;">操作</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody class="gztr">' + tbody + '</tbody>\
|
||||
</table>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>'
|
||||
});
|
||||
|
||||
$('#btn_backup').click(function(){
|
||||
myPost('set_db_backup',{name:db_name}, function(data){
|
||||
layer.msg('执行成功!');
|
||||
|
||||
setTimeout(function(){
|
||||
layer.close(s);
|
||||
setBackup(db_name,obj);
|
||||
},2000);
|
||||
});
|
||||
});
|
||||
$('#database_table tbody').html(tbody);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function dbList(page, search){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
@@ -1027,6 +1160,7 @@ function dbList(page, search){
|
||||
<button onclick="setRootPwd(0,\''+rdata.info['root_pwd']+'\')" title="设置MySQL管理员密码" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">root密码</button>\
|
||||
<button onclick="openPhpmyadmin(\'\',\'root\',\''+rdata.info['root_pwd']+'\')" title="打开phpMyadmin" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">phpMyAdmin</button>\
|
||||
<button onclick="setDbAccess(\'root\')" title="ROOT权限" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">ROOT权限</button>\
|
||||
<button onclick="fixDbAccess(\'root\')" title="修复" class="btn btn-default btn-sm" type="button" style="margin-right: 5px;">修复</button>\
|
||||
<span style="float:right"> \
|
||||
<button batch="true" style="float: right;display: none;margin-left:10px;" onclick="delDbBatch();" title="删除选中项" class="btn btn-default btn-sm">删除选中</button>\
|
||||
</span>\
|
||||
@@ -1237,7 +1371,7 @@ function repTools(db_name, res){
|
||||
type: 1,
|
||||
title: "MySQL工具箱【" + db_name + "】",
|
||||
area: ['780px', '580px'],
|
||||
closeBtn: 2,
|
||||
closeBtn: 1,
|
||||
shadeClose: false,
|
||||
content: '<div class="pd15">\
|
||||
<div class="db_list">\
|
||||
@@ -1332,7 +1466,7 @@ function addMasterRepSlaveUser(){
|
||||
yes:function(index){
|
||||
var data = $("#add_master").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['address']){
|
||||
dataObj['address'] = dataObj['dataAccess'];
|
||||
}
|
||||
@@ -1377,7 +1511,7 @@ function updateMasterRepSlaveUser(username){
|
||||
$('#submit_update_master').click(function(){
|
||||
var data = $("#update_master").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
myPost('update_master_rep_slave_user', data, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
@@ -1488,7 +1622,7 @@ function setDbMasterAccess(username){
|
||||
yes:function(index){
|
||||
var data = $("#set_db_access").serialize();
|
||||
data = decodeURIComponent(data);
|
||||
var dataObj = str2Obj(data);
|
||||
var dataObj = toArrayObject(data);
|
||||
if(!dataObj['access']){
|
||||
dataObj['access'] = dataObj['dataAccess'];
|
||||
if ( dataObj['dataAccess'] == 'ip'){
|
||||
@@ -1961,9 +2095,14 @@ function masterOrSlaveConf(version=''){
|
||||
|
||||
|
||||
function getMasterStatus(){
|
||||
myPost('get_master_status', '', function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
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});
|
||||
return;
|
||||
}
|
||||
|
||||
var rdata = rdata.data;
|
||||
var limitCon = '\
|
||||
<p class="conf_p">\
|
||||
|
||||
@@ -17,7 +17,7 @@ which rpcgen
|
||||
if [ "$?" != "0" ];then
|
||||
|
||||
if [ ! -f ${SOURCE_ROOT}/rpcsvc-proto-1.4.tar.gz ];then
|
||||
wget -O ${SOURCE_ROOT}/rpcsvc-proto-1.4.tar.gz https://github.com/thkukuk/rpcsvc-proto/releases/download/v1.4/rpcsvc-proto-1.4.tar.gz
|
||||
wget --no-check-certificate -O ${SOURCE_ROOT}/rpcsvc-proto-1.4.tar.gz https://github.com/thkukuk/rpcsvc-proto/releases/download/v1.4/rpcsvc-proto-1.4.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${SERVER_ROOT}/rpcsvc-proto-1.4 ];then
|
||||
|
||||
@@ -51,13 +51,15 @@ Install_mysql()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
if [ ! -f ${mysqlDir}/mysql-5.5.62.tar.gz ];then
|
||||
wget -O ${mysqlDir}/mysql-5.5.62.tar.gz --tries=3 https://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.62.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-5.5.62.tar.gz --tries=3 https://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.62.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mysqlDir}/mysql-5.5.62 ];then
|
||||
|
||||
@@ -54,14 +54,16 @@ Install_mysql()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
|
||||
if [ ! -f ${mysqlDir}/mysql-5.6.50.tar.gz ];then
|
||||
wget -O ${mysqlDir}/mysql-5.6.50.tar.gz --tries=3 https://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.50.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-5.6.50.tar.gz --tries=3 https://cdn.mysql.com/Downloads/MySQL-5.6/mysql-5.6.50.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -d ${mysqlDir}/mysql-5.6.50 ];then
|
||||
|
||||
@@ -56,15 +56,17 @@ Install_mysql()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
cd ${rootPath}/plugins/mysql/lib && /bin/bash rpcgen.sh
|
||||
|
||||
if [ ! -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
|
||||
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
@@ -76,7 +78,7 @@ Install_mysql()
|
||||
else
|
||||
# 重新下载
|
||||
rm -rf ${mysqlDir}/mysql-${VERSION}
|
||||
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -90,8 +90,10 @@ Install_mysql()
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "1" ];then
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
@@ -107,7 +109,7 @@ Install_mysql()
|
||||
fi
|
||||
|
||||
if [ ! -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
|
||||
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
@@ -119,7 +121,7 @@ Install_mysql()
|
||||
else
|
||||
# 重新下载
|
||||
rm -rf ${mysqlDir}/mysql-${VERSION}
|
||||
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
|
||||
wget --no-check-certificate -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-8.0/mysql-boost-${VERSION}.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -161,7 +163,7 @@ Install_mysql()
|
||||
|
||||
LIBTIRPC_VER=`pkg-config libtirpc --modversion`
|
||||
if [ ! -f ${mysqlDir}/libtirpc_1.2.5.orig.tar.bz2 ];then
|
||||
wget -O ${mysqlDir}/libtirpc_1.2.5.orig.tar.bz2 https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/libtirpc/1.2.5-1ubuntu0.1/libtirpc_1.2.5.orig.tar.bz2
|
||||
wget --no-check-certificate -O ${mysqlDir}/libtirpc_1.2.5.orig.tar.bz2 https://launchpad.net/ubuntu/+archive/primary/+sourcefiles/libtirpc/1.2.5-1ubuntu0.1/libtirpc_1.2.5.orig.tar.bz2
|
||||
cd ${mysqlDir} && tar -jxvf libtirpc_1.2.5.orig.tar.bz2
|
||||
cd libtirpc-1.2.5 && ./configure
|
||||
fi
|
||||
|
||||
@@ -842,7 +842,7 @@ def setSafeVerify():
|
||||
cobj = json.loads(content)
|
||||
|
||||
cobj['safe_verify']['time'] = args['time']
|
||||
cobj['safe_verify']['cpu'] = args['cpu']
|
||||
cobj['safe_verify']['cpu'] = int(args['cpu'])
|
||||
|
||||
if args['auto'] == '0':
|
||||
cobj['safe_verify']['auto'] = False
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"name":"op_waf",
|
||||
"type":"其他插件",
|
||||
"ps":"有效防止sql注入/xss/一句话木马等常见渗透攻击",
|
||||
"install_pre_inspection":true,
|
||||
"shell":"install.sh",
|
||||
"checks":"server/op_waf",
|
||||
"path":"server/op_waf",
|
||||
|
||||
@@ -1612,8 +1612,6 @@ function wafSite(){
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function wafLogRequest(page){
|
||||
var args = {};
|
||||
args['page'] = page;
|
||||
@@ -1640,9 +1638,9 @@ function wafLogRequest(page){
|
||||
list += '<td><span class="overflow_hide" style="width:112px;">' + getLocalTime(data[i]['time'])+'</span></td>';
|
||||
list += '<td><span class="overflow_hide" style="width:50px;">' + data[i]['domain'] +'</span></td>';
|
||||
list += '<td><span class="overflow_hide" style="width:60px;">' + data[i]['ip'] +'</span></td>';
|
||||
list += '<td><span class="overflow_hide" style="width:50px;">' + data[i]['uri'] +'</span></td>';
|
||||
list += '<td><span class="overflow_hide" style="width:50px;">' + data[i]['uri'] +'</span></td>';// data[i]['uri']
|
||||
list += '<td><span class="overflow_hide" style="width:50px;">' + data[i]['rule_name'] +'</span></td>';
|
||||
list += '<td><span class="overflow_hide" style="width:200px;">' + data[i]['reason'] +'</span></td>';
|
||||
list += '<td><span class="overflow_hide" style="width:200px;">' + entitiesEncode(data[i]['reason']) +'</span></td>';//data[i]['reason']
|
||||
list += '<td><a data-id="'+i+'" href="javascript:;" class="btlink details" title="详情">详情</a></td>';
|
||||
list += '</tr>';
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ http
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name 127.0.0.1;
|
||||
allow 127.0.0.1;
|
||||
location /nginx_status {
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
<p class="bgw" onclick="orPluginService('openresty');">服务</p>
|
||||
<p onclick="pluginInitD('openresty');">自启动</p>
|
||||
<p onclick="pluginConfig('openresty');">配置修改</p>
|
||||
<p onclick="getOpenrestyStatus();">负载状态</p>
|
||||
<p onclick="getOpStatus();">负载状态</p>
|
||||
<p onclick="setOpCfg();">性能调整</p>
|
||||
<p onclick="pluginLogs('openresty');">错误日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
@@ -14,9 +15,7 @@
|
||||
|
||||
</div>
|
||||
|
||||
<!-- <script type="text/javascript" src="/plugins/file?name=openresty&f=js/openresty.js"></script> -->
|
||||
<script type="text/javascript">
|
||||
|
||||
$.getScript( "/plugins/file?name=openresty&f=js/openresty.js", function(){
|
||||
orPluginService('openresty');
|
||||
});
|
||||
|
||||
+122
-4
@@ -6,6 +6,7 @@ import os
|
||||
import time
|
||||
import threading
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
@@ -52,6 +53,13 @@ def getArgs():
|
||||
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 clearTemp():
|
||||
path_bin = getServerDir() + "/nginx"
|
||||
mw.execShell('rm -rf ' + path_bin + '/client_body_temp')
|
||||
@@ -232,7 +240,7 @@ def restyOp_restart():
|
||||
check = getServerDir() + "/bin/openresty -t"
|
||||
check_data = mw.execShell(check)
|
||||
if not check_data[1].find('test is successful') > -1:
|
||||
return check_data[1]
|
||||
return 'ERROR: 配置出错<br><a style="color:red;">' + check_data[1].replace("\n", '<br>') + '</a>'
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
threading.Timer(2, op_submit_systemctl_restart, args=()).start()
|
||||
@@ -291,8 +299,8 @@ def initdUinstall():
|
||||
def runInfo():
|
||||
# 取Openresty负载状态
|
||||
try:
|
||||
url = 'http://' + mw.getHostAddr() + '/nginx_status'
|
||||
result = mw.httpGet(url)
|
||||
url = 'http://127.0.0.1/nginx_status'
|
||||
result = mw.httpGet(url, timeout=1)
|
||||
tmp = result.split()
|
||||
data = {}
|
||||
data['active'] = tmp[2]
|
||||
@@ -304,7 +312,8 @@ def runInfo():
|
||||
data['Waiting'] = tmp[15]
|
||||
return mw.getJson(data)
|
||||
except Exception as e:
|
||||
url = 'http://127.0.0.1/nginx_status'
|
||||
|
||||
url = 'http://' + mw.getHostAddr() + '/nginx_status'
|
||||
result = mw.httpGet(url)
|
||||
tmp = result.split()
|
||||
data = {}
|
||||
@@ -324,6 +333,111 @@ def errorLogPath():
|
||||
return getServerDir() + '/nginx/logs/error.log'
|
||||
|
||||
|
||||
def getCfg():
|
||||
cfg = getConf()
|
||||
content = mw.readFile(cfg)
|
||||
|
||||
unitrep = "[kmgKMG]"
|
||||
cfg_args = [
|
||||
{"name": "worker_processes", "ps": "处理进程,auto表示自动,数字表示进程数", 'type': 2},
|
||||
{"name": "worker_connections", "ps": "最大并发链接数", 'type': 2},
|
||||
{"name": "keepalive_timeout", "ps": "连接超时时间", 'type': 2},
|
||||
{"name": "gzip", "ps": "是否开启压缩传输", 'type': 1},
|
||||
{"name": "gzip_min_length", "ps": "最小压缩文件", 'type': 2},
|
||||
{"name": "gzip_comp_level", "ps": "压缩率", 'type': 2},
|
||||
{"name": "client_max_body_size", "ps": "最大上传文件", 'type': 2},
|
||||
{"name": "server_names_hash_bucket_size",
|
||||
"ps": "服务器名字的hash表大小", 'type': 2},
|
||||
{"name": "client_header_buffer_size", "ps": "客户端请求头buffer大小", 'type': 2},
|
||||
]
|
||||
|
||||
# {"name": "client_body_buffer_size", "ps": "请求主体缓冲区"}
|
||||
rdata = []
|
||||
for i in cfg_args:
|
||||
rep = "(%s)\s+(\w+)" % i["name"]
|
||||
k = re.search(rep, content)
|
||||
if not k:
|
||||
return mw.returnJson(False, "获取 key {} 失败".format(k))
|
||||
k = k.group(1)
|
||||
v = re.search(rep, content)
|
||||
if not v:
|
||||
return mw.returnJson(False, "获取 value {} 失败".format(v))
|
||||
v = v.group(2)
|
||||
|
||||
if re.search(unitrep, v):
|
||||
u = str.upper(v[-1])
|
||||
v = v[:-1]
|
||||
if len(u) == 1:
|
||||
psstr = u + "B," + i["ps"]
|
||||
else:
|
||||
psstr = u + "," + i["ps"]
|
||||
else:
|
||||
u = ""
|
||||
|
||||
kv = {"name": k, "value": v, "unit": u,
|
||||
"ps": i["ps"], "type": i["type"]}
|
||||
rdata.append(kv)
|
||||
|
||||
return mw.returnJson(True, "ok", rdata)
|
||||
|
||||
|
||||
def setCfg():
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, [
|
||||
'worker_processes', 'worker_connections', 'keepalive_timeout',
|
||||
'gzip', 'gzip_min_length', 'gzip_comp_level', 'client_max_body_size',
|
||||
'server_names_hash_bucket_size', 'client_header_buffer_size'
|
||||
])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
cfg = getConf()
|
||||
mw.backFile(cfg)
|
||||
content = mw.readFile(cfg)
|
||||
|
||||
unitrep = "[kmgKMG]"
|
||||
cfg_args = [
|
||||
{"name": "worker_processes", "ps": "处理进程,auto表示自动,数字表示进程数", 'type': 2},
|
||||
{"name": "worker_connections", "ps": "最大并发链接数", 'type': 2},
|
||||
{"name": "keepalive_timeout", "ps": "连接超时时间", 'type': 2},
|
||||
{"name": "gzip", "ps": "是否开启压缩传输", 'type': 1},
|
||||
{"name": "gzip_min_length", "ps": "最小压缩文件", 'type': 2},
|
||||
{"name": "gzip_comp_level", "ps": "压缩率", 'type': 2},
|
||||
{"name": "client_max_body_size", "ps": "最大上传文件", 'type': 2},
|
||||
{"name": "server_names_hash_bucket_size",
|
||||
"ps": "服务器名字的hash表大小", 'type': 2},
|
||||
{"name": "client_header_buffer_size", "ps": "客户端请求头buffer大小", 'type': 2},
|
||||
]
|
||||
|
||||
# print(args)
|
||||
for k, v in args.items():
|
||||
# print(k, v)
|
||||
rep = "%s\s+[^kKmMgG\;\n]+" % k
|
||||
if k == "worker_processes" or k == "gzip":
|
||||
if not re.search("auto|on|off|\d+", v):
|
||||
return mw.returnJson(False, '参数值错误')
|
||||
else:
|
||||
if not re.search("\d+", v):
|
||||
return mw.returnJson(False, '参数值错误,请输入数字整数')
|
||||
|
||||
if re.search(rep, content):
|
||||
newconf = "%s %s" % (k, v)
|
||||
content = re.sub(rep, newconf, content)
|
||||
elif re.search(rep, content):
|
||||
newconf = "%s %s" % (k, v)
|
||||
content = re.sub(rep, newconf, content)
|
||||
|
||||
mw.writeFile(cfg, content)
|
||||
isError = mw.checkWebConfig()
|
||||
if (isError != True):
|
||||
mw.restoreFile(cfg)
|
||||
return mw.returnJson(False, 'ERROR: 配置出错<br><a style="color:red;">' + isError.replace("\n", '<br>') + '</a>')
|
||||
|
||||
mw.restartWeb()
|
||||
return mw.returnJson(True, '设置成功')
|
||||
|
||||
|
||||
def installPreInspection():
|
||||
return 'ok'
|
||||
|
||||
@@ -356,5 +470,9 @@ if __name__ == "__main__":
|
||||
print(runInfo())
|
||||
elif func == 'error_log':
|
||||
print(errorLogPath())
|
||||
elif func == 'get_cfg':
|
||||
print(getCfg())
|
||||
elif func == 'set_cfg':
|
||||
print(setCfg())
|
||||
else:
|
||||
print('error')
|
||||
|
||||
@@ -16,16 +16,19 @@ install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
openrestyDir=${serverPath}/source/openresty
|
||||
|
||||
if id www &> /dev/null ;then
|
||||
echo "www UID is `id -u www`"
|
||||
echo "www Shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
echo "www uid is `id -u www`"
|
||||
echo "www shell is `grep "^www:" /etc/passwd |cut -d':' -f7 `"
|
||||
else
|
||||
groupadd www
|
||||
# useradd -g www -s /sbin/nologin www
|
||||
useradd -g www -s /bin/bash www
|
||||
fi
|
||||
|
||||
Install_openresty()
|
||||
{
|
||||
if [ -d $serverPath/openresty ];then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ----- cpu start ------
|
||||
if [ -z "${cpuCore}" ]; then
|
||||
cpuCore="1"
|
||||
@@ -43,6 +46,12 @@ Install_openresty()
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
|
||||
if [ "$cpuCore" -gt "2" ];then
|
||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
||||
else
|
||||
cpuCore="1"
|
||||
fi
|
||||
# ----- cpu end ------
|
||||
|
||||
mkdir -p ${openrestyDir}
|
||||
@@ -59,10 +68,12 @@ Install_openresty()
|
||||
cd ${openrestyDir}/openresty-${VERSION} && ./configure \
|
||||
--prefix=$serverPath/openresty \
|
||||
--with-ipv6 \
|
||||
--with-stream \
|
||||
--with-http_v2_module \
|
||||
--with-http_ssl_module \
|
||||
--with-http_slice_module \
|
||||
--with-http_stub_status_module \
|
||||
--with-http_sub_module \
|
||||
--with-http_realip_module
|
||||
# --without-luajit-gc64
|
||||
# --with-debug
|
||||
@@ -79,6 +90,7 @@ Install_openresty()
|
||||
#初始化
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/openresty/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/openresty/index.py initd_install
|
||||
rm -rf $openrestyDir
|
||||
fi
|
||||
echo '安装完成' > $install_tmp
|
||||
}
|
||||
|
||||
@@ -111,8 +111,10 @@ function orPluginOpServiceOp(a,b,c,d,a,v,request_callback){
|
||||
|
||||
|
||||
//查看Nginx负载状态
|
||||
function getOpenrestyStatus() {
|
||||
function getOpStatus() {
|
||||
var loadT = layer.msg('正在处理,请稍后...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'openresty', func:'run_info'}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
showMsg(data.msg, function(){}, null,3000);
|
||||
return;
|
||||
@@ -134,3 +136,78 @@ function getOpenrestyStatus() {
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function setOpCfg(){
|
||||
orPost('get_cfg', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var rdata = rdata.data;
|
||||
// console.log(rdata);
|
||||
|
||||
var mlist = '';
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
var w = '70'
|
||||
var ibody = '<input style="width: ' + w + 'px;" class="bt-input-text mr5" name="' + rdata[i].name + '" value="' + rdata[i].value + '" type="text" >';
|
||||
switch (rdata[i].type) {
|
||||
case 0:
|
||||
var selected_1 = (rdata[i].value == 1) ? 'selected' : '';
|
||||
var selected_0 = (rdata[i].value == 0) ? 'selected' : '';
|
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
|
||||
<option value="1" ' + selected_1 + '>开启</option>\
|
||||
<option value="0" ' + selected_0 + '>关闭</option>\
|
||||
</select>';
|
||||
break;
|
||||
case 1:
|
||||
var selected_1 = (rdata[i].value == 'on') ? 'selected' : '';
|
||||
var selected_0 = (rdata[i].value == 'off') ? 'selected' : '';
|
||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
|
||||
<option value="on" ' + selected_1 + '>开启</option>\
|
||||
<option value="off" ' + selected_0 + '>关闭</option>\
|
||||
</select>';
|
||||
break;
|
||||
}
|
||||
mlist += '<p style="margin-top:15px;"><span>' + rdata[i].name + '</span>' + ibody + "<b class='unit c9'>"+rdata[i].unit+"</b>" +', <font class="c9">' + rdata[i].ps + '</font></p>';
|
||||
}
|
||||
var con = '<style>.conf_p p{margin-bottom: 2px}</style><div class="conf_p" style="margin-bottom:0">\
|
||||
' + mlist + '\
|
||||
<div style="margin-top:10px; padding-right:15px" class="text-right">\
|
||||
<button class="btn btn-success btn-sm mr5" onclick="setOpCfg()">刷新</button>\
|
||||
<button class="btn btn-success btn-sm" onclick="submitConf()">保存</button>\
|
||||
</div>\
|
||||
</div>'
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
function submitConf() {
|
||||
var data = {
|
||||
worker_processes: $("input[name='worker_processes']").val(),
|
||||
worker_connections: $("input[name='worker_connections']").val(),
|
||||
keepalive_timeout: $("input[name='keepalive_timeout']").val(),
|
||||
gzip: $("select[name='gzip']").val() || 'on',
|
||||
gzip_min_length: $("input[name='gzip_min_length']").val(),
|
||||
gzip_comp_level: $("input[name='gzip_comp_level']").val(),
|
||||
client_max_body_size: $("input[name='client_max_body_size']").val(),
|
||||
server_names_hash_bucket_size: $("input[name='server_names_hash_bucket_size']").val(),
|
||||
client_header_buffer_size: $("input[name='client_header_buffer_size']").val(),
|
||||
};
|
||||
|
||||
// console.log(data);
|
||||
orPost('set_cfg', data, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
// console.log(rdata);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -173,6 +173,17 @@ def initReplace(version):
|
||||
makeOpConf(version)
|
||||
phpFpmWwwReplace(version)
|
||||
|
||||
install_ok = getServerDir() + "/" + version + "/install.ok"
|
||||
if not os.path.exists(install_ok):
|
||||
phpini = getConf(version)
|
||||
ssl_crt = mw.getSslCrt()
|
||||
|
||||
cmd_openssl = "sed -i \"s#;openssl.cafile=#openssl.cafile=" + ssl_crt + "#\" " + phpini
|
||||
mw.execShell(cmd_openssl)
|
||||
cmd_curl = "sed -i \"s#;curl.cainfo =#curl.cainfo=" + ssl_crt + "#\" " + phpini
|
||||
mw.execShell(cmd_curl)
|
||||
|
||||
mw.writeFile(install_ok, 'ok')
|
||||
# systemd
|
||||
# mw.execShell('systemctl daemon-reload')
|
||||
return 'ok'
|
||||
@@ -806,7 +817,8 @@ def installPreInspection(version):
|
||||
sysId = sys_id[0].strip()
|
||||
|
||||
if not sysName in ('debian', 'ubuntu'):
|
||||
return '暂时支持debian,ubuntu'
|
||||
return '仅支持debian,ubuntu'
|
||||
|
||||
return 'ok'
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user