mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 05:59:25 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf00bd3d98 | ||
|
|
ad3f42059d | ||
|
|
9a1d3f5e15 | ||
|
|
f2246cf8ba | ||
|
|
81aabd3910 | ||
|
|
235b1dc5e4 | ||
|
|
ad007b07a5 | ||
|
|
53cc020108 | ||
|
|
71d63f3d68 | ||
|
|
917b3f6099 | ||
|
|
36341f66f1 | ||
|
|
2a16e1d262 | ||
|
|
d27db369dc | ||
|
|
6619ae0bc5 | ||
|
|
da1646eaed | ||
|
|
bf88621629 | ||
|
|
7497c4608a | ||
|
|
b0ee844b84 | ||
|
|
3efa46ce70 | ||
|
|
aaaef570a4 | ||
|
|
53c651724a | ||
|
|
dd8c97f4b8 | ||
|
|
b4e1a5947e | ||
|
|
784056d465 | ||
|
|
b1fbdf8d60 | ||
|
|
f9459089a4 | ||
|
|
36c3967e38 | ||
|
|
c7ba5fa2d9 | ||
|
|
5f2f6d15ed | ||
|
|
5e3c81d785 | ||
|
|
76560bc4fd | ||
|
|
e84a104584 | ||
|
|
afe7175941 | ||
|
|
4b7c821a91 | ||
|
|
1941479092 | ||
|
|
bfcfc2015a | ||
|
|
8a5daeb327 | ||
|
|
66049068aa | ||
|
|
e2d680cb2a | ||
|
|
719eec4b98 | ||
|
|
9ea859f94c | ||
|
|
0bdd384f46 | ||
|
|
c3d20f358c | ||
|
|
7a6454e126 | ||
|
|
d683069fef | ||
|
|
5e7e7af1a7 | ||
|
|
5894323eec | ||
|
|
1cd4996527 | ||
|
|
78786a92e9 | ||
|
|
67d5d3fac5 | ||
|
|
5caf8f52bc | ||
|
|
b838caea8b | ||
|
|
57d4ef5fc9 | ||
|
|
ca3d8cccc9 | ||
|
|
c56aa2efa3 | ||
|
|
f41ef634bf | ||
|
|
80e3a73fa4 | ||
|
|
c4788c03f9 | ||
|
|
501012b4e6 | ||
|
|
e7b927bdef | ||
|
|
9c818b0a5d | ||
|
|
8faf553e1d | ||
|
|
e22f296e38 | ||
|
|
b3deeb5a39 | ||
|
|
2ddb4e9ef8 | ||
|
|
74b1d424b9 | ||
|
|
cd13d0bbe7 | ||
|
|
5dc97276c1 | ||
|
|
9da7f04379 | ||
|
|
0bee208795 | ||
|
|
af660daa30 | ||
|
|
71a2b43c06 | ||
|
|
ad644c3cf9 | ||
|
|
e676790250 | ||
|
|
135b307a98 | ||
|
|
c95c760aef | ||
|
|
60125e6bbb | ||
|
|
fbef641839 | ||
|
|
37431a76b6 | ||
|
|
49cfeb7a39 | ||
|
|
faf433b77d | ||
|
|
d0b70841c2 | ||
|
|
bf8a820343 | ||
|
|
ae1e2cd972 | ||
|
|
46da6c0dd0 | ||
|
|
1e827944ab | ||
|
|
09bbd5280d | ||
|
|
01a887efad | ||
|
|
aa236bac0b | ||
|
|
bcc1ae3b8f | ||
|
|
1acc9a4b76 | ||
|
|
e1b57621d5 | ||
|
|
0f9bd8d387 | ||
|
|
24eb4fe994 | ||
|
|
7799d3436a | ||
|
|
f3f1aaa041 | ||
|
|
d7d907945a | ||
|
|
6961ff7996 | ||
|
|
27047cb169 | ||
|
|
25f3b5b18d | ||
|
|
a9efe0f808 | ||
|
|
847a40e743 | ||
|
|
9f59f479a2 | ||
|
|
c8b955f282 | ||
|
|
b4cee43517 | ||
|
|
a33c1261b3 | ||
|
|
8fd3476126 | ||
|
|
664852c26f | ||
|
|
b356ad5a43 | ||
|
|
ce96f54aa7 | ||
|
|
028bfe13ab | ||
|
|
93061a1138 | ||
|
|
66f0b8691c | ||
|
|
22ac89bc2c | ||
|
|
4edf9c1bb7 | ||
|
|
8169f89ddb | ||
|
|
8c82641cb0 | ||
|
|
5e5606a586 | ||
|
|
d4d0538996 | ||
|
|
d03c630b48 | ||
|
|
698b5c2623 | ||
|
|
c9817cb1c6 | ||
|
|
76d2acac76 | ||
|
|
feb58ca3ad | ||
|
|
2748d248b4 | ||
|
|
e008de3d2c | ||
|
|
57c9ca8e78 | ||
|
|
db90443239 | ||
|
|
883ce06c1c | ||
|
|
9c9b0b9ae5 | ||
|
|
dd8341867f | ||
|
|
15e6ca97e1 | ||
|
|
1996cb03ce | ||
|
|
7d0834397d | ||
|
|
54055f2174 | ||
|
|
33c77f0e90 | ||
|
|
7d4c4a9ef9 | ||
|
|
fbe211b3ec | ||
|
|
53e98bd5fe | ||
|
|
8a7be7e61c | ||
|
|
29de642a1a | ||
|
|
e73533b611 | ||
|
|
89e5d57926 | ||
|
|
283d3c5f1f | ||
|
|
69cde4ebc3 | ||
|
|
e5a9f2c197 | ||
|
|
b3f495efb8 | ||
|
|
c0310a2628 | ||
|
|
496e94ad54 | ||
|
|
beb00d46e0 | ||
|
|
9e123f067b | ||
|
|
aba594caf2 | ||
|
|
f67be6d59f | ||
|
|
bb5240dc43 | ||
|
|
e24bf5313c | ||
|
|
f17a986461 | ||
|
|
2c31318a5c | ||
|
|
7c4231d9c0 | ||
|
|
462f7b78ec | ||
|
|
83466e927e | ||
|
|
d8123d9350 | ||
|
|
23c3b553e9 | ||
|
|
9c2129e638 | ||
|
|
a29b2ac731 | ||
|
|
944040cc03 | ||
|
|
9d9615acc9 | ||
|
|
e3f42c8f67 | ||
|
|
6e9dbe4bd5 | ||
|
|
e71329485a | ||
|
|
5d0e24f0d5 | ||
|
|
78263f6a06 | ||
|
|
ce70fdc784 | ||
|
|
184610acb9 | ||
|
|
1b668d546f | ||
|
|
b7df4f57ad | ||
|
|
817e7607e5 | ||
|
|
d36df7b24c | ||
|
|
e63a643c7b | ||
|
|
0cfd2fc971 | ||
|
|
9b3383dd0e | ||
|
|
9b266ffd7d | ||
|
|
345a5be488 | ||
|
|
0a178f196a | ||
|
|
8abc166dd2 | ||
|
|
a3e0fe817b | ||
|
|
7ab4572bdd | ||
|
|
165f6ee323 | ||
|
|
e565390d5b | ||
|
|
7502fb7e08 | ||
|
|
026f191de2 | ||
|
|
6d7b58e65c | ||
|
|
6953140238 | ||
|
|
97963a67aa | ||
|
|
1112e31a5f | ||
|
|
5358191adf | ||
|
|
4f52e4a520 | ||
|
|
abcabeb2a1 | ||
|
|
c592086d29 | ||
|
|
f93dd8ebec | ||
|
|
92283d1cfc | ||
|
|
f29b15dd60 | ||
|
|
84f2d212f4 | ||
|
|
5fb00f7108 | ||
|
|
fcea7a0610 | ||
|
|
f9b364c435 | ||
|
|
e9743ce97e | ||
|
|
8c2475192b | ||
|
|
35c279d93a | ||
|
|
7c5a7fe822 | ||
|
|
09ee8a0c61 | ||
|
|
7bda3c0cd6 | ||
|
|
d8a5fcab90 | ||
|
|
1d8bc48a9b | ||
|
|
2d39f431c5 | ||
|
|
b78cbb3c39 | ||
|
|
d55450e0c9 | ||
|
|
7cc10a9bdb | ||
|
|
fdebeab6b2 | ||
|
|
fdc1a93e51 | ||
|
|
e9978642c8 | ||
|
|
823c6f1f79 | ||
|
|
7bbb49a459 | ||
|
|
2bbbe3f17f | ||
|
|
9e8d036ee7 | ||
|
|
7ee6e491e8 | ||
|
|
10ffa66dd8 | ||
|
|
85d2f2f702 | ||
|
|
0917ec52de | ||
|
|
da872c1d92 | ||
|
|
91919426f4 | ||
|
|
7f7196c55e | ||
|
|
cb86245a35 | ||
|
|
a319c43d54 | ||
|
|
d07faf396e | ||
|
|
fc718ff727 | ||
|
|
bacac94186 | ||
|
|
c925e09ea6 | ||
|
|
2de9b736f5 | ||
|
|
24d3aeabb0 | ||
|
|
3a33a4c758 | ||
|
|
109f562f06 | ||
|
|
f74702cbad | ||
|
|
be9365e4e6 | ||
|
|
6a61e66c05 | ||
|
|
42d07c1cec | ||
|
|
3886dab6b5 | ||
|
|
d17ebf1e9c | ||
|
|
a6644cc706 | ||
|
|
43071db317 | ||
|
|
e5c53323a5 | ||
|
|
d08ba45f5f | ||
|
|
eba73c71bc | ||
|
|
fe63f684f3 | ||
|
|
f19ef94dca | ||
|
|
685aa7868d | ||
|
|
2e927da78c | ||
|
|
4391a3ccd7 | ||
|
|
27041ee0e0 | ||
|
|
e09085a64c | ||
|
|
8216000f35 | ||
|
|
36d59c6c67 | ||
|
|
363f97119c | ||
|
|
f86980b805 | ||
|
|
805b804a10 | ||
|
|
2f22cdb36e | ||
|
|
7254b9b862 | ||
|
|
ad9ab2d7af | ||
|
|
c8c4a0dbbe | ||
|
|
f425fb1ea2 | ||
|
|
970c6dbe54 | ||
|
|
3f529ac798 | ||
|
|
4be2f60b5b | ||
|
|
305b9ca7cf | ||
|
|
fdf0c4e02f | ||
|
|
52dc2210a4 | ||
|
|
579b118495 | ||
|
|
0fac1b026b | ||
|
|
a0c891ed92 | ||
|
|
98f3ad52dd | ||
|
|
ada1aeac05 | ||
|
|
272d71ed97 | ||
|
|
1a69d55da1 | ||
|
|
8a4174a8a4 | ||
|
|
7d58ba316d | ||
|
|
d4af727e5a | ||
|
|
3a8c93b595 | ||
|
|
25fe2e79bb | ||
|
|
84ebfc4254 | ||
|
|
2bdba8aa8d | ||
|
|
60be806398 | ||
|
|
b919de1fd6 | ||
|
|
087dcc7f40 | ||
|
|
be2cfa4407 | ||
|
|
e86707d752 | ||
|
|
b31c49ac11 | ||
|
|
d013595431 | ||
|
|
9e9dad7325 | ||
|
|
1f52d69410 | ||
|
|
5a221d9cb3 | ||
|
|
4abd1df942 | ||
|
|
ee84266acb | ||
|
|
4fadf4c275 | ||
|
|
89b5a762d1 | ||
|
|
759e1432f8 | ||
|
|
d3e9fbb5db | ||
|
|
e3c60de0e7 | ||
|
|
1cd7667f7b | ||
|
|
d0ac8bd70c | ||
|
|
89e20482a0 | ||
|
|
9036d88fab | ||
|
|
919ca8ed83 | ||
|
|
e41055443e | ||
|
|
ad15bb303f | ||
|
|
a6e0af5672 | ||
|
|
dbd3c86970 | ||
|
|
7659e654a9 | ||
|
|
32c74fd85d | ||
|
|
383fd3b068 | ||
|
|
d8aed860a7 | ||
|
|
68a8751137 | ||
|
|
bb0f0ced62 | ||
|
|
04ce9541a2 | ||
|
|
2be2565736 | ||
|
|
b5776f903f | ||
|
|
5052ea11b0 | ||
|
|
a578eeef01 | ||
|
|
d1dcbcb0d6 | ||
|
|
0916e96448 | ||
|
|
7616acccb9 | ||
|
|
2499c296e7 | ||
|
|
ceb41fef68 | ||
|
|
aaaefdb996 | ||
|
|
0bef98d83e | ||
|
|
a21ac3fa6c | ||
|
|
de9fdd6e87 | ||
|
|
6991a3ecfc | ||
|
|
863b42800b | ||
|
|
3bf83a6202 | ||
|
|
ee6e6f8286 | ||
|
|
7370ef9816 | ||
|
|
8572b93ed0 | ||
|
|
337ba1fa1e | ||
|
|
1ad11de98e | ||
|
|
a9aaf268fc | ||
|
|
d618f36f89 | ||
|
|
929ead12bc | ||
|
|
89991b8417 | ||
|
|
af8f9fb1a9 | ||
|
|
4a09695343 | ||
|
|
5aead0ad7c | ||
|
|
8324a89edb | ||
|
|
de6ed476fb | ||
|
|
9342e31faf | ||
|
|
061c2d86eb | ||
|
|
1937a6344e | ||
|
|
5e91ac8fe9 | ||
|
|
ff32ab721f | ||
|
|
8d213a2444 | ||
|
|
ca10177754 | ||
|
|
7cbabaa04b | ||
|
|
805bd0a3ad | ||
|
|
cf003d9f62 | ||
|
|
2e22b7307c | ||
|
|
4d346dd6c8 | ||
|
|
35a7025530 | ||
|
|
9ad51c81d8 | ||
|
|
30da2fe60d | ||
|
|
b16ca19ca8 | ||
|
|
986687b829 | ||
|
|
0cec515297 | ||
|
|
e54ea53017 | ||
|
|
755901b4ca | ||
|
|
90d0d3ba72 | ||
|
|
f65a8a24e0 | ||
|
|
2c7d50e3bc | ||
|
|
91a71a1eb3 | ||
|
|
875acda8a5 | ||
|
|
52e138ae56 | ||
|
|
a769623a24 | ||
|
|
d7a4e1d4be | ||
|
|
057e152845 | ||
|
|
f80ac8e9f0 | ||
|
|
aceb26e309 | ||
|
|
1d078a63ca | ||
|
|
f0ba3d58d6 | ||
|
|
14f2fad644 | ||
|
|
58f0cd69b7 | ||
|
|
9326138c6e | ||
|
|
ceffb49d61 | ||
|
|
a4e2b2d8b4 | ||
|
|
1ba42fdc4b | ||
|
|
b0ab2e28cb | ||
|
|
2471784d1f | ||
|
|
78049fa34f | ||
|
|
09c25924fe | ||
|
|
e8e2487f27 | ||
|
|
cf930aeca1 | ||
|
|
e6d380c321 | ||
|
|
065b6430f2 | ||
|
|
e1c03474eb | ||
|
|
3aef5f7bbf | ||
|
|
cebeb7fe90 | ||
|
|
c5d8166a2a | ||
|
|
ff30de33ab | ||
|
|
7700eb92ec | ||
|
|
0c8f84e81f | ||
|
|
245d026726 | ||
|
|
1ac8bf51f2 | ||
|
|
248e6b1e0e | ||
|
|
6ff5d4128b | ||
|
|
82e39f6be4 | ||
|
|
780dfb08a3 | ||
|
|
dd586576a7 | ||
|
|
c77efccd19 | ||
|
|
962b0fa9c5 | ||
|
|
5532dcd968 | ||
|
|
ce2d060c94 | ||
|
|
3c388ada21 | ||
|
|
c81ddebcd4 | ||
|
|
9ff01c3cfb | ||
|
|
6a981e1e8f | ||
|
|
3643d63a90 | ||
|
|
8560880944 | ||
|
|
4210bb87a9 | ||
|
|
6473d68421 | ||
|
|
009b599831 | ||
|
|
1c4536980c | ||
|
|
9b62a46312 | ||
|
|
bb100b6bf2 | ||
|
|
81fba581bd | ||
|
|
36cc799c1a | ||
|
|
6d64401e22 | ||
|
|
8e81f423f9 | ||
|
|
ea4677b2c4 | ||
|
|
774cf403f1 | ||
|
|
3e3e53e58b | ||
|
|
e0678c8b4c | ||
|
|
c0bdf2659f | ||
|
|
ae3cc4bd0b | ||
|
|
0f8c9ee740 | ||
|
|
4bc4ff5eda | ||
|
|
7568bd10d8 | ||
|
|
28410d2bf5 | ||
|
|
c56246a9d7 | ||
|
|
5770c6d3c5 | ||
|
|
b9fed0b6e9 | ||
|
|
899e58500e | ||
|
|
c6a8841a91 | ||
|
|
40e8393c43 | ||
|
|
ec3d29fc2b | ||
|
|
fba632c393 | ||
|
|
5dec539d40 | ||
|
|
0119e72771 | ||
|
|
c1ffb36642 | ||
|
|
29d8779233 | ||
|
|
6e9a26c331 | ||
|
|
e2a491ab97 | ||
|
|
f1fb16366c | ||
|
|
29ffc62b7c | ||
|
|
f0d8f12f89 | ||
|
|
ef36d8729e | ||
|
|
28bf685e73 | ||
|
|
3f424668a7 | ||
|
|
dfa53c4c4c | ||
|
|
0b712c7242 | ||
|
|
101792a081 | ||
|
|
0055fa98fa | ||
|
|
52a8cc6946 | ||
|
|
3da1ff214f | ||
|
|
ed509e2d8d | ||
|
|
5dfc0f7ebb | ||
|
|
1129d5753a | ||
|
|
0c48e0fcbb | ||
|
|
6a28e72273 | ||
|
|
82fc1a3609 | ||
|
|
73ff1c664e | ||
|
|
9093d4bc3f | ||
|
|
d50936349c | ||
|
|
20d85d0bd7 | ||
|
|
fc904c9a5d | ||
|
|
59e616919f | ||
|
|
3447c1e48f | ||
|
|
d7c6879d2f | ||
|
|
c0240836f7 | ||
|
|
99c6c26859 | ||
|
|
7b0e65de42 | ||
|
|
29c737121b | ||
|
|
318d123015 | ||
|
|
093f8b14f8 | ||
|
|
2f48df6013 | ||
|
|
7f42ee741c | ||
|
|
abfb92eaa5 | ||
|
|
3f8a822d5e | ||
|
|
f9bec73252 | ||
|
|
a9530b0630 | ||
|
|
33fe1095d7 | ||
|
|
ae5a947898 | ||
|
|
b1128cbddb | ||
|
|
ead8de6e0f | ||
|
|
caf3924b09 | ||
|
|
526caf0497 | ||
|
|
c20dc4af94 | ||
|
|
be500c898e | ||
|
|
d2ccea3520 | ||
|
|
051f992e91 | ||
|
|
af6b96d18b | ||
|
|
996786a7b7 | ||
|
|
42bedca172 | ||
|
|
51e3d26492 | ||
|
|
5ff6ee2763 | ||
|
|
64f0ff8ad9 | ||
|
|
7a6f4323d2 | ||
|
|
f927914ff1 | ||
|
|
02ad9c95ee | ||
|
|
4d9c102e8b | ||
|
|
ebb53ada1d | ||
|
|
87f4307655 | ||
|
|
21cf48b08b | ||
|
|
dd6d9cf09a | ||
|
|
e0e889bbff | ||
|
|
18b36b08a7 | ||
|
|
1389280a70 | ||
|
|
8bc9500b23 | ||
|
|
49a358ccfa | ||
|
|
c9bf5f59f4 | ||
|
|
577e5f3512 | ||
|
|
343b815823 | ||
|
|
3819e2f470 | ||
|
|
0e5f762919 | ||
|
|
e9eab63e99 | ||
|
|
be43b537cc | ||
|
|
6b85710504 | ||
|
|
c2d89a91ab | ||
|
|
682f8309c4 | ||
|
|
586302b575 | ||
|
|
4af7183dbd | ||
|
|
a488f106ca | ||
|
|
f05de84dc2 | ||
|
|
fe4c95276d | ||
|
|
abc6e8f597 | ||
|
|
0fc03c81db | ||
|
|
8a6dbf22c0 | ||
|
|
8c18023f64 | ||
|
|
fd521eff3f | ||
|
|
55f8e3fd72 | ||
|
|
1a26224b6f | ||
|
|
f9ab290d07 | ||
|
|
70a30412a5 | ||
|
|
ed63341750 | ||
|
|
81fea53bc7 | ||
|
|
eab194f5d1 | ||
|
|
0b5299dbe0 | ||
|
|
e5f399e700 | ||
|
|
f7ee3a9aed | ||
|
|
aa60d52662 | ||
|
|
9249ed7896 | ||
|
|
a470b3c53c | ||
|
|
0851e95fb2 | ||
|
|
b6f7334f5e | ||
|
|
27b77f8570 | ||
|
|
3d888961bc | ||
|
|
5edc4fb713 | ||
|
|
214954b298 | ||
|
|
13b0b2752e | ||
|
|
a2918e651f | ||
|
|
55dd1d7d5a | ||
|
|
df50eceeed | ||
|
|
e1de6dd514 | ||
|
|
08328bbb86 | ||
|
|
6abc5b365b | ||
|
|
6cc1279729 | ||
|
|
aeafaa2832 | ||
|
|
e74a511763 | ||
|
|
f86159eeac | ||
|
|
8097164475 | ||
|
|
4ebb44e4c0 | ||
|
|
584f93461a | ||
|
|
e21f0a53e5 | ||
|
|
1d31a0eae0 | ||
|
|
ded33ed6b4 | ||
|
|
b703758d0e | ||
|
|
33493ac03c | ||
|
|
74e63c5bbd | ||
|
|
f2d34e5551 | ||
|
|
89c529f44c | ||
|
|
56b728601b | ||
|
|
bf1d2daeaa | ||
|
|
cac45b3732 | ||
|
|
ee498b7094 | ||
|
|
385113fe4d | ||
|
|
5dbfc5bd51 | ||
|
|
b76e0f606a | ||
|
|
047702f26d | ||
|
|
eb219caada | ||
|
|
78b2046f19 | ||
|
|
5fe85730e6 | ||
|
|
adb72ef33b | ||
|
|
d9c8a46031 | ||
|
|
24f520bdc9 | ||
|
|
7492756997 | ||
|
|
616af16635 | ||
|
|
916d39e205 | ||
|
|
017958b6b0 | ||
|
|
d403c4c4ad | ||
|
|
9f1481db07 | ||
|
|
47e0ec5fae | ||
|
|
a2377d960e | ||
|
|
60f1ce2575 | ||
|
|
0e368f7157 | ||
|
|
3cf5c5b190 | ||
|
|
4ed07beca3 | ||
|
|
cee9619883 | ||
|
|
5db4a96fc9 | ||
|
|
2e6b7bf5cd | ||
|
|
f404caa763 | ||
|
|
062a518492 | ||
|
|
0310cab3ae | ||
|
|
4a0b8df57f |
+1
-2
@@ -110,7 +110,6 @@ tmp/*
|
||||
*.zip
|
||||
logs/*
|
||||
data/*.db
|
||||
data/control.conf
|
||||
data/iplist.txt
|
||||
data/json/index.json
|
||||
data/json/config.json
|
||||
@@ -159,11 +158,11 @@ data/unauthorized_status.pl
|
||||
plugins/vip_*
|
||||
plugins/own_*
|
||||
plugins/my_*
|
||||
plugins/op_auth
|
||||
plugins/l2tp
|
||||
plugins/openlitespeed
|
||||
plugins/tamper_proof
|
||||
plugins/cryptocurrency_trade
|
||||
plugins/gdrive
|
||||
plugins/mtproxy
|
||||
plugins/zimg
|
||||
plugins/bk_demo
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
|
||||
复制了后台管理界面,按照自己想要的方式写了一版。
|
||||
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
@@ -66,6 +66,10 @@ Talk is cheap, show me the code. -- linus
|
||||
- 插件地址 - https://github.com/mw-plugin
|
||||
- 开发文档 - https://github.com/midoks/mdserver-web/wiki/插件开发
|
||||
|
||||
## 其他插件
|
||||
|
||||
- OP鉴权 - https://github.com/mw-plugin/op_auth
|
||||
|
||||
|
||||
# Note
|
||||
|
||||
@@ -77,10 +81,16 @@ PHP[53-72]支持phpMyAdmin[4.4.15]
|
||||
PHP[72-82]支持phpMyAdmin[5.2.0]
|
||||
```
|
||||
|
||||
# 郑重声明
|
||||
|
||||
不卖、不会监控(统计使用除外)、更不会注入病毒,大家使用方便(望大家不吝捐赠)。
|
||||
|
||||
- https://www.youtube.com/watch?v=2taa5K-Jmmw
|
||||
|
||||
|
||||
# 特别赞助
|
||||
|
||||
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.pw/)
|
||||
- [鲲鹏vpn,免费试用,解锁流媒体和chatGPT](https://down.xbjc888.top/?agent_code=github)
|
||||
|
||||
# AD - VPS推荐 - 🙏
|
||||
|
||||
@@ -100,20 +110,18 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
|
||||
```
|
||||
|
||||
|
||||
### 版本更新 0.16.0
|
||||
### 版本更新 0.16.2
|
||||
|
||||
yum install -y libargon2-devel
|
||||
apt install -y libargon2-dev
|
||||
|
||||
OP防火墙 - 重载即可
|
||||
|
||||
* 增加PHP83。
|
||||
* 面板日志单独为一页并加入日志审计功能。
|
||||
* 修复webssh服务器读取问题。
|
||||
* 站点批量删除修复。
|
||||
* OP防火墙-修复`自动强制验证`关闭不生效。
|
||||
* 新增OneDrive备份插件。
|
||||
* FTP备份优化。
|
||||
* keepalived插件改造,集成mysql高可用配置。
|
||||
* redis(主从/集群)配置识别。
|
||||
* MySQL主从同步1236错误,添加修复功能。
|
||||
* MySQL二进制日志查看。
|
||||
* 源码安装成功后删除解压包,节省体积。
|
||||
* 网站统计-增加查询条件。
|
||||
* php增加yaml扩展。
|
||||
* php扩展ioncube修复。
|
||||
* php-fpm增加【按需】配置。
|
||||
* gitea/gogs同步功能改造。
|
||||
|
||||
### JSDelivr安装地址
|
||||
|
||||
|
||||
@@ -123,6 +123,11 @@ class cert_api:
|
||||
return True
|
||||
|
||||
def createCertCron(self):
|
||||
|
||||
if mw.isAppleSystem():
|
||||
print('在Macos上不支持创建证书自动续签任务!')
|
||||
return ''
|
||||
|
||||
# 创建证书自动续签任务
|
||||
try:
|
||||
import crontab_api
|
||||
|
||||
@@ -149,6 +149,7 @@ def initUserInfo():
|
||||
|
||||
data = mw.M('users').where('id=?', (1,)).getField('password')
|
||||
if data == '21232f297a57a5a743894a0e4a801fc3':
|
||||
|
||||
pwd = mw.getRandomString(8).lower()
|
||||
file_pw = mw.getRunDir() + '/data/default.pl'
|
||||
mw.writeFile(file_pw, pwd)
|
||||
|
||||
@@ -27,7 +27,7 @@ from flask import request
|
||||
|
||||
class config_api:
|
||||
|
||||
__version = '0.16.0'
|
||||
__version = '0.16.2'
|
||||
__api_addr = 'data/api.json'
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -283,6 +283,9 @@ class crontab_api:
|
||||
return mw.returnJson(is_check_pass, msg)
|
||||
|
||||
addData = self.add(params)
|
||||
if type(addData) == str:
|
||||
return addData
|
||||
|
||||
if addData > 0:
|
||||
return mw.returnJson(True, '添加成功')
|
||||
return mw.returnJson(False, '添加失败')
|
||||
|
||||
+56
-6
@@ -87,6 +87,12 @@ class files_api:
|
||||
path = request.form.get('path', '')
|
||||
return self.unzip(sfile, dfile, stype, path)
|
||||
|
||||
def uncompressApi(self):
|
||||
sfile = request.form.get('sfile', '')
|
||||
dfile = request.form.get('dfile', '')
|
||||
path = request.form.get('path', '')
|
||||
return self.uncompress(sfile, dfile, path)
|
||||
|
||||
# 移动文件或目录
|
||||
def mvFileApi(self):
|
||||
sfile = request.form.get('sfile', '')
|
||||
@@ -801,7 +807,7 @@ class files_api:
|
||||
if path.find("web_conf") > 0:
|
||||
mw.restartWeb()
|
||||
|
||||
mw.writeLog('文件管理', '文件保存成功', (path,))
|
||||
mw.writeLog('文件管理', '文件[{1}]保存成功', (path,))
|
||||
return mw.returnJson(True, '文件保存成功')
|
||||
except Exception as ex:
|
||||
return mw.returnJson(False, '文件保存错误:' + str(ex))
|
||||
@@ -825,15 +831,59 @@ class files_api:
|
||||
mw.execShell("cd '" + path + "' && tar -zcvf '" +
|
||||
dfile + "' " + sfiles + " > " + tmps + " 2>&1")
|
||||
self.setFileAccept(dfile)
|
||||
mw.writeLog("文件管理", '文件压缩成功!', (sfile, dfile))
|
||||
mw.writeLog("文件管理", '文件[{1}]压缩[{2}]成功!', (sfile, dfile))
|
||||
return mw.returnJson(True, '文件压缩成功!')
|
||||
except:
|
||||
return mw.returnJson(False, '文件压缩失败!')
|
||||
|
||||
def unzip(self, sfile, dfile, stype, path):
|
||||
|
||||
def uncompress(self, sfile, dfile, path):
|
||||
if not os.path.exists(sfile):
|
||||
return mw.returnMsg(False, '指定文件不存在!')
|
||||
return mw.returnJson(False, '指定文件不存在!')
|
||||
|
||||
filename = os.path.basename(sfile)
|
||||
extension = os.path.splitext(filename)[-1]
|
||||
extension = extension.strip('.')
|
||||
|
||||
tar_gz = 'tar.gz'
|
||||
tar_gz_len = len(tar_gz)
|
||||
suffix_gz = sfile[-tar_gz_len:]
|
||||
if suffix_gz == tar_gz:
|
||||
extension = suffix_gz
|
||||
|
||||
if not extension in ['tar.gz', 'gz', 'zip', 'rar']:
|
||||
return mw.returnJson(False, '现在仅支持gz,zip,rar格式解压!')
|
||||
|
||||
if mw.isAppleSystem() and extension == 'rar':
|
||||
return mw.returnJson(False, 'macosx暂时不支持rar格式解压')
|
||||
|
||||
try:
|
||||
tmps = mw.getRunDir() + '/tmp/panelExec.log'
|
||||
if extension == 'zip':
|
||||
cmd = "cd " + path + " && unzip -o -d '" + dfile + \
|
||||
"' '" + sfile + "' > " + tmps + " 2>&1 &"
|
||||
mw.execShell(cmd)
|
||||
if extension == 'tar.gz':
|
||||
cmd = "cd " + path + " && tar -zxvf " + sfile + \
|
||||
" -C " + dfile + " > " + tmps + " 2>&1 &"
|
||||
mw.execShell(cmd)
|
||||
if extension == 'gz':
|
||||
cmd = "cd " + path + " && gunzip -k " + sfile + " > " + tmps + " 2>&1 &"
|
||||
mw.execShell(cmd)
|
||||
if extension == 'rar':
|
||||
cmd = "cd " + path + " && unrar x " + sfile + \
|
||||
" " + dfile + " > " + tmps + " 2>&1 &"
|
||||
mw.execShell(cmd)
|
||||
|
||||
if os.path.exists(dfile):
|
||||
self.setFileAccept(dfile)
|
||||
mw.writeLog("文件管理", '文件[{1}]解压[{2}]成功!', (sfile, dfile))
|
||||
return mw.returnJson(True, '文件解压成功!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '文件解压失败!:' + str(e))
|
||||
|
||||
def unzip(self, sfile, dfile, stype, path):
|
||||
if not os.path.exists(sfile):
|
||||
return mw.returnJson(False, '指定文件不存在!')
|
||||
|
||||
try:
|
||||
tmps = mw.getRunDir() + '/tmp/panelExec.log'
|
||||
@@ -850,7 +900,7 @@ class files_api:
|
||||
" -C " + dfile + " > " + tmps + " 2>&1 &")
|
||||
|
||||
self.setFileAccept(dfile)
|
||||
mw.writeLog("文件管理", '文件解压成功!', (sfile, dfile))
|
||||
mw.writeLog("文件管理", '文件[{1}]解压[{2}]成功!', (sfile, dfile))
|
||||
return mw.returnJson(True, '文件解压成功!')
|
||||
except:
|
||||
return mw.returnJson(False, '文件解压失败!')
|
||||
|
||||
+98
-37
@@ -84,12 +84,13 @@ class firewall_api:
|
||||
port = request.form.get('port', '').strip()
|
||||
ps = request.form.get('ps', '').strip()
|
||||
stype = request.form.get('type', '').strip()
|
||||
protocol = request.form.get('protocol', '').strip()
|
||||
|
||||
data = self.addAcceptPortArgs(port, ps, stype)
|
||||
data = self.addAcceptPortArgs(port, ps, stype, protocol)
|
||||
return mw.getJson(data)
|
||||
|
||||
# 添加放行端口
|
||||
def addAcceptPortArgs(self, port, ps, stype):
|
||||
def addAcceptPortArgs(self, port, ps, stype, protocol='tcp'):
|
||||
import re
|
||||
import time
|
||||
|
||||
@@ -103,12 +104,13 @@ class firewall_api:
|
||||
if mw.M('firewall').where("port=?", (port,)).count() > 0:
|
||||
return mw.returnData(False, '您要放行的端口已存在,无需重复放行!')
|
||||
|
||||
msg = mw.getInfo('放行端口[{1}]成功', (port,))
|
||||
msg = mw.getInfo('放行端口[{1}][{2}]成功', (port, protocol,))
|
||||
mw.writeLog("防火墙管理", msg)
|
||||
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||
mw.M('firewall').add('port,ps,addtime', (port, ps, addtime))
|
||||
mw.M('firewall').add('port,protocol,ps,addtime',
|
||||
(port, protocol, ps, addtime))
|
||||
|
||||
self.addAcceptPort(port)
|
||||
self.addAcceptPort(port, protocol)
|
||||
self.firewallReload()
|
||||
return mw.returnData(True, '添加放行(' + port + ')端口成功!')
|
||||
|
||||
@@ -139,32 +141,64 @@ class firewall_api:
|
||||
self.firewallReload()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
|
||||
# 删除放行端口
|
||||
def delAcceptPortApi(self):
|
||||
port = request.form.get('port', '').strip()
|
||||
sid = request.form.get('id', '').strip()
|
||||
mw_port = mw.readFile('data/port.pl')
|
||||
try:
|
||||
if(port == mw_port):
|
||||
return mw.returnJson(False, '失败,不能删除当前面板端口!')
|
||||
if self.__isUfw:
|
||||
def delAcceptPortArgs(self, port, protocol='tcp'):
|
||||
if self.__isUfw:
|
||||
if protocol == 'tcp':
|
||||
mw.execShell('ufw delete allow ' + port + '/tcp')
|
||||
elif self.__isFirewalld:
|
||||
port = port.replace(':', '-')
|
||||
if protocol == 'udp':
|
||||
mw.execShell('ufw delete allow ' + port + '/udp')
|
||||
if protocol == 'tcp/udp':
|
||||
mw.execShell('ufw delete allow ' + port + '/tcp')
|
||||
mw.execShell('ufw delete allow ' + port + '/udp')
|
||||
elif self.__isFirewalld:
|
||||
port = port.replace(':', '-')
|
||||
if protocol == 'tcp':
|
||||
mw.execShell(
|
||||
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
|
||||
if protocol == 'udp':
|
||||
mw.execShell(
|
||||
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
|
||||
if protocol == 'tcp/udp':
|
||||
mw.execShell(
|
||||
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
|
||||
mw.execShell(
|
||||
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
|
||||
elif self.__isIptables:
|
||||
elif self.__isIptables:
|
||||
if protocol == 'tcp':
|
||||
mw.execShell(
|
||||
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
|
||||
else:
|
||||
pass
|
||||
msg = mw.getInfo('删除防火墙放行端口[{1}]成功!', (port,))
|
||||
mw.writeLog("防火墙管理", msg)
|
||||
if protocol == 'udp':
|
||||
mw.execShell(
|
||||
'iptables -D INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT')
|
||||
if protocol == 'tcp/udp':
|
||||
mw.execShell(
|
||||
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
|
||||
mw.execShell(
|
||||
'iptables -D INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT')
|
||||
else:
|
||||
pass
|
||||
|
||||
mw.M('firewall').where("port=?", (port,)).delete()
|
||||
|
||||
msg = mw.getInfo('删除防火墙放行端口[{1}][{2}]成功!', (port, protocol,))
|
||||
mw.writeLog("防火墙管理", msg)
|
||||
|
||||
self.firewallReload()
|
||||
return True
|
||||
|
||||
# 删除放行端口
|
||||
def delAcceptPortApi(self):
|
||||
port = request.form.get('port', '').strip()
|
||||
protocol = request.form.get('protocol', 'tcp').strip()
|
||||
sid = request.form.get('id', '').strip()
|
||||
mw_port = mw.readFile('data/port.pl')
|
||||
|
||||
if(port == mw_port):
|
||||
return mw.returnJson(False, '失败,不能删除当前面板端口!')
|
||||
try:
|
||||
self.delAcceptPortArgs(port, protocol)
|
||||
mw.M('firewall').where("id=?", (sid,)).delete()
|
||||
|
||||
self.firewallReload()
|
||||
return mw.returnJson(True, '删除成功!')
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, '删除失败!:' + str(e))
|
||||
@@ -214,16 +248,13 @@ class firewall_api:
|
||||
|
||||
data['pass_prohibit_status'] = False
|
||||
# 密码登陆配置检查
|
||||
pass_rep = "#PasswordAuthentication\s+(\w*)\s*\n"
|
||||
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
|
||||
else:
|
||||
data['pass_prohibit_status'] = True
|
||||
|
||||
data['port'] = port
|
||||
data['status'] = status
|
||||
@@ -299,11 +330,17 @@ class firewall_api:
|
||||
|
||||
conf = mw.readFile(file)
|
||||
|
||||
if status == '1':
|
||||
pass_rep = "PasswordAuthentication\s+(\w*)\s*\n"
|
||||
pass_status = re.search(pass_rep, conf)
|
||||
if not pass_status:
|
||||
rep = "(#)?PasswordAuthentication\s+(\w*)\s*\n"
|
||||
conf = re.sub(rep, "PasswordAuthentication yes\n", conf)
|
||||
|
||||
if status == '1':
|
||||
rep = "PasswordAuthentication\s+(\w*)\s*\n"
|
||||
conf = re.sub(rep, "PasswordAuthentication yes\n", conf)
|
||||
else:
|
||||
rep = "(#)?PasswordAuthentication\s+(\w*)\s*\n"
|
||||
rep = "PasswordAuthentication\s+(\w*)\s*\n"
|
||||
conf = re.sub(rep, "PasswordAuthentication no\n", conf)
|
||||
mw.writeFile(file, conf)
|
||||
mw.execShell("systemctl restart sshd.service")
|
||||
@@ -389,7 +426,7 @@ class firewall_api:
|
||||
|
||||
start = (page - 1) * limit
|
||||
|
||||
_list = mw.M('firewall').field('id,port,ps,addtime').limit(
|
||||
_list = mw.M('firewall').field('id,port,protocol,ps,addtime').limit(
|
||||
str(start) + ',' + str(limit)).order('id desc').select()
|
||||
data = {}
|
||||
data['data'] = _list
|
||||
@@ -403,16 +440,40 @@ class firewall_api:
|
||||
data['page'] = mw.getPage(_page)
|
||||
return mw.getJson(data)
|
||||
|
||||
def addAcceptPort(self, port):
|
||||
def addAcceptPort(self, port, protocol='tcp'):
|
||||
if self.__isUfw:
|
||||
mw.execShell('ufw allow ' + port + '/tcp')
|
||||
if protocol == 'tcp':
|
||||
mw.execShell('ufw allow ' + port + '/tcp')
|
||||
if protocol == 'udp':
|
||||
mw.execShell('ufw allow ' + port + '/udp')
|
||||
if protocol == 'tcp/udp':
|
||||
mw.execShell('ufw allow ' + port + '/tcp')
|
||||
mw.execShell('ufw allow ' + port + '/udp')
|
||||
elif self.__isFirewalld:
|
||||
port = port.replace(':', '-')
|
||||
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
|
||||
mw.execShell(cmd)
|
||||
if protocol == 'tcp':
|
||||
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
|
||||
mw.execShell(cmd)
|
||||
if protocol == 'udp':
|
||||
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/udp'
|
||||
mw.execShell(cmd)
|
||||
if protocol == 'tcp/udp':
|
||||
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
|
||||
mw.execShell(cmd)
|
||||
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/udp'
|
||||
mw.execShell(cmd)
|
||||
elif self.__isIptables:
|
||||
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
|
||||
mw.execShell(cmd)
|
||||
if protocol == 'tcp':
|
||||
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
|
||||
mw.execShell(cmd)
|
||||
if protocol == 'udp':
|
||||
cmd = 'iptables -I INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT'
|
||||
mw.execShell(cmd)
|
||||
if protocol == 'tcp/udp':
|
||||
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
|
||||
mw.execShell(cmd)
|
||||
cmd = 'iptables -I INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT'
|
||||
mw.execShell(cmd)
|
||||
else:
|
||||
pass
|
||||
return True
|
||||
|
||||
+3
-3
@@ -425,13 +425,13 @@ def getFileMd5(filename):
|
||||
|
||||
def getRandomString(length):
|
||||
# 取随机字符串
|
||||
str = ''
|
||||
rnd_str = ''
|
||||
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
|
||||
chrlen = len(chars) - 1
|
||||
random = Random()
|
||||
for i in range(length):
|
||||
str += chars[random.randint(0, chrlen)]
|
||||
return str
|
||||
rnd_str += chars[random.randint(0, chrlen)]
|
||||
return rnd_str
|
||||
|
||||
|
||||
def getUniqueId():
|
||||
|
||||
+51
-20
@@ -52,6 +52,7 @@ class plugins_api:
|
||||
__plugin_dir = 'plugins'
|
||||
__type = 'data/json/type.json'
|
||||
__index = 'data/json/index.json'
|
||||
__index_data = None
|
||||
setupPath = None
|
||||
|
||||
def __init__(self):
|
||||
@@ -60,6 +61,14 @@ class plugins_api:
|
||||
self.__type = mw.getRunDir() + '/data/json/type.json'
|
||||
self.__index = mw.getRunDir() + '/data/json/index.json'
|
||||
|
||||
self.initIndexData()
|
||||
|
||||
def initIndexData(self):
|
||||
if not os.path.exists(self.__index):
|
||||
mw.writeFile(self.__index, '[]')
|
||||
|
||||
self.__index_data = json.loads(mw.readFile(self.__index))
|
||||
|
||||
##### ----- start ----- ###
|
||||
def listApi(self):
|
||||
sType = request.args.get('type', '0')
|
||||
@@ -615,20 +624,37 @@ class plugins_api:
|
||||
|
||||
return plugins_info
|
||||
|
||||
def checkDisplayIndex(self, name, version):
|
||||
if not os.path.exists(self.__index):
|
||||
mw.writeFile(self.__index, '[]')
|
||||
def checkIndexList(self, name, version):
|
||||
indexList = self.__index_data
|
||||
for i in indexList:
|
||||
nv = i.split('-')
|
||||
if nv[0] == name:
|
||||
return True
|
||||
return False
|
||||
|
||||
indexList = json.loads(mw.readFile(self.__index))
|
||||
if type(version) == list:
|
||||
for index in range(len(version)):
|
||||
vname = name + '-' + version[index]
|
||||
def checkDisplayIndex(self, name, version, coexist):
|
||||
# if not os.path.exists(self.__index):
|
||||
# mw.writeFile(self.__index, '[]')
|
||||
# indexList = json.loads(mw.readFile(self.__index))
|
||||
|
||||
indexList = self.__index_data
|
||||
if coexist:
|
||||
if type(version) == list:
|
||||
for index in range(len(version)):
|
||||
vname = name + '-' + version[index]
|
||||
if vname in indexList:
|
||||
return True
|
||||
else:
|
||||
vname = name + '-' + version
|
||||
if vname in indexList:
|
||||
return True
|
||||
|
||||
else:
|
||||
vname = name + '-' + version
|
||||
if vname in indexList:
|
||||
return True
|
||||
if type(version) == list:
|
||||
for index in range(len(version)):
|
||||
return self.checkIndexList(name, version)
|
||||
else:
|
||||
return self.checkIndexList(name, version)
|
||||
return False
|
||||
|
||||
def getVersion(self, path):
|
||||
@@ -695,7 +721,7 @@ class plugins_api:
|
||||
pInfo['task'] = self.checkSetupTask(
|
||||
pInfo['name'], info['versions'], coexist)
|
||||
pInfo['display'] = self.checkDisplayIndex(
|
||||
info['name'], pInfo['versions'])
|
||||
info['name'], pInfo['versions'], coexist)
|
||||
|
||||
pInfo['setup'] = os.path.exists(pInfo['install_checks'])
|
||||
|
||||
@@ -800,10 +826,10 @@ class plugins_api:
|
||||
continue
|
||||
path = self.__plugin_dir + '/' + dirinfo
|
||||
if os.path.isdir(path):
|
||||
json_file = path + '/info.json'
|
||||
if os.path.exists(json_file):
|
||||
info_file = path + '/info.json'
|
||||
if os.path.exists(info_file):
|
||||
try:
|
||||
data = json.loads(mw.readFile(json_file))
|
||||
data = json.loads(mw.readFile(info_file))
|
||||
# 判断是否搜索
|
||||
if kw != '' and not self.searchKey(data, kw):
|
||||
continue
|
||||
@@ -976,19 +1002,24 @@ class plugins_api:
|
||||
plugin_name = '-'.join(tmpArr)
|
||||
plugin_ver = tmp[tmp_len - 1]
|
||||
|
||||
json_file = self.__plugin_dir + '/' + plugin_name + '/info.json'
|
||||
if os.path.exists(json_file):
|
||||
content = mw.readFile(json_file)
|
||||
read_json_file = self.__plugin_dir + '/' + plugin_name + '/info.json'
|
||||
if os.path.exists(read_json_file):
|
||||
content = mw.readFile(read_json_file)
|
||||
try:
|
||||
data = json.loads(content)
|
||||
data = self.makeList(data)
|
||||
for index in range(len(data)):
|
||||
if data[index]['versions'] == plugin_ver or plugin_ver in data[index]['versions']:
|
||||
if data[index]['coexist']:
|
||||
if data[index]['versions'] == plugin_ver or plugin_ver in data[index]['versions']:
|
||||
data[index]['display'] = True
|
||||
plist.append(data[index])
|
||||
continue
|
||||
else:
|
||||
data[index]['display'] = True
|
||||
plist.append(data[index])
|
||||
continue
|
||||
|
||||
except Exception as e:
|
||||
print('getIndexList:', e)
|
||||
print('getIndexList:', mw.getTracebackInfo())
|
||||
|
||||
# 使用gevent模式时,无法使用多进程
|
||||
# plist = self.checkStatusMProcess(plist)
|
||||
|
||||
+38
-10
@@ -1149,8 +1149,9 @@ class site_api:
|
||||
domains = request.form.get('domains', '')
|
||||
status = request.form.get('status', '')
|
||||
name = request.form.get('name', '')
|
||||
none = request.form.get('none', '')
|
||||
sid = request.form.get('id', '')
|
||||
return self.setSecurity(sid, name, fix, domains, status)
|
||||
return self.setSecurity(sid, name, fix, domains, status, none)
|
||||
|
||||
def getLogsApi(self):
|
||||
siteName = request.form.get('siteName', '')
|
||||
@@ -2430,9 +2431,28 @@ location ^~ {from} {\n\
|
||||
tmp = re.search(rep, conf).group()
|
||||
data['fix'] = re.search(
|
||||
"\(.+\)\$", tmp).group().replace('(', '').replace(')$', '').replace('|', ',')
|
||||
data['domains'] = ','.join(re.search(
|
||||
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp).groups()[0].split())
|
||||
data['status'] = True
|
||||
|
||||
data['status'] = False
|
||||
data['none'] = False
|
||||
|
||||
valid_referers = re.search(
|
||||
"valid_referers\s+(.+);\n", tmp)
|
||||
valid_referers_none = re.search(
|
||||
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp)
|
||||
|
||||
if valid_referers or valid_referers_none:
|
||||
data['status'] = True
|
||||
|
||||
if valid_referers_none:
|
||||
domain_t = valid_referers_none.groups()[0].split()
|
||||
data['domains'] = ','.join(domain_t)
|
||||
data['none'] = True
|
||||
elif valid_referers:
|
||||
domain_t = valid_referers.groups()[0].split()
|
||||
data['domains'] = ','.join(domain_t)
|
||||
data['none'] = False
|
||||
|
||||
# print(data)
|
||||
else:
|
||||
data['fix'] = 'jpg,jpeg,gif,png,js,css'
|
||||
domains = mw.M('domain').where(
|
||||
@@ -2442,19 +2462,27 @@ location ^~ {from} {\n\
|
||||
tmp.append(domain['name'])
|
||||
data['domains'] = ','.join(tmp)
|
||||
data['status'] = False
|
||||
data['none'] = False
|
||||
return mw.getJson(data)
|
||||
|
||||
def setSecurity(self, sid, name, fix, domains, status):
|
||||
def setSecurity(self, sid, name, fix, domains, status, none=''):
|
||||
if len(fix) < 2:
|
||||
return mw.returnJson(False, 'URL后缀不能为空!')
|
||||
file = self.getHostConf(name)
|
||||
if os.path.exists(file):
|
||||
conf = mw.readFile(file)
|
||||
if conf.find('SECURITY-START') != -1:
|
||||
if status == 'false':
|
||||
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
conf = re.sub(rep, '', conf)
|
||||
mw.writeLog('网站管理', '站点[' + name + ']已关闭防盗链设置!')
|
||||
else:
|
||||
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
|
||||
conf = re.sub(rep, '', conf)
|
||||
|
||||
valid_referers = domains.strip().replace(',', ' ')
|
||||
if none == 'true':
|
||||
valid_referers = 'none blocked ' + valid_referers
|
||||
|
||||
pre_path = self.setupPath + "/php/conf"
|
||||
re_path = "include\s+" + pre_path + "/enable-php-"
|
||||
rconf = '''#SECURITY-START 防盗链配置
|
||||
@@ -2462,13 +2490,13 @@ location ^~ {from} {\n\
|
||||
{
|
||||
expires 30d;
|
||||
access_log /dev/null;
|
||||
valid_referers none blocked %s;
|
||||
valid_referers %s;
|
||||
if ($invalid_referer){
|
||||
return 404;
|
||||
}
|
||||
}
|
||||
#SECURITY-END
|
||||
include %s/enable-php-''' % (fix.strip().replace(',', '|'), domains.strip().replace(',', ' '), pre_path)
|
||||
include %s/enable-php-''' % (fix.strip().replace(',', '|'), valid_referers, pre_path)
|
||||
conf = re.sub(re_path, rconf, conf)
|
||||
mw.writeLog('网站管理', '站点[' + name + ']已开启防盗链!')
|
||||
mw.writeFile(file, conf)
|
||||
@@ -2477,7 +2505,7 @@ location ^~ {from} {\n\
|
||||
|
||||
def getPhpVersion(self):
|
||||
phpVersions = ('00', '52', '53', '54', '55',
|
||||
'56', '70', '71', '72', '73', '74', '80', '81', '82')
|
||||
'56', '70', '71', '72', '73', '74', '80', '81', '82', '83')
|
||||
data = []
|
||||
for val in phpVersions:
|
||||
tmp = {}
|
||||
@@ -2760,7 +2788,7 @@ location ^~ {from} {\n\
|
||||
|
||||
self.saveCert(keyPath, certPath)
|
||||
|
||||
msg = mw.getInfo('网站[{}]开启SSL成功!', siteName)
|
||||
msg = mw.getInfo('网站[{1}]开启SSL成功!', (siteName,))
|
||||
mw.writeLog('网站管理', msg)
|
||||
|
||||
mw.restartWeb()
|
||||
|
||||
@@ -273,10 +273,26 @@ class system_api:
|
||||
title = mw.readFile(titlePl).strip()
|
||||
return title
|
||||
|
||||
def getSystemDeviceTemperature(self):
|
||||
if not hasattr(psutil, "sensors_temperatures"):
|
||||
return False, "platform not supported"
|
||||
temps = psutil.sensors_temperatures()
|
||||
if not temps:
|
||||
return False, "can't read any temperature"
|
||||
for name, entries in temps.items():
|
||||
for entry in entries:
|
||||
return True, entry.label
|
||||
# print("%-20s %s °C (high = %s °C, critical = %s °C)" % (
|
||||
# entry.label or name, entry.current, entry.high,
|
||||
# entry.critical))
|
||||
return False, ""
|
||||
|
||||
def getSystemVersion(self):
|
||||
#
|
||||
# 取操作系统版本
|
||||
current_os = mw.getOs()
|
||||
# sys_temper = self.getSystemDeviceTemperature()
|
||||
# print(sys_temper)
|
||||
# mac
|
||||
if current_os == 'darwin':
|
||||
data = mw.execShell('sw_vers')[0]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
DIR=$(cd "$(dirname "$0")"; pwd)
|
||||
MDIR=$(dirname "$DIR")
|
||||
|
||||
@@ -46,6 +46,10 @@ mw_start(){
|
||||
|
||||
|
||||
mw_start_debug(){
|
||||
if [ ! -f $DIR/logs/task.log ];then
|
||||
echo '' > $DIR/logs/task.log
|
||||
fi
|
||||
|
||||
python3 task.py >> $DIR/logs/task.log 2>&1 &
|
||||
port=7200
|
||||
if [ -f /www/server/mdserver-web/data/port.pl ];then
|
||||
|
||||
@@ -4,7 +4,16 @@
|
||||
- 面板相关命令
|
||||
|
||||
```
|
||||
/etc/init.d/mw default
|
||||
/etc/init.d/mw default | 显示登录信息
|
||||
/etc/init.d/mw db | 快捷连接数据库
|
||||
----------------------------------------
|
||||
|
||||
mw debug | 开发测试
|
||||
mw venv | 进入虚拟环境
|
||||
mw mirror | 切换镜像
|
||||
mw install_app | 快捷安装常用软件
|
||||
mw update | 更新到正式
|
||||
mw update_dev | 更新到开发
|
||||
|
||||
service mw [start|stop|reload|restart|status]
|
||||
```
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
30
|
||||
@@ -40,14 +40,16 @@ CREATE TABLE IF NOT EXISTS `crontab` (
|
||||
CREATE TABLE IF NOT EXISTS `firewall` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`port` TEXT,
|
||||
`protocol` TEXT DEFAULT 'tcp',
|
||||
`ps` TEXT,
|
||||
`addtime` TEXT
|
||||
);
|
||||
|
||||
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
|
||||
(1, '80', '网站默认端口', '0000-00-00 00:00:00'),
|
||||
(2, '443', 'HTTPS', '0000-00-00 00:00:00'),
|
||||
(3, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00');
|
||||
ALTER TABLE `firewall` ADD COLUMN `protocol` TEXT DEFAULT 'tcp';
|
||||
|
||||
INSERT INTO `firewall` (`id`, `port`, `protocol`, `ps`, `addtime`) VALUES
|
||||
(1, '80', 'tcp','网站默认端口', '0000-00-00 00:00:00'),
|
||||
(2, '443', 'tcp', 'HTTPS', '0000-00-00 00:00:00');
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +57,7 @@ CREATE TABLE IF NOT EXISTS `logs` (
|
||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
`type` TEXT,
|
||||
`log` TEXT,
|
||||
`uid` TEXT,
|
||||
`uid` INTEGER DEFAULT '1',
|
||||
`addtime` TEXT
|
||||
);
|
||||
ALTER TABLE `logs` ADD COLUMN `uid` INTEGER DEFAULT '1';
|
||||
|
||||
@@ -52,8 +52,8 @@ def createBgTask():
|
||||
removeBgTask()
|
||||
args = {
|
||||
"period": "day",
|
||||
"hour": "2",
|
||||
"minute": "30",
|
||||
"hour": "0",
|
||||
"minute": "15",
|
||||
}
|
||||
createBgTaskByName(getPluginName(), args)
|
||||
|
||||
|
||||
@@ -0,0 +1,365 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
import io
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
# -----------------------------
|
||||
import google.oauth2.credentials
|
||||
import google_auth_oauthlib.flow
|
||||
from googleapiclient.discovery import build
|
||||
from google_auth_oauthlib.flow import InstalledAppFlow
|
||||
from google.auth.transport.requests import Request
|
||||
from googleapiclient.http import MediaFileUpload
|
||||
from googleapiclient.http import MediaIoBaseDownload
|
||||
|
||||
|
||||
class gdriveclient():
|
||||
__plugin_dir = ''
|
||||
__server_dir = ''
|
||||
|
||||
__credentials = "/root/credentials.json"
|
||||
__backup_dir_name = "backup"
|
||||
__creds = None
|
||||
__exclude = ""
|
||||
__scpos = ['https://www.googleapis.com/auth/drive.file']
|
||||
_title = 'Google Drive'
|
||||
_name = 'Google Drive'
|
||||
__debug = False
|
||||
|
||||
_DEFAULT_AUTH_PROMPT_MESSAGE = (
|
||||
'Please visit this URL to authorize this application: {url}')
|
||||
"""str: The message to display when prompting the user for
|
||||
authorization."""
|
||||
_DEFAULT_AUTH_CODE_MESSAGE = (
|
||||
'Enter the authorization code: ')
|
||||
"""str: The message to display when prompting the user for the
|
||||
authorization code. Used only by the console strategy."""
|
||||
|
||||
_DEFAULT_WEB_SUCCESS_MESSAGE = (
|
||||
'The authentication flow has completed, you may close this window.')
|
||||
|
||||
def __init__(self, plugin_dir, server_dir):
|
||||
self.__plugin_dir = plugin_dir
|
||||
self.__server_dir = server_dir
|
||||
self.set_creds()
|
||||
|
||||
# self.get_exclode()
|
||||
|
||||
def setDebug(self, d=False):
|
||||
self.__debug = d
|
||||
|
||||
def D(self, msg=''):
|
||||
if self.__debug:
|
||||
print(msg)
|
||||
|
||||
# 检查gdrive连接
|
||||
def _check_connect(self):
|
||||
try:
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(
|
||||
pageSize=10, fields="nextPageToken, files(id, name)").execute()
|
||||
results.get('files', [])
|
||||
except:
|
||||
return False
|
||||
return True
|
||||
|
||||
# 设置creds
|
||||
def set_creds(self):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
if os.path.exists(token_file):
|
||||
with open(token_file, 'rb') as token:
|
||||
tmp_data = json.load(token)['credentials']
|
||||
self.__creds = google.oauth2.credentials.Credentials(
|
||||
tmp_data['token'],
|
||||
tmp_data['refresh_token'],
|
||||
tmp_data['id_token'],
|
||||
tmp_data['token_uri'],
|
||||
tmp_data['client_id'],
|
||||
tmp_data['client_secret'],
|
||||
tmp_data['scopes'])
|
||||
# if not self._check_connect():
|
||||
# return False
|
||||
# else:
|
||||
# return True
|
||||
|
||||
def get_sign_in_url(self):
|
||||
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
|
||||
self.__plugin_dir + '/credentials.json',
|
||||
scopes=self.__scpos)
|
||||
# flow.redirect_uri = 'https://drive.aapanel.com'
|
||||
flow.redirect_uri = 'https://drive.aapanel.com'
|
||||
auth_url, state = flow.authorization_url(
|
||||
access_type='offline',
|
||||
prompt='consent',
|
||||
include_granted_scopes='false')
|
||||
return auth_url, state
|
||||
|
||||
def set_auth_url(self, url):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
if os.path.exists(token_file):
|
||||
return mw.returnJson(True, "验证成功")
|
||||
|
||||
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
|
||||
self.__plugin_dir + '/credentials.json',
|
||||
scopes=self.__scpos,
|
||||
state=url.split('state=')[1].split('&code=')[0])
|
||||
# flow.redirect_uri = 'https://localhost'
|
||||
flow.redirect_uri = 'https://drive.aapanel.com'
|
||||
flow.fetch_token(authorization_response=url)
|
||||
credentials = flow.credentials
|
||||
|
||||
credentials_data = {}
|
||||
credentials_data['credentials'] = {
|
||||
'token': credentials.token,
|
||||
'id_token': credentials.id_token,
|
||||
'refresh_token': credentials.refresh_token,
|
||||
'token_uri': credentials.token_uri,
|
||||
'client_id': credentials.client_id,
|
||||
'client_secret': credentials.client_secret,
|
||||
'scopes': credentials.scopes}
|
||||
with open(token_file, 'w') as token:
|
||||
json.dump(credentials_data, token)
|
||||
if not self.set_creds():
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
return mw.returnJson(True, "验证成功")
|
||||
|
||||
# 获取token
|
||||
def get_token(self, get):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
import requests
|
||||
try:
|
||||
respone = requests.get("https://www.google.com", timeout=2)
|
||||
except:
|
||||
return mw.returnJson(False, "连接谷歌失败")
|
||||
if respone.status_code != 200:
|
||||
return mw.returnJson(False, "连接谷歌失败")
|
||||
if not self.set_creds():
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
if not os.path.exists(token_file):
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
return mw.returnJson(True, "验证成功")
|
||||
|
||||
# 获取auth_url
|
||||
def get_auth_url(self, get):
|
||||
self.get_sign_in_url()
|
||||
if os.path.exists("/tmp/auth_url"):
|
||||
return mw.readFile("/tmp/auth_url")
|
||||
|
||||
# 检查连接
|
||||
def check_connect(self, get):
|
||||
token_file = self.__server_dir + '/token.json'
|
||||
if os.path.exists(token_file):
|
||||
with open(token_file, 'rb') as token:
|
||||
self.set_creds()
|
||||
else:
|
||||
self.D("Failed to get Google token, please verify before use")
|
||||
return mw.returnJson(True, "Failed to get Google token, please verify before use")
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(
|
||||
pageSize=10, fields="nextPageToken, files(id, name)").execute()
|
||||
try:
|
||||
results.get('files', [])
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
return mw.returnJson(True, "验证成功")
|
||||
except:
|
||||
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
|
||||
|
||||
def _get_filename(self, filename):
|
||||
l = filename.split("/")
|
||||
return l[-1]
|
||||
|
||||
def _create_folder_cycle(self, filepath):
|
||||
l = filepath.split("/")
|
||||
fid_list = []
|
||||
for i in l:
|
||||
if not i:
|
||||
continue
|
||||
fid = self.__get_folder_id(i)
|
||||
if fid:
|
||||
fid_list.append(fid)
|
||||
continue
|
||||
if not fid_list:
|
||||
fid_list.append("")
|
||||
fid_list.append(self.create_folder(i, fid_list[-1]))
|
||||
return fid_list[-1]
|
||||
|
||||
def build_object_name(self, data_type, file_name):
|
||||
"""根据数据类型构建对象存储名称
|
||||
|
||||
:param data_type:
|
||||
:param file_name:
|
||||
:return:
|
||||
"""
|
||||
|
||||
import re
|
||||
prefix_dict = {
|
||||
"site": "web",
|
||||
"database": "db",
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
if not prefix_dict.get(data_type):
|
||||
print("data_type 类型错误!!!")
|
||||
exit(1)
|
||||
|
||||
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+\."
|
||||
sub_search = re.search(file_regx.lower(), file_name)
|
||||
sub_path_name = ""
|
||||
if sub_search:
|
||||
sub_path_name = sub_search.groups()[0]
|
||||
sub_path_name += '/'
|
||||
# 构建OS存储路径
|
||||
object_name = self.__backup_dir_name + \
|
||||
'/{}/{}'.format(data_type, sub_path_name)
|
||||
|
||||
if object_name[:1] == "/":
|
||||
object_name = object_name[1:]
|
||||
return object_name
|
||||
|
||||
# 上传文件
|
||||
def upload_file(self, filename, data_type=None):
|
||||
"""
|
||||
get.filename 上传后的文件名
|
||||
get.filepath 上传文件路径
|
||||
被面板新版计划任务调用时
|
||||
get表示file_name
|
||||
:param get:
|
||||
:return:
|
||||
"""
|
||||
# filename = filename
|
||||
filepath = self.build_object_name(data_type, filename)
|
||||
_filename = self._get_filename(filename)
|
||||
self.D(filepath)
|
||||
self.D(filename)
|
||||
|
||||
parents = self._create_folder_cycle(filepath)
|
||||
self.D(parents)
|
||||
drive_service = build('drive', 'v3', credentials=self.__creds)
|
||||
file_metadata = {'name': _filename, 'parents': [parents]}
|
||||
media = MediaFileUpload(filename, resumable=True)
|
||||
file = drive_service.files().create(
|
||||
body=file_metadata, media_body=media, fields='id').execute()
|
||||
self.D('Upload Success ,File ID: %s' % file.get('id'))
|
||||
return True
|
||||
|
||||
def _get_file_id(self, filename):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, q="name='{}'".format(
|
||||
filename), fields="nextPageToken, files(id, name)").execute()
|
||||
items = results.get('files', [])
|
||||
if not items:
|
||||
return []
|
||||
else:
|
||||
for item in items:
|
||||
return item["id"]
|
||||
|
||||
def delete_file(self, filename=None, data_type=None):
|
||||
file_id = self._get_file_id(filename)
|
||||
self.delete_file_by_id(file_id)
|
||||
return True
|
||||
|
||||
def delete_file_by_id(self, file_id):
|
||||
self.D("delete id:{}".format(file_id))
|
||||
try:
|
||||
drive_service = build('drive', 'v3', credentials=self.__creds)
|
||||
drive_service.files().delete(fileId=file_id).execute()
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
|
||||
# 创建目录
|
||||
def create_folder(self, folder_name, parents=""):
|
||||
self.D(self.__creds)
|
||||
self.D("folder_name: {}".format(folder_name))
|
||||
self.D("parents: {}".format(parents))
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
file_metadata = {
|
||||
'name': folder_name,
|
||||
'mimeType': 'application/vnd.google-apps.folder'
|
||||
}
|
||||
if parents:
|
||||
file_metadata['parents'] = [parents]
|
||||
folder = service.files().create(body=file_metadata, fields='id').execute()
|
||||
self.D('Create Folder ID: %s' % folder.get('id'))
|
||||
return folder.get('id')
|
||||
|
||||
def get_rootdir_id(self, folder_name='backup'):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, q="name='{}' and mimeType='application/vnd.google-apps.folder'".format(folder_name),
|
||||
fields="nextPageToken, files(id, name,size,parents,webViewLink)").execute()
|
||||
items = results.get('files', [])
|
||||
if len(items) == 0:
|
||||
self.create_folder(folder_name)
|
||||
return self.get_rootdir_id(folder_name)
|
||||
|
||||
return items[0]['parents'][0]
|
||||
|
||||
# 获取目录id
|
||||
def __get_folder_id(self, floder_name):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, q="name='{}' and mimeType='application/vnd.google-apps.folder'".format(floder_name),
|
||||
fields="nextPageToken, files(id, name)").execute()
|
||||
items = results.get('files', [])
|
||||
if not items:
|
||||
return []
|
||||
else:
|
||||
for item in items:
|
||||
return item["id"]
|
||||
|
||||
def get_res_info(self, rid):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().get(fileId='{}'.format(rid)).execute()
|
||||
return results
|
||||
|
||||
def get_id_list(self, driveId=''):
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
results = service.files().list(pageSize=10, driveId="{}".format(driveId),
|
||||
fields="nextPageToken, files(id, name,size,parents)").execute()
|
||||
items = results.get('files', [])
|
||||
return items
|
||||
|
||||
def get_list(self, dir_id='', next_page_token=''):
|
||||
if dir_id == '':
|
||||
dir_id = self.get_rootdir_id(self.__backup_dir_name)
|
||||
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
cmd_query = "trashed=false and '{}' in parents".format(dir_id)
|
||||
results = service.files().list(pageSize=10, q=cmd_query, orderBy='folder asc',
|
||||
fields="nextPageToken, files(id, name,size,createdTime,parents,webViewLink)").execute()
|
||||
items = results.get('files', [])
|
||||
nextPageToken = results.get('nextPageToken', [])
|
||||
# print(items)
|
||||
# print(nextPageToken)
|
||||
return items
|
||||
|
||||
def get_exclode(self, exclude=[]):
|
||||
if not exclude:
|
||||
tmp_exclude = os.getenv('MW_EXCLUDE')
|
||||
if tmp_exclude:
|
||||
exclude = tmp_exclude.split(',')
|
||||
if not exclude:
|
||||
return ""
|
||||
for ex in exclude:
|
||||
self.__exclude += " --exclude=\"" + ex + "\""
|
||||
self.__exclude += " "
|
||||
return self.__exclude
|
||||
|
||||
def download_file(self, filename):
|
||||
file_id = self._get_file_id(filename)
|
||||
service = build('drive', 'v3', credentials=self.__creds)
|
||||
request = service.files().get_media(fileId=file_id)
|
||||
with open('/tmp/{}'.format(filename), 'wb') as fh:
|
||||
downloader = MediaIoBaseDownload(fh, request)
|
||||
done = False
|
||||
while done is False:
|
||||
status, done = downloader.next_chunk()
|
||||
print("Download %d%%." % int(status.progress() * 100))
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"web": {
|
||||
"client_id": "226011946234-d3e1vashgag64utjedu1ljt9u39ncrpq.apps.googleusercontent.com",
|
||||
"project_id": "light-willow-341609",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_secret": "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",
|
||||
"redirect_uris": [
|
||||
"https://drive.aapanel.com"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"web": {
|
||||
"client_id": "540181629246-1horo9i4htamdbhiqar9rcbq33bqe2ob.apps.googleusercontent.com",
|
||||
"project_id": "plated-inn-369901",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_secret": "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",
|
||||
"redirect_uris": ["https://drive.aapanel.com"]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,310 @@
|
||||
<style>
|
||||
.upyunCon {
|
||||
height: 428px;
|
||||
}
|
||||
|
||||
.up-place {
|
||||
height: 62px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.up-place .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.up-place .place-input {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
overflow: hidden;
|
||||
margin: 1px 0 0 -1px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
.place-input ul {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.place-input ul li {
|
||||
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.place-input ul li a {
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upyunlist {
|
||||
height: 516px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.up-bottom {
|
||||
background-color: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.up-use {
|
||||
line-height: 50px
|
||||
}
|
||||
|
||||
.list-list .cursor span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.btn-title {
|
||||
margin-top: 1px
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 10px;
|
||||
font-style: oblique;
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
<div class="upyunCon">
|
||||
<div class="up-place pd15">
|
||||
<button id="backBtn" class="btn btn-default btn-sm glyphicon glyphicon-arrow-left pull-left" title="后退"></button>
|
||||
<input id="myPath" type="hidden" value="">
|
||||
<input id="curPath" type="hidden" value="">
|
||||
<div class="place-input pull-left">
|
||||
<div style="width:1400px;height:28px"><ul></ul></div>
|
||||
</div>
|
||||
<button class="refreshBtn btn btn-default btn-sm glyphicon glyphicon-refresh pull-left mr20" title="刷新" style="margin-left:-1px;"></button>
|
||||
<button class="btn btn-default btn-sm pull-right btn-title" onclick="authApi()">授权</button>
|
||||
<button class="btn btn-default btn-sm pull-right mr20 btn-title" onclick="createDir()">新建文件夹</button>
|
||||
</div>
|
||||
|
||||
<div class="upyunlist pd15">
|
||||
<div class="divtable" style="margin-bottom:15px">
|
||||
<table class="table table-hover">
|
||||
<thead><tr><th>名称</th><th>大小</th><th>更新时间</th><th class="text-right">操作</th></tr></thead>
|
||||
<tbody class="list-list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style type="text/css">
|
||||
.check_api {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.up-place {
|
||||
height: 62px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.up-place .btn {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.up-place .place-input {
|
||||
background-color: #f3f3f3;
|
||||
border: 1px solid #ccc;
|
||||
height: 30px;
|
||||
line-height: 28px;
|
||||
overflow: hidden;
|
||||
margin: 1px 0 0 -1px;
|
||||
width: 340px;
|
||||
}
|
||||
|
||||
.place-input ul {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.place-input ul li {
|
||||
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
|
||||
float: left;
|
||||
padding-left: 10px;
|
||||
padding-right: 18px;
|
||||
}
|
||||
|
||||
.place-input ul li a {
|
||||
height: 28px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upyunlist {
|
||||
height: 546px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.up-bottom {
|
||||
background-color: #fafafa;
|
||||
border-top: 1px solid #eee;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.up-use {
|
||||
line-height: 50px
|
||||
}
|
||||
|
||||
.list-list .cursor span {
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.btn-title {
|
||||
margin-top: 1px
|
||||
}
|
||||
|
||||
.step_item{
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.step_item .serial_box{
|
||||
display: inline-block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.step_item .serial{
|
||||
width: 70px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
float: left;
|
||||
}
|
||||
.step_item .serial span{
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
line-height: 28px;
|
||||
font-size: 11px;
|
||||
border-radius: 50%;
|
||||
color: #20a53a;
|
||||
border: 2px solid #20a53a;
|
||||
}
|
||||
.step_item .serial_title{
|
||||
margin-bottom: 10px;
|
||||
font-size: 15px;
|
||||
line-height: 30px;
|
||||
color: #666;
|
||||
}
|
||||
.step_two_url{
|
||||
display: inline-block;
|
||||
overflow: hidden;
|
||||
width: 380px;
|
||||
/*text-overflow: ellipsis;*/
|
||||
white-space: nowrap;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
margin-right: 15px;
|
||||
border-radius: 2px;
|
||||
padding: 0 10px;
|
||||
float: left;
|
||||
width:360px;
|
||||
padding-right: 35px;
|
||||
}
|
||||
.btn_btlink{
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
border: 1px solid #20a53a;
|
||||
color: #fff;
|
||||
background-color: #20a53a;
|
||||
margin-right:10px;
|
||||
}
|
||||
.btn_btlink:hover{
|
||||
color: #fff;
|
||||
background-color: #10952a;
|
||||
border-color: #398439;
|
||||
}
|
||||
.btn_btlink a:visited{
|
||||
color: #fff;
|
||||
background-color: #10952a;
|
||||
border-color: #398439;
|
||||
}
|
||||
.view_video{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.view_video ul li{
|
||||
line-height: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
.setp_one i{
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 25px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.google_drive{
|
||||
width:465px;
|
||||
height:100px;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/html" id="check_api">
|
||||
<div class="check_api">
|
||||
<div class="step_two">
|
||||
<div class="step_item">
|
||||
<div class="serial"><span>1</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">阅读简易操作教程:如何获取Google Drive授权?</div>
|
||||
<div class="serial_conter">
|
||||
<div class="view_video">
|
||||
<ul>
|
||||
<li>1. 点击下面第<div class="serial" style="float: none;width: 45px;"><span>2</span></div>步中的 打开授权链接。<li>
|
||||
<li>2. 在新窗口页面上登录Google Drive账号。阅读授权权限,并同意。<li>
|
||||
<li>3. 页面跳转后,将浏览器的地址栏地址复制到第<div class="serial" style="float: none;width: 45px;"><span>3</span></div>步的文本框中。<li>
|
||||
<li>4. 点击 获取授权,随即完成授权。<li>
|
||||
</ul>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step_item pb15">
|
||||
<div class="serial"><span>2</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">操作1:👇打开授权链接,根据网页提示对插件进行授权。</div>
|
||||
<div class="serial_conter step_two" style="width: 500px;">
|
||||
<input class="bt-input-text mr5 step_two_url" type="text" disabled>
|
||||
<span class="ico-copy mr10" data-copy="" style="vertical-align: middle;cursor: pointer;margin-left: -37px;margin-right: 20px;"></span>
|
||||
<a href="" class="btn_btlink open_btlink" target="_blank" style="padding: 7px 10px;">打开授权链接</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="step_item">
|
||||
<div class="serial"><span>3</span></div>
|
||||
<div class="serial_box">
|
||||
<div class="serial_title">操作2:复制回浏览器跳转后的地址:</div>
|
||||
<div class="serial_conter">
|
||||
<textarea row="3" placeholder="验证URL地址" class="bt-input-text google_drive" style="resize: none;"/></br>
|
||||
<button type="button" class="btn btn-success btn-sm set_auth_btn">获取授权</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<script type="text/javascript" src="/plugins/file?name=gdrive&f=js/gdrive.js"></script>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=gdrive&f=js/gdrive.js", function(){
|
||||
gdList('');
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,338 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
# print(sys.platform)
|
||||
if sys.platform != "darwin":
|
||||
os.chdir("/www/server/mdserver-web")
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
import db
|
||||
|
||||
_ver = sys.version_info
|
||||
is_py2 = (_ver[0] == 2)
|
||||
is_py3 = (_ver[0] == 3)
|
||||
|
||||
DEBUG = False
|
||||
|
||||
if is_py2:
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf-8')
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'gdrive'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def in_array(name, arr=[]):
|
||||
for x in arr:
|
||||
if name == x:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
sys.path.append(getPluginDir() + "/class")
|
||||
from gdriveclient import gdriveclient
|
||||
|
||||
|
||||
gd = gdriveclient(getPluginDir(), getServerDir())
|
||||
gd.setDebug(False)
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[2:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':', 1)
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
|
||||
def status():
|
||||
return 'start'
|
||||
|
||||
|
||||
def isAuthApi():
|
||||
cfg = getServerDir() + "/token.json"
|
||||
if os.path.exists(cfg):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def getConf():
|
||||
if not isAuthApi():
|
||||
sign_in_url, state = gd.get_sign_in_url()
|
||||
return mw.returnJson(False, "未授权!", {'auth_url': sign_in_url})
|
||||
return mw.returnJson(True, "OK")
|
||||
|
||||
|
||||
def setAuthUrl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['url'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
url = args['url']
|
||||
|
||||
try:
|
||||
if url.startswith("http://"):
|
||||
url = url.replace("http://", "https://")
|
||||
token = gd.set_auth_url(url)
|
||||
# gd.store_token(token)
|
||||
# gd.store_user()
|
||||
return mw.returnJson(True, "授权成功!")
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, "授权失败2!:" + str(e))
|
||||
return mw.returnJson(False, "授权失败!:" + str(e))
|
||||
|
||||
|
||||
def clearAuth():
|
||||
token = getServerDir() + "/token.json"
|
||||
if os.path.exists(token):
|
||||
os.remove(token)
|
||||
return mw.returnJson(True, "清空授权成功!")
|
||||
|
||||
|
||||
def getList():
|
||||
if not isAuthApi():
|
||||
return mw.returnJson(False, "未配置,请点击`授权`", [])
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file_id'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
try:
|
||||
flist = gd.get_list(args['file_id'])
|
||||
return mw.returnJson(True, "ok", flist)
|
||||
except Exception as e:
|
||||
return mw.returnJson(False, str(e), [])
|
||||
|
||||
|
||||
def createDir():
|
||||
if not isAuthApi():
|
||||
return mw.returnJson(False, "未配置,请点击`授权`", [])
|
||||
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['parents', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
isok = gd.create_folder(args['name'], args['parents'])
|
||||
if isok:
|
||||
return mw.returnJson(True, "创建成功")
|
||||
return mw.returnJson(False, "创建失败")
|
||||
|
||||
|
||||
def deleteDir():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['dir_name', 'path'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
isok = gd.delete_file_by_id(args['dir_name'])
|
||||
if isok:
|
||||
return mw.returnJson(True, "删除成功")
|
||||
return mw.returnJson(False, "文件不为空,删除失败!")
|
||||
|
||||
|
||||
def deleteFile():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['path', 'filename'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
isok = gd.delete_file(args['filename'])
|
||||
if isok:
|
||||
return mw.returnJson(True, "删除成功")
|
||||
return mw.returnJson(False, "删除失败")
|
||||
|
||||
|
||||
def findPathName(path, filename):
|
||||
f = os.scandir(path)
|
||||
l = []
|
||||
for ff in f:
|
||||
t = {}
|
||||
if ff.name.find(filename) > -1:
|
||||
t['filename'] = path + '/' + ff.name
|
||||
l.append(t)
|
||||
return l
|
||||
|
||||
|
||||
def backupAllFunc(stype):
|
||||
if not isAuthApi():
|
||||
mw.echoInfo("未授权API,无法使用!!!")
|
||||
return ''
|
||||
|
||||
os.chdir(mw.getRunDir())
|
||||
backup_dir = mw.getBackupDir()
|
||||
run_dir = mw.getRunDir()
|
||||
|
||||
stype = sys.argv[1]
|
||||
name = sys.argv[2]
|
||||
num = sys.argv[3]
|
||||
|
||||
prefix_dict = {
|
||||
"site": "web",
|
||||
"database": "db",
|
||||
"path": "path",
|
||||
}
|
||||
|
||||
backups = []
|
||||
sql = db.Sql()
|
||||
|
||||
# print("stype:", stype)
|
||||
# 提前获取-清理多余备份
|
||||
if stype == 'site':
|
||||
pid = sql.table('sites').where('name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('0', pid)).field('id,filename').select()
|
||||
if stype == 'database':
|
||||
db_path = mw.getServerDir() + '/mysql'
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
if stype == 'path':
|
||||
backup_path = backup_dir + '/path'
|
||||
_name = 'path_{}'.format(os.path.basename(name))
|
||||
backups = findPathName(backup_path, _name)
|
||||
|
||||
# 其他类型关系性数据库(mysql类的)
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
db_path = mw.getServerDir() + '/' + plugin_name
|
||||
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
|
||||
'name=?', (name,)).getField('id')
|
||||
backups = sql.table('backup').where(
|
||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
||||
|
||||
args = stype + " " + name + " " + num
|
||||
cmd = 'python3 ' + run_dir + '/scripts/backup.py ' + args
|
||||
if stype.find('database_') > -1:
|
||||
plugin_name = stype.replace('database_', '')
|
||||
args = "database " + name + " " + num
|
||||
cmd = 'python3 ' + run_dir + '/plugins/' + \
|
||||
plugin_name + '/scripts/backup.py ' + args
|
||||
|
||||
if stype == 'path':
|
||||
name = os.path.basename(name)
|
||||
|
||||
# print("cmd:", cmd)
|
||||
os.system(cmd)
|
||||
|
||||
# 开始执行上传信息.
|
||||
if stype.find('database_') > -1:
|
||||
bk_name = 'database'
|
||||
plugin_name = stype.replace('database_', '')
|
||||
bk_prefix = plugin_name + '/db'
|
||||
stype = 'database'
|
||||
else:
|
||||
bk_prefix = prefix_dict[stype]
|
||||
bk_name = stype
|
||||
|
||||
find_path = backup_dir + '/' + bk_name + '/' + bk_prefix + '_' + name
|
||||
find_new_file = "ls " + find_path + \
|
||||
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
|
||||
|
||||
# print(find_new_file)
|
||||
|
||||
filename = mw.execShell(find_new_file)[0].strip()
|
||||
if filename == "":
|
||||
mw.echoInfo("not find upload file!")
|
||||
return False
|
||||
|
||||
mw.echoInfo("准备上传文件 {}".format(filename))
|
||||
mw.echoStart('开始上传')
|
||||
# gd.setDebug(False)
|
||||
gd.upload_file(filename, stype)
|
||||
mw.echoEnd('上传成功')
|
||||
|
||||
# print(backups)
|
||||
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
|
||||
mw.echoStart('开始删除远程备份')
|
||||
num = int(num)
|
||||
sep = len(backups) - num
|
||||
if sep > -1:
|
||||
for backup in backups:
|
||||
fn = os.path.basename(backup['filename'])
|
||||
gd.delete_file(fn, stype)
|
||||
mw.echoInfo("---已清理远程过期备份文件:" + fn)
|
||||
sep -= 1
|
||||
if sep < 0:
|
||||
break
|
||||
mw.echoEnd('结束删除远程备份')
|
||||
|
||||
return ''
|
||||
|
||||
|
||||
def installPreInspection():
|
||||
return 'ok'
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'install_pre_inspection':
|
||||
print(installPreInspection())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'set_auth_url':
|
||||
print(setAuthUrl())
|
||||
elif func == 'clear_auth':
|
||||
print(clearAuth())
|
||||
elif func == "get_list":
|
||||
print(getList())
|
||||
elif func == "create_dir":
|
||||
print(createDir())
|
||||
elif func == "delete_dir":
|
||||
print(deleteDir())
|
||||
elif func == 'delete_file':
|
||||
print(deleteFile())
|
||||
elif in_array(func, ['site', 'database', 'path']) or func.find('database_') > -1:
|
||||
print(backupAllFunc(func))
|
||||
else:
|
||||
print('error')
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"hook":["backup"],
|
||||
"id":998,
|
||||
"title":"谷歌云网盘",
|
||||
"tip":"lib",
|
||||
"name":"gdrive",
|
||||
"type":"扩展",
|
||||
"ps":"备份你的数据到谷歌云网盘",
|
||||
"versions":"2.0",
|
||||
"shell":"install.sh",
|
||||
"checks": "server/gdrive",
|
||||
"path":"server/gdrive",
|
||||
"author":"google",
|
||||
"home":"https://drive.google.com/",
|
||||
"api_doc":"https://developers.google.com/drive/api/guides/about-sdk?hl=zh_CN",
|
||||
"api_doc2":"https://developers.google.cn/drive/api/reference/rest/v3/comments/list?hl=zh-cn",
|
||||
"date":"2022-06-26",
|
||||
"pid":"5"
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# cd /www/server/mdserver-web/plugins/gdrive && /bin/bash install.sh install 2.0
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
PATH=$PATH:${rootPath}/bin
|
||||
export PATH
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
VERSION=$2
|
||||
|
||||
Install_App()
|
||||
{
|
||||
tmp_ping=`ping -c 1 google.com 2>&1`
|
||||
echo $tmp_ping
|
||||
if [ $? -eq 0 ];then
|
||||
tmp=`python -V 2>&1|awk '{print $2}'`
|
||||
pVersion=${tmp:0:3}
|
||||
|
||||
|
||||
which pip
|
||||
if [ "$?" -eq "0" ];then
|
||||
tmp=$(pip list|grep google-api-python-client|awk '{print $2}')
|
||||
if [ "$tmp" != '2.39.0' ];then
|
||||
pip install --upgrade google-api-python-client
|
||||
# pip uninstall google-api-python-client -y
|
||||
pip install -I google-api-python-client==2.39.0 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
tmp=$(pip list|grep google-auth-httplib2|awk '{print $2}')
|
||||
if [ "$tmp" != '0.1.0' ];then
|
||||
pip uninstall google-auth-httplib2 -y
|
||||
pip install -I google-auth-httplib2==0.1.0 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
tmp=$(pip list|grep google-auth-oauthlib|awk '{print $2}')
|
||||
if [ "$tmp" != '0.5.0' ];then
|
||||
# pip uninstall google-auth-oauthlib -y
|
||||
pip install -I google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
tmp=$(pip list|grep -E '^httplib2'|awk '{print $2}')
|
||||
if [ "$tmp" != '0.18.1' ];then
|
||||
# pip uninstall httplib2 -y
|
||||
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
else
|
||||
pip install -I pyOpenSSL
|
||||
pip install -I google-api-python-client==2.39.0 google-auth-httplib2==0.1.0 google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
|
||||
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
|
||||
fi
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
|
||||
mkdir -p $serverPath/gdrive
|
||||
echo "${VERSION}" > $serverPath/gdrive/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
else
|
||||
echo '服务器连接不上谷歌云!安装失败!' > $install_tmp
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
rm -rf $serverPath/gdrive
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
|
||||
action=$1
|
||||
type=$2
|
||||
|
||||
echo $action $type
|
||||
if [ "${action}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
@@ -0,0 +1,260 @@
|
||||
|
||||
function gdPost(method,args,callback){
|
||||
var _args = null;
|
||||
if (typeof(args) == 'string'){
|
||||
_args = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
_args = JSON.stringify(args);
|
||||
}
|
||||
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
$.post('/plugins/run', {name:'gdrive', func:method, args:_args}, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
|
||||
function createDir(){
|
||||
layer.open({
|
||||
type: 1,
|
||||
area: "400px",
|
||||
title: "创建目录",
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
btn: ['确定','取消'],
|
||||
content:'<div class="bingfa bt-form c6" style="padding-bottom: 10px;">\
|
||||
<p>\
|
||||
<span class="span_tit">目录名称:</span>\
|
||||
<input style="width: 200px;" type="text" name="newPath" value="">\
|
||||
</p>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("input[name='newPath']").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(index,layero){
|
||||
var name = $("input[name='newPath']").val();
|
||||
if(name == ''){
|
||||
layer.msg('目录名称不能为空!',{icon:2});
|
||||
return;
|
||||
}
|
||||
var parents = $("#myPath").val();
|
||||
var cur_file_id = $('#curPath').val();
|
||||
if (cur_file_id!=''){
|
||||
parents = cur_file_id;
|
||||
}
|
||||
|
||||
var dirname = name;
|
||||
var loadT = layer.msg('正在创建目录['+dirname+']...',{icon:16,time:0,shade: [0.3, '#000']});
|
||||
gdPost('create_dir', {parents:parents,name:dirname}, function(data){
|
||||
layer.close(loadT);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if(rdata.status) {
|
||||
showMsg(rdata.msg, function(){
|
||||
layer.close(index);
|
||||
var file_id = $('#myPath').val();
|
||||
if (cur_file_id!=''){
|
||||
file_id = cur_file_id;
|
||||
}
|
||||
gdList(file_id);
|
||||
} ,{icon:1}, 2000);
|
||||
} else{
|
||||
layer.msg(rdata.msg,{icon:2});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//设置API
|
||||
function authApi(){
|
||||
|
||||
gdPost('conf', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
|
||||
// console.log(rdata);
|
||||
// console.log(rdata.data.auth_url);
|
||||
var apicon = '';
|
||||
if (rdata.status){
|
||||
|
||||
var html = '';
|
||||
html += '<button id="clear_auth" onclick="clearAuth();" class="btn btn-default btn-sm">清空配置</button>';
|
||||
|
||||
var loadOpen = layer.open({
|
||||
type: 1,
|
||||
title: '已授权',
|
||||
area: '240px',
|
||||
content:'<div class="change-default pd20">'+html+'</div>',
|
||||
success: function(){
|
||||
$('#clear_auth').click(function(){
|
||||
gdPost('clear_auth', {}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
layer.close(loadOpen);
|
||||
gdList('');
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
||||
} else{
|
||||
apicon = '<div class="new_form">'+$("#check_api").html()+'</div>';
|
||||
}
|
||||
|
||||
var layer_auth = layer.open({
|
||||
type: 1,
|
||||
area: "620px",
|
||||
title: "Google Drive 授权",
|
||||
closeBtn: 1,
|
||||
shift: 5,
|
||||
shadeClose: false,
|
||||
content:apicon,
|
||||
success:function(layero,index){
|
||||
// console.log(layero,index);
|
||||
if (!rdata.status){
|
||||
$('.check_api .step_two_url').val(rdata.data['auth_url']);
|
||||
$('.check_api .open_btlink').attr('href',rdata.data['auth_url']);
|
||||
|
||||
$('.check_api .ico-copy').click(function(){
|
||||
copyPass(rdata.data['auth_url']);
|
||||
});
|
||||
|
||||
$('.check_api .set_auth_btn').click(function(){
|
||||
|
||||
var url = $('.check_api .google_drive').val();
|
||||
if ( url == ''){
|
||||
layer.msg("验证URL不能为空",{icon:2});
|
||||
return;
|
||||
}
|
||||
// console.log(url);
|
||||
gdPost('set_auth_url', {url:url}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
var show_time = 2000;
|
||||
if (!rdata.status){
|
||||
show_time = 10000;
|
||||
}
|
||||
|
||||
showMsg(rdata.msg,function(){
|
||||
if (rdata.status){
|
||||
layer.close(layer_auth);
|
||||
gdList('');
|
||||
}
|
||||
},{icon:rdata.status?1:2},show_time);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
//计算当前目录偏移
|
||||
function upPathLeft(){
|
||||
var UlWidth = $(".place-input ul").width();
|
||||
var SpanPathWidth = $(".place-input").width() - 20;
|
||||
var Ml = UlWidth - SpanPathWidth;
|
||||
if(UlWidth > SpanPathWidth ){
|
||||
$(".place-input ul").css("left",-Ml)
|
||||
}
|
||||
else{
|
||||
$(".place-input ul").css("left",0)
|
||||
}
|
||||
}
|
||||
|
||||
function getGDTime(a) {
|
||||
return new Date(a).format("yyyy/MM/dd hh:mm:ss")
|
||||
}
|
||||
|
||||
function gdList(file_id){
|
||||
$('#curPath').val(file_id);
|
||||
gdPost('get_list', {file_id:file_id}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
console.log(rdata);
|
||||
if(rdata.status === false){
|
||||
showMsg(rdata.msg,function(){
|
||||
authApi();
|
||||
},{icon:2},2000);
|
||||
return;
|
||||
}
|
||||
|
||||
var mlist = rdata.data;
|
||||
var listBody = '';
|
||||
var listFiles = '';
|
||||
for(var i=0;i<mlist.length;i++){
|
||||
if(mlist[i].size == null){
|
||||
listFiles += '<tr><td class="cursor" onclick="gdList(\''+(mlist[i].id).replace('//','/')+'\')"><span class="ico ico-folder"></span>\<span>'+mlist[i].name+'</span></td>\
|
||||
<td>-</td>\
|
||||
<td>-</td>\
|
||||
<td class="text-right"><a class="btlink" onclick="deleteFile(\''+mlist[i].id+'\', true)">删除</a></td></tr>'
|
||||
}else{
|
||||
listFiles += '<tr><td class="cursor"><span class="ico ico-file"></span><span>'+mlist[i].name+'</span></td>\
|
||||
<td>'+toSize(mlist[i].size)+'</td>\
|
||||
<td>'+getGDTime(mlist[i].createdTime)+'</td>\
|
||||
<td class="text-right"><a target="_blank" href="'+mlist[i].webViewLink+'" class="btlink">下载</a> | <a class="btlink" onclick="deleteFile(\''+mlist[i].name+'\', false)">删除</a></td></tr>'
|
||||
}
|
||||
}
|
||||
listBody += listFiles;
|
||||
var pathLi = '<li><a title="根目录" onclick="gdList(\'\')">根目录</a></li>';
|
||||
|
||||
if (mlist.length>0){
|
||||
$('#myPath').val(mlist[0]['parents'][0]);
|
||||
}
|
||||
|
||||
$(".upyunCon .place-input ul").html(pathLi);
|
||||
$(".upyunlist .list-list").html(listBody);
|
||||
|
||||
$('#backBtn').unbind().click(function() {
|
||||
gdList('');
|
||||
});
|
||||
|
||||
$('.upyunCon .refreshBtn').unbind().click(function(){
|
||||
var file_id = $('#myPath').val();
|
||||
gdList(file_id);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//删除文件
|
||||
function deleteFile(name, is_dir){
|
||||
if (is_dir === false){
|
||||
safeMessage('删除文件','删除后将无法恢复,真的要删除['+name+']吗?',function(){
|
||||
var path = $("#myPath").val();
|
||||
var filename = name;
|
||||
gdPost('delete_file', {filename:filename,path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
var file_id = $('#myPath').val();
|
||||
gdList(file_id);
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
safeMessage('删除文件夹','删除后将无法恢复,真的要删除文件资源['+name+']吗?',function(){
|
||||
var path = $("#myPath").val();
|
||||
gdPost('delete_dir', {dir_name:name,path:path}, function(rdata){
|
||||
var rdata = $.parseJSON(rdata.data);
|
||||
showMsg(rdata.msg,function(){
|
||||
var file_id = $('#myPath').val();
|
||||
gdList(file_id);
|
||||
},{icon:rdata.status?1:2},2000);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8
|
||||
|
||||
# python3 plugins/gdrive/t/test.py
|
||||
# https://console.cloud.google.com/apis/credentials/consent?project=plated-inn-369901
|
||||
|
||||
# https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=226011946234-d3e1vashgag64utjedu1ljt9u39ncrpq.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fdrive.aapanel.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&state=I2da4aZUwqgmikrgrqAwwSjyoEHVs1&access_type=offline&prompt=consent&include_granted_scopes=false
|
||||
|
||||
|
||||
# https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/08125e6b-6502-4ac9-9548-ad682f00848d/objectId/62b1d655-9828-47ed-be99-65eb18c3a929/isMSAApp~/false/defaultBlade/Overview/appSignInAudience/AzureADandPersonalMicrosoftAccount/servicePrincipalCreated~/true
|
||||
|
||||
# 0WA8Q~sZkZFZKv50ryP4ux~.fpVtbHw7BuTZmbQB
|
||||
# client_id:d9878fac-8526-4ff6-8036-e1c92dd9dd80
|
||||
|
||||
# 08125e6b-6502-4ac9-9548-ad682f00848d
|
||||
|
||||
|
||||
# /drive/v2internal/files?openDrive=false&reason=102&syncType=0&errorRecovery=false&q=trashed = false and '1-z6gUXseXmlxmntvkLzOe_tYFT5tdhM9' in parents&fields=kind,nextPageToken,items(kind,modifiedDate,hasVisitorPermissions,containsUnsubscribedChildren,modifiedByMeDate,lastViewedByMeDate,alternateLink,fileSize,owners(kind,permissionId,emailAddressFromAccount,id),lastModifyingUser(kind,permissionId,emailAddressFromAccount,id),customerId,ancestorHasAugmentedPermissions,hasThumbnail,thumbnailVersion,title,id,resourceKey,abuseIsAppealable,abuseNoticeReason,shared,accessRequestsCount,sharedWithMeDate,userPermission(role),explicitlyTrashed,mimeType,quotaBytesUsed,copyable,subscribed,folderColor,hasChildFolders,fileExtension,primarySyncParentId,sharingUser(kind,permissionId,emailAddressFromAccount,id),flaggedForAbuse,folderFeatures,spaces,sourceAppId,recency,recencyReason,version,actionItems,teamDriveId,hasAugmentedPermissions,createdDate,primaryDomainName,organizationDisplayName,passivelySubscribed,trashingUser(kind,permissionId,emailAddressFromAccount,id),trashedDate,parents(id),capabilities(canMoveItemIntoTeamDrive,canUntrash,canModifyContentRestriction,canMoveItemWithinTeamDrive,canMoveItemOutOfTeamDrive,canDeleteChildren,canTrashChildren,canRequestApproval,canReadCategoryMetadata,canEditCategoryMetadata,canAddMyDriveParent,canRemoveMyDriveParent,canShareChildFiles,canShareChildFolders,canRead,canMoveItemWithinDrive,canMoveChildrenWithinDrive,canAddFolderFromAnotherDrive,canChangeSecurityUpdateEnabled,canBlockOwner,canReportSpamOrAbuse,canCopy,canDownload,canEdit,canAddChildren,canDelete,canRemoveChildren,canShare,canTrash,canRename,canReadTeamDrive,canMoveTeamDriveItem),contentRestrictions(readOnly),approvalMetadata(approvalVersion,approvalSummaries,hasIncomingApproval),shortcutDetails(targetId,targetMimeType,targetLookupStatus,targetFile,canRequestAccessToTarget),spamMetadata(markedAsSpamDate,inSpamView),labels(starred,trashed,restricted,viewed)),incompleteSearch&appDataFilter=NO_APP_DATA&spaces=drive&maxResults=200&supportsTeamDrives=true&includeItemsFromAllDrives=true&corpora=default&orderBy=folder,title_natural asc&retryCount=0&key=AIzaSyD_InbmSFufIEps5UAt2NmB_3LvBH3Sz_8 HTTP/1.1
|
||||
|
||||
# http://localhost/?code=M.C106_BAY.2.3e12c859-6107-0c5b-9ef4-14b3fb8269ba&state=JzHdzHXmA7x6zl7Be6cJ6uOlf9Bg69
|
||||
|
||||
|
||||
# python3 /www/mdserver-web/plugins/gdrive/index.py site bbs.midoks.me 3
|
||||
# python3 /www/mdserver-web/plugins/gdrive/index.py database t1 3
|
||||
# python3 /www/server/mdserver-web/plugins/msonedrive/index.py path
|
||||
# /Users/midoks/Desktop/dev/python 3
|
||||
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import json
|
||||
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'gdrive'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
# print(getPluginDir())
|
||||
sys.path.append(getPluginDir() + "/class")
|
||||
from gdriveclient import gdriveclient
|
||||
|
||||
|
||||
gd = gdriveclient(getPluginDir(), getServerDir())
|
||||
gd.setDebug(True)
|
||||
# sign_in_url, state = gd.get_sign_in_url()
|
||||
# print(sign_in_url)
|
||||
|
||||
# url = 'https://localhost/?state=GH2YZ1VeytzVB1BqJJpQZIBk2GGAub&code=4/0Adeu5BXnD2dQvXx8Sg0WPn1XiMpihcRBNaG1yaFKIo86gUiG7q65KU1MaNCxrj_f2bjkwQ&scope=https://www.googleapis.com/auth/drive.file'
|
||||
# t = gd.set_auth_url(url)
|
||||
# print(t)
|
||||
|
||||
# def set_auth_url(url):
|
||||
# try:
|
||||
# if url.startswith("http://"):
|
||||
# url = url.replace("http://", "https://")
|
||||
# token = msodc.get_token_from_authorized_url(
|
||||
# authorized_url=url)
|
||||
# msodc.store_token(token)
|
||||
# msodc.store_user()
|
||||
# return mw.returnJson(True, "授权成功!")
|
||||
# except Exception as e:
|
||||
# print(e)
|
||||
# return mw.returnJson(False, "授权失败2!:" + str(e))
|
||||
# return mw.returnJson(False, "授权失败!:" + str(e))
|
||||
|
||||
# url = 'http://localhost/?code=M.C106_BAY.2.310112f3-a158-c400-9667-d158cbd1de6c&state=jEJz0ucR9bpZYD9PGxp2GgRDotrzO6'
|
||||
# token = set_auth_url(url)
|
||||
# print(token)
|
||||
|
||||
# token = msodc.get_token()
|
||||
# print("token:", token)
|
||||
|
||||
# t = gd.get_list('')
|
||||
# print(t)
|
||||
|
||||
# t = gd.get_id_list('1u7LjXGj1KoN-ltAdTRaib7IZJpsEnPdz')
|
||||
# print(t)
|
||||
|
||||
# t = gd.create_folder('backup_demo')
|
||||
# print(t)
|
||||
|
||||
# t = msodc.delete_object('backup')
|
||||
# print(t)
|
||||
|
||||
|
||||
# t = gd.upload_file('web_t1.cn_20230830_134549.tar.gz', 'site')
|
||||
# print(t)
|
||||
# print(gd.error_msg)
|
||||
|
||||
# /Users/midoks/Desktop/mwdev/server/mdserver-web/paramiko.log
|
||||
# backup/site/paramiko.log
|
||||
# |-正在上传到 backup/site/paramiko.log...
|
||||
# True
|
||||
|
||||
|
||||
t = gd.upload_file(
|
||||
'db_zzzvps_20230830_210727.sql.gz', 'datebase')
|
||||
print(t)
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
H_DIR={$HOOK_DIR}
|
||||
HL_DIR={$HOOK_LOGS_DIR}
|
||||
|
||||
|
||||
SH_LIST=`cd ${H_DIR} && ls | grep ".sh$"`
|
||||
|
||||
for sh_f in $SH_LIST; do
|
||||
ABS_FILE=${H_DIR}/${sh_f}
|
||||
ABS_LOGS=${HL_DIR}/${sh_f}.log
|
||||
echo "sh ${ABS_FILE} 2>${ABS_LOGS}"
|
||||
sh -x ${ABS_FILE} 2>${ABS_LOGS}
|
||||
done
|
||||
@@ -1,13 +1,21 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('gitea');">服务</p>
|
||||
<p onclick="pluginInitD('gitea');">自启动</p>
|
||||
<!-- <p onclick="pluginConfig('gitea',null, 'init_conf');">启动配置</p> -->
|
||||
<p onclick="gogsEdit();">手动编辑</p>
|
||||
<p onclick="pluginConfig('gitea',null, 'conf');">配置文件</p>
|
||||
<p onclick="gogsSetConfig();">配置修改</p>
|
||||
<p onclick="giteaUserList();">用户列表</p>
|
||||
<p onclick="giteaRepoList();">项目列表</p>
|
||||
<!-- <p onclick="pluginLogs('gitea',null,'run_log');">运行日志</p> -->
|
||||
<!-- <p onclick="pluginLogs('gitea',null,'post_receive_log');" title="提交post-receive日志">提交日志</p> -->
|
||||
<p onclick="giteaRead();">使用说明</p>
|
||||
@@ -18,6 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(530);
|
||||
$.getScript( "/plugins/file?name=gitea&f=js/gitea.js",function(){
|
||||
pluginService('gitea');
|
||||
});
|
||||
|
||||
+402
-19
@@ -453,6 +453,13 @@ def submitGogsConf():
|
||||
return mw.returnJson(True, '设置成功')
|
||||
|
||||
|
||||
def gogsEditTpl():
|
||||
data = {}
|
||||
data['post_receive'] = getPluginDir() + '/hook/post-receive.tpl'
|
||||
data['commit'] = getPluginDir() + '/hook/commit.tpl'
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
def userList():
|
||||
|
||||
conf = getConf()
|
||||
@@ -473,7 +480,66 @@ def userList():
|
||||
|
||||
page = int(args['page'])
|
||||
page_size = int(args['page_size'])
|
||||
tojs = args['tojs']
|
||||
search = ''
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
|
||||
user_where1 = ''
|
||||
user_where2 = ''
|
||||
if search != '':
|
||||
user_where1 = ' where name like "%' + search + '%"'
|
||||
user_where2 = ' where name like "%' + search + '%"'
|
||||
|
||||
data = {}
|
||||
|
||||
data['root_url'] = getRootUrl()
|
||||
|
||||
start = (page - 1) * page_size
|
||||
list_count = pQuery('select count(id) as num from user' + user_where1)
|
||||
count = list_count[0]["num"]
|
||||
list_data = pQuery(
|
||||
'select id,name,email from user ' + user_where2 + ' order by id desc limit ' + str(start) + ',' + str(page_size))
|
||||
data['list'] = mw.getPage({'count': count, 'p': page,
|
||||
'row': page_size, 'tojs': 'gogsUserList'})
|
||||
data['page'] = page
|
||||
data['page_size'] = page_size
|
||||
data['page_count'] = int(math.ceil(count / page_size))
|
||||
data['data'] = list_data
|
||||
return mw.returnJson(True, 'OK', data)
|
||||
|
||||
|
||||
def checkRepoListIsHasScript(data):
|
||||
path = getRootPath()
|
||||
for x in range(len(data)):
|
||||
name = data[x]['name'] + '/' + data[x]['repo'] + '.git'
|
||||
path_tmp = path + '/' + name + '/custom_hooks/commit'
|
||||
if os.path.exists(path_tmp):
|
||||
data[x]['has_hook'] = True
|
||||
else:
|
||||
data[x]['has_hook'] = False
|
||||
return data
|
||||
|
||||
|
||||
def repoList():
|
||||
|
||||
conf = getConf()
|
||||
if not os.path.exists(conf):
|
||||
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
|
||||
|
||||
conf = getDbConfValue()
|
||||
gtype = getGiteaDbType(conf)
|
||||
if gtype != 'mysql':
|
||||
return mw.returnJson(False, "仅支持mysql数据操作!")
|
||||
|
||||
import math
|
||||
args = getArgs()
|
||||
|
||||
data = checkArgs(args, ['page', 'page_size'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
page = int(args['page'])
|
||||
page_size = int(args['page_size'])
|
||||
search = ''
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
@@ -482,14 +548,25 @@ def userList():
|
||||
|
||||
data['root_url'] = getRootUrl()
|
||||
|
||||
start = (page - 1) * page_size
|
||||
list_count = pQuery('select count(id) as num from user')
|
||||
repo_where1 = ''
|
||||
repo_where2 = ''
|
||||
if search != '':
|
||||
repo_where1 = ' where name like "%' + search + '%"'
|
||||
repo_where2 = ' where r.name like "%' + search + '%"'
|
||||
|
||||
start = (page - 1) * page_size
|
||||
list_count = pQuery(
|
||||
'select count(id) as num from repository' + repo_where1)
|
||||
count = list_count[0]["num"]
|
||||
list_data = pQuery(
|
||||
'select id,name,email from user order by id desc limit ' + str(start) + ',' + str(page_size))
|
||||
data['list'] = mw.getPage(
|
||||
{'count': count, 'p': page, 'row': page_size, 'tojs': tojs})
|
||||
sql = 'select r.id,r.owner_id,r.name as repo, u.name from repository r left join user u on r.owner_id=u.id ' + repo_where2 + ' order by r.id desc limit ' + \
|
||||
str(start) + ',' + str(page_size)
|
||||
# print(sql)
|
||||
list_data = pQuery(sql)
|
||||
# print(list_data)
|
||||
list_data = checkRepoListIsHasScript(list_data)
|
||||
|
||||
data['list'] = mw.getPage({'count': count, 'p': page,
|
||||
'row': page_size, 'tojs': 'gogsRepoListPage'})
|
||||
data['page'] = page
|
||||
data['page_size'] = page_size
|
||||
data['page_count'] = int(math.ceil(count / page_size))
|
||||
@@ -586,11 +663,9 @@ def projectScriptEdit():
|
||||
|
||||
def projectScriptLoad():
|
||||
args = getArgs()
|
||||
if not 'user' in args:
|
||||
return mw.returnJson(True, 'username missing')
|
||||
|
||||
if not 'name' in args:
|
||||
return mw.returnJson(True, 'project name missing')
|
||||
data = checkArgs(args, ['user', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
@@ -670,11 +745,299 @@ def projectScriptDebug():
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
def gogsEdit():
|
||||
data = {}
|
||||
data['post_receive'] = getPluginDir() + '/hook/post-receive.tpl'
|
||||
data['commit'] = getPluginDir() + '/hook/commit.tpl'
|
||||
return mw.getJson(data)
|
||||
def projectScriptRun():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
|
||||
path = getRootPath() + '/' + user + '/' + name
|
||||
commit_sh = path + '/custom_hooks/commit'
|
||||
commit_log = path + '/custom_hooks/sh.log'
|
||||
script_run = 'sh -x ' + commit_sh + ' 2>' + commit_log
|
||||
|
||||
if not os.path.exists(commit_sh):
|
||||
return mw.returnJson(False, '脚本文件不存在!')
|
||||
|
||||
mw.execShell(script_run)
|
||||
mw.execShell('chown -R www:www ' + commit_log)
|
||||
return mw.returnJson(True, '脚本文件执行成功,观察日志!')
|
||||
|
||||
|
||||
def projectScriptSelf():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
|
||||
self_path = custom_hooks + '/self'
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
mw.execShell("chown -R www:www " + self_path)
|
||||
|
||||
self_logs_path = custom_hooks + '/self_logs'
|
||||
if not os.path.exists(self_logs_path):
|
||||
os.mkdir(self_logs_path)
|
||||
mw.execShell("chown -R www:www " + self_logs_path)
|
||||
|
||||
self_hook_file = custom_hooks + '/self_hook.sh'
|
||||
self_hook_exist = False
|
||||
if os.path.exists(self_hook_file):
|
||||
self_hook_exist = True
|
||||
|
||||
dlist = []
|
||||
if os.path.exists(self_path):
|
||||
for filename in os.listdir(self_path):
|
||||
tmp = {}
|
||||
filePath = self_path + '/' + filename
|
||||
if os.path.isfile(filePath):
|
||||
tmp['path'] = filePath
|
||||
tmp['name'] = os.path.basename(filePath)
|
||||
tmp['is_hidden'] = False
|
||||
if tmp['name'].endswith('.txt'):
|
||||
tmp['is_hidden'] = True
|
||||
|
||||
dlist.append(tmp)
|
||||
|
||||
dlist_sum = len(dlist)
|
||||
# print(dlist)
|
||||
rdata = {}
|
||||
rdata['data'] = dlist
|
||||
rdata['self_hook'] = self_hook_exist
|
||||
rdata['list'] = mw.getPage(
|
||||
{'count': dlist_sum, 'p': 1, 'row': 100, 'tojs': 'self_page'})
|
||||
|
||||
return mw.returnJson(True, 'ok', rdata)
|
||||
|
||||
|
||||
def projectScriptSelf_Create():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
self_path = path = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
abs_file = self_path + '/' + file + '.sh'
|
||||
if os.path.exists(abs_file):
|
||||
return mw.returnJson(False, '脚本已经存在!')
|
||||
|
||||
mw.writeFile(abs_file, "#!/bin/bash\necho `date +'%Y-%m-%d %H:%M:%S'`\n")
|
||||
mw.execShell('chown -R www:www ' + abs_file)
|
||||
rdata = {}
|
||||
rdata['abs_file'] = abs_file
|
||||
return mw.returnJson(True, '创建文件成功!', rdata)
|
||||
|
||||
|
||||
def projectScriptSelf_Del():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
abs_file = self_path + '/' + file
|
||||
# print(abs_file)
|
||||
if not os.path.exists(abs_file):
|
||||
return mw.returnJson(False, '脚本已经删除!')
|
||||
|
||||
os.remove(abs_file)
|
||||
|
||||
# 日志也删除
|
||||
log_file = custom_hooks + '/self_logs/' + file + '.log'
|
||||
if os.path.exists(log_file):
|
||||
os.remove(log_file)
|
||||
|
||||
return mw.returnJson(True, '脚本删除成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Logs():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
self_path = path = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks/self_logs'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
logs_file = self_path + '/' + file + '.log'
|
||||
if os.path.exists(logs_file):
|
||||
rdata = {}
|
||||
rdata['path'] = logs_file
|
||||
return mw.returnJson(True, 'ok', rdata)
|
||||
|
||||
return mw.returnJson(False, '日志不存在!')
|
||||
|
||||
|
||||
def projectScriptSelf_Run():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self/' + file
|
||||
self_logs_path = custom_hooks + '/self_logs/' + file + '.log'
|
||||
|
||||
shell = "sh -x " + self_path + " 2>" + self_logs_path + ' &'
|
||||
mw.execShell(shell)
|
||||
mw.execShell("chown -R www:www " + self_logs_path)
|
||||
return mw.returnJson(True, '执行成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Rename():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'o_file', 'n_file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
o_file = args['o_file']
|
||||
n_file = args['n_file']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
o_file_abs = self_path + '/' + o_file + '.sh'
|
||||
if not os.path.exists(o_file_abs):
|
||||
return mw.returnJson(False, '原文件已经不存在了!')
|
||||
|
||||
n_file_abs = self_path + '/' + n_file + '.sh'
|
||||
|
||||
os.rename(o_file_abs, n_file_abs)
|
||||
|
||||
# 日志也删除
|
||||
log_file = custom_hooks + '/self_logs/' + o_file + '.sh.log'
|
||||
if os.path.exists(log_file):
|
||||
os.remove(log_file)
|
||||
|
||||
return mw.returnJson(True, '重命名成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Enable():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'enable'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
enable = args['enable']
|
||||
|
||||
custom_path = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
|
||||
# 替换commit配置
|
||||
commit_path = custom_path + '/commit'
|
||||
note = '#Gogs Script Don`t Remove and Change'
|
||||
|
||||
self_file = custom_path + '/self_hook.sh'
|
||||
self_hook_tpl = getPluginDir() + '/hook/self_hook.tpl'
|
||||
|
||||
if enable == '1':
|
||||
content = mw.readFile(self_hook_tpl)
|
||||
content = content.replace('{$HOOK_DIR}', custom_path + '/self')
|
||||
content = content.replace(
|
||||
'{$HOOK_LOGS_DIR}', custom_path + '/self_logs')
|
||||
mw.writeFile(self_file, content)
|
||||
mw.execShell("chmod 777 " + self_file)
|
||||
mw.execShell("chown -R www:www " + self_file)
|
||||
|
||||
commit_content = mw.readFile(commit_path)
|
||||
commit_content += "\n\n" + "bash " + self_file + " " + note
|
||||
mw.writeFile(commit_path, commit_content)
|
||||
|
||||
return mw.returnJson(True, '开启成功!')
|
||||
else:
|
||||
commit_content = mw.readFile(commit_path)
|
||||
rep = ".*" + note
|
||||
commit_content = re.sub(rep, '', commit_content, re.M)
|
||||
commit_content = commit_content.strip()
|
||||
mw.writeFile(commit_path, commit_content)
|
||||
if os.path.exists(self_file):
|
||||
os.remove(self_file)
|
||||
return mw.returnJson(True, '关闭成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Status():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file', 'status'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
status = args['status']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
# 日志也删除
|
||||
log_file = custom_hooks + '/self_logs/' + file + '.log'
|
||||
if os.path.exists(log_file):
|
||||
os.remove(log_file)
|
||||
|
||||
if status == '1':
|
||||
file_abs = self_path + '/' + file
|
||||
file_text_abs = self_path + '/' + file + '.txt'
|
||||
os.rename(file_abs, file_text_abs)
|
||||
return mw.returnJson(True, '开始禁用成功!')
|
||||
else:
|
||||
file_abs = self_path + '/' + file.strip('.txt')
|
||||
file_text_abs = self_path + '/' + file
|
||||
os.rename(file_text_abs, file_abs)
|
||||
return mw.returnJson(True, '开始使用成功!')
|
||||
|
||||
return mw.returnJson(True, '禁用成功!')
|
||||
|
||||
|
||||
def getRsaPublic():
|
||||
@@ -745,8 +1108,12 @@ if __name__ == "__main__":
|
||||
print(getGogsConf())
|
||||
elif func == 'submit_gogs_conf':
|
||||
print(submitGogsConf())
|
||||
elif func == 'gogs_edit_tpl':
|
||||
print(gogsEditTpl())
|
||||
elif func == 'user_list':
|
||||
print(userList())
|
||||
elif func == 'repo_list':
|
||||
print(repoList())
|
||||
elif func == 'user_project_list':
|
||||
print(userProjectList())
|
||||
elif func == 'project_script_edit':
|
||||
@@ -757,8 +1124,24 @@ if __name__ == "__main__":
|
||||
print(projectScriptUnload())
|
||||
elif func == 'project_script_debug':
|
||||
print(projectScriptDebug())
|
||||
elif func == 'gogs_edit':
|
||||
print(gogsEdit())
|
||||
elif func == 'project_script_run':
|
||||
print(projectScriptRun())
|
||||
elif func == 'project_script_self':
|
||||
print(projectScriptSelf())
|
||||
elif func == 'project_script_self_create':
|
||||
print(projectScriptSelf_Create())
|
||||
elif func == 'project_script_self_del':
|
||||
print(projectScriptSelf_Del())
|
||||
elif func == 'project_script_self_logs':
|
||||
print(projectScriptSelf_Logs())
|
||||
elif func == 'project_script_self_run':
|
||||
print(projectScriptSelf_Run())
|
||||
elif func == 'project_script_self_rename':
|
||||
print(projectScriptSelf_Rename())
|
||||
elif func == 'project_script_self_enable':
|
||||
print(projectScriptSelf_Enable())
|
||||
elif func == 'project_script_self_status':
|
||||
print(projectScriptSelf_Status())
|
||||
elif func == 'get_rsa_public':
|
||||
print(getRsaPublic())
|
||||
elif func == 'get_total_statistics':
|
||||
|
||||
+414
-10
@@ -118,6 +118,7 @@ function gogsEdit(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
function giteaUserList(page, search) {
|
||||
|
||||
var _data = {};
|
||||
@@ -130,7 +131,6 @@ function giteaUserList(page, search) {
|
||||
if(typeof(search) != 'undefined'){
|
||||
_data['search'] = search;
|
||||
}
|
||||
_data['tojs'] = 'giteaUserList';
|
||||
|
||||
gogsPost('user_list', _data, function(data){
|
||||
|
||||
@@ -140,7 +140,7 @@ function giteaUserList(page, search) {
|
||||
return;
|
||||
}
|
||||
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找用户名" id="find_user" style="height: 28px; border-radius: 3px;width: 435px;">';
|
||||
content += '<button class="btn btn-success btn-sm" onclick="userFind();">查找</button></div>';
|
||||
content += '<button class="btn btn-success btn-sm find_user" >查找</button></div>';
|
||||
|
||||
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
|
||||
content += '<thead><tr>';
|
||||
@@ -154,24 +154,31 @@ function giteaUserList(page, search) {
|
||||
|
||||
ulist = rdata['data']['data'];
|
||||
for (i in ulist){
|
||||
email = ulist[i]["email"] == '' ? '无' : ulist[i]["email"];
|
||||
|
||||
var email = ulist[i]["email"] == '' ? '无' : ulist[i]["email"];
|
||||
var user_url = rdata['data']['root_url'] + ulist[i]["name"];
|
||||
content += '<tr><td>'+ulist[i]["id"]+'</td>'+
|
||||
'<td>'+ulist[i]["name"]+'</td>'+
|
||||
'<td>'+email+'</td>'+
|
||||
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i]["name"]+'\')">项目管理</a></td>'+
|
||||
'<td><a class="btlink" target="_blank" href="'+user_url+'">项目管理</a></td>'+
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
content += '</tbody>';
|
||||
content += '</table></div>';
|
||||
|
||||
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>';
|
||||
var page_html = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
|
||||
page_html += rdata['data']['list'];
|
||||
page_html += '</div></ul></div>';
|
||||
|
||||
content += page;
|
||||
content += page_html;
|
||||
|
||||
$(".soft-man-con").html(content);
|
||||
|
||||
$('.find_user').click(function(){
|
||||
var name = $('#find_user').val();
|
||||
giteaUserList(page, name);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -336,6 +343,403 @@ function projectScriptDebug(user,name,index){
|
||||
});
|
||||
}
|
||||
|
||||
function gogsRepoListPage(page, search){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
if(typeof(search) != 'undefined'){
|
||||
_data['search'] = search;
|
||||
}
|
||||
|
||||
gogsPost('repo_list', _data, function(data){
|
||||
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
var ulist = rdata['data']['data'];
|
||||
var body = ''
|
||||
for (i in ulist){
|
||||
// console.log(ulist[i]);
|
||||
|
||||
var option = '';
|
||||
if(ulist[i]['has_hook']){
|
||||
option += '<a class="btlink unload" data-index="'+i+'">卸载脚本</a>' + ' | ';
|
||||
option += '<a class="btlink load" data-index="'+i+'">重载</a>' + ' | ';
|
||||
option += '<a class="btlink edit" data-index="'+i+'">编辑</a>' + ' | ';
|
||||
option += '<a class="btlink debug" data-index="'+i+'">日志</a>' + ' | ';
|
||||
option += '<a class="btlink run" data-index="'+i+'">手动</a>' + ' | ';
|
||||
option += '<a class="btlink scripts" data-index="'+i+'" onclick="projectScriptSelf(\''+ulist[i]["name"]+'\',\''+ulist[i]["repo"]+'\')" >自定义</a>';
|
||||
} else{
|
||||
option += '<a data-index="'+i+'" class="btlink load">加载脚本</a>';
|
||||
}
|
||||
|
||||
|
||||
body += '<tr><td>'+ulist[i]["id"]+'</td>'+
|
||||
'<td class="overflow_hide" style="width:70px;">' + ulist[i]["name"]+'</td>'+
|
||||
'<td class="overflow_hide" style="width:70px;display: inline-block;">' + ulist[i]["repo"]+'</td>'+
|
||||
'<td>' +
|
||||
'<a class="btlink" target="_blank" href="'+rdata['data']['root_url']+ulist[i]["name"]+'/'+ulist[i]["repo"]+'">源码</a>' + ' | ' +
|
||||
option +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
$('#repo_list tbody').html(body);
|
||||
$('#repo_list_page').html(rdata['data']['list']);
|
||||
|
||||
$('.find_repo').click(function(){
|
||||
var find_repo = $('#find_repo').val();
|
||||
gogsRepoListPage(page, find_repo);
|
||||
});
|
||||
|
||||
|
||||
$('#repo_list .load').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
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(){
|
||||
gogsRepoListPage(page, search);
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#repo_list .unload').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
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(){
|
||||
gogsRepoListPage(page, search);
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#repo_list .edit').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
gogsPost('project_script_edit', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (rdata['status']){
|
||||
onlineEditFile(0, rdata['data']['path']);
|
||||
} else {
|
||||
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#repo_list .debug').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
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']});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#repo_list .run').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
gogsPost('project_script_run', {'user':user,'name':name}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
layer.msg(data.msg,{icon:data.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
});
|
||||
|
||||
//---------
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function giteaRepoList() {
|
||||
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找项目" id="find_repo" style="height: 28px; border-radius: 3px;width: 435px;">';
|
||||
content += '<button class="btn btn-success btn-sm find_repo">查找</button></div>';
|
||||
|
||||
content += '<div id="repo_list" class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
|
||||
content += '<thead><tr>';
|
||||
content += '<th style="width:50px;">序号</th>';
|
||||
content += '<th style="width:80px;">用户/组织</th>';
|
||||
content += '<th style="width:80px;">项目名</th>';
|
||||
content += '<th>操作</th>';
|
||||
content += '</tr></thead>';
|
||||
|
||||
content += '<tbody></tbody>';
|
||||
content += '</table></div>';
|
||||
|
||||
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="repo_list_page" class="page"></ul></div>';
|
||||
|
||||
content += page;
|
||||
|
||||
$(".soft-man-con").html(content);
|
||||
|
||||
gogsRepoListPage(1);
|
||||
}
|
||||
|
||||
function projectScriptSelfRender(user, name){
|
||||
gogsPost('project_script_self', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
var data = rdata['data']['data'];
|
||||
|
||||
if (rdata['data']['self_hook']){
|
||||
$('#open_script').prop('checked',true);
|
||||
}
|
||||
|
||||
var body = '';
|
||||
if(data.length == 0 ){
|
||||
body += '<tr><td colspan="3" style="text-align:center;">无脚本数据</td></tr>';
|
||||
} else{
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var b_status = '<a class="btlink status" data-index="'+i+'" target="_blank">已使用</a>';
|
||||
if (data[i]["is_hidden"]){
|
||||
b_status = '<a class="btlink status" data-index="'+i+'" target="_blank">已隐藏</a>';
|
||||
}
|
||||
|
||||
body += '<tr>'+
|
||||
'<td>' + data[i]["name"]+'</td>'+
|
||||
'<td>' + b_status + '</td>'+
|
||||
'<td>' +
|
||||
'<a class="btlink del" data-index="'+i+'" target="_blank">删除</a>' + ' | ' +
|
||||
'<a class="btlink edit" data-index="'+i+'" target="_blank">编辑</a>' + ' | ' +
|
||||
'<a class="btlink logs" data-index="'+i+'" target="_blank">日志</a>' + ' | ' +
|
||||
'<a class="btlink run" data-index="'+i+'" target="_blank">手动</a>' + ' | ' +
|
||||
'<a class="btlink rename" data-index="'+i+'" target="_blank">重命名</a>' +
|
||||
'</td></tr>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$('#gogs_self_table tbody').html(body);
|
||||
$('#gogs_self_table .page').html(rdata['data']['list']);
|
||||
|
||||
$('#gogs_self_table .status').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
var status = '1';
|
||||
if (data[i]["is_hidden"]){
|
||||
status = '0';
|
||||
}
|
||||
gogsPost('project_script_self_status', {'user':user,'name':name,'file':file, status:status}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.code?2:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#gogs_self_table .del').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
gogsPost('project_script_self_del', {'user':user,'name':name,'file':file}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.code?2:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#gogs_self_table .edit').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var path = data[i]["path"];
|
||||
onlineEditFile(0,path);
|
||||
});
|
||||
|
||||
$('#gogs_self_table .logs').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
gogsPost('project_script_self_logs', {'user':user,'name':name,'file':file}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
if (rdata['status']){
|
||||
onlineEditFile(0, rdata['data']['path']);
|
||||
} else {
|
||||
layer.msg(rdata.msg,{icon:data.status?2:1,time:2000,shade: [0.3, '#000']});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#gogs_self_table .run').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
if (data[i]["is_hidden"]){
|
||||
layer.msg("已经禁用,不能执行!",{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
gogsPost('project_script_self_run', {'user':user,'name':name,'file':file}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg,{icon:data.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#gogs_self_table .rename').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
|
||||
if (data[i]["is_hidden"]){
|
||||
layer.msg("已经禁用,不能执行!",{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
file = file.split('.sh')[0];
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
shift: 5,
|
||||
closeBtn: 1,
|
||||
area: '320px',
|
||||
title: '重命名',
|
||||
btn:['设置','关闭'],
|
||||
content: '<div class="bt-form pd20">\
|
||||
<div class="line">\
|
||||
<input type="text" class="bt-input-text" name="Name" id="newFileName" value="'+file+'" placeholder="文件名" style="width:100%" />\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("#newFileName").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(){
|
||||
var n_file = $("#newFileName").val();
|
||||
var o_file = file;
|
||||
|
||||
gogsPost('project_script_self_rename', {'user':user,'name':name,'o_file':o_file,'n_file':n_file}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
$(".layui-layer-btn1").click();
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.code?2:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
//-----
|
||||
});
|
||||
//------
|
||||
});
|
||||
}
|
||||
|
||||
//新建文件
|
||||
function createScriptFile(type, user, name, file) {
|
||||
if (type == 1) {
|
||||
gogsPost('project_script_self_create', {'user':user,'name':name,'file': file }, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if(!rdata['status']){
|
||||
layer.msg(rdata.msg,{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
showMsg(rdata.msg, function(){
|
||||
$(".layui-layer-btn1").click();
|
||||
onlineEditFile(0,rdata['data']['abs_file']);
|
||||
projectScriptSelfRender(user, name);
|
||||
}, {icon:1,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
return;
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
shift: 5,
|
||||
closeBtn: 1,
|
||||
area: '320px',
|
||||
title: '新建自定义脚本',
|
||||
btn:['新建','关闭'],
|
||||
content: '<div class="bt-form pd20">\
|
||||
<div class="line">\
|
||||
<input type="text" class="bt-input-text" name="Name" id="newFileName" value="" placeholder="文件名" style="width:100%" />\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("#newFileName").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(){
|
||||
var file = $("#newFileName").val();;
|
||||
createScriptFile(1, user, name, file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptSelf(user, name){
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '项目('+user+'/'+name+')自定义脚本',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd15'>\
|
||||
<button id='create_script' class='btn btn-success btn-sm' type='button' style='margin-right: 5px;''>添加脚本</button>\
|
||||
<div style='float:right;'>\
|
||||
<span style='line-height: 23px;'>开启自定义脚本</span>\
|
||||
<input class='btswitch btswitch-ios' id='open_script' type='checkbox'>\
|
||||
<label id='script_hook_enable' class='btswitch-btn' for='open_script' style='display: inline-flex;line-height:38px;margin-left: 4px;float: right;'></label>\
|
||||
</div>\
|
||||
<div id='gogs_self_table' class='divtable' style='margin-top:5px;'>\
|
||||
<table class='table table-hover'>\
|
||||
<thead><tr><th style='width:100px;'>脚本文件名</th><th>状态</th><th>操作</th></tr></thead>\
|
||||
<tbody></tbody>\
|
||||
</table>\
|
||||
<div class='dataTables_paginate paging_bootstrap pagination' style='margin-top:0px;'>\
|
||||
<ul class='page'><div class='gogs_page'></div></ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>",
|
||||
success:function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
|
||||
$('#create_script').click(function(){
|
||||
createScriptFile(0, user, name);
|
||||
});
|
||||
|
||||
$('#script_hook_enable').click(function(){
|
||||
var enable = $('#open_script').prop('checked');
|
||||
var enable_option = '0';
|
||||
if (!enable){
|
||||
enable_option = '1';
|
||||
}
|
||||
gogsPost('project_script_self_enable', {'user':user,'name':name,'enable':enable_option}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.status?1:2,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getRsaPublic(){
|
||||
gogsPost('get_rsa_public', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
@@ -361,8 +765,8 @@ function giteaRead(){
|
||||
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>默认使用MySQL,第一个启动加载各种配置,并修改成正确的数据库配置</li>';
|
||||
readme += '<li>邮件端口使用456,gogs仅支持使用STARTTLS的SMTP协议</li>';
|
||||
readme += '<li>如果使用项目中脚本本地同步,<a target="_blank" href="https://github.com/midoks/mdserver-web/wiki/%E6%8F%92%E4%BB%B6%E7%AE%A1%E7%90%86%5Bgogs%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%5D#%E5%90%AF%E5%8A%A8gogs%E5%90%8E%E5%A6%82%E6%9E%9C%E8%A6%81%E4%BD%BF%E7%94%A8hook%E8%84%9A%E6%9C%AC%E5%90%8C%E6%AD%A5%E4%BB%A3%E7%A0%81%E9%9C%80%E8%A6%81%E5%BC%80%E5%90%AFssh%E7%AB%AF%E5%8F%A3">点击查看</></li>';
|
||||
readme += '<li>邮件端口使用456,gitea仅支持使用STARTTLS的SMTP协议</li>';
|
||||
readme += '<li>项目【加载脚本】后,会自动同步到wwwroot目录下</li>';
|
||||
readme += '<li><a href="#" onclick="getRsaPublic();">点击查看本机公钥</></li>';
|
||||
readme += '</ul>';
|
||||
|
||||
|
||||
@@ -10,14 +10,19 @@ 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
|
||||
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
|
||||
git clone $GITADDR
|
||||
git clone $GITADDR --branch main
|
||||
if [ "$?" != "0" ];then
|
||||
git clone $GITADDR
|
||||
fi
|
||||
fi
|
||||
|
||||
unset GIT_DIR
|
||||
|
||||
cd $GIT_PROJECT_DIR && git pull
|
||||
|
||||
# func 2
|
||||
@@ -26,9 +31,17 @@ 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
|
||||
if [ -f $GIT_PROJECT_DIR/exclude.list ];then
|
||||
rsync -vauP --delete --exclude-from="$GIT_PROJECT_DIR/exclude.list" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
else
|
||||
rsync -vauP --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
||||
fi
|
||||
fi
|
||||
|
||||
sysName=`uname`
|
||||
if [ $sysName == 'Darwin' ]; then
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
H_DIR={$HOOK_DIR}
|
||||
HL_DIR={$HOOK_LOGS_DIR}
|
||||
|
||||
|
||||
SH_LIST=`cd ${H_DIR} && ls | grep ".sh$"`
|
||||
|
||||
for sh_f in $SH_LIST; do
|
||||
ABS_FILE=${H_DIR}/${sh_f}
|
||||
ABS_LOGS=${HL_DIR}/${sh_f}.log
|
||||
echo "sh ${ABS_FILE} 2>${ABS_LOGS}"
|
||||
sh -x ${ABS_FILE} 2>${ABS_LOGS}
|
||||
done
|
||||
+14
-3
@@ -1,13 +1,22 @@
|
||||
<style>
|
||||
.overflow_hide {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
</style>
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('gogs');">服务</p>
|
||||
<p onclick="pluginInitD('gogs');">自启动</p>
|
||||
<!-- <p onclick="pluginConfig('gogs',null, 'init_conf');">启动配置</p> -->
|
||||
<p onclick="gogsEdit();">手动编辑</p>
|
||||
<p onclick="gogsEditTpl();">手动编辑</p>
|
||||
<p onclick="pluginConfig('gogs',null, 'conf');">配置文件</p>
|
||||
<p onclick="gogsSetConfig();">配置修改</p>
|
||||
<p onclick="gogsUserList();">用户列表</p>
|
||||
<p onclick="gogsRepoList();">项目列表</p>
|
||||
<p onclick="pluginLogs('gogs',null,'run_log');">运行日志</p>
|
||||
<p onclick="pluginLogs('gogs',null,'post_receive_log');" title="提交post-receive日志">提交日志</p>
|
||||
<p onclick="gogsRead();">使用说明</p>
|
||||
@@ -18,6 +27,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$.getScript( "/plugins/file?name=gogs&f=js/gogs.js");
|
||||
pluginService('gogs');
|
||||
resetPluginWinHeight(530);
|
||||
$.getScript( "/plugins/file?name=gogs&f=js/gogs.js",function(){
|
||||
pluginService('gogs');
|
||||
});
|
||||
</script>
|
||||
+394
-12
@@ -456,6 +456,13 @@ def submitGogsConf():
|
||||
return mw.returnJson(True, '设置成功')
|
||||
|
||||
|
||||
def gogsEditTpl():
|
||||
data = {}
|
||||
data['post_receive'] = getPluginDir() + '/hook/post-receive.tpl'
|
||||
data['commit'] = getPluginDir() + '/hook/commit.tpl'
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
def userList():
|
||||
|
||||
conf = getConf()
|
||||
@@ -470,6 +477,66 @@ def userList():
|
||||
import math
|
||||
args = getArgs()
|
||||
|
||||
data = checkArgs(args, ['page', 'page_size'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
page = int(args['page'])
|
||||
page_size = int(args['page_size'])
|
||||
search = ''
|
||||
if 'search' in args:
|
||||
search = args['search']
|
||||
|
||||
user_where1 = ''
|
||||
user_where2 = ''
|
||||
if search != '':
|
||||
user_where1 = ' where name like "%' + search + '%"'
|
||||
user_where2 = ' where name like "%' + search + '%"'
|
||||
|
||||
data = {}
|
||||
|
||||
data['root_url'] = getRootUrl()
|
||||
|
||||
start = (page - 1) * page_size
|
||||
list_count = pQuery('select count(id) as num from user' + user_where1)
|
||||
count = list_count[0]["num"]
|
||||
list_data = pQuery(
|
||||
'select id,name,email from user ' + user_where2 + ' order by id desc limit ' + str(start) + ',' + str(page_size))
|
||||
data['list'] = mw.getPage({'count': count, 'p': page,
|
||||
'row': page_size, 'tojs': 'gogsUserList'})
|
||||
data['page'] = page
|
||||
data['page_size'] = page_size
|
||||
data['page_count'] = int(math.ceil(count / page_size))
|
||||
data['data'] = list_data
|
||||
return mw.returnJson(True, 'OK', data)
|
||||
|
||||
|
||||
def checkRepoListIsHasScript(data):
|
||||
path = getRootPath()
|
||||
for x in range(len(data)):
|
||||
name = data[x]['name'] + '/' + data[x]['repo'] + '.git'
|
||||
path_tmp = path + '/' + name + '/custom_hooks/post-receive'
|
||||
if os.path.exists(path_tmp):
|
||||
data[x]['has_hook'] = True
|
||||
else:
|
||||
data[x]['has_hook'] = False
|
||||
return data
|
||||
|
||||
|
||||
def repoList():
|
||||
|
||||
conf = getConf()
|
||||
if not os.path.exists(conf):
|
||||
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
|
||||
|
||||
conf = getDbConfValue()
|
||||
gtype = getGogsDbType(conf)
|
||||
if gtype != 'mysql':
|
||||
return mw.returnJson(False, "仅支持mysql数据操作!")
|
||||
|
||||
import math
|
||||
args = getArgs()
|
||||
|
||||
data = checkArgs(args, ['page', 'page_size'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
@@ -484,13 +551,25 @@ def userList():
|
||||
|
||||
data['root_url'] = getRootUrl()
|
||||
|
||||
repo_where1 = ''
|
||||
repo_where2 = ''
|
||||
if search != '':
|
||||
repo_where1 = ' where name like "%' + search + '%"'
|
||||
repo_where2 = ' where r.name like "%' + search + '%"'
|
||||
|
||||
start = (page - 1) * page_size
|
||||
list_count = pQuery('select count(id) as num from user')
|
||||
list_count = pQuery(
|
||||
'select count(id) as num from repository' + repo_where1)
|
||||
count = list_count[0]["num"]
|
||||
list_data = pQuery(
|
||||
'select id,name,email from user order by id desc limit ' + str(start) + ',' + str(page_size))
|
||||
sql = 'select r.id,r.owner_id,r.name as repo, u.name from repository r left join user u on r.owner_id=u.id ' + repo_where2 + ' order by r.id desc limit ' + \
|
||||
str(start) + ',' + str(page_size)
|
||||
# print(sql)
|
||||
list_data = pQuery(sql)
|
||||
# print(list_data)
|
||||
list_data = checkRepoListIsHasScript(list_data)
|
||||
|
||||
data['list'] = mw.getPage({'count': count, 'p': page,
|
||||
'row': page_size, 'tojs': 'gogsUserList'})
|
||||
'row': page_size, 'tojs': 'gogsRepoListPage'})
|
||||
data['page'] = page
|
||||
data['page_size'] = page_size
|
||||
data['page_count'] = int(math.ceil(count / page_size))
|
||||
@@ -561,7 +640,7 @@ def userProjectList():
|
||||
data['data'] = ret_data
|
||||
data['args'] = args
|
||||
data['list'] = mw.getPage(
|
||||
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectList'})
|
||||
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectListPage'})
|
||||
|
||||
return mw.returnJson(True, 'OK', data)
|
||||
|
||||
@@ -668,11 +747,294 @@ def projectScriptDebug():
|
||||
return mw.getJson(data)
|
||||
|
||||
|
||||
def gogsEdit():
|
||||
data = {}
|
||||
data['post_receive'] = getPluginDir() + '/hook/post-receive.tpl'
|
||||
data['commit'] = getPluginDir() + '/hook/commit.tpl'
|
||||
return mw.getJson(data)
|
||||
def projectScriptRun():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
|
||||
path = getRootPath() + '/' + user + '/' + name
|
||||
commit_sh = path + '/custom_hooks/commit'
|
||||
commit_log = path + '/custom_hooks/sh.log'
|
||||
script_run = 'sh -x ' + commit_sh + ' 2>' + commit_log
|
||||
|
||||
if not os.path.exists(commit_sh):
|
||||
return mw.returnJson(False, '脚本文件不存在!')
|
||||
|
||||
mw.execShell(script_run)
|
||||
return mw.returnJson(True, '脚本文件执行成功,观察日志!')
|
||||
|
||||
|
||||
def projectScriptSelf():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
|
||||
self_path = custom_hooks + '/self'
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
self_logs_path = custom_hooks + '/self_logs'
|
||||
if not os.path.exists(self_logs_path):
|
||||
os.mkdir(self_logs_path)
|
||||
|
||||
self_hook_file = custom_hooks + '/self_hook.sh'
|
||||
self_hook_exist = False
|
||||
if os.path.exists(self_hook_file):
|
||||
self_hook_exist = True
|
||||
|
||||
dlist = []
|
||||
if os.path.exists(self_path):
|
||||
for filename in os.listdir(self_path):
|
||||
tmp = {}
|
||||
filePath = self_path + '/' + filename
|
||||
if os.path.isfile(filePath):
|
||||
tmp['path'] = filePath
|
||||
tmp['name'] = os.path.basename(filePath)
|
||||
tmp['is_hidden'] = False
|
||||
if tmp['name'].endswith('.txt'):
|
||||
tmp['is_hidden'] = True
|
||||
|
||||
dlist.append(tmp)
|
||||
|
||||
dlist_sum = len(dlist)
|
||||
# print(dlist)
|
||||
rdata = {}
|
||||
rdata['data'] = dlist
|
||||
rdata['self_hook'] = self_hook_exist
|
||||
rdata['list'] = mw.getPage(
|
||||
{'count': dlist_sum, 'p': 1, 'row': 100, 'tojs': 'self_page'})
|
||||
|
||||
return mw.returnJson(True, 'ok', rdata)
|
||||
|
||||
|
||||
def projectScriptSelf_Create():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
self_path = path = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
abs_file = self_path + '/' + file + '.sh'
|
||||
if os.path.exists(abs_file):
|
||||
return mw.returnJson(False, '脚本已经存在!')
|
||||
|
||||
mw.writeFile(abs_file, "#!/bin/bash\necho `date +'%Y-%m-%d %H:%M:%S'`\n")
|
||||
|
||||
rdata = {}
|
||||
rdata['abs_file'] = abs_file
|
||||
return mw.returnJson(True, '创建文件成功!', rdata)
|
||||
|
||||
|
||||
def projectScriptSelf_Del():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
abs_file = self_path + '/' + file
|
||||
# print(abs_file)
|
||||
if not os.path.exists(abs_file):
|
||||
return mw.returnJson(False, '脚本已经删除!')
|
||||
|
||||
os.remove(abs_file)
|
||||
|
||||
# 日志也删除
|
||||
log_file = custom_hooks + '/self_logs/' + file + '.log'
|
||||
if os.path.exists(log_file):
|
||||
os.remove(log_file)
|
||||
|
||||
return mw.returnJson(True, '脚本删除成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Logs():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
self_path = path = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks/self_logs'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
logs_file = self_path + '/' + file + '.log'
|
||||
if os.path.exists(logs_file):
|
||||
rdata = {}
|
||||
rdata['path'] = logs_file
|
||||
return mw.returnJson(True, 'ok', rdata)
|
||||
|
||||
return mw.returnJson(False, '日志不存在!')
|
||||
|
||||
|
||||
def projectScriptSelf_Run():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self/' + file
|
||||
self_logs_path = custom_hooks + '/self_logs/' + file + '.log'
|
||||
|
||||
shell = "sh -x " + self_path + " 2>" + self_logs_path + ' &'
|
||||
mw.execShell(shell)
|
||||
return mw.returnJson(True, '执行成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Rename():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'o_file', 'n_file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
o_file = args['o_file']
|
||||
n_file = args['n_file']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
o_file_abs = self_path + '/' + o_file + '.sh'
|
||||
if not os.path.exists(o_file_abs):
|
||||
return mw.returnJson(False, '原文件已经不存在了!')
|
||||
|
||||
n_file_abs = self_path + '/' + n_file + '.sh'
|
||||
|
||||
os.rename(o_file_abs, n_file_abs)
|
||||
|
||||
# 日志也删除
|
||||
log_file = custom_hooks + '/self_logs/' + o_file + '.sh.log'
|
||||
if os.path.exists(log_file):
|
||||
os.remove(log_file)
|
||||
|
||||
return mw.returnJson(True, '重命名成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Enable():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'enable'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
enable = args['enable']
|
||||
|
||||
custom_path = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
|
||||
# 替换commit配置
|
||||
commit_path = custom_path + '/commit'
|
||||
note = '#Gogs Script Don`t Remove and Change'
|
||||
|
||||
self_file = custom_path + '/self_hook.sh'
|
||||
self_hook_tpl = getPluginDir() + '/hook/self_hook.tpl'
|
||||
|
||||
if enable == '1':
|
||||
content = mw.readFile(self_hook_tpl)
|
||||
content = content.replace('{$HOOK_DIR}', custom_path + '/self')
|
||||
content = content.replace(
|
||||
'{$HOOK_LOGS_DIR}', custom_path + '/self_logs')
|
||||
mw.writeFile(self_file, content)
|
||||
mw.execShell("chmod 777 " + self_file)
|
||||
|
||||
commit_content = mw.readFile(commit_path)
|
||||
commit_content += "\n\n" + "bash " + self_file + " " + note
|
||||
mw.writeFile(commit_path, commit_content)
|
||||
|
||||
return mw.returnJson(True, '开启成功!')
|
||||
else:
|
||||
commit_content = mw.readFile(commit_path)
|
||||
rep = ".*" + note
|
||||
commit_content = re.sub(rep, '', commit_content, re.M)
|
||||
commit_content = commit_content.strip()
|
||||
mw.writeFile(commit_path, commit_content)
|
||||
if os.path.exists(self_file):
|
||||
os.remove(self_file)
|
||||
return mw.returnJson(True, '关闭成功!')
|
||||
|
||||
|
||||
def projectScriptSelf_Status():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['user', 'name', 'file', 'status'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
user = args['user']
|
||||
name = args['name'] + '.git'
|
||||
file = args['file']
|
||||
status = args['status']
|
||||
|
||||
custom_hooks = getRootPath() + '/' + user + '/' + \
|
||||
name + '/custom_hooks'
|
||||
self_path = custom_hooks + '/self'
|
||||
|
||||
if not os.path.exists(self_path):
|
||||
os.mkdir(self_path)
|
||||
|
||||
# 日志也删除
|
||||
log_file = custom_hooks + '/self_logs/' + file + '.log'
|
||||
if os.path.exists(log_file):
|
||||
os.remove(log_file)
|
||||
|
||||
if status == '1':
|
||||
file_abs = self_path + '/' + file
|
||||
file_text_abs = self_path + '/' + file + '.txt'
|
||||
os.rename(file_abs, file_text_abs)
|
||||
return mw.returnJson(True, '开始禁用成功!')
|
||||
else:
|
||||
file_abs = self_path + '/' + file.strip('.txt')
|
||||
file_text_abs = self_path + '/' + file
|
||||
os.rename(file_text_abs, file_abs)
|
||||
return mw.returnJson(True, '开始使用成功!')
|
||||
|
||||
return mw.returnJson(True, '禁用成功!')
|
||||
|
||||
|
||||
def getRsaPublic():
|
||||
@@ -732,8 +1094,12 @@ if __name__ == "__main__":
|
||||
print(getGogsConf())
|
||||
elif func == 'submit_gogs_conf':
|
||||
print(submitGogsConf())
|
||||
elif func == 'gogs_edit_tpl':
|
||||
print(gogsEditTpl())
|
||||
elif func == 'user_list':
|
||||
print(userList())
|
||||
elif func == 'repo_list':
|
||||
print(repoList())
|
||||
elif func == 'user_project_list':
|
||||
print(userProjectList())
|
||||
elif func == 'project_script_edit':
|
||||
@@ -744,8 +1110,24 @@ if __name__ == "__main__":
|
||||
print(projectScriptUnload())
|
||||
elif func == 'project_script_debug':
|
||||
print(projectScriptDebug())
|
||||
elif func == 'gogs_edit':
|
||||
print(gogsEdit())
|
||||
elif func == 'project_script_run':
|
||||
print(projectScriptRun())
|
||||
elif func == 'project_script_self':
|
||||
print(projectScriptSelf())
|
||||
elif func == 'project_script_self_create':
|
||||
print(projectScriptSelf_Create())
|
||||
elif func == 'project_script_self_del':
|
||||
print(projectScriptSelf_Del())
|
||||
elif func == 'project_script_self_logs':
|
||||
print(projectScriptSelf_Logs())
|
||||
elif func == 'project_script_self_run':
|
||||
print(projectScriptSelf_Run())
|
||||
elif func == 'project_script_self_rename':
|
||||
print(projectScriptSelf_Rename())
|
||||
elif func == 'project_script_self_enable':
|
||||
print(projectScriptSelf_Enable())
|
||||
elif func == 'project_script_self_status':
|
||||
print(projectScriptSelf_Status())
|
||||
elif func == 'get_rsa_public':
|
||||
print(getRsaPublic())
|
||||
elif func == 'get_total_statistics':
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"ps": "Gogs是一款极易搭建的自助Git服务",
|
||||
"name": "gogs",
|
||||
"title": "Gogs",
|
||||
"versions": ["0.11.86","0.12.9"],
|
||||
"versions": ["0.11.86","0.12.9","0.13.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/gogs",
|
||||
"path":"server/gogs",
|
||||
|
||||
@@ -9,6 +9,10 @@ serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
if [ -f ${rootPath}/bin/activate ];then
|
||||
source ${rootPath}/bin/activate
|
||||
fi
|
||||
|
||||
|
||||
GOGS_DOWNLOAD='https://dl.gogs.io'
|
||||
|
||||
|
||||
+482
-45
@@ -1,19 +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 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);
|
||||
}
|
||||
@@ -113,9 +102,8 @@ function submitGogsConf() {
|
||||
});
|
||||
}
|
||||
|
||||
function gogsEdit(){
|
||||
|
||||
gogsPost('gogs_edit',{} , function(data){
|
||||
function gogsEditTpl(){
|
||||
gogsPost('gogs_edit_tpl',{} , function(data){
|
||||
// console.log(data);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
var edit = '<p class="status">通用的手动编辑:</p>';
|
||||
@@ -149,7 +137,7 @@ function gogsUserList(page, search) {
|
||||
return;
|
||||
}
|
||||
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找用户名" id="find_user" style="height: 28px; border-radius: 3px;width: 435px;">';
|
||||
content += '<button class="btn btn-success btn-sm" onclick="userFind();">查找</button></div>';
|
||||
content += '<button class="btn btn-success btn-sm find_user" >查找</button></div>';
|
||||
|
||||
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
|
||||
content += '<thead><tr>';
|
||||
@@ -163,28 +151,84 @@ function gogsUserList(page, search) {
|
||||
|
||||
ulist = rdata['data']['data'];
|
||||
for (i in ulist){
|
||||
email = ulist[i]["email"] == '' ? '无' : ulist[i]["email"];
|
||||
|
||||
var email = ulist[i]["email"] == '' ? '无' : ulist[i]["email"];
|
||||
var user_url = rdata['data']['root_url'] + ulist[i]["name"];
|
||||
content += '<tr><td>'+ulist[i]["id"]+'</td>'+
|
||||
'<td>'+ulist[i]["name"]+'</td>'+
|
||||
'<td>'+email+'</td>'+
|
||||
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i]["name"]+'\')">项目管理</a></td>'+
|
||||
'<td><a class="btlink" target="_blank" href="'+user_url+'">项目管理</a></td>'+
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
content += '</tbody>';
|
||||
content += '</table></div>';
|
||||
|
||||
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>';
|
||||
var page_html = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
|
||||
page_html += rdata['data']['list'];
|
||||
page_html += '</div></ul></div>';
|
||||
|
||||
content += page;
|
||||
content += page_html;
|
||||
|
||||
$(".soft-man-con").html(content);
|
||||
|
||||
$('.find_user').click(function(){
|
||||
var name = $('#find_user').val();
|
||||
gogsUserList(page, name);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function userProjectList(user, search){
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '用户('+user+')项目列表',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div>\
|
||||
<div id='gogs_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 class='page'><div class='gogs_page'></div></ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>",
|
||||
success:function(){
|
||||
userProjectListPage(user,search);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function userProjectList2(user, search){
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '用户('+user+')项目列表',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd20 c6'>\
|
||||
<div>\
|
||||
<div id='gogs_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 class='page'><div class='gogs_page'></div></ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>",
|
||||
success:function(){
|
||||
userProjectListPage(user,search);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function userProjectListPage(user, search){
|
||||
var req = {};
|
||||
if (!isNaN(user)){
|
||||
req['page'] = user;
|
||||
@@ -200,8 +244,7 @@ function userProjectList(user, search){
|
||||
if(typeof(search) != 'undefined'){
|
||||
req['search'] = search;
|
||||
}
|
||||
|
||||
$('.layui-layer-close1').click();
|
||||
|
||||
gogsPost('user_project_list', req, function(data){
|
||||
var rdata = [];
|
||||
try {
|
||||
@@ -218,7 +261,8 @@ function userProjectList(user, search){
|
||||
var project_list = rdata['data']['data'];
|
||||
for (i in project_list) {
|
||||
var name = project_list[i]['name'];
|
||||
list += '<tr><td>'+name+'</td>\
|
||||
list += '<tr>\
|
||||
<td>'+name+'</td>\
|
||||
<td>\
|
||||
<a class="btlink" target="_blank" href="'+rdata['data']['root_url']+user+'/'+name+'">源码</a> | \
|
||||
<a class="btlink" onclick="projectScript(\''+user+'\',\''+name+'\','+project_list[i]['has_hook']+');">脚本</a>\
|
||||
@@ -226,28 +270,180 @@ 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>';
|
||||
$('#gogs_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'];
|
||||
$('#gogs_table .gogs_page').html(page);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function gogsRepoListPage(page, search){
|
||||
var _data = {};
|
||||
if (typeof(page) =='undefined'){
|
||||
var page = 1;
|
||||
}
|
||||
|
||||
_data['page'] = page;
|
||||
_data['page_size'] = 10;
|
||||
if(typeof(search) != 'undefined'){
|
||||
_data['search'] = search;
|
||||
}
|
||||
|
||||
gogsPost('repo_list', _data, function(data){
|
||||
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (!rdata.status){
|
||||
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
var ulist = rdata['data']['data'];
|
||||
var body = ''
|
||||
for (i in ulist){
|
||||
// console.log(ulist[i]);
|
||||
|
||||
var option = '';
|
||||
if(ulist[i]['has_hook']){
|
||||
option += '<a class="btlink unload" data-index="'+i+'">卸载脚本</a>' + ' | ';
|
||||
option += '<a class="btlink load" data-index="'+i+'">重载</a>' + ' | ';
|
||||
option += '<a class="btlink edit" data-index="'+i+'">编辑</a>' + ' | ';
|
||||
option += '<a class="btlink debug" data-index="'+i+'">日志</a>' + ' | ';
|
||||
option += '<a class="btlink run" data-index="'+i+'">手动</a>' + ' | ';
|
||||
option += '<a class="btlink scripts" data-index="'+i+'" onclick="projectScriptSelf(\''+ulist[i]["name"]+'\',\''+ulist[i]["repo"]+'\')" >自定义</a>';
|
||||
} else{
|
||||
option += '<a data-index="'+i+'" class="btlink load">加载脚本</a>';
|
||||
}
|
||||
|
||||
|
||||
body += '<tr><td>'+ulist[i]["id"]+'</td>'+
|
||||
'<td class="overflow_hide" style="width:70px;">' + ulist[i]["name"]+'</td>'+
|
||||
'<td class="overflow_hide" style="width:70px;display: inline-block;">' + ulist[i]["repo"]+'</td>'+
|
||||
'<td>' +
|
||||
'<a class="btlink" target="_blank" href="'+rdata['data']['root_url']+ulist[i]["name"]+'/'+ulist[i]["repo"]+'">源码</a>' + ' | ' +
|
||||
option +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
}
|
||||
|
||||
$('#repo_list tbody').html(body);
|
||||
$('#repo_list_page').html(rdata['data']['list']);
|
||||
|
||||
$('.find_repo').click(function(){
|
||||
var find_repo = $('#find_repo').val();
|
||||
gogsRepoListPage(page, find_repo);
|
||||
});
|
||||
|
||||
|
||||
$('#repo_list .load').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
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(){
|
||||
gogsRepoListPage(page, search);
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#repo_list .unload').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
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(){
|
||||
gogsRepoListPage(page, search);
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#repo_list .edit').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
gogsPost('project_script_edit', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if (rdata['status']){
|
||||
onlineEditFile(0, rdata['data']['path']);
|
||||
} else {
|
||||
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#repo_list .debug').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
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']});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#repo_list .run').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var user = ulist[i]["name"];
|
||||
var name = ulist[i]["repo"];
|
||||
|
||||
gogsPost('project_script_run', {'user':user,'name':name}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
layer.msg(data.msg,{icon:data.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
});
|
||||
|
||||
//---------
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function gogsRepoList() {
|
||||
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找项目" id="find_repo" style="height: 28px; border-radius: 3px;width: 435px;">';
|
||||
content += '<button class="btn btn-success btn-sm find_repo" >查找</button></div>';
|
||||
|
||||
content += '<div id="repo_list" class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
|
||||
content += '<thead><tr>';
|
||||
content += '<th style="width:50px;">序号</th>';
|
||||
content += '<th style="width:80px;">用户/组织</th>';
|
||||
content += '<th style="width:80px;">项目名</th>';
|
||||
content += '<th>操作</th>';
|
||||
content += '</tr></thead>';
|
||||
|
||||
content += '<tbody></tbody>';
|
||||
content += '</table></div>';
|
||||
|
||||
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="repo_list_page" class="page"></ul></div>';
|
||||
|
||||
content += page;
|
||||
|
||||
$(".soft-man-con").html(content);
|
||||
|
||||
gogsRepoListPage(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function projectScript(user, name,has_hook){
|
||||
// console.log(user,name,has_hook);
|
||||
var html = '';
|
||||
@@ -288,7 +484,7 @@ function projectScriptLoad(user,name){
|
||||
|
||||
layer.msg('加载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){
|
||||
userProjectList(1);
|
||||
gogsRepoListPage(1);
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
@@ -302,11 +498,18 @@ function projectScriptUnload(user,name){
|
||||
|
||||
layer.msg('卸载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
|
||||
setTimeout(function(){
|
||||
userProjectList(1);
|
||||
gogsRepoListPage(1);
|
||||
}, 2000);
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptRun(user, name){
|
||||
gogsPost('project_script_run', {'user':user,'name':name}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
layer.msg(data.msg,{icon:data.code?2:1,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptDebug(user,name){
|
||||
gogsPost('project_script_debug', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
@@ -318,6 +521,240 @@ function projectScriptDebug(user,name){
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function projectScriptSelfRender(user, name){
|
||||
gogsPost('project_script_self', {'user':user,'name':name}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
|
||||
var data = rdata['data']['data'];
|
||||
|
||||
if (rdata['data']['self_hook']){
|
||||
$('#open_script').prop('checked',true);
|
||||
}
|
||||
|
||||
var body = '';
|
||||
if(data.length == 0 ){
|
||||
body += '<tr><td colspan="3" style="text-align:center;">无脚本数据</td></tr>';
|
||||
} else{
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var b_status = '<a class="btlink status" data-index="'+i+'" target="_blank">已使用</a>';
|
||||
if (data[i]["is_hidden"]){
|
||||
b_status = '<a class="btlink status" data-index="'+i+'" target="_blank">已隐藏</a>';
|
||||
}
|
||||
|
||||
body += '<tr>'+
|
||||
'<td>' + data[i]["name"]+'</td>'+
|
||||
'<td>' + b_status + '</td>'+
|
||||
'<td>' +
|
||||
'<a class="btlink del" data-index="'+i+'" target="_blank">删除</a>' + ' | ' +
|
||||
'<a class="btlink edit" data-index="'+i+'" target="_blank">编辑</a>' + ' | ' +
|
||||
'<a class="btlink logs" data-index="'+i+'" target="_blank">日志</a>' + ' | ' +
|
||||
'<a class="btlink run" data-index="'+i+'" target="_blank">手动</a>' + ' | ' +
|
||||
'<a class="btlink rename" data-index="'+i+'" target="_blank">重命名</a>' +
|
||||
'</td></tr>';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$('#gogs_self_table tbody').html(body);
|
||||
$('#gogs_self_table .page').html(rdata['data']['list']);
|
||||
|
||||
$('#gogs_self_table .status').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
var status = '1';
|
||||
if (data[i]["is_hidden"]){
|
||||
status = '0';
|
||||
}
|
||||
gogsPost('project_script_self_status', {'user':user,'name':name,'file':file, status:status}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.code?2:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#gogs_self_table .del').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
gogsPost('project_script_self_del', {'user':user,'name':name,'file':file}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.code?2:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
});
|
||||
|
||||
$('#gogs_self_table .edit').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var path = data[i]["path"];
|
||||
onlineEditFile(0,path);
|
||||
});
|
||||
|
||||
$('#gogs_self_table .logs').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
gogsPost('project_script_self_logs', {'user':user,'name':name,'file':file}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
if (rdata['status']){
|
||||
onlineEditFile(0, rdata['data']['path']);
|
||||
} else {
|
||||
layer.msg(rdata.msg,{icon:data.status?2:1,time:2000,shade: [0.3, '#000']});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#gogs_self_table .run').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
if (data[i]["is_hidden"]){
|
||||
layer.msg("已经禁用,不能执行!",{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
gogsPost('project_script_self_run', {'user':user,'name':name,'file':file}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
layer.msg(rdata.msg,{icon:data.status?1:2,time:2000,shade: [0.3, '#000']});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
$('#gogs_self_table .rename').click(function(){
|
||||
var i = $(this).data('index');
|
||||
var file = data[i]["name"];
|
||||
|
||||
if (data[i]["is_hidden"]){
|
||||
layer.msg("已经禁用,不能执行!",{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
file = file.split('.sh')[0];
|
||||
|
||||
layer.open({
|
||||
type: 1,
|
||||
shift: 5,
|
||||
closeBtn: 1,
|
||||
area: '320px',
|
||||
title: '重命名',
|
||||
btn:['设置','关闭'],
|
||||
content: '<div class="bt-form pd20">\
|
||||
<div class="line">\
|
||||
<input type="text" class="bt-input-text" name="Name" id="newFileName" value="'+file+'" placeholder="文件名" style="width:100%" />\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("#newFileName").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(){
|
||||
var n_file = $("#newFileName").val();
|
||||
var o_file = file;
|
||||
|
||||
gogsPost('project_script_self_rename', {'user':user,'name':name,'o_file':o_file,'n_file':n_file}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
$(".layui-layer-btn1").click();
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.code?2:1,time:2000,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
}
|
||||
});
|
||||
//-----
|
||||
});
|
||||
//------
|
||||
});
|
||||
}
|
||||
|
||||
//新建文件
|
||||
function createScriptFile(type, user, name, file) {
|
||||
if (type == 1) {
|
||||
gogsPost('project_script_self_create', {'user':user,'name':name,'file': file }, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
if(!rdata['status']){
|
||||
layer.msg(rdata.msg,{icon:2,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
showMsg(rdata.msg, function(){
|
||||
$(".layui-layer-btn1").click();
|
||||
onlineEditFile(0,rdata['data']['abs_file']);
|
||||
projectScriptSelfRender(user, name);
|
||||
}, {icon:1,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
return;
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
shift: 5,
|
||||
closeBtn: 1,
|
||||
area: '320px',
|
||||
title: '新建自定义脚本',
|
||||
btn:['新建','关闭'],
|
||||
content: '<div class="bt-form pd20">\
|
||||
<div class="line">\
|
||||
<input type="text" class="bt-input-text" name="Name" id="newFileName" value="" placeholder="文件名" style="width:100%" />\
|
||||
</div>\
|
||||
</div>',
|
||||
success:function(){
|
||||
$("#newFileName").focus().keyup(function(e){
|
||||
if(e.keyCode == 13) $(".layui-layer-btn0").click();
|
||||
});
|
||||
},
|
||||
yes:function(){
|
||||
var file = $("#newFileName").val();;
|
||||
createScriptFile(1, user, name, file);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function projectScriptSelf(user, name){
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '项目('+user+'/'+name+')自定义脚本',
|
||||
area: '500px',
|
||||
content:"<div class='bt-form pd15'>\
|
||||
<button id='create_script' class='btn btn-success btn-sm' type='button' style='margin-right: 5px;''>添加脚本</button>\
|
||||
<div style='float:right;'>\
|
||||
<span style='line-height: 23px;'>开启自定义脚本</span>\
|
||||
<input class='btswitch btswitch-ios' id='open_script' type='checkbox'>\
|
||||
<label id='script_hook_enable' class='btswitch-btn' for='open_script' style='display: inline-flex;line-height:38px;margin-left: 4px;float: right;'></label>\
|
||||
</div>\
|
||||
<div id='gogs_self_table' class='divtable' style='margin-top:5px;'>\
|
||||
<table class='table table-hover'>\
|
||||
<thead><tr><th style='width:100px;'>脚本文件名</th><th>状态</th><th>操作</th></tr></thead>\
|
||||
<tbody></tbody>\
|
||||
</table>\
|
||||
<div class='dataTables_paginate paging_bootstrap pagination' style='margin-top:0px;'>\
|
||||
<ul class='page'><div class='gogs_page'></div></ul>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>",
|
||||
success:function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
|
||||
$('#create_script').click(function(){
|
||||
createScriptFile(0, user, name);
|
||||
});
|
||||
|
||||
$('#script_hook_enable').click(function(){
|
||||
var enable = $('#open_script').prop('checked');
|
||||
var enable_option = '0';
|
||||
if (!enable){
|
||||
enable_option = '1';
|
||||
}
|
||||
gogsPost('project_script_self_enable', {'user':user,'name':name,'enable':enable_option}, function(data){
|
||||
var data = $.parseJSON(data.data);
|
||||
showMsg(data.msg ,function(){
|
||||
projectScriptSelfRender(user, name);
|
||||
},{icon:data.status?1:2,shade: [0.3, '#000']},2000);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getRsaPublic(){
|
||||
gogsPost('get_rsa_public', {}, function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
@@ -344,7 +781,7 @@ function gogsRead(){
|
||||
var readme = '<ul class="help-info-text c7">';
|
||||
readme += '<li>默认使用MySQL,第一个启动加载各种配置,并修改成正确的数据库配置</li>';
|
||||
readme += '<li>邮件端口使用456,gogs仅支持使用STARTTLS的SMTP协议</li>';
|
||||
readme += '<li>如果使用项目中脚本本地同步,<a target="_blank" href="https://github.com/midoks/mdserver-web/wiki/%E6%8F%92%E4%BB%B6%E7%AE%A1%E7%90%86%5Bgogs%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%5D#%E5%90%AF%E5%8A%A8gogs%E5%90%8E%E5%A6%82%E6%9E%9C%E8%A6%81%E4%BD%BF%E7%94%A8hook%E8%84%9A%E6%9C%AC%E5%90%8C%E6%AD%A5%E4%BB%A3%E7%A0%81%E9%9C%80%E8%A6%81%E5%BC%80%E5%90%AFssh%E7%AB%AF%E5%8F%A3">点击查看</></li>';
|
||||
readme += '<li>项目【加载脚本】后,会自动同步到wwwroot目录下</li>';
|
||||
readme += '<li><a href="#" onclick="getRsaPublic();">点击查看本机公钥</></li>';
|
||||
readme += '</ul>';
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
global
|
||||
daemon
|
||||
#一般情况下,可关闭
|
||||
log 127.0.0.1 local0
|
||||
pidfile /tmp/haproxy.pid
|
||||
maxconn 4000
|
||||
user haproxy
|
||||
group haproxy
|
||||
|
||||
|
||||
defaults
|
||||
mode http
|
||||
log global
|
||||
@@ -20,6 +20,7 @@ listen stats
|
||||
mode http
|
||||
bind *:10800
|
||||
stats enable
|
||||
stats refresh 10
|
||||
stats uri /haproxy
|
||||
stats realm Haproxy\ Statistics
|
||||
stats auth admin:admin
|
||||
@@ -28,10 +29,11 @@ frontend http-in
|
||||
bind *:1080
|
||||
default_backend servers
|
||||
option forwardfor
|
||||
option httpclose
|
||||
#option httpclose
|
||||
option http-keep-alive
|
||||
|
||||
backend servers
|
||||
balance roundrobin
|
||||
server web1 0.0.0.0:9090 check
|
||||
server web1 0.0.0.0:9090 check inter 2000 rise 2 fall 5
|
||||
|
||||
|
||||
|
||||
+11
-15
@@ -97,6 +97,8 @@ def contentReplace(content):
|
||||
service_path = mw.getServerDir()
|
||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$HA_USER}', mw.getRandomString(8))
|
||||
content = content.replace('{$HA_PWD}', mw.getRandomString(10))
|
||||
content = content.replace('{$SERVER_APP}', service_path + '/haproxy')
|
||||
return content
|
||||
|
||||
@@ -150,6 +152,13 @@ def initDreplace():
|
||||
def haOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
# check config
|
||||
sdir = getServerDir()
|
||||
cmd_check = sdir+'/sbin/haproxy -c -f ' + sdir + '/haproxy.conf'
|
||||
chk_data = mw.execShell(cmd_check)
|
||||
if chk_data[1]!= '':
|
||||
return chk_data[1]
|
||||
|
||||
if not mw.isAppleSystem():
|
||||
data = mw.execShell('systemctl ' + method + ' haproxy')
|
||||
if data[1] == '':
|
||||
@@ -206,19 +215,8 @@ def initdUinstall():
|
||||
|
||||
|
||||
def runLog():
|
||||
path = getConf()
|
||||
content = mw.readFile(path)
|
||||
rep = 'log\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0]
|
||||
|
||||
|
||||
def getPort():
|
||||
path = getConf()
|
||||
content = mw.readFile(path)
|
||||
rep = 'listen\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0]
|
||||
path = getServerDir() + "/haproxy.log"
|
||||
return path
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@@ -247,7 +245,5 @@ if __name__ == "__main__":
|
||||
print(readConfigTpl())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'query_log':
|
||||
print(queryLog())
|
||||
else:
|
||||
print('error')
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
|
||||
# for mac
|
||||
export PATH=$PATH:/opt/homebrew/bin
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
@@ -23,12 +25,12 @@ else
|
||||
fi
|
||||
|
||||
if [ "${2}" == "" ];then
|
||||
echo '缺少安装脚本...' > $install_tmp
|
||||
echo '缺少安装脚本...'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d $curPath/versions/$2 ];then
|
||||
echo '缺少安装脚本2...' > $install_tmp
|
||||
echo '缺少安装脚本2...'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ function spPostMin(method, args, callback){
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
layer.msg(data.msg,{icon:0,time:10000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
global
|
||||
daemon
|
||||
pidfile /tmp/haproxy.pid
|
||||
maxconn 4000
|
||||
user haproxy
|
||||
group haproxy
|
||||
|
||||
|
||||
defaults
|
||||
mode http
|
||||
log global
|
||||
option httplog
|
||||
timeout connect 10s
|
||||
timeout client 15s
|
||||
timeout server 15s
|
||||
|
||||
|
||||
listen stats
|
||||
mode http
|
||||
bind *:10800
|
||||
stats enable
|
||||
stats refresh 10
|
||||
stats uri /haproxy
|
||||
stats realm Haproxy\ Statistics
|
||||
stats auth {$HA_USER}:{$HA_PWD}
|
||||
|
||||
frontend http-in
|
||||
bind *:1080
|
||||
default_backend servers
|
||||
option forwardfor
|
||||
option http-keep-alive
|
||||
|
||||
backend servers
|
||||
balance roundrobin
|
||||
server web1 0.0.0.0:9090 check inter 2000 rise 2 fall 5
|
||||
|
||||
|
||||
@@ -20,12 +20,26 @@ VERSION=2.6.4
|
||||
MIN_VERSION=2.6
|
||||
Install_App()
|
||||
{
|
||||
|
||||
echo '正在安装脚本文件...' > $install_tmp
|
||||
echo '正在安装Haproxy软件...'
|
||||
mkdir -p $serverPath/haproxy
|
||||
|
||||
APP_DIR=${serverPath}/source/haproxy
|
||||
mkdir -p $APP_DIR
|
||||
|
||||
|
||||
LOCAL_ADDR=common
|
||||
cn=$(curl -fsSL -m 10 -s http://ipinfo.io/json | grep "\"country\": \"CN\"")
|
||||
if [ ! -z "$cn" ] || [ "$?" == "0" ] ;then
|
||||
LOCAL_ADDR=cn
|
||||
fi
|
||||
|
||||
|
||||
if [ "${LOCAL_ADDR}" == "cn" ];then
|
||||
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
|
||||
wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://dl.midoks.me/soft/haproxy/haproxy-${VERSION}.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
|
||||
if [ $sysName == 'Darwin' ]; then
|
||||
@@ -49,7 +63,28 @@ Install_App()
|
||||
fi
|
||||
|
||||
echo $MIN_VERSION > $serverPath/haproxy/version.pl
|
||||
echo 'Install_HA' > $install_tmp
|
||||
echo '安装Haproxy成功' > $install_tmp
|
||||
|
||||
#Haproxy日志配置
|
||||
if [ -f /etc/rsyslog.conf ];then
|
||||
find_ha=`cat /etc/rsyslog.conf | grep haproxy`
|
||||
if [ "$find_ha" != "" ];then
|
||||
echo $find_ha
|
||||
else
|
||||
echo "---------------------------------------------"
|
||||
echo "" > ${serverPath}/haproxy/haproxy.log
|
||||
echo "local0.* ${serverPath}/haproxy/haproxy.log" >> /etc/rsyslog.conf
|
||||
systemctl restart syslog
|
||||
echo "syslog默认的haproxy配置"
|
||||
echo "local0.* ${serverPath}/haproxy/haproxy.log >> /etc/rsyslog.conf"
|
||||
echo "---------------------------------------------"
|
||||
fi
|
||||
fi
|
||||
|
||||
#删除解压源码
|
||||
if [ -d ${APP_DIR}/haproxy-${VERSION} ];then
|
||||
rm -rf ${APP_DIR}/haproxy-${VERSION}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
@@ -59,7 +94,7 @@ Uninstall_App()
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/haproxy
|
||||
echo "Uninstall_HA" > $install_tmp
|
||||
echo "卸载Haproxy成功"
|
||||
}
|
||||
|
||||
action=$1
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
! Configuration File for keepalived
|
||||
|
||||
global_defs {
|
||||
router_id MYSQL_MHA
|
||||
}
|
||||
|
||||
vrrp_script chk_mysql_port {
|
||||
script "{$SERVER_PATH}/keepalived/scripts/chk.sh mysql"
|
||||
interval 2
|
||||
weight –5
|
||||
fall 2
|
||||
rise 1
|
||||
}
|
||||
|
||||
vrrp_instance VI_MYSQL {
|
||||
state MASTER
|
||||
interface {$ETH_XX}
|
||||
virtual_router_id 51
|
||||
priority 100
|
||||
advert_int 1
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass 1111
|
||||
}
|
||||
virtual_ipaddress {
|
||||
192.168.10.10
|
||||
}
|
||||
|
||||
track_script {
|
||||
chk_mysql_port
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 562 B |
Executable
+22
@@ -0,0 +1,22 @@
|
||||
<div class="bt-form">
|
||||
<div class='plugin_version'></div>
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('keepalived');">服务</p>
|
||||
<p onclick="pluginInitD('keepalived');">自启动</p>
|
||||
<!-- <p onclick="pluginConfig('keepalived');">配置修改</p> -->
|
||||
<p onclick="pluginConfigTpl('keepalived',$('.plugin_version').attr('version'));">配置修改</p>
|
||||
<p onclick="pluginConfigListTpl('keepalived',$('.plugin_version').attr('version'),'config_scripts_tpl','read_config_tpl');">脚本模板</p>
|
||||
<p onclick="pluginLogs('keepalived','','run_log');">日志</p>
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(530);
|
||||
$.getScript( "/plugins/file?name=keepalived&f=js/keepalived.js", function(){
|
||||
pluginService('keepalived', $('.plugin_version').attr('version'));
|
||||
});
|
||||
</script>
|
||||
Executable
+353
@@ -0,0 +1,353 @@
|
||||
# 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 'keepalived'
|
||||
|
||||
|
||||
def getPluginDir():
|
||||
return mw.getPluginDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getServerDir():
|
||||
return mw.getServerDir() + '/' + getPluginName()
|
||||
|
||||
|
||||
def getInitDFile():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return '/tmp/' + getPluginName()
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
return '/etc/rc.d/' + getPluginName()
|
||||
|
||||
return '/etc/init.d/' + getPluginName()
|
||||
|
||||
|
||||
def getConf():
|
||||
path = getServerDir() + "/etc/keepalived/keepalived.conf"
|
||||
return path
|
||||
|
||||
|
||||
def getConfTpl():
|
||||
path = getPluginDir() + "/config/keepalived.conf"
|
||||
return path
|
||||
|
||||
|
||||
def getInitDTpl():
|
||||
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
|
||||
return path
|
||||
|
||||
|
||||
def getArgs():
|
||||
args = sys.argv[3:]
|
||||
tmp = {}
|
||||
args_len = len(args)
|
||||
|
||||
if args_len == 1:
|
||||
t = args[0].strip('{').strip('}')
|
||||
if t.strip() == '':
|
||||
tmp = []
|
||||
else:
|
||||
t = t.split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
tmp[t[0]] = t[1]
|
||||
elif args_len > 1:
|
||||
for i in range(len(args)):
|
||||
t = args[i].split(':')
|
||||
tmp[t[0]] = t[1]
|
||||
return tmp
|
||||
|
||||
def checkArgs(data, ck=[]):
|
||||
for i in range(len(ck)):
|
||||
if not ck[i] in data:
|
||||
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
|
||||
return (True, mw.returnJson(True, 'ok'))
|
||||
|
||||
def configTpl():
|
||||
path = getPluginDir() + '/tpl'
|
||||
pathFile = os.listdir(path)
|
||||
tmp = []
|
||||
for one in pathFile:
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
def readConfigTpl():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file'])
|
||||
if not data[0]:
|
||||
return data[1]
|
||||
|
||||
content = mw.readFile(args['file'])
|
||||
content = contentReplace(content)
|
||||
return mw.returnJson(True, 'ok', content)
|
||||
|
||||
|
||||
def defaultScriptsTpl():
|
||||
path = getServerDir() + "/scripts/chk.sh"
|
||||
return path
|
||||
|
||||
def configScriptsTpl():
|
||||
path = getServerDir() + '/scripts'
|
||||
pathFile = os.listdir(path)
|
||||
tmp = []
|
||||
for one in pathFile:
|
||||
file = path + '/' + one
|
||||
tmp.append(file)
|
||||
return mw.getJson(tmp)
|
||||
|
||||
|
||||
def status():
|
||||
data = mw.execShell(
|
||||
"ps aux|grep keepalived |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
|
||||
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def contentReplace(content):
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
content = content.replace('{$SERVER_PATH}', service_path)
|
||||
content = content.replace('{$PLUGIN_PATH}', getPluginDir())
|
||||
|
||||
# 网络接口
|
||||
ethx = mw.execShell("route -n | grep ^0.0.0.0 | awk '{print $8}'")
|
||||
if ethx[1]!='':
|
||||
# 未找到
|
||||
content = content.replace('{$ETH_XX}', 'eth1')
|
||||
else:
|
||||
# 已找到
|
||||
content = content.replace('{$ETH_XX}', ethx[0])
|
||||
|
||||
|
||||
return content
|
||||
|
||||
|
||||
def copyScripts():
|
||||
# 复制检查脚本
|
||||
src_scripts_path = getPluginDir() + '/scripts'
|
||||
dst_scripts_path = getServerDir() + '/scripts'
|
||||
if not os.path.exists(dst_scripts_path):
|
||||
mw.execShell('mkdir -p ' + dst_scripts_path)
|
||||
olist = os.listdir(src_scripts_path)
|
||||
for o in range(len(olist)):
|
||||
src_file = src_scripts_path+'/'+olist[o]
|
||||
dst_file = dst_scripts_path+'/'+olist[o]
|
||||
|
||||
content = mw.readFile(src_file)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(dst_file, content)
|
||||
|
||||
cmd = 'chmod +x ' + dst_file
|
||||
mw.execShell(cmd)
|
||||
return True
|
||||
return False
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
# initd replace
|
||||
if not os.path.exists(file_bin):
|
||||
content = mw.readFile(file_tpl)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(file_bin, content)
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
# log
|
||||
dataLog = getServerDir() + '/data'
|
||||
if not os.path.exists(dataLog):
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
# config replace
|
||||
dst_conf = getServerDir() + '/etc/keepalived/keepalived.conf'
|
||||
dst_conf_init = getServerDir() + '/init.pl'
|
||||
if not os.path.exists(dst_conf_init):
|
||||
content = mw.readFile(getConfTpl())
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(dst_conf, content)
|
||||
mw.writeFile(dst_conf_init, 'ok')
|
||||
|
||||
# 复制检查脚本
|
||||
copyScripts()
|
||||
|
||||
# systemd
|
||||
systemDir = mw.systemdCfgDir()
|
||||
systemService = systemDir + '/' + getPluginName() + '.service'
|
||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
||||
systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
|
||||
service_path = mw.getServerDir()
|
||||
content = mw.readFile(systemServiceTpl)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(systemService, content)
|
||||
mw.execShell('systemctl daemon-reload')
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def kpOp(method):
|
||||
file = initDreplace()
|
||||
|
||||
current_os = mw.getOs()
|
||||
if current_os == "darwin":
|
||||
data = mw.execShell(file + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
if current_os.startswith("freebsd"):
|
||||
data = mw.execShell('service ' + getPluginName() + ' ' + method)
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
|
||||
if data[1] == '':
|
||||
return 'ok'
|
||||
return data[1]
|
||||
|
||||
|
||||
def start():
|
||||
return kpOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return kpOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
status = kpOp('restart')
|
||||
|
||||
log_file = runLog()
|
||||
mw.execShell("echo '' > " + log_file)
|
||||
return status
|
||||
|
||||
|
||||
def reload():
|
||||
return kpOp('reload')
|
||||
|
||||
|
||||
def getPort():
|
||||
conf = getServerDir() + '/keepalived.conf'
|
||||
content = mw.readFile(conf)
|
||||
|
||||
rep = "^(" + 'port' + ')\s*([.0-9A-Za-z_& ~]+)'
|
||||
tmp = re.search(rep, content, re.M)
|
||||
if tmp:
|
||||
return tmp.groups()[1]
|
||||
|
||||
return '6379'
|
||||
|
||||
|
||||
def initdStatus():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
|
||||
shell_cmd = 'systemctl status ' + \
|
||||
getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
# freebsd initd install
|
||||
if current_os.startswith('freebsd'):
|
||||
import shutil
|
||||
source_bin = initDreplace()
|
||||
initd_bin = getInitDFile()
|
||||
shutil.copyfile(source_bin, initd_bin)
|
||||
mw.execShell('chmod +x ' + initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl enable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
os.remove(initd_bin)
|
||||
mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
|
||||
return 'ok'
|
||||
|
||||
mw.execShell('systemctl disable ' + getPluginName())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def runLog():
|
||||
return getServerDir() + '/' + getPluginName() + '.log'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
func = sys.argv[1]
|
||||
if func == 'status':
|
||||
print(status())
|
||||
elif func == 'start':
|
||||
print(start())
|
||||
elif func == 'stop':
|
||||
print(stop())
|
||||
elif func == 'restart':
|
||||
print(restart())
|
||||
elif func == 'reload':
|
||||
print(reload())
|
||||
elif func == 'initd_status':
|
||||
print(initdStatus())
|
||||
elif func == 'initd_install':
|
||||
print(initdInstall())
|
||||
elif func == 'initd_uninstall':
|
||||
print(initdUinstall())
|
||||
elif func == 'run_info':
|
||||
print(runInfo())
|
||||
elif func == 'conf':
|
||||
print(getConf())
|
||||
elif func == 'run_log':
|
||||
print(runLog())
|
||||
elif func == 'config_tpl':
|
||||
print(configTpl())
|
||||
elif func == 'default_scripts_tpl':
|
||||
print(defaultScriptsTpl())
|
||||
elif func == 'config_scripts_tpl':
|
||||
print(configScriptsTpl())
|
||||
elif func == 'read_config_tpl':
|
||||
print(readConfigTpl())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "[<span style='color:red;'>内网</span>]优秀的高可用软件",
|
||||
"name": "keepalived",
|
||||
"title": "keepalived",
|
||||
"shell": "install.sh",
|
||||
"versions":["2.2.8"],
|
||||
"tip": "soft",
|
||||
"checks": "server/keepalived",
|
||||
"path": "server/keepalived",
|
||||
"display": 1,
|
||||
"author": "keepalived",
|
||||
"date": "2023-10-22",
|
||||
"home": "https://keepalived.org/download.html",
|
||||
"type": "soft",
|
||||
"pid": "4"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Redis In-Memory Data Store
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
ExecStart={$SERVER_PATH}/keepalived/sbin/keepalived -D
|
||||
ExecReload=/bin/kill -USR1 $MAINPID
|
||||
Restart=on-failure
|
||||
StandardOutput={$SERVER_PATH}/keepalived/keepalived.log
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,78 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Startup script for the Keepalived daemon
|
||||
#
|
||||
# processname: keepalived
|
||||
# pidfile: /var/run/keepalived.pid
|
||||
# config: /etc/keepalived/keepalived.conf
|
||||
# chkconfig: - 21 79
|
||||
# description: Start and stop Keepalived
|
||||
|
||||
# Source function library
|
||||
if [ -f /etc/rc.d/init.d/functions ];then
|
||||
. /etc/rc.d/init.d/functions
|
||||
fi
|
||||
|
||||
SYS_KP_FILE={$SERVER_PATH}/keepalived/etc/sysconfig/keepalived
|
||||
# Source configuration file (we set KEEPALIVED_OPTIONS there)
|
||||
if [ -f $SYS_KP_FILE ];then
|
||||
. $SYS_KP_FILE
|
||||
fi
|
||||
|
||||
RETVAL=0
|
||||
prog="keepalived"
|
||||
|
||||
start() {
|
||||
echo -n $"Starting $prog: "
|
||||
{$SERVER_PATH}/keepalived/sbin/keepalived ${KEEPALIVED_OPTIONS}
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Stopping $prog: "
|
||||
pkill keepalived
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog
|
||||
}
|
||||
|
||||
reload() {
|
||||
echo -n $"Reloading $prog: "
|
||||
pkill keepalived -1
|
||||
RETVAL=$?
|
||||
echo
|
||||
}
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
reload)
|
||||
reload
|
||||
;;
|
||||
restart)
|
||||
stop
|
||||
start
|
||||
;;
|
||||
condrestart)
|
||||
if [ -f /var/lock/subsys/$prog ]; then
|
||||
stop
|
||||
start
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
status keepalived
|
||||
RETVAL=$?
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|reload|restart|condrestart|status}"
|
||||
RETVAL=1
|
||||
esac
|
||||
|
||||
exit $RETVAL
|
||||
Executable
+100
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
|
||||
# for mac
|
||||
export PATH=$PATH:/opt/homebrew/bin
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/keepalived && bash install.sh install 2.2.8
|
||||
# cd /www/server/mdserver-web/plugins/keepalived && bash install.sh install 2.2.8
|
||||
|
||||
# /www/server/keepalived/init.d/keepalived start
|
||||
|
||||
# systemctl status keepalived
|
||||
# systemctl restart keepalived
|
||||
# ifconfig
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
VERSION=$2
|
||||
|
||||
Install_App()
|
||||
{
|
||||
echo '正在安装keepalived脚本文件...'
|
||||
mkdir -p $serverPath/source/keepalived
|
||||
|
||||
if [ ! -f $serverPath/source/keepalived/keepalived-${VERSION}.tar.gz ];then
|
||||
wget -O $serverPath/source/keepalived/keepalived-${VERSION}.tar.gz https://keepalived.org/software/keepalived-${VERSION}.tar.gz
|
||||
fi
|
||||
|
||||
#检测文件是否损坏.
|
||||
md5_file_ok=8c26f75a8767e5341d82696e1e717115
|
||||
if [ -f $serverPath/source/keepalived/keepalived-${VERSION}.tar.gz ];then
|
||||
md5_file=`md5sum $serverPath/source/keepalived/keepalived-${VERSION}.tar.gz | awk '{print $1}'`
|
||||
if [ "${md5_file}" != "${md5_file_ok}" ]; then
|
||||
echo "keepalived-${version} 下载文件不完整,重新安装"
|
||||
rm -rf $serverPath/source/keepalived/keepalived-${VERSION}.tar.gz
|
||||
fi
|
||||
fi
|
||||
|
||||
echo $serverPath/keepalived/keepalived-${VERSION}
|
||||
if [ -d $serverPath/keepalived/keepalived-${VERSION} ];then
|
||||
cd $serverPath/keepalived/keepalived-${VERSION}
|
||||
else
|
||||
cd $serverPath/source/keepalived && tar -zxvf keepalived-${VERSION}.tar.gz
|
||||
cd $serverPath/keepalived/keepalived-${VERSION}
|
||||
fi
|
||||
|
||||
cd $serverPath/source/keepalived/keepalived-${VERSION}
|
||||
|
||||
./configure --prefix=$serverPath/keepalived && make && make install
|
||||
|
||||
# for test
|
||||
# mkdir -p $serverPath/keepalived
|
||||
if [ -d $serverPath/keepalived ];then
|
||||
echo "${VERSION}" > $serverPath/keepalived/version.pl
|
||||
echo 'keepalived安装完成'
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/keepalived/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/keepalived/index.py initd_install
|
||||
fi
|
||||
|
||||
if [ -d $serverPath/source/keepalived/keepalived-${VERSION} ];then
|
||||
rm -rf $serverPath/source/keepalived/keepalived-${VERSION}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_App()
|
||||
{
|
||||
if [ -f /usr/lib/systemd/system/keepalived.service ];then
|
||||
systemctl stop keepalived
|
||||
systemctl disable keepalived
|
||||
rm -rf /usr/lib/systemd/system/keepalived.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f /lib/systemd/system/keepalived.service ];then
|
||||
systemctl stop keepalived
|
||||
systemctl disable keepalived
|
||||
rm -rf /lib/systemd/system/keepalived.service
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
if [ -f $serverPath/keepalived/initd/keepalived ];then
|
||||
$serverPath/keepalived/initd/keepalived stop
|
||||
fi
|
||||
|
||||
rm -rf $serverPath/keepalived
|
||||
echo "keepalived卸载完成"
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_App
|
||||
else
|
||||
Uninstall_App
|
||||
fi
|
||||
Executable
+143
@@ -0,0 +1,143 @@
|
||||
function kpPost(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'keepalived';
|
||||
req_data['func'] = method;
|
||||
req_data['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
//错误展示10S
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function kpPostCallbak(method, version, args,callback){
|
||||
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'keepalived';
|
||||
req_data['func'] = method;
|
||||
args['version'] = version;
|
||||
|
||||
if (typeof(args) == 'string'){
|
||||
req_data['args'] = JSON.stringify(toArrayObject(args));
|
||||
} else {
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/callback', req_data, function(data) {
|
||||
layer.close(loadT);
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
//redis负载状态 start
|
||||
function redisStatus(version) {
|
||||
|
||||
redisPost('run_info',version, {},function(data){
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// if (!rdata.status){
|
||||
// layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
// return;
|
||||
// }
|
||||
|
||||
hit = (parseInt(rdata.keyspace_hits) / (parseInt(rdata.keyspace_hits) + parseInt(rdata.keyspace_misses)) * 100).toFixed(2);
|
||||
var con = '<div class="divtable">\
|
||||
<table class="table table-hover table-bordered" style="width: 490px;">\
|
||||
<thead><th>字段</th><th>当前值</th><th>说明</th></thead>\
|
||||
<tbody>\
|
||||
<tr><th>uptime_in_days</th><td>' + rdata.uptime_in_days + '</td><td>已运行天数</td></tr>\
|
||||
<tr><th>tcp_port</th><td>' + rdata.tcp_port + '</td><td>当前监听端口</td></tr>\
|
||||
<tr><th>connected_clients</th><td>' + rdata.connected_clients + '</td><td>连接的客户端数量</td></tr>\
|
||||
<tr><th>used_memory_rss</th><td>' + toSize(rdata.used_memory_rss) + '</td><td>Redis当前占用的系统内存总量</td></tr>\
|
||||
<tr><th>used_memory</th><td>' + toSize(rdata.used_memory) + '</td><td>Redis当前已分配的内存总量</td></tr>\
|
||||
<tr><th>used_memory_peak</th><td>' + toSize(rdata.used_memory_peak) + '</td><td>Redis历史分配内存的峰值</td></tr>\
|
||||
<tr><th>mem_fragmentation_ratio</th><td>' + rdata.mem_fragmentation_ratio + '%</td><td>内存碎片比率</td></tr>\
|
||||
<tr><th>total_connections_received</th><td>' + rdata.total_connections_received + '</td><td>运行以来连接过的客户端的总数量</td></tr>\
|
||||
<tr><th>total_commands_processed</th><td>' + rdata.total_commands_processed + '</td><td>运行以来执行过的命令的总数量</td></tr>\
|
||||
<tr><th>instantaneous_ops_per_sec</th><td>' + rdata.instantaneous_ops_per_sec + '</td><td>服务器每秒钟执行的命令数量</td></tr>\
|
||||
<tr><th>keyspace_hits</th><td>' + rdata.keyspace_hits + '</td><td>查找数据库键成功的次数</td></tr>\
|
||||
<tr><th>keyspace_misses</th><td>' + rdata.keyspace_misses + '</td><td>查找数据库键失败的次数</td></tr>\
|
||||
<tr><th>hit</th><td>' + hit + '%</td><td>查找数据库键命中率</td></tr>\
|
||||
<tr><th>latest_fork_usec</th><td>' + rdata.latest_fork_usec + '</td><td>最近一次 fork() 操作耗费的微秒数</td></tr>\
|
||||
<tbody>\
|
||||
</table></div>';
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
//redis负载状态 end
|
||||
|
||||
//配置修改
|
||||
function getRedisConfig(version) {
|
||||
redisPost('get_redis_conf', version,'',function(data){
|
||||
// console.log(data);
|
||||
var rdata = $.parseJSON(data.data);
|
||||
// console.log(rdata);
|
||||
var mlist = '';
|
||||
for (var i = 0; i < rdata.length; i++) {
|
||||
var w = '70'
|
||||
if (rdata[i].name == 'error_reporting') w = '250';
|
||||
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><span>' + rdata[i].name + '</span>' + ibody + ', <font>' + 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="getRedisConfig(\'' + version + '\')">刷新</button>\
|
||||
<button class="btn btn-success btn-sm" onclick="submitConf(\'' + version + '\')">保存</button></div>\
|
||||
</div>'
|
||||
$(".soft-man-con").html(con);
|
||||
});
|
||||
}
|
||||
|
||||
//提交配置
|
||||
function submitConf(version) {
|
||||
var data = {
|
||||
version: version,
|
||||
bind: $("input[name='bind']").val(),
|
||||
'port': $("input[name='port']").val(),
|
||||
'timeout': $("input[name='timeout']").val(),
|
||||
maxclients: $("input[name='maxclients']").val(),
|
||||
databases: $("input[name='databases']").val(),
|
||||
requirepass: $("input[name='requirepass']").val(),
|
||||
maxmemory: $("input[name='maxmemory']").val(),
|
||||
};
|
||||
|
||||
redisPost('submit_redis_conf', version, data, function(ret_data){
|
||||
var rdata = $.parseJSON(ret_data.data);
|
||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 计划任务,恢复后,可自动拉起keepalived
|
||||
# bash {$SERVER_PATH}/keepalived/scripts/chk.sh mysql
|
||||
|
||||
cd {$SERVER_PATH}/keepalived
|
||||
|
||||
# check script bash
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
|
||||
SOFT=$1
|
||||
|
||||
if [ "$SOFT" == "mysql" ];then
|
||||
bash ${rootPath}/keepalived/scripts/chk_mysql.sh > ${rootPath}/keepalived/keepalived.log
|
||||
else
|
||||
echo "you should use [chk.sh mysql] exp ."
|
||||
fi
|
||||
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 计划任务,恢复后,可自动拉起keepalived
|
||||
# bash {$SERVER_PATH}/keepalived/scripts/chk_mysql.sh
|
||||
|
||||
counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
|
||||
data_time=`date +'%Y-%m-%d %H:%M:%S'`
|
||||
|
||||
if [ "${counter}" -eq "0" ]; then
|
||||
echo "${data_time}: start check mysql status, mysql is down, stop keepalive ..."
|
||||
systemctl stop keepalived
|
||||
echo "${data_time}: start check mysql end !!!"
|
||||
fi
|
||||
|
||||
|
||||
# 恢复后,自动拉起
|
||||
# systemctl start keepalived
|
||||
if [ "${counter}" -gt "0" ]; then
|
||||
echo "${data_time}: start check mysql status, mysql is up, start keepalive"
|
||||
|
||||
keepalived_status=`which systemctl && systemctl status keepalived | grep Active | grep inactive`
|
||||
if [ "$keepalived_status" != "" ];then
|
||||
systemctl start keepalived
|
||||
fi
|
||||
|
||||
echo "${data_time}: start check mysql end !!!"
|
||||
fi
|
||||
@@ -0,0 +1,46 @@
|
||||
# keepalived for lvs-nat
|
||||
# 未测试通过
|
||||
|
||||
global_defs {
|
||||
router_id HA_LVS
|
||||
}
|
||||
|
||||
vrrp_sync_group HA_LVS_NAT {
|
||||
group {
|
||||
HA_LVS_NAT
|
||||
}
|
||||
}
|
||||
|
||||
vrrp_instance HA_LVS_NAT {
|
||||
state MASTER
|
||||
interface bond1
|
||||
virtual_router_id 222
|
||||
priority 100
|
||||
advert_int 1
|
||||
nopreempt
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass 1111
|
||||
}
|
||||
virtual_ipaddress {
|
||||
192.168.212.100/25 dev bond1
|
||||
}
|
||||
}
|
||||
|
||||
virtual_server 192.168.212.100 80 {
|
||||
delay_loop 6
|
||||
lb_algo rr
|
||||
lb_kind NAT
|
||||
protocol TCP
|
||||
|
||||
real_server 192.168.212.129 80 {
|
||||
weight 100
|
||||
TCP_CHECK {
|
||||
connect_timeout 3
|
||||
nb_get_retry 3
|
||||
delay_before_retry 3
|
||||
connect_port 15000
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
! Configuration File for keepalived
|
||||
|
||||
global_defs {
|
||||
router_id MYSQL_MHA
|
||||
}
|
||||
|
||||
vrrp_script chk_mysql_port {
|
||||
script "{$SERVER_PATH}/scripts/chk.sh mysql"
|
||||
interval 2
|
||||
weight –5
|
||||
fall 2
|
||||
rise 1
|
||||
}
|
||||
|
||||
vrrp_instance VI_MYSQL {
|
||||
state 这里所有节点定义为BACKUP
|
||||
interface {$ETH_XX}
|
||||
virtual_router_id 51
|
||||
priority 100
|
||||
advert_int 1
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass 1111
|
||||
}
|
||||
virtual_ipaddress {
|
||||
192.168.10.10
|
||||
}
|
||||
|
||||
track_script {
|
||||
chk_mysql_port
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
! Configuration File for keepalived
|
||||
|
||||
global_defs {
|
||||
router_id MYSQL_MHA
|
||||
}
|
||||
|
||||
vrrp_script chk_mysql_port {
|
||||
script "{$SERVER_PATH}/scripts/chk.sh mysql"
|
||||
interval 2
|
||||
weight –5
|
||||
fall 2
|
||||
rise 1
|
||||
}
|
||||
|
||||
vrrp_instance VI_MYSQL {
|
||||
state MASTER
|
||||
interface {$ETH_XX}
|
||||
virtual_router_id 51
|
||||
priority 101
|
||||
advert_int 1
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass 1111
|
||||
}
|
||||
virtual_ipaddress {
|
||||
192.168.10.10
|
||||
}
|
||||
|
||||
track_script {
|
||||
chk_mysql_port
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
! Configuration File for keepalived
|
||||
|
||||
global_defs {
|
||||
# 路由标识,主从保持一致
|
||||
router_id MYSQL_MHA
|
||||
}
|
||||
|
||||
#检测mysql服务是否在运行。有很多方式,比如进程,用脚本检测等等
|
||||
vrrp_script chk_mysql_port {
|
||||
# 这里通过脚本监测
|
||||
script "{$SERVER_PATH}/scripts/chk.sh mysql"
|
||||
# 脚本执行间隔,每2s检测一次
|
||||
interval 2
|
||||
# 脚本结果导致的优先级变更,检测失败(脚本返回非0)则优先级 -5
|
||||
weight –5
|
||||
# 检测连续2次失败才算确定是真失败。会用weight减少优先级(1-255之间)
|
||||
fall 2
|
||||
# 检测1次成功就算成功。但不修改优先级
|
||||
rise 1
|
||||
}
|
||||
|
||||
vrrp_instance VI_1 {
|
||||
# 这里所有节点定义为BACKUP/MASTER
|
||||
state BACKUP
|
||||
# 指定虚拟ip的网卡(可能需要手动查看)
|
||||
# route -n | grep ^0.0.0.0 | awk '{print $8}'
|
||||
interface {$ETH_XX}
|
||||
# 路由器标识,MASTER和BACKUP必须是一致的
|
||||
virtual_router_id 51
|
||||
# 定义优先级,数字越大,优先级越高,在同一个vrrp_instance下,MASTER的优先级必须大于BACKUP的优先级
|
||||
priority 99
|
||||
# 通知间隔秒数(心跳频率)
|
||||
advert_int 1
|
||||
# 不抢占模式,在优先级高的机器上设置即可,优先级低的机器可不设置
|
||||
nopreempt
|
||||
# 认证信息配置,主从服务器保持一致
|
||||
authentication {
|
||||
auth_type PASS
|
||||
auth_pass 1111
|
||||
}
|
||||
virtual_ipaddress {
|
||||
# 虚拟IP(VIP) | 根据情况设置
|
||||
192.168.10.10
|
||||
}
|
||||
|
||||
track_script {
|
||||
chk_mysql_port
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Executable
+19
@@ -0,0 +1,19 @@
|
||||
<div class="bt-form">
|
||||
<div class="bt-w-main">
|
||||
<div class="bt-w-menu">
|
||||
<p class="bgw" onclick="pluginService('lvs');">服务</p>
|
||||
<p onclick="pluginInitD('lvs');">自启动</p>
|
||||
<p onclick="pluginConfig('lvs');">配置修改</p>
|
||||
<!-- <p onclick="pluginLogs('lvs','','run_log',30);">运行日志</p> -->
|
||||
</div>
|
||||
<div class="bt-w-con pd15">
|
||||
<div class="soft-man-con"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
resetPluginWinHeight(480);
|
||||
$.getScript( "/plugins/file?name=lvs&f=js/lvs.js", function(){
|
||||
pluginService('lvs');
|
||||
});
|
||||
</script>
|
||||
Executable
+180
@@ -0,0 +1,180 @@
|
||||
# coding:utf-8
|
||||
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import string
|
||||
import subprocess
|
||||
|
||||
sys.path.append(os.getcwd() + "/class/core")
|
||||
import mw
|
||||
|
||||
app_debug = False
|
||||
if mw.isAppleSystem():
|
||||
app_debug = True
|
||||
|
||||
|
||||
def getPluginName():
|
||||
return 'lvs'
|
||||
|
||||
def getIpvsadm():
|
||||
return 'ipvsadm'
|
||||
|
||||
|
||||
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 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 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 getConf():
|
||||
path = '/etc/default/ipvsadm'
|
||||
return path
|
||||
|
||||
|
||||
def status():
|
||||
data = mw.execShell("which ipvsadm")
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
|
||||
def initDreplace():
|
||||
|
||||
file_tpl = getInitDTpl()
|
||||
service_path = os.path.dirname(os.getcwd())
|
||||
|
||||
initD_path = getServerDir() + '/init.d'
|
||||
if not os.path.exists(initD_path):
|
||||
os.mkdir(initD_path)
|
||||
file_bin = initD_path + '/' + getPluginName()
|
||||
|
||||
# initd replace
|
||||
if not os.path.exists(file_bin):
|
||||
content = mw.readFile(file_tpl)
|
||||
content = contentReplace(content)
|
||||
mw.writeFile(file_bin, content)
|
||||
mw.execShell('chmod +x ' + file_bin)
|
||||
|
||||
|
||||
return file_bin
|
||||
|
||||
|
||||
def haOp(method):
|
||||
return 'ok'
|
||||
|
||||
|
||||
def start():
|
||||
return haOp('start')
|
||||
|
||||
|
||||
def stop():
|
||||
return haOp('stop')
|
||||
|
||||
|
||||
def restart():
|
||||
return haOp('restart')
|
||||
|
||||
|
||||
def reload():
|
||||
return haOp('reload')
|
||||
|
||||
def initdStatus():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
if current_os.startswith('freebsd'):
|
||||
initd_bin = getInitDFile()
|
||||
if os.path.exists(initd_bin):
|
||||
return 'ok'
|
||||
|
||||
shell_cmd = 'systemctl status ' + \
|
||||
getPluginName() + ' | grep loaded | grep "enabled;"'
|
||||
data = mw.execShell(shell_cmd)
|
||||
if data[0] == '':
|
||||
return 'fail'
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdInstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('systemctl enable ' + getIpvsadm())
|
||||
return 'ok'
|
||||
|
||||
|
||||
def initdUinstall():
|
||||
current_os = mw.getOs()
|
||||
if current_os == 'darwin':
|
||||
return "Apple Computer does not support"
|
||||
|
||||
mw.execShell('systemctl disable ' + getIpvsadm())
|
||||
return 'ok'
|
||||
|
||||
def runLog():
|
||||
path = getConf()
|
||||
content = mw.readFile(path)
|
||||
rep = 'log\s*=\s*(.*)'
|
||||
tmp = re.search(rep, content)
|
||||
return tmp.groups()[0]
|
||||
|
||||
|
||||
|
||||
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 == 'conf':
|
||||
print(getConf())
|
||||
else:
|
||||
print('error')
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"sort": 7,
|
||||
"ps": "[<span style='color:red;'>内网</span>]LVS超强负载均衡,通过ipvsadm管理[<span style='color:red;'>暂时不可用</span>]",
|
||||
"name": "lvs",
|
||||
"title": "LVS",
|
||||
"shell": "install.sh",
|
||||
"versions":["1.0"],
|
||||
"updates":["1.0"],
|
||||
"tip": "soft",
|
||||
"checks": "server/lvs",
|
||||
"path": "server/lvs",
|
||||
"display": 1,
|
||||
"author": "midoks",
|
||||
"date": "2023-11-17",
|
||||
"home": "http://www.linuxvirtualserver.org/",
|
||||
"type": 0,
|
||||
"pid": "4"
|
||||
}
|
||||
Executable
+83
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH=$PATH:/opt/homebrew/bin
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
sys_os=`uname`
|
||||
VERSION=1.6.22
|
||||
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/lvs && bash install.sh install 1.0
|
||||
# cd /www/server/mdserver-web/plugins/lvs && bash install.sh install 1.0
|
||||
|
||||
|
||||
Install_LVS(){
|
||||
mkdir -p $serverPath/source
|
||||
|
||||
which ipvsadm
|
||||
if [ "$?" == "0" ];then
|
||||
echo '已安装LVS!!'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo '正在安装LVS...'
|
||||
|
||||
# 检测平台命令
|
||||
which apt
|
||||
if [ "$?" == "0" ];then
|
||||
apt install -y ipvsadm
|
||||
fi
|
||||
|
||||
which yum
|
||||
if [ "$?" == "0" ];then
|
||||
yum install -y ipvsadm
|
||||
fi
|
||||
|
||||
which ipvsadm
|
||||
if [ "$?" == "0" ];then
|
||||
echo '正在安装LVS成功!'
|
||||
mkdir -p $serverPath/lvs
|
||||
|
||||
ipv_version=`ipvsadm -v | awk '{print $2}'`
|
||||
if [ "$ipv_version" != "" ];then
|
||||
echo "$ipv_version" > $serverPath/lvs/version.pl
|
||||
else
|
||||
echo '1.0' > $serverPath/lvs/version.pl
|
||||
fi
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/lvs/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/lvs/index.py initd_install
|
||||
else
|
||||
echo '正在安装LVS失败!'
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_LVS()
|
||||
{
|
||||
# 检测平台命令
|
||||
which apt
|
||||
if [ "$?" == "0" ];then
|
||||
apt remove -y ipvsadm
|
||||
fi
|
||||
|
||||
which yum
|
||||
if [ "$?" == "0" ];then
|
||||
yum uninstall -y ipvsadm
|
||||
fi
|
||||
echo "卸载LVS完成"
|
||||
|
||||
if [ -d $serverPath/lvs ];then
|
||||
rm -rf $serverPath/lvs
|
||||
fi
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_LVS
|
||||
else
|
||||
Uninstall_LVS
|
||||
fi
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
function lvsPostMin(method, args, callback){
|
||||
|
||||
var req_data = {};
|
||||
req_data['name'] = 'lvs';
|
||||
req_data['func'] = method;
|
||||
|
||||
if (typeof(args) != 'undefined' && args!=''){
|
||||
req_data['args'] = JSON.stringify(args);
|
||||
}
|
||||
|
||||
$.post('/plugins/run', req_data, function(data) {
|
||||
if (!data.status){
|
||||
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
||||
return;
|
||||
}
|
||||
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
},'json');
|
||||
}
|
||||
|
||||
function lvsPost(method, args, callback, msg = '正在获取...'){
|
||||
var loadT = layer.msg(msg, { icon: 16, time: 0, shade: 0.3 });
|
||||
lvsPostMin(method,args,function(data){
|
||||
layer.close(loadT);
|
||||
if(typeof(callback) == 'function'){
|
||||
callback(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function secToTime(s) {
|
||||
var t;
|
||||
if(s > -1){
|
||||
var hour = Math.floor(s/3600);
|
||||
var min = Math.floor(s/60) % 60;
|
||||
var sec = s % 60;
|
||||
if(hour < 10) {
|
||||
t = '0'+ hour + ":";
|
||||
} else {
|
||||
t = hour + ":";
|
||||
}
|
||||
|
||||
if(min < 10){t += "0";}
|
||||
t += min + ":";
|
||||
if(sec < 10){t += "0";}
|
||||
t += sec.toFixed(2);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
debian
|
||||
|
||||
# 查看网卡
|
||||
ls /sys/class/net/
|
||||
|
||||
ifconfig ens256 172.16.204.100 netmask 255.255.255.255 broadcast 192.168.212.100 up
|
||||
|
||||
route add -host 172.16.204.100 dev ens256
|
||||
|
||||
|
||||
ipvsadm -A -t 172.16.204.100:80 -s rr
|
||||
ipvsadm -a -t 172.16.204.100:80 -r 172.16.204.129:80 -m
|
||||
|
||||
# 清空LVS规则
|
||||
|
||||
ipvsadm -C
|
||||
|
||||
# 查看LVS
|
||||
|
||||
ipvsadm -L -n
|
||||
@@ -402,6 +402,8 @@ def initMariaDbPwd():
|
||||
pwd + ' -e "drop database test";'
|
||||
mw.execShell(drop_test_db)
|
||||
|
||||
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
|
||||
|
||||
# 删除冗余账户
|
||||
hostname = mw.execShell('hostname')[0].strip()
|
||||
if hostname != 'localhost':
|
||||
@@ -412,8 +414,6 @@ def initMariaDbPwd():
|
||||
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
|
||||
|
||||
|
||||
@@ -755,6 +755,11 @@ def importDbBackup():
|
||||
return mw.returnJson(True, 'ok')
|
||||
|
||||
|
||||
def rootPwd():
|
||||
return pSqliteDb('config').where(
|
||||
'id=?', (1,)).getField('mysql_root')
|
||||
|
||||
|
||||
def importDbExternal():
|
||||
args = getArgs()
|
||||
data = checkArgs(args, ['file', 'name'])
|
||||
@@ -2740,6 +2745,8 @@ if __name__ == "__main__":
|
||||
print(setMyPort())
|
||||
elif func == 'init_pwd':
|
||||
print(initMysqlPwd())
|
||||
elif func == 'root_pwd':
|
||||
print(rootPwd())
|
||||
elif func == 'get_db_list':
|
||||
print(getDbList())
|
||||
elif func == 'set_db_backup':
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"uninstall_pre_inspection":true,
|
||||
"checks": "server/mariadb",
|
||||
"path": "server/mariadb",
|
||||
"versions":["10.6","10.7","10.8","10.9","10.11","11.0"],
|
||||
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3"],
|
||||
"shell":"install.sh",
|
||||
"checks":"server/mariadb",
|
||||
"path":"server/mariadb",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
@@ -102,16 +102,17 @@ Install_app()
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
# https://mariadb.org/download/?t=mariadb
|
||||
@@ -105,16 +105,17 @@ Install_app()
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.6' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
@@ -92,16 +92,17 @@ Install_app()
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.7' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
@@ -92,16 +92,17 @@ Install_app()
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.8' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
@@ -102,16 +102,17 @@ Install_app()
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.9' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
||||
@@ -14,7 +14,7 @@ sysName=`uname`
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
mariadbDir=${serverPath}/source/mariadb
|
||||
|
||||
MY_VER=11.0.1
|
||||
MY_VER=11.0.3
|
||||
|
||||
Install_app()
|
||||
{
|
||||
@@ -101,16 +101,18 @@ Install_app()
|
||||
|
||||
if [ -d $serverPath/mariadb ];then
|
||||
echo '10.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败' > $install_tmp
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.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=11.1.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
|
||||
|
||||
INSTALL_CMD=cmake
|
||||
# check cmake version
|
||||
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
|
||||
if [ "$CMAKE_VERSION" -eq "2" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
INSTALL_CMD=cmake3
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-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.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.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=11.2.1
|
||||
|
||||
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
|
||||
|
||||
INSTALL_CMD=cmake
|
||||
# check cmake version
|
||||
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
|
||||
if [ "$CMAKE_VERSION" -eq "2" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
INSTALL_CMD=cmake3
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-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.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
#https://dev.mysql.com/downloads/mysql/5.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=11.3.0
|
||||
|
||||
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
|
||||
|
||||
INSTALL_CMD=cmake
|
||||
# check cmake version
|
||||
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
|
||||
if [ "$CMAKE_VERSION" -eq "2" ];then
|
||||
mkdir -p /var/log/mariadb
|
||||
touch /var/log/mariadb/mariadb.log
|
||||
INSTALL_CMD=cmake3
|
||||
fi
|
||||
|
||||
if [ ! -d $serverPath/mariadb ];then
|
||||
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
|
||||
-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.11' > $serverPath/mariadb/version.pl
|
||||
echo '安装完成'
|
||||
else
|
||||
echo '安装失败'
|
||||
echo 'install fail'>&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
||||
rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
Uninstall_app()
|
||||
{
|
||||
rm -rf $serverPath/mariadb
|
||||
echo '卸载完成' > $install_tmp
|
||||
}
|
||||
|
||||
action=$1
|
||||
if [ "${1}" == 'install' ];then
|
||||
Install_app
|
||||
else
|
||||
Uninstall_app
|
||||
fi
|
||||
@@ -92,8 +92,10 @@ def checkArgs(data, ck=[]):
|
||||
|
||||
|
||||
def status():
|
||||
data = mw.execShell(
|
||||
"ps aux|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
||||
cmd = "ps aux|grep " + getPluginName() + " |grep -v grep | grep -v mdserver-web | awk '{print $2}'"
|
||||
# print(cmd)
|
||||
data = mw.execShell(cmd)
|
||||
# print(data)
|
||||
if data[0] == '':
|
||||
return 'stop'
|
||||
return 'start'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"title": "Memcached",
|
||||
"shell": "install.sh",
|
||||
"versions":["1.6"],
|
||||
"updates":["1.6.15"],
|
||||
"updates":["1.6.21"],
|
||||
"tip": "soft",
|
||||
"checks": "server/memcached",
|
||||
"path":"server/memcached",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
export PATH
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH=$PATH:/opt/homebrew/bin
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
@@ -9,8 +8,10 @@ rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
sys_os=`uname`
|
||||
VERSION=1.6.22
|
||||
|
||||
VERSION=1.6.15
|
||||
echo $sys_os
|
||||
|
||||
Install_mem(){
|
||||
mkdir -p $serverPath/source
|
||||
@@ -23,9 +24,18 @@ Install_mem(){
|
||||
|
||||
cd $serverPath/source && tar -zxvf memcached.tar.gz
|
||||
|
||||
|
||||
OPTIONS=''
|
||||
if [ ${sys_os} == "Darwin" ]; then
|
||||
LIB_DEPEND_DIR=`brew info libevent | grep /opt/homebrew/Cellar/libevent | cut -d \ -f 1 | awk 'END {print}'`
|
||||
OPTIONS="${OPTIONS} --with-libevent=${LIB_DEPEND_DIR}"
|
||||
fi
|
||||
|
||||
echo "./configure --prefix=${serverPath}/memcached && make && make install"
|
||||
cd $serverPath/source/memcached-${VERSION} && ./configure --prefix=$serverPath/memcached && make && make install
|
||||
cd $serverPath/source/memcached-${VERSION}
|
||||
./configure --prefix=$serverPath/memcached \
|
||||
$OPTIONS
|
||||
|
||||
make && make install
|
||||
|
||||
if [ -d $serverPath/memcached ];then
|
||||
echo '1.6' > $serverPath/memcached/version.pl
|
||||
@@ -33,6 +43,8 @@ Install_mem(){
|
||||
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/memcached/index.py start
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/memcached/index.py initd_install
|
||||
|
||||
rm -rf $serverPath/source/memcached-${VERSION}
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -404,8 +404,8 @@ class classApi:
|
||||
write_log("|-正在解压文件到目录[{}]...".format(dpath))
|
||||
self.write_speed('done', '正在解压')
|
||||
|
||||
self.send('/files/unzip', {"sfile": zip_dst, "dfile": dpath,
|
||||
"type": "tar", "coding": "UTF-8", "password": "undefined"})
|
||||
self.send('/files/uncompress',
|
||||
{"sfile": zip_dst, "dfile": dpath, 'path': dpath})
|
||||
self.send('/files/exec_shell',
|
||||
{"shell": "rm -f " + zip_dst, "path": "/www"}, 30)
|
||||
return True
|
||||
|
||||
@@ -133,6 +133,8 @@ def mgOp(method):
|
||||
|
||||
|
||||
def start():
|
||||
mw.execShell(
|
||||
'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/www/server/lib/openssl11/lib')
|
||||
return mgOp('start')
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ User=root
|
||||
Group=root
|
||||
#EnvironmentFile=-/etc/default/mongod
|
||||
Environment="MONGODB_CONFIG_OVERRIDE_NOFORK=1"
|
||||
Environment="LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/www/server/lib/openssl11/lib"
|
||||
PIDFile={$SERVER_PATH}/mongodb/mongodb.pid
|
||||
ExecStart={$SERVER_PATH}/mongodb/bin/mongod -f {$SERVER_PATH}/mongodb/mongodb.conf
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
# https://www.mongodb.com/try/download/community
|
||||
|
||||
'''
|
||||
cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 7.0
|
||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
||||
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 7.0
|
||||
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mongodb/index.py start
|
||||
|
||||
cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mongodb/index.py start
|
||||
'''
|
||||
|
||||
|
||||
curPath=`pwd`
|
||||
@@ -58,6 +56,8 @@ Install_app()
|
||||
# OSNAME=rhel
|
||||
# fi
|
||||
|
||||
cd ${rootPath}/plugins/php/lib && /bin/bash openssl_11.sh
|
||||
|
||||
shell_file=${curPath}/versions/${VERSION}/${OSNAME}.sh
|
||||
|
||||
if [ -f $shell_file ];then
|
||||
@@ -70,7 +70,7 @@ Install_app()
|
||||
if [ "$?" == "0" ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
echo "${VERSION}" > $serverPath/mongodb/version.pl
|
||||
echo '安装完成' > $install_tmp
|
||||
echo 'mongodb安装完成'
|
||||
|
||||
#初始化
|
||||
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py start
|
||||
@@ -92,7 +92,7 @@ Uninstall_app()
|
||||
systemctl daemon-reload
|
||||
fi
|
||||
|
||||
echo "Uninstall_mongodb" > $install_tmp
|
||||
echo 'mongodb卸载完成'
|
||||
}
|
||||
|
||||
action=$1
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -63,4 +64,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -39,5 +40,7 @@ fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -43,4 +44,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -39,4 +40,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -41,4 +42,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -50,4 +51,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -28,7 +29,7 @@ FILE_NAME_TGZ=${FILE_NAME}.tgz
|
||||
MG_DIR=$serverPath/source/mongodb
|
||||
mkdir -p $MG_DIR
|
||||
|
||||
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
|
||||
if [ ! -f ${MG_DIR}/${FILE_NAME_TGZ} ]; then
|
||||
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
|
||||
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
|
||||
fi
|
||||
@@ -39,5 +40,7 @@ fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -43,4 +44,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -41,4 +42,7 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -56,4 +57,6 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -39,5 +40,8 @@ fi
|
||||
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#!/bin/bash
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
|
||||
export PATH
|
||||
|
||||
curPath=`pwd`
|
||||
rootPath=$(dirname "$curPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
rootPath=$(dirname "$rootPath")
|
||||
serverPath=$(dirname "$rootPath")
|
||||
|
||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
||||
@@ -43,4 +44,7 @@ fi
|
||||
if [ ! -d $serverPath/mongodb/bin ];then
|
||||
mkdir -p $serverPath/mongodb
|
||||
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
|
||||
fi
|
||||
fi
|
||||
|
||||
cd ${MG_DIR} && rm -rf ${MG_DIR}/${FILE_NAME}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user