mirror of
https://github.com/midoks/mdserver-web.git
synced 2026-10-10 04:19:26 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26a6a80504 | ||
|
|
498799578a | ||
|
|
6a5b009766 | ||
|
|
8e23411be8 | ||
|
|
b597255d68 | ||
|
|
8979011ec3 | ||
|
|
11a21f9a8b | ||
|
|
1a12f625cd | ||
|
|
11e44d5b0e | ||
|
|
47c1394de6 | ||
|
|
5e7fa28feb | ||
|
|
d04f891ee7 | ||
|
|
3d28e0a3cb | ||
|
|
37112546b9 | ||
|
|
cb719c9973 | ||
|
|
7ec5fe84b2 | ||
|
|
c68cce0198 | ||
|
|
0d7fd11de5 | ||
|
|
643a2e8cf8 | ||
|
|
35ee7d3d10 | ||
|
|
2ce3871ee2 | ||
|
|
812ce86187 | ||
|
|
3d44b3014f | ||
|
|
092494a216 | ||
|
|
a21ad254b7 | ||
|
|
ebd6b9f389 | ||
|
|
33b90a976b | ||
|
|
2518d32019 | ||
|
|
4ded4679f3 | ||
|
|
28d3996d17 | ||
|
|
b76950ed3b | ||
|
|
d49aa168eb | ||
|
|
5304d0b228 | ||
|
|
56e4ef1a4e | ||
|
|
91fc83e0ba | ||
|
|
fc0fdd5772 | ||
|
|
0d0007d9a1 | ||
|
|
a74ace856a | ||
|
|
f46af799a9 | ||
|
|
3e4facbf57 | ||
|
|
ff9466d0a4 | ||
|
|
9cbcff5dbc | ||
|
|
90834415bf | ||
|
|
c2862ab5d4 | ||
|
|
664a7864bc | ||
|
|
9cf6a40493 | ||
|
|
028422337e | ||
|
|
5f10d9433c | ||
|
|
ed49f0b0bd | ||
|
|
090fc0f243 | ||
|
|
f2df81694f | ||
|
|
6cf2e2d6b6 | ||
|
|
defdc3d3b8 | ||
|
|
6d1d1b882e | ||
|
|
54f90c9300 | ||
|
|
a1aa7d465d | ||
|
|
62214c2a88 | ||
|
|
d5a4958566 | ||
|
|
0bca4a3589 | ||
|
|
30bc8b1ec1 | ||
|
|
0472102a3a | ||
|
|
2da863d98a | ||
|
|
88bab4b15b | ||
|
|
d1b4a1cde1 | ||
|
|
d88f6903da | ||
|
|
3a53b360b7 | ||
|
|
3e5b951a41 | ||
|
|
272b6fdeea | ||
|
|
49ac781e87 | ||
|
|
b4f9fa0976 | ||
|
|
96baa99bdc | ||
|
|
5db4f39c76 | ||
|
|
23dadd7f6f | ||
|
|
7d8d48f3d5 | ||
|
|
74fd4bbe08 | ||
|
|
30240443e6 | ||
|
|
e069c3a24e | ||
|
|
73e75abb5f | ||
|
|
b35d516a8e | ||
|
|
aa1875612b | ||
|
|
b189d5b485 | ||
|
|
33b43b253c | ||
|
|
86cfb1b9cf | ||
|
|
f93afb772c | ||
|
|
bd49bd3004 | ||
|
|
db26b09eba | ||
|
|
85da65ad1e | ||
|
|
d9a409ffcc | ||
|
|
ea923a45a6 | ||
|
|
7480cfb5d8 | ||
|
|
be513af18e | ||
|
|
1c5e61a3de | ||
|
|
d26474f222 | ||
|
|
03c796775a | ||
|
|
182d434f84 | ||
|
|
7c1d409e61 | ||
|
|
dab12535f2 | ||
|
|
deffb3d61b | ||
|
|
a4a45f2005 | ||
|
|
32d6a89bd4 | ||
|
|
f41c2454ee | ||
|
|
76dba077c0 | ||
|
|
1c34488abb | ||
|
|
6742d971eb | ||
|
|
3de01da4ba | ||
|
|
4ba526ca2b | ||
|
|
a4e8b6a137 | ||
|
|
50ad3ed7e7 | ||
|
|
64d29659f7 | ||
|
|
2794f49df4 | ||
|
|
3e27f85719 | ||
|
|
a4d70f2294 | ||
|
|
f3cd1f597e | ||
|
|
489c363daf | ||
|
|
77f44481b3 | ||
|
|
fcd4ba024a | ||
|
|
ce6b15939d | ||
|
|
baaccb7960 | ||
|
|
fb559e9f11 | ||
|
|
283a2c052b | ||
|
|
a7bd9e3290 | ||
|
|
b64dbb9aa4 | ||
|
|
d9f63c3a9a | ||
|
|
3c02af41bc | ||
|
|
ac87a6c8b1 | ||
|
|
f19dd2a2b9 | ||
|
|
cef7215fdc | ||
|
|
edb4fc96e1 | ||
|
|
af9f8b73ba | ||
|
|
c85152e85a | ||
|
|
2ee2440c68 | ||
|
|
ecfafc9723 | ||
|
|
dbb4414e65 | ||
|
|
a028e93881 | ||
|
|
475cb5176d | ||
|
|
8b07bd80e6 | ||
|
|
50d26d932f | ||
|
|
22b5ab1179 | ||
|
|
f7c76fb261 | ||
|
|
6531f686ad | ||
|
|
b716f05fb4 | ||
|
|
9a98f1c859 | ||
|
|
e92fc4cfd1 | ||
|
|
da1a76cbef | ||
|
|
fa6b7c21ac | ||
|
|
11748fd33b | ||
|
|
267bbe3865 | ||
|
|
dd27e4b076 | ||
|
|
459229ba15 | ||
|
|
94c5161fde | ||
|
|
5646d1404c | ||
|
|
ef8a10b68d | ||
|
|
c772696f3e | ||
|
|
45faf4e9dd | ||
|
|
5cbca9232c | ||
|
|
742bb6d86d | ||
|
|
b14accd83e | ||
|
|
8ae01d8d36 | ||
|
|
5db1e58e6a | ||
|
|
a2e6d2f280 | ||
|
|
83f3d224ed | ||
|
|
73693620df | ||
|
|
72eb67dfda | ||
|
|
c55b4a02c8 | ||
|
|
721efd6a16 | ||
|
|
61c8ce4b6f | ||
|
|
ce95ca6905 | ||
|
|
01dee5fe1f | ||
|
|
1a72edee9a | ||
|
|
27b6ad0280 | ||
|
|
ae9e6921c3 | ||
|
|
b51eb99027 | ||
|
|
2e584c540d | ||
|
|
bbf258e1a7 | ||
|
|
53d57716aa | ||
|
|
e9a6e5477d | ||
|
|
46ca8a6b44 | ||
|
|
d6f88caf3d | ||
|
|
abc85902a2 | ||
|
|
9edc8bbea2 | ||
|
|
443d3efd37 | ||
|
|
948bcde358 | ||
|
|
83aa3cfca6 | ||
|
|
976c88ed44 | ||
|
|
0db16797b5 | ||
|
|
b7802fc898 | ||
|
|
741dffd5db | ||
|
|
2c9f11bcfe | ||
|
|
16893e51e6 | ||
|
|
34a43a6af9 | ||
|
|
4dd5d946d9 | ||
|
|
7e63f686b9 | ||
|
|
7b57972179 | ||
|
|
a758a36bdc | ||
|
|
84123c603d | ||
|
|
33f9c09a07 |
@@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
name: BUG提交
|
|
||||||
about: 问题描述
|
|
||||||
---
|
|
||||||
|
|
||||||
## 什么系统 ?
|
|
||||||
|
|
||||||
Debian x, Centos x, Centos x stream, Ubuntu x?
|
|
||||||
|
|
||||||
## 错误信息 ?
|
|
||||||
|
|
||||||
Ex:
|
|
||||||
```bash
|
|
||||||
................start mw success
|
|
||||||
bash: line 149: ./scripts/init.d/mw: No such file or directory
|
|
||||||
```
|
|
||||||
|
|
||||||
## 错误截图 ?
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
## 浏览器版本 ?
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
## 软件版本(插件/面板) ?
|
|
||||||
|
|
||||||
...
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
name: 需求提交
|
|
||||||
about: 需求描述
|
|
||||||
---
|
|
||||||
|
|
||||||
## 需求
|
|
||||||
|
|
||||||
想开发一个什么插件?
|
|
||||||
想有什么功能?
|
|
||||||
|
|
||||||
|
|
||||||
## 提供参考
|
|
||||||
|
|
||||||
给开发者提供参考!
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
name: Bug提交
|
|
||||||
description: 提交错误报告以帮助我们改进
|
|
||||||
labels: ["\U0001F48A bug"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
感谢您花时间填写此错误报告!
|
|
||||||
|
|
||||||
- 如有疑问,请讨论[Discussions](https://github.com/midoks/mdserver-web/discussions).
|
|
||||||
- 检查以确保尚未有人打开类似的[issue](https://github.com/midoks/mdserver-web/issues).
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: 操作系统
|
|
||||||
description: |
|
|
||||||
请指定您报告的确切操作系统名称和版本,例如"CentOS 7"、"Ubuntu 20.04"。
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 描述错误
|
|
||||||
description: 对bug的清晰而简洁的描述。
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
blank_issues_enabled: true
|
|
||||||
contact_links:
|
|
||||||
- name: 提出问题
|
|
||||||
url: https://github.com/midoks/mdserver-web/discussions
|
|
||||||
about: 请在讨论中提出问题。
|
|
||||||
- name: 提出建议
|
|
||||||
url: https://github.com/midoks/mdserver-web/discussions/categories/proposal
|
|
||||||
about: 请在讨论中提出建议。
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
name: Bug提交
|
|
||||||
description: 提交错误报告以帮助我们改进
|
|
||||||
labels: ["\U0001F48A bug"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
感谢您花时间填写此错误报告!
|
|
||||||
|
|
||||||
- 如有疑问,请讨论[Discussions](https://github.com/midoks/mdserver-web/discussions).
|
|
||||||
- 检查以确保尚未有人打开类似的[issue](https://github.com/midoks/mdserver-web/issues).
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: 操作系统
|
|
||||||
description: |
|
|
||||||
请指定您报告的确切操作系统名称和版本,例如"CentOS 7"、"Ubuntu 20.04"。
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 描述错误
|
|
||||||
description: 对bug的清晰而简洁的描述。
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
name: Bug提交
|
|
||||||
description: 提交错误报告以帮助我们改进
|
|
||||||
labels: ["\U0001F48A bug"]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
感谢您花时间填写此错误报告!
|
|
||||||
|
|
||||||
- 如有疑问,请讨论[Discussions](https://github.com/midoks/mdserver-web/discussions).
|
|
||||||
- 检查以确保尚未有人打开类似的[issue](https://github.com/midoks/mdserver-web/issues).
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: 操作系统
|
|
||||||
description: |
|
|
||||||
请指定您报告的确切操作系统名称和版本,例如"CentOS 7"、"Ubuntu 20.04"。
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: 描述错误
|
|
||||||
description: 对bug的清晰而简洁的描述。
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
### 合并描述
|
|
||||||
|
|
||||||
对pull请求的内容进行清晰、简洁的描述,即应该解决什么问题?
|
|
||||||
|
|
||||||
问题链接:<!--将问题链接粘贴到此处,如果不适用,请填写“不适用”->
|
|
||||||
|
|
||||||
### 清单
|
|
||||||
|
|
||||||
- [ ] 我添加了测试用例来覆盖新代码。
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
||||||
|
|
||||||
name: MW APP MySQL55
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-22.04]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
#runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v3
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install MW
|
|
||||||
run: |
|
|
||||||
sudo bash scripts/install_dev.sh
|
|
||||||
- name: Install MySQL55
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/mysql && sudo bash install.sh install 5.5
|
|
||||||
- name: Start DEBUG
|
|
||||||
run: |
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
python3 task.py &
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
||||||
|
|
||||||
name: MW APP MySQL56
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-22.04]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
#runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v3
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install MW
|
|
||||||
run: |
|
|
||||||
sudo bash scripts/install_dev.sh
|
|
||||||
- name: Install MySQL56
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/mysql && sudo bash install.sh install 5.6
|
|
||||||
- name: Start DEBUG
|
|
||||||
run: |
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
python3 task.py &
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
||||||
|
|
||||||
name: MW APP MySQL57
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-22.04]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
#runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v3
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install MW
|
|
||||||
run: |
|
|
||||||
sudo bash scripts/install_dev.sh
|
|
||||||
- name: Install MySQL57
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/mysql && sudo bash install.sh install 5.7
|
|
||||||
- name: Start DEBUG
|
|
||||||
run: |
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
python3 task.py &
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
||||||
|
|
||||||
name: MW APP MySQL80
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-22.04]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
#runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v3
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install MW
|
|
||||||
run: |
|
|
||||||
sudo bash scripts/install_dev.sh
|
|
||||||
- name: Install MySQL80
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/mysql && sudo bash install.sh install 8.0
|
|
||||||
- name: Start DEBUG
|
|
||||||
run: |
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
python3 task.py &
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
||||||
|
|
||||||
name: MW APP OpenResty
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master", "dev" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master", "dev" ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
#runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v3
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install MW
|
|
||||||
run: |
|
|
||||||
sudo bash scripts/install_dev.sh
|
|
||||||
- name: Install OpenResty
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/openresty && sudo bash install.sh install 1.21.4.1
|
|
||||||
- name: Start DEBUG
|
|
||||||
run: |
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
python3 task.py &
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# This workflow will install Python dependencies, run tests and lint with a single version of Python
|
|
||||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
||||||
|
|
||||||
name: MW APP PHP
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ubuntu-latest]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
#runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- name: Set up Python 3.10
|
|
||||||
uses: actions/setup-python@v3
|
|
||||||
with:
|
|
||||||
python-version: "3.10"
|
|
||||||
- name: Install MW
|
|
||||||
run: |
|
|
||||||
sudo bash scripts/install_dev.sh
|
|
||||||
- name: Install PHP53
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 53
|
|
||||||
- name: Install PHP54
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 54
|
|
||||||
- name: Install PHP55
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 55
|
|
||||||
- name: Install PHP56
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 56
|
|
||||||
- name: Install PHP70
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 70
|
|
||||||
- name: Install PHP71
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 71
|
|
||||||
- name: Install PHP72
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 72
|
|
||||||
- name: Install PHP73
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 73
|
|
||||||
- name: Install PHP74
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 74
|
|
||||||
- name: Install PHP80
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 80
|
|
||||||
- name: Install PHP81
|
|
||||||
run: |
|
|
||||||
cd /www/server/mdserver-web/plugins/php && sudo bash install.sh install 81
|
|
||||||
- name: Start DEBUG
|
|
||||||
run: |
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
python3 task.py &
|
|
||||||
+6
-49
@@ -8,11 +8,13 @@ __pycache__/
|
|||||||
|
|
||||||
# Distribution / packaging
|
# Distribution / packaging
|
||||||
.Python
|
.Python
|
||||||
|
build/
|
||||||
develop-eggs/
|
develop-eggs/
|
||||||
dist/
|
dist/
|
||||||
downloads/
|
downloads/
|
||||||
eggs/
|
eggs/
|
||||||
.eggs/
|
.eggs/
|
||||||
|
lib/
|
||||||
lib64/
|
lib64/
|
||||||
parts/
|
parts/
|
||||||
sdist/
|
sdist/
|
||||||
@@ -104,52 +106,7 @@ venv.bak/
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.idea/*.xml
|
.idea/*.xml
|
||||||
.idea/*.iml
|
.idea/*.iml
|
||||||
tmp/*
|
tmp/*.pl
|
||||||
*.swp
|
tmp/*.log
|
||||||
*.zip
|
data/json/index.json
|
||||||
scripts/init.d/mw
|
data/system.db
|
||||||
logs/*
|
|
||||||
data/*.db
|
|
||||||
data/control.conf
|
|
||||||
data/iplist.txt
|
|
||||||
data/json/index.json
|
|
||||||
data/json/config.json
|
|
||||||
data/site.pl
|
|
||||||
data/admin_path.pl
|
|
||||||
data/close.pl
|
|
||||||
ssl/input.pl
|
|
||||||
data/datadir.pl
|
|
||||||
data/502Task.pl
|
|
||||||
data/default.pl
|
|
||||||
data/backup.pl
|
|
||||||
data/default_site.pl
|
|
||||||
lib/python*
|
|
||||||
|
|
||||||
bin
|
|
||||||
pyvenv.cfg
|
|
||||||
include
|
|
||||||
share
|
|
||||||
pip-selfcheck.json
|
|
||||||
|
|
||||||
scripts/mdserver-web
|
|
||||||
data/api_login.txt
|
|
||||||
data/sessions
|
|
||||||
data/ssl.pl
|
|
||||||
data/port.pl
|
|
||||||
data/ipv6.pl
|
|
||||||
data/restart.pl
|
|
||||||
data/ssl.pl
|
|
||||||
data/edate.pl
|
|
||||||
data/osname.pl
|
|
||||||
data/system.db-journal
|
|
||||||
data/hook_*.json
|
|
||||||
|
|
||||||
plugins/l2tp
|
|
||||||
plugins/openlitespeed
|
|
||||||
plugins/gdrive
|
|
||||||
plugins/mtproxy
|
|
||||||
plugins/zimg
|
|
||||||
plugins/bk_demo
|
|
||||||
debug.out
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -186,7 +186,7 @@
|
|||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright [midoks] [midoks of copyright owner]
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -1,148 +1,7 @@
|
|||||||
### mdserver-web 0.9.6
|
# mdweb
|
||||||
|
简单的Linux面板
|
||||||
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
|
|
||||||
复制了后台管理界面,按照自己想要的方式写了一版。
|
|
||||||
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
[](https://github.com/midoks/mdserver-web/wiki)
|
|
||||||
[](https://www.jsdelivr.com/package/gh/midoks/mdserver-web)
|
|
||||||
|
|
||||||
* SSH终端工具
|
|
||||||
* 面板收藏功能
|
|
||||||
* 网站子目录绑定
|
|
||||||
* 网站备份功能
|
|
||||||
* 插件方式管理
|
|
||||||
|
|
||||||
基本上可以使用,后续会继续优化!欢迎提供意见!
|
|
||||||
|
|
||||||
- 吹水组 - https://t.me/mdserver_web
|
|
||||||
- [兼容性测试报告](/compatibility.md)
|
|
||||||
- [常用命令说明](/cmd.md)
|
|
||||||
|
|
||||||
### 主要插件介绍
|
|
||||||
|
|
||||||
* OpenResty - 轻量级,占有内存少,并发能力强。
|
|
||||||
* PHP[52-81] - PHP是世界上最好的编程语言。
|
|
||||||
* MySQL - 一种关系数据库管理系统。
|
|
||||||
* MariaDB - 是MySQL的一个重要分支。
|
|
||||||
* MongoDB - 一种非关系NOSQL数据库管理系统。
|
|
||||||
* phpMyAdmin - 著名Web端MySQL管理工具。
|
|
||||||
* Memcached - 一个高性能的分布式内存对象缓存系统。
|
|
||||||
* Redis - 一个高性能的KV数据库。
|
|
||||||
* PureFtpd - 一款专注于程序健壮和软件安全的免费FTP服务器软件。
|
|
||||||
* Gogs - 一款极易搭建的自助Git服务。
|
|
||||||
* Rsyncd - 通用同步服务。
|
|
||||||
|
|
||||||
|
|
||||||
### 插件开发相关
|
|
||||||
|
|
||||||
|
### 自动安装
|
||||||
```
|
```
|
||||||
插件文档还不完善,如果有不明白的地方提Issue! 我会尽力完善。
|
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | sh
|
||||||
如果你自己写了插件,想分享出来,也可以提Issue。
|
```
|
||||||
```
|
|
||||||
|
|
||||||
- 简单例子 - https://github.com/mw-plugin/simple-plugin
|
|
||||||
- 插件地址 - https://github.com/mw-plugin
|
|
||||||
- 开发文档 - https://github.com/midoks/mdserver-web/wiki/插件开发
|
|
||||||
|
|
||||||
|
|
||||||
# Note
|
|
||||||
|
|
||||||
```
|
|
||||||
phpMyAdmin[4.4.15]支持MySQL[5.5-5.7]
|
|
||||||
phpMyAdmin[5.2.0]支持MySQL[8.0]
|
|
||||||
|
|
||||||
PHP[53-72]支持phpMyAdmin[4.4.15]
|
|
||||||
PHP[72-81]支持phpMyAdmin[5.2.0]
|
|
||||||
```
|
|
||||||
|
|
||||||
# Docker
|
|
||||||
|
|
||||||
- 由[DDSRem](https://github.com/DDSRem)开发维护。
|
|
||||||
- https://hub.docker.com/r/ddsderek/mw-server
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:443 -p 888:888 ddsderek/mw-server:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### 版本更新 0.9.6
|
|
||||||
|
|
||||||
* 增加插件备份功能.
|
|
||||||
* supervisor增加错误日志查看.
|
|
||||||
* MariaDB安装源优化.
|
|
||||||
|
|
||||||
|
|
||||||
### JSDelivr安装地址
|
|
||||||
|
|
||||||
- 初始安装
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/install.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
- 直接更新
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/update.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
### 备用地址
|
|
||||||
|
|
||||||
- 初始安装
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/install.sh | bash
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- 直接更新
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### 通用软件安装[命令行安装]
|
|
||||||
|
|
||||||
- 需已经安装mdserver-web
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/app.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### DEV使用
|
|
||||||
|
|
||||||
```
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
|
|
||||||
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
|
|
||||||
```
|
|
||||||
|
|
||||||
### 微信赞助
|
|
||||||
[](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/weixin_zz.jpg)
|
|
||||||
|
|
||||||
|
|
||||||
### 无图不真相
|
|
||||||
|
|
||||||
[](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/mdw.jpg)
|
|
||||||
|
|
||||||
|
|
||||||
### Stargazers over time
|
|
||||||
|
|
||||||
[](https://starchart.cc/midoks/mdserver-web)
|
|
||||||
|
|
||||||
|
|
||||||
### 感谢开发赞助
|
|
||||||
|
|
||||||
[](https://digitalvirt.com/)
|
|
||||||
|
|
||||||
### 授权许可
|
|
||||||
|
|
||||||
本项目采用 Apache 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://github.com/midoks/mdserver-web/blob/master/LICENSE) 文件中。
|
|
||||||
|
|
||||||
@@ -1,37 +1,55 @@
|
|||||||
# coding:utf-8
|
# coding:utf-8
|
||||||
|
|
||||||
# pip install profiler_online
|
|
||||||
# 性能测试
|
|
||||||
# from profiler_online import run_profiler
|
|
||||||
# run_profiler()
|
|
||||||
|
|
||||||
from gevent import monkey
|
|
||||||
monkey.patch_all()
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
from route import app, socketio
|
import time
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
sys.path.append("/class/core/")
|
||||||
|
reload(sys)
|
||||||
|
sys.setdefaultencoding('utf8')
|
||||||
|
|
||||||
|
import route
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
|
||||||
from gevent.pywsgi import WSGIServer
|
app = Flask(__name__)
|
||||||
from geventwebsocket.handler import WebSocketHandler
|
app.debug = True
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_MODULES = (
|
||||||
|
(route.dashboard, "/"),
|
||||||
|
(route.site, "/site"),
|
||||||
|
(route.files, "/files"),
|
||||||
|
(route.soft, "/soft"),
|
||||||
|
(route.config, "/config"),
|
||||||
|
(route.plugins, "/plugins"),
|
||||||
|
(route.task, "/task"),
|
||||||
|
(route.system, "/system"),
|
||||||
|
(route.database, "/database"),
|
||||||
|
(route.crontab, "/crontab"),
|
||||||
|
(route.firewall, "/firewall"),
|
||||||
|
(route.control, "/control"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# print "time.time(): %f " % time.time()
|
||||||
|
app.config.version = "0.0.1" + str(time.time())
|
||||||
|
|
||||||
|
app.config['SECRET_KEY'] = os.urandom(24)
|
||||||
|
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=7)
|
||||||
|
|
||||||
|
|
||||||
|
def setting_modules(app, modules):
|
||||||
|
for module, url_prefix in modules:
|
||||||
|
app.register_blueprint(module, url_prefix=url_prefix)
|
||||||
|
|
||||||
|
setting_modules(app, DEFAULT_MODULES)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
app.run()
|
||||||
PORT = 7200
|
|
||||||
if os.path.exists('data/port.pl'):
|
|
||||||
f = open('data/port.pl')
|
|
||||||
PORT = int(f.read())
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
HOST = '0.0.0.0'
|
|
||||||
http_server = WSGIServer(
|
|
||||||
(HOST, PORT), app, handler_class=WebSocketHandler)
|
|
||||||
|
|
||||||
http_server.serve_forever()
|
|
||||||
|
|
||||||
socketio.run(app, host=HOST, port=PORT)
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print(ex)
|
print ex
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
import string
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
import shlex
|
|
||||||
import datetime
|
|
||||||
import subprocess
|
|
||||||
import re
|
|
||||||
import hashlib
|
|
||||||
from random import Random
|
|
||||||
|
|
||||||
import mw
|
|
||||||
import db
|
|
||||||
|
|
||||||
from flask import redirect
|
|
||||||
|
|
||||||
|
|
||||||
def init():
|
|
||||||
initDB()
|
|
||||||
initUserInfo()
|
|
||||||
initInitD()
|
|
||||||
|
|
||||||
|
|
||||||
def local():
|
|
||||||
result = checkClose()
|
|
||||||
if result:
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
# 检查面板是否关闭
|
|
||||||
def checkClose():
|
|
||||||
if os.path.exists('data/close.pl'):
|
|
||||||
return redirect('/close')
|
|
||||||
|
|
||||||
|
|
||||||
def initDB():
|
|
||||||
try:
|
|
||||||
sql = db.Sql().dbfile('default')
|
|
||||||
csql = mw.readFile('data/sql/default.sql')
|
|
||||||
csql_list = csql.split(';')
|
|
||||||
for index in range(len(csql_list)):
|
|
||||||
sql.execute(csql_list[index], ())
|
|
||||||
|
|
||||||
except Exception as ex:
|
|
||||||
print(str(ex))
|
|
||||||
|
|
||||||
|
|
||||||
def doContentReplace(src, dst):
|
|
||||||
content = mw.readFile(src)
|
|
||||||
content = content.replace("{$SERVER_PATH}", mw.getRunDir())
|
|
||||||
mw.writeFile(dst, content)
|
|
||||||
|
|
||||||
|
|
||||||
def initInitD():
|
|
||||||
|
|
||||||
# systemctl
|
|
||||||
# 有问题
|
|
||||||
# if os.path.exists('/lib/systemd/system'):
|
|
||||||
# systemd_mw = '/lib/systemd/system/mw.service'
|
|
||||||
# systemd_mw_task = '/lib/systemd/system/mw-task.service'
|
|
||||||
|
|
||||||
# systemd_mw_tpl = mw.getRunDir() + '/scripts/init.d/mw.service.tpl'
|
|
||||||
# systemd_mw_task_tpl = mw.getRunDir() + '/scripts/init.d/mw-task.service.tpl'
|
|
||||||
|
|
||||||
# os.remove(systemd_mw)
|
|
||||||
# os.remove(systemd_mw_task)
|
|
||||||
# doContentReplace(systemd_mw_tpl, systemd_mw)
|
|
||||||
# doContentReplace(systemd_mw_task_tpl, systemd_mw_task)
|
|
||||||
|
|
||||||
# mw.execShell('systemctl enable mw')
|
|
||||||
# mw.execShell('systemctl enable mw-task')
|
|
||||||
# mw.execShell('systemctl daemon-reload')
|
|
||||||
|
|
||||||
script = mw.getRunDir() + '/scripts/init.d/mw.tpl'
|
|
||||||
script_bin = mw.getRunDir() + '/scripts/init.d/mw'
|
|
||||||
doContentReplace(script, script_bin)
|
|
||||||
mw.execShell('chmod +x ' + script_bin)
|
|
||||||
|
|
||||||
# 在linux系统中,确保/etc/init.d存在
|
|
||||||
if not mw.isAppleSystem() and not os.path.exists("/etc/init.d"):
|
|
||||||
mw.execShell('mkdir -p /etc/init.d')
|
|
||||||
|
|
||||||
# initd
|
|
||||||
if os.path.exists("/etc/init.d"):
|
|
||||||
initd_bin = '/etc/init.d/mw'
|
|
||||||
if not os.path.exists(initd_bin):
|
|
||||||
import shutil
|
|
||||||
shutil.copyfile(script_bin, initd_bin)
|
|
||||||
mw.execShell('chmod +x ' + initd_bin)
|
|
||||||
# 加入自启动
|
|
||||||
mw.execShell('which chkconfig && chkconfig --add mw')
|
|
||||||
mw.execShell('which update-rc.d && update-rc.d -f mw defaults')
|
|
||||||
|
|
||||||
# 获取系统IPV4
|
|
||||||
mw.setHostAddr(mw.getLocalIp())
|
|
||||||
|
|
||||||
|
|
||||||
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)
|
|
||||||
mw.M('users').where('id=?', (1,)).setField(
|
|
||||||
'password', mw.md5(pwd))
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import mw
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import pwd
|
|
||||||
|
|
||||||
from flask import session
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
|
|
||||||
class config_api:
|
|
||||||
|
|
||||||
__version = '0.9.5'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
##### ----- start ----- ###
|
|
||||||
|
|
||||||
# 取面板列表
|
|
||||||
def getPanelListApi(self):
|
|
||||||
data = mw.M('panel').field(
|
|
||||||
'id,title,url,username,password,click,addtime').order('click desc').select()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def addPanelInfoApi(self):
|
|
||||||
title = request.form.get('title', '')
|
|
||||||
url = request.form.get('url', '')
|
|
||||||
username = request.form.get('username', '')
|
|
||||||
password = request.form.get('password', '')
|
|
||||||
# 校验是还是重复
|
|
||||||
isAdd = mw.M('panel').where(
|
|
||||||
'title=? OR url=?', (title, url)).count()
|
|
||||||
if isAdd:
|
|
||||||
return mw.returnJson(False, '备注或面板地址重复!')
|
|
||||||
isRe = mw.M('panel').add('title,url,username,password,click,addtime',
|
|
||||||
(title, url, username, password, 0, int(time.time())))
|
|
||||||
if isRe:
|
|
||||||
return mw.returnJson(True, '添加成功!')
|
|
||||||
return mw.returnJson(False, '添加失败!')
|
|
||||||
|
|
||||||
# 删除面板资料
|
|
||||||
def delPanelInfoApi(self):
|
|
||||||
mid = request.form.get('id', '')
|
|
||||||
isExists = mw.M('panel').where('id=?', (mid,)).count()
|
|
||||||
if not isExists:
|
|
||||||
return mw.returnJson(False, '指定面板资料不存在!')
|
|
||||||
mw.M('panel').where('id=?', (mid,)).delete()
|
|
||||||
return mw.returnJson(True, '删除成功!')
|
|
||||||
|
|
||||||
# 修改面板资料
|
|
||||||
def setPanelInfoApi(self):
|
|
||||||
title = request.form.get('title', '')
|
|
||||||
url = request.form.get('url', '')
|
|
||||||
username = request.form.get('username', '')
|
|
||||||
password = request.form.get('password', '')
|
|
||||||
mid = request.form.get('id', '')
|
|
||||||
# 校验是还是重复
|
|
||||||
isSave = mw.M('panel').where(
|
|
||||||
'(title=? OR url=?) AND id!=?', (title, url, mid)).count()
|
|
||||||
if isSave:
|
|
||||||
return mw.returnJson(False, '备注或面板地址重复!')
|
|
||||||
|
|
||||||
# 更新到数据库
|
|
||||||
isRe = mw.M('panel').where('id=?', (mid,)).save(
|
|
||||||
'title,url,username,password', (title, url, username, password))
|
|
||||||
if isRe:
|
|
||||||
return mw.returnJson(True, '修改成功!')
|
|
||||||
return mw.returnJson(False, '修改失败!')
|
|
||||||
|
|
||||||
def syncDateApi(self):
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return mw.returnJson(True, '开发系统不必同步时间!')
|
|
||||||
|
|
||||||
data = mw.execShell('ntpdate -s time.nist.gov')
|
|
||||||
if data[0] == '':
|
|
||||||
return mw.returnJson(True, '同步成功!')
|
|
||||||
return mw.returnJson(False, '同步失败:' + data[0])
|
|
||||||
|
|
||||||
def setPasswordApi(self):
|
|
||||||
password1 = request.form.get('password1', '')
|
|
||||||
password2 = request.form.get('password2', '')
|
|
||||||
if password1 != password2:
|
|
||||||
return mw.returnJson(False, '两次输入的密码不一致,请重新输入!')
|
|
||||||
if len(password1) < 5:
|
|
||||||
return mw.returnJson(False, '用户密码不能小于5位!')
|
|
||||||
mw.M('users').where("username=?", (session['username'],)).setField(
|
|
||||||
'password', mw.md5(password1.strip()))
|
|
||||||
return mw.returnJson(True, '密码修改成功!')
|
|
||||||
|
|
||||||
def setNameApi(self):
|
|
||||||
name1 = request.form.get('name1', '')
|
|
||||||
name2 = request.form.get('name2', '')
|
|
||||||
if name1 != name2:
|
|
||||||
return mw.returnJson(False, '两次输入的用户名不一致,请重新输入!')
|
|
||||||
if len(name1) < 3:
|
|
||||||
return mw.returnJson(False, '用户名长度不能少于3位')
|
|
||||||
|
|
||||||
mw.M('users').where("username=?", (session['username'],)).setField(
|
|
||||||
'username', name1.strip())
|
|
||||||
|
|
||||||
session['username'] = name1
|
|
||||||
return mw.returnJson(True, '用户修改成功!')
|
|
||||||
|
|
||||||
def setApi(self):
|
|
||||||
webname = request.form.get('webname', '')
|
|
||||||
port = request.form.get('port', '')
|
|
||||||
host_ip = request.form.get('host_ip', '')
|
|
||||||
domain = request.form.get('domain', '')
|
|
||||||
sites_path = request.form.get('sites_path', '')
|
|
||||||
backup_path = request.form.get('backup_path', '')
|
|
||||||
|
|
||||||
if domain != '':
|
|
||||||
reg = "^([\w\-\*]{1,100}\.){1,4}(\w{1,10}|\w{1,10}\.\w{1,10})$"
|
|
||||||
if not re.match(reg, domain):
|
|
||||||
return mw.returnJson(False, '主域名格式不正确')
|
|
||||||
|
|
||||||
if int(port) >= 65535 or int(port) < 100:
|
|
||||||
return mw.returnJson(False, '端口范围不正确!')
|
|
||||||
|
|
||||||
if webname != mw.getConfig('title'):
|
|
||||||
mw.setConfig('title', webname)
|
|
||||||
|
|
||||||
if sites_path != mw.getWwwDir():
|
|
||||||
mw.setWwwDir(sites_path)
|
|
||||||
|
|
||||||
if backup_path != mw.getWwwDir():
|
|
||||||
mw.setBackupDir(backup_path)
|
|
||||||
|
|
||||||
if port != mw.getHostPort():
|
|
||||||
import system_api
|
|
||||||
import firewall_api
|
|
||||||
|
|
||||||
if os.path.exists("/lib/systemd/system/firewalld.service"):
|
|
||||||
if not firewall_api.firewall_api().getFwStatus():
|
|
||||||
return mw.returnJson(False, 'firewalld必须先启动!')
|
|
||||||
|
|
||||||
mw.setHostPort(port)
|
|
||||||
|
|
||||||
msg = mw.getInfo('放行端口[{1}]成功', (port,))
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
|
|
||||||
mw.M('firewall').add('port,ps,addtime', (port, "配置修改", addtime))
|
|
||||||
|
|
||||||
firewall_api.firewall_api().addAcceptPort(port)
|
|
||||||
firewall_api.firewall_api().firewallReload()
|
|
||||||
|
|
||||||
system_api.system_api().restartMw()
|
|
||||||
|
|
||||||
if host_ip != mw.getHostAddr():
|
|
||||||
mw.setHostAddr(host_ip)
|
|
||||||
|
|
||||||
mhost = mw.getHostAddr()
|
|
||||||
info = {
|
|
||||||
'uri': '/config',
|
|
||||||
'host': mhost + ':' + port
|
|
||||||
}
|
|
||||||
return mw.returnJson(True, '保存成功!', info)
|
|
||||||
|
|
||||||
def setAdminPathApi(self):
|
|
||||||
admin_path = request.form.get('admin_path', '').strip()
|
|
||||||
admin_path_checks = ['/', '/close', '/login', '/do_login', '/site',
|
|
||||||
'/sites', '/download_file', '/control', '/crontab',
|
|
||||||
'/firewall', '/files', 'config', '/soft', '/system',
|
|
||||||
'/code', '/ssl', '/plugins']
|
|
||||||
if admin_path == '':
|
|
||||||
admin_path = '/'
|
|
||||||
if admin_path != '/':
|
|
||||||
if len(admin_path) < 6:
|
|
||||||
return mw.returnJson(False, '安全入口地址长度不能小于6位!')
|
|
||||||
if admin_path in admin_path_checks:
|
|
||||||
return mw.returnJson(False, '该入口已被面板占用,请使用其它入口!')
|
|
||||||
if not re.match("^/[\w\./-_]+$", admin_path):
|
|
||||||
return mw.returnJson(False, '入口地址格式不正确,示例: /my_panel')
|
|
||||||
else:
|
|
||||||
domain = mw.readFile('data/domain.conf')
|
|
||||||
if not domain:
|
|
||||||
domain = ''
|
|
||||||
limitip = mw.readFile('data/limitip.conf')
|
|
||||||
if not limitip:
|
|
||||||
limitip = ''
|
|
||||||
if not domain.strip() and not limitip.strip():
|
|
||||||
return mw.returnJson(False, '警告,关闭安全入口等于直接暴露你的后台地址在外网,十分危险,至少开启以下一种安全方式才能关闭:<a style="color:red;"><br>1、绑定访问域名<br>2、绑定授权IP</a>')
|
|
||||||
|
|
||||||
admin_path_file = 'data/admin_path.pl'
|
|
||||||
admin_path_old = '/'
|
|
||||||
if os.path.exists(admin_path_file):
|
|
||||||
admin_path_old = mw.readFile(admin_path_file).strip()
|
|
||||||
|
|
||||||
if admin_path_old != admin_path:
|
|
||||||
mw.writeFile(admin_path_file, admin_path)
|
|
||||||
mw.restartMw()
|
|
||||||
return mw.returnJson(True, '修改成功!')
|
|
||||||
|
|
||||||
def closePanelApi(self):
|
|
||||||
filename = 'data/close.pl'
|
|
||||||
if os.path.exists(filename):
|
|
||||||
os.remove(filename)
|
|
||||||
return mw.returnJson(True, '开启成功')
|
|
||||||
mw.writeFile(filename, 'True')
|
|
||||||
mw.execShell("chmod 600 " + filename)
|
|
||||||
mw.execShell("chown root.root " + filename)
|
|
||||||
return mw.returnJson(True, '面板已关闭!')
|
|
||||||
|
|
||||||
def setIpv6StatusApi(self):
|
|
||||||
ipv6_file = 'data/ipv6.pl'
|
|
||||||
if os.path.exists('data/ipv6.pl'):
|
|
||||||
os.remove(ipv6_file)
|
|
||||||
mw.writeLog('面板设置', '关闭面板IPv6兼容!')
|
|
||||||
else:
|
|
||||||
mw.writeFile(ipv6_file, 'True')
|
|
||||||
mw.writeLog('面板设置', '开启面板IPv6兼容!')
|
|
||||||
mw.restartMw()
|
|
||||||
return mw.returnJson(True, '设置成功!')
|
|
||||||
|
|
||||||
# 获取面板证书
|
|
||||||
def getPanelSslApi(self):
|
|
||||||
cert = {}
|
|
||||||
cert['privateKey'] = mw.readFile('ssl/privateKey.pem')
|
|
||||||
cert['certPem'] = mw.readFile('ssl/certificate.pem')
|
|
||||||
cert['rep'] = os.path.exists('ssl/input.pl')
|
|
||||||
return mw.getJson(cert)
|
|
||||||
|
|
||||||
# 保存面板证书
|
|
||||||
def savePanelSslApi(self):
|
|
||||||
keyPath = 'ssl/privateKey.pem'
|
|
||||||
certPath = 'ssl/certificate.pem'
|
|
||||||
checkCert = '/tmp/cert.pl'
|
|
||||||
|
|
||||||
certPem = request.form.get('certPem', '').strip()
|
|
||||||
privateKey = request.form.get('privateKey', '').strip()
|
|
||||||
|
|
||||||
mw.writeFile(checkCert, certPem)
|
|
||||||
if privateKey:
|
|
||||||
mw.writeFile(keyPath, privateKey)
|
|
||||||
if certPem:
|
|
||||||
mw.writeFile(certPath, certPem)
|
|
||||||
if not mw.checkCert(checkCert):
|
|
||||||
return mw.returnJson(False, '证书错误,请检查!')
|
|
||||||
mw.writeFile('ssl/input.pl', 'True')
|
|
||||||
return mw.returnJson(True, '证书已保存!')
|
|
||||||
|
|
||||||
# 设置面板SSL
|
|
||||||
def setPanelSslApi(self):
|
|
||||||
sslConf = mw.getRunDir() + '/data/ssl.pl'
|
|
||||||
if os.path.exists(sslConf):
|
|
||||||
os.system('rm -f ' + sslConf)
|
|
||||||
return mw.returnJson(True, 'SSL已关闭,请使用http协议访问面板!')
|
|
||||||
else:
|
|
||||||
os.system('pip install cffi==1.10')
|
|
||||||
os.system('pip install cryptography==2.1')
|
|
||||||
os.system('pip install pyOpenSSL==16.2')
|
|
||||||
try:
|
|
||||||
if not self.createSSL():
|
|
||||||
return mw.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
|
|
||||||
mw.writeFile(sslConf, 'True')
|
|
||||||
except Exception as ex:
|
|
||||||
return mw.returnJson(False, '开启失败,无法自动安装pyOpenSSL组件!<p>请尝试手动安装: pip install pyOpenSSL</p>')
|
|
||||||
return mw.returnJson(True, '开启成功,请使用https协议访问面板!')
|
|
||||||
|
|
||||||
def getApi(self):
|
|
||||||
data = {}
|
|
||||||
return mw.getJson(data)
|
|
||||||
##### ----- end ----- ###
|
|
||||||
|
|
||||||
# 自签证书
|
|
||||||
def createSSL(self):
|
|
||||||
if os.path.exists('ssl/input.pl'):
|
|
||||||
return True
|
|
||||||
import OpenSSL
|
|
||||||
key = OpenSSL.crypto.PKey()
|
|
||||||
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
|
|
||||||
cert = OpenSSL.crypto.X509()
|
|
||||||
cert.set_serial_number(0)
|
|
||||||
cert.get_subject().CN = mw.getLocalIp()
|
|
||||||
cert.set_issuer(cert.get_subject())
|
|
||||||
cert.gmtime_adj_notBefore(0)
|
|
||||||
cert.gmtime_adj_notAfter(86400 * 3650)
|
|
||||||
cert.set_pubkey(key)
|
|
||||||
cert.sign(key, 'md5')
|
|
||||||
cert_ca = OpenSSL.crypto.dump_certificate(
|
|
||||||
OpenSSL.crypto.FILETYPE_PEM, cert)
|
|
||||||
private_key = OpenSSL.crypto.dump_privatekey(
|
|
||||||
OpenSSL.crypto.FILETYPE_PEM, key)
|
|
||||||
if len(cert_ca) > 100 and len(private_key) > 100:
|
|
||||||
mw.writeFile('ssl/certificate.pem', cert_ca)
|
|
||||||
mw.writeFile('ssl/privateKey.pem', private_key)
|
|
||||||
print(cert_ca, private_key)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getVersion(self):
|
|
||||||
return self.__version
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['title'] = mw.getConfig('title')
|
|
||||||
data['site_path'] = mw.getWwwDir()
|
|
||||||
data['backup_path'] = mw.getBackupDir()
|
|
||||||
sformat = 'date +"%Y-%m-%d %H:%M:%S %Z %z"'
|
|
||||||
data['systemdate'] = mw.execShell(sformat)[0].strip()
|
|
||||||
|
|
||||||
data['port'] = mw.getHostPort()
|
|
||||||
data['ip'] = mw.getHostAddr()
|
|
||||||
|
|
||||||
admin_path_file = 'data/admin_path.pl'
|
|
||||||
if not os.path.exists(admin_path_file):
|
|
||||||
data['admin_path'] = '/'
|
|
||||||
else:
|
|
||||||
data['admin_path'] = mw.readFile(admin_path_file)
|
|
||||||
|
|
||||||
ipv6_file = 'data/ipv6.pl'
|
|
||||||
if os.path.exists('data/ipv6.pl'):
|
|
||||||
data['ipv6'] = 'checked'
|
|
||||||
else:
|
|
||||||
data['ipv6'] = ''
|
|
||||||
|
|
||||||
ssl_file = 'data/ssl.pl'
|
|
||||||
if os.path.exists('data/ssl.pl'):
|
|
||||||
data['ssl'] = 'checked'
|
|
||||||
else:
|
|
||||||
data['ssl'] = ''
|
|
||||||
|
|
||||||
data['site_count'] = mw.M('sites').count()
|
|
||||||
|
|
||||||
data['username'] = mw.M('users').where(
|
|
||||||
"id=?", (1,)).getField('username')
|
|
||||||
|
|
||||||
return data
|
|
||||||
@@ -1,549 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import mw
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import pwd
|
|
||||||
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
|
|
||||||
class crontab_api:
|
|
||||||
|
|
||||||
field = 'id,name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress'
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
##### ----- start ----- ###
|
|
||||||
def listApi(self):
|
|
||||||
p = request.args.get('p', 1)
|
|
||||||
psize = 10
|
|
||||||
|
|
||||||
startPage = (int(p) - 1) * psize
|
|
||||||
pageInfo = str(startPage) + ',' + str(psize)
|
|
||||||
|
|
||||||
_list = mw.M('crontab').where('', ()).field(
|
|
||||||
self.field).limit(pageInfo).order('id desc').select()
|
|
||||||
|
|
||||||
data = []
|
|
||||||
for i in range(len(_list)):
|
|
||||||
tmp = _list[i]
|
|
||||||
if _list[i]['type'] == "day":
|
|
||||||
tmp['type'] = '每天'
|
|
||||||
tmp['cycle'] = mw.getInfo('每天, {1}点{2}分 执行', (str(
|
|
||||||
_list[i]['where_hour']), str(_list[i]['where_minute'])))
|
|
||||||
elif _list[i]['type'] == "day-n":
|
|
||||||
tmp['type'] = mw.getInfo(
|
|
||||||
'每{1}天', (str(_list[i]['where1']),))
|
|
||||||
tmp['cycle'] = mw.getInfo('每隔{1}天, {2}点{3}分 执行', (str(
|
|
||||||
_list[i]['where1']), str(_list[i]['where_hour']), str(_list[i]['where_minute'])))
|
|
||||||
elif _list[i]['type'] == "hour":
|
|
||||||
tmp['type'] = '每小时'
|
|
||||||
tmp['cycle'] = mw.getInfo(
|
|
||||||
'每小时, 第{1}分钟 执行', (str(_list[i]['where_minute']),))
|
|
||||||
elif _list[i]['type'] == "hour-n":
|
|
||||||
tmp['type'] = mw.getInfo(
|
|
||||||
'每{1}小时', (str(_list[i]['where1']),))
|
|
||||||
tmp['cycle'] = mw.getInfo('每{1}小时, 第{2}分钟 执行', (str(
|
|
||||||
_list[i]['where1']), str(_list[i]['where_minute'])))
|
|
||||||
elif _list[i]['type'] == "minute-n":
|
|
||||||
tmp['type'] = mw.getInfo(
|
|
||||||
'每{1}分钟', (str(_list[i]['where1']),))
|
|
||||||
tmp['cycle'] = mw.getInfo(
|
|
||||||
'每隔{1}分钟执行', (str(_list[i]['where1']),))
|
|
||||||
elif _list[i]['type'] == "week":
|
|
||||||
tmp['type'] = '每周'
|
|
||||||
if not _list[i]['where1']:
|
|
||||||
_list[i]['where1'] = '0'
|
|
||||||
tmp['cycle'] = mw.getInfo('每周{1}, {2}点{3}分执行', (self.toWeek(int(
|
|
||||||
_list[i]['where1'])), str(_list[i]['where_hour']), str(_list[i]['where_minute'])))
|
|
||||||
elif _list[i]['type'] == "month":
|
|
||||||
tmp['type'] = '每月'
|
|
||||||
tmp['cycle'] = mw.getInfo('每月, {1}日 {2}点{3}分执行', (str(_list[i]['where1']), str(
|
|
||||||
_list[i]['where_hour']), str(_list[i]['where_minute'])))
|
|
||||||
data.append(tmp)
|
|
||||||
|
|
||||||
_ret = {}
|
|
||||||
_ret['data'] = data
|
|
||||||
|
|
||||||
count = mw.M('crontab').where('', ()).count()
|
|
||||||
_page = {}
|
|
||||||
_page['count'] = count
|
|
||||||
_page['p'] = p
|
|
||||||
_page['row'] = psize
|
|
||||||
_page['tojs'] = "getCronData"
|
|
||||||
|
|
||||||
_ret['list'] = mw.getPage(_page)
|
|
||||||
_ret['p'] = p
|
|
||||||
return mw.getJson(_ret)
|
|
||||||
|
|
||||||
# 设置计划任务状态
|
|
||||||
def setCronStatusApi(self):
|
|
||||||
mid = request.form.get('id', '')
|
|
||||||
cronInfo = mw.M('crontab').where(
|
|
||||||
'id=?', (mid,)).field(self.field).find()
|
|
||||||
status = 1
|
|
||||||
if cronInfo['status'] == status:
|
|
||||||
status = 0
|
|
||||||
self.removeForCrond(cronInfo['echo'])
|
|
||||||
else:
|
|
||||||
cronInfo['status'] = 1
|
|
||||||
self.syncToCrond(cronInfo)
|
|
||||||
|
|
||||||
mw.M('crontab').where('id=?', (mid,)).setField('status', status)
|
|
||||||
mw.writeLog(
|
|
||||||
'计划任务', '修改计划任务[' + cronInfo['name'] + ']状态为[' + str(status) + ']')
|
|
||||||
return mw.returnJson(True, '设置成功')
|
|
||||||
|
|
||||||
# 获取指定任务数据
|
|
||||||
def getCrondFindApi(self):
|
|
||||||
sid = request.form.get('id', '')
|
|
||||||
data = mw.M('crontab').where(
|
|
||||||
'id=?', (sid,)).field(self.field).find()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def modifyCrondApi(self):
|
|
||||||
sid = request.form.get('id', '')
|
|
||||||
iname = request.form.get('name', '')
|
|
||||||
field_type = request.form.get('type', '')
|
|
||||||
week = request.form.get('week', '')
|
|
||||||
where1 = request.form.get('where1', '')
|
|
||||||
hour = request.form.get('hour', '')
|
|
||||||
minute = request.form.get('minute', '')
|
|
||||||
save = request.form.get('save', '')
|
|
||||||
backup_to = request.form.get('backup_to', '')
|
|
||||||
stype = request.form.get('stype', '')
|
|
||||||
sname = request.form.get('sname', '')
|
|
||||||
sbody = request.form.get('sbody', '')
|
|
||||||
urladdress = request.form.get('urladdress', '')
|
|
||||||
|
|
||||||
if len(iname) < 1:
|
|
||||||
return mw.returnJson(False, '任务名称不能为空!')
|
|
||||||
|
|
||||||
params = {
|
|
||||||
'name': iname,
|
|
||||||
'type': field_type,
|
|
||||||
'week': week,
|
|
||||||
'where1': where1,
|
|
||||||
'hour': hour,
|
|
||||||
'minute': minute,
|
|
||||||
'save': save,
|
|
||||||
'backup_to': backup_to,
|
|
||||||
'stype': stype,
|
|
||||||
'sname': sname,
|
|
||||||
'sbody': sbody,
|
|
||||||
'urladdress': urladdress,
|
|
||||||
}
|
|
||||||
cuonConfig, get, name = self.getCrondCycle(params)
|
|
||||||
cronInfo = mw.M('crontab').where(
|
|
||||||
'id=?', (sid,)).field(self.field).find()
|
|
||||||
del(cronInfo['id'])
|
|
||||||
del(cronInfo['addtime'])
|
|
||||||
cronInfo['name'] = get['name']
|
|
||||||
cronInfo['type'] = get['type']
|
|
||||||
cronInfo['where1'] = get['where1']
|
|
||||||
cronInfo['where_hour'] = get['hour']
|
|
||||||
cronInfo['where_minute'] = get['minute']
|
|
||||||
cronInfo['save'] = get['save']
|
|
||||||
cronInfo['backup_to'] = get['backup_to']
|
|
||||||
cronInfo['sbody'] = get['sbody']
|
|
||||||
cronInfo['urladdress'] = get['urladdress']
|
|
||||||
|
|
||||||
addData = mw.M('crontab').where('id=?', (sid,)).save('name,type,where1,where_hour,where_minute,save,backup_to,sbody,urladdress', (get[
|
|
||||||
'name'], field_type, get['where1'], get['hour'], get['minute'], get['save'], get['backup_to'], get['sbody'], get['urladdress']))
|
|
||||||
self.removeForCrond(cronInfo['echo'])
|
|
||||||
self.syncToCrond(cronInfo)
|
|
||||||
mw.writeLog('计划任务', '修改计划任务[' + cronInfo['name'] + ']成功')
|
|
||||||
return mw.returnJson(True, '修改成功')
|
|
||||||
|
|
||||||
def logsApi(self):
|
|
||||||
sid = request.form.get('id', '')
|
|
||||||
echo = mw.M('crontab').where("id=?", (sid,)).field('echo').find()
|
|
||||||
logFile = mw.getServerDir() + '/cron/' + echo['echo'] + '.log'
|
|
||||||
if not os.path.exists(logFile):
|
|
||||||
return mw.returnJson(False, '当前日志为空!')
|
|
||||||
log = mw.getNumLines(logFile, 500)
|
|
||||||
return mw.returnJson(True, log)
|
|
||||||
|
|
||||||
def addApi(self):
|
|
||||||
iname = request.form.get('name', '')
|
|
||||||
field_type = request.form.get('type', '')
|
|
||||||
week = request.form.get('week', '')
|
|
||||||
where1 = request.form.get('where1', '')
|
|
||||||
hour = request.form.get('hour', '')
|
|
||||||
minute = request.form.get('minute', '')
|
|
||||||
save = request.form.get('save', '')
|
|
||||||
backup_to = request.form.get('backupTo', '')
|
|
||||||
stype = request.form.get('sType', '')
|
|
||||||
sname = request.form.get('sName', '')
|
|
||||||
sbody = request.form.get('sBody', '')
|
|
||||||
urladdress = request.form.get('urladdress', '')
|
|
||||||
|
|
||||||
if len(iname) < 1:
|
|
||||||
return mw.returnJson(False, '任务名称不能为空!')
|
|
||||||
|
|
||||||
params = {
|
|
||||||
'name': iname,
|
|
||||||
'type': field_type,
|
|
||||||
'week': week,
|
|
||||||
'where1': where1,
|
|
||||||
'hour': hour,
|
|
||||||
'minute': minute,
|
|
||||||
'save': save,
|
|
||||||
'backup_to': backup_to,
|
|
||||||
'stype': stype,
|
|
||||||
'sname': sname,
|
|
||||||
'sbody': sbody,
|
|
||||||
'urladdress': urladdress,
|
|
||||||
}
|
|
||||||
|
|
||||||
addData = self.add(params)
|
|
||||||
if addData > 0:
|
|
||||||
return mw.returnJson(True, '添加成功')
|
|
||||||
return mw.returnJson(False, '添加失败')
|
|
||||||
|
|
||||||
def add(self, params):
|
|
||||||
|
|
||||||
iname = params["name"]
|
|
||||||
field_type = params["type"]
|
|
||||||
week = params["week"]
|
|
||||||
where1 = params["where1"]
|
|
||||||
hour = params["hour"]
|
|
||||||
minute = params["minute"]
|
|
||||||
save = params["save"]
|
|
||||||
backup_to = params["backup_to"]
|
|
||||||
stype = params["stype"]
|
|
||||||
sname = params["sname"]
|
|
||||||
sbody = params["sbody"]
|
|
||||||
urladdress = params["urladdress"]
|
|
||||||
|
|
||||||
# print params
|
|
||||||
cronConfig, get, name = self.getCrondCycle(params)
|
|
||||||
cronPath = mw.getServerDir() + '/cron'
|
|
||||||
cronName = self.getShell(params)
|
|
||||||
|
|
||||||
if type(cronName) == dict:
|
|
||||||
return cronName
|
|
||||||
|
|
||||||
cronConfig += ' ' + cronPath + '/' + cronName + \
|
|
||||||
' >> ' + cronPath + '/' + cronName + '.log 2>&1'
|
|
||||||
|
|
||||||
# print(cronConfig)
|
|
||||||
if not mw.isAppleSystem():
|
|
||||||
wRes = self.writeShell(cronConfig)
|
|
||||||
if type(wRes) != bool:
|
|
||||||
return wRes
|
|
||||||
self.crondReload()
|
|
||||||
|
|
||||||
add_time = time.strftime('%Y-%m-%d %X', time.localtime())
|
|
||||||
task_id = mw.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress',
|
|
||||||
(iname, field_type, where1, hour, minute, cronName, add_time, 1, save, backup_to, stype, sname, sbody, urladdress,))
|
|
||||||
return task_id
|
|
||||||
|
|
||||||
def startTaskApi(self):
|
|
||||||
sid = request.form.get('id', '')
|
|
||||||
echo = mw.M('crontab').where('id=?', (sid,)).getField('echo')
|
|
||||||
execstr = mw.getServerDir() + '/cron/' + echo
|
|
||||||
os.system('chmod +x ' + execstr)
|
|
||||||
os.system('nohup ' + execstr + ' >> ' + execstr + '.log 2>&1 &')
|
|
||||||
return mw.returnJson(True, '任务已执行!')
|
|
||||||
|
|
||||||
def delApi(self):
|
|
||||||
task_id = request.form.get('id', '')
|
|
||||||
try:
|
|
||||||
data = self.delete(task_id)
|
|
||||||
if not data[0]:
|
|
||||||
return mw.returnJson(False, data[1])
|
|
||||||
return mw.returnJson(True, '删除成功')
|
|
||||||
except Exception as e:
|
|
||||||
return mw.returnJson(False, '删除失败:' + str(e))
|
|
||||||
|
|
||||||
def delete(self, tid):
|
|
||||||
|
|
||||||
find = mw.M('crontab').where("id=?", (tid,)).field('name,echo').find()
|
|
||||||
if not self.removeForCrond(find['echo']):
|
|
||||||
return (False, '无法写入文件,请检查是否开启了系统加固功能!')
|
|
||||||
|
|
||||||
cronPath = mw.getServerDir() + '/cron'
|
|
||||||
sfile = cronPath + '/' + find['echo']
|
|
||||||
|
|
||||||
if os.path.exists(sfile):
|
|
||||||
os.remove(sfile)
|
|
||||||
sfile = cronPath + '/' + find['echo'] + '.log'
|
|
||||||
if os.path.exists(sfile):
|
|
||||||
os.remove(sfile)
|
|
||||||
|
|
||||||
mw.M('crontab').where("id=?", (tid,)).delete()
|
|
||||||
mw.writeLog('计划任务', mw.getInfo('删除计划任务[{1}]成功!', (find['name'],)))
|
|
||||||
return (True, "OK")
|
|
||||||
|
|
||||||
def delLogsApi(self):
|
|
||||||
sid = request.form.get('id', '')
|
|
||||||
try:
|
|
||||||
echo = mw.M('crontab').where("id=?", (sid,)).getField('echo')
|
|
||||||
logFile = mw.getServerDir() + '/cron/' + echo + '.log'
|
|
||||||
os.remove(logFile)
|
|
||||||
return mw.returnJson(True, '任务日志已清空!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '任务日志清空失败!')
|
|
||||||
|
|
||||||
# 取数据列表
|
|
||||||
def getDataListApi(self):
|
|
||||||
stype = request.form.get('type', '')
|
|
||||||
|
|
||||||
bak_data = []
|
|
||||||
|
|
||||||
if stype == 'sites' or stype == 'databases':
|
|
||||||
hookPath = mw.getPanelDataDir() + "/hook_backup.json"
|
|
||||||
if os.path.exists(hookPath):
|
|
||||||
t = mw.readFile(hookPath)
|
|
||||||
bak_data = json.loads(t)
|
|
||||||
|
|
||||||
if stype == 'databases':
|
|
||||||
db_list = {}
|
|
||||||
db_list['orderOpt'] = bak_data
|
|
||||||
path = mw.getServerDir() + '/mysql'
|
|
||||||
if not os.path.exists(path + '/mysql.db'):
|
|
||||||
db_list['data'] = []
|
|
||||||
else:
|
|
||||||
db_list['data'] = mw.M('databases').dbPos(
|
|
||||||
path, 'mysql').field('name,ps').select()
|
|
||||||
return mw.getJson(db_list)
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['orderOpt'] = bak_data
|
|
||||||
|
|
||||||
data['data'] = mw.M(stype).field('name,ps').select()
|
|
||||||
return mw.getJson(data)
|
|
||||||
##### ----- start ----- ###
|
|
||||||
|
|
||||||
# 转换大写星期
|
|
||||||
def toWeek(self, num):
|
|
||||||
wheres = {
|
|
||||||
0: '日',
|
|
||||||
1: '一',
|
|
||||||
2: '二',
|
|
||||||
3: '三',
|
|
||||||
4: '四',
|
|
||||||
5: '五',
|
|
||||||
6: '六'
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
return wheres[num]
|
|
||||||
except:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def getCrondCycle(self, params):
|
|
||||||
cuonConfig = ''
|
|
||||||
name = ''
|
|
||||||
if params['type'] == "day":
|
|
||||||
cuonConfig = self.getDay(params)
|
|
||||||
name = '每天'
|
|
||||||
elif params['type'] == "day-n":
|
|
||||||
cuonConfig = self.getDay_N(params)
|
|
||||||
name = mw.getInfo('每{1}天', (params['where1'],))
|
|
||||||
elif params['type'] == "hour":
|
|
||||||
cuonConfig = self.getHour(params)
|
|
||||||
name = '每小时'
|
|
||||||
elif params['type'] == "hour-n":
|
|
||||||
cuonConfig = self.getHour_N(params)
|
|
||||||
name = '每小时'
|
|
||||||
elif params['type'] == "minute-n":
|
|
||||||
cuonConfig = self.minute_N(params)
|
|
||||||
elif params['type'] == "week":
|
|
||||||
params['where1'] = params['week']
|
|
||||||
cuonConfig = self.week(params)
|
|
||||||
elif params['type'] == "month":
|
|
||||||
cuonConfig = self.month(params)
|
|
||||||
return cuonConfig, params, name
|
|
||||||
|
|
||||||
# 取任务构造Day
|
|
||||||
def getDay(self, param):
|
|
||||||
cuonConfig = "{0} {1} * * * ".format(param['minute'], param['hour'])
|
|
||||||
return cuonConfig
|
|
||||||
# 取任务构造Day_n
|
|
||||||
|
|
||||||
def getDay_N(self, param):
|
|
||||||
cuonConfig = "{0} {1} */{2} * * ".format(
|
|
||||||
param['minute'], param['hour'], param['where1'])
|
|
||||||
return cuonConfig
|
|
||||||
|
|
||||||
# 取任务构造Hour
|
|
||||||
def getHour(self, param):
|
|
||||||
cuonConfig = "{0} * * * * ".format(param['minute'])
|
|
||||||
return cuonConfig
|
|
||||||
|
|
||||||
# 取任务构造Hour-N
|
|
||||||
def getHour_N(self, param):
|
|
||||||
cuonConfig = "{0} */{1} * * * ".format(
|
|
||||||
param['minute'], param['where1'])
|
|
||||||
return cuonConfig
|
|
||||||
|
|
||||||
# 取任务构造Minute-N
|
|
||||||
def minute_N(self, param):
|
|
||||||
cuonConfig = "*/{0} * * * * ".format(param['where1'])
|
|
||||||
return cuonConfig
|
|
||||||
|
|
||||||
# 取任务构造week
|
|
||||||
def week(self, param):
|
|
||||||
cuonConfig = "{0} {1} * * {2}".format(
|
|
||||||
param['minute'], param['hour'], param['week'])
|
|
||||||
return cuonConfig
|
|
||||||
|
|
||||||
# 取任务构造Month
|
|
||||||
def month(self, param):
|
|
||||||
cuonConfig = "{0} {1} {2} * * ".format(
|
|
||||||
param['minute'], param['hour'], param['where1'])
|
|
||||||
return cuonConfig
|
|
||||||
|
|
||||||
# 取执行脚本
|
|
||||||
def getShell(self, param):
|
|
||||||
# try:
|
|
||||||
stype = param['stype']
|
|
||||||
if stype == 'toFile':
|
|
||||||
shell = param.sFile
|
|
||||||
else:
|
|
||||||
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
|
|
||||||
log = '.log'
|
|
||||||
|
|
||||||
script_dir = mw.getServerDir() + "/mdserver-web/scripts"
|
|
||||||
|
|
||||||
wheres = {
|
|
||||||
'path': head + "python " + script_dir + "/backup.py path " + param['sname'] + " " + str(param['save']),
|
|
||||||
'site': head + "python " + script_dir + "/backup.py site " + param['sname'] + " " + str(param['save']),
|
|
||||||
'database': head + "python " + script_dir + "/backup.py database " + param['sname'] + " " + str(param['save']),
|
|
||||||
'logs': head + "python " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
|
|
||||||
'rememory': head + "/bin/bash " + script_dir + '/rememory.sh'
|
|
||||||
}
|
|
||||||
if param['backup_to'] != 'localhost':
|
|
||||||
cfile = mw.getPluginDir() + "/" + \
|
|
||||||
param['backup_to'] + "/index.py"
|
|
||||||
wheres = {
|
|
||||||
'path': head + "python3 " + cfile + " path " + param['sname'] + " " + str(param['save']),
|
|
||||||
'site': head + "python3 " + cfile + " site " + param['sname'] + " " + str(param['save']),
|
|
||||||
'database': head + "python3 " + cfile + " database " + param['sname'] + " " + str(param['save']),
|
|
||||||
'logs': head + "python3 " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
|
|
||||||
'rememory': head + "/bin/bash " + script_dir + '/rememory.sh'
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
shell = wheres[stype]
|
|
||||||
except:
|
|
||||||
if stype == 'toUrl':
|
|
||||||
shell = head + "curl -sS --connect-timeout 10 -m 60 '" + \
|
|
||||||
param['urladdress'] + "'"
|
|
||||||
else:
|
|
||||||
shell = head + param['sbody'].replace("\r\n", "\n")
|
|
||||||
|
|
||||||
shell += '''
|
|
||||||
echo "----------------------------------------------------------------------------"
|
|
||||||
endDate=`date +"%Y-%m-%d %H:%M:%S"`
|
|
||||||
echo "★[$endDate] Successful"
|
|
||||||
echo "----------------------------------------------------------------------------"
|
|
||||||
'''
|
|
||||||
cronPath = mw.getServerDir() + '/cron'
|
|
||||||
if not os.path.exists(cronPath):
|
|
||||||
mw.execShell('mkdir -p ' + cronPath)
|
|
||||||
|
|
||||||
if not 'echo' in param:
|
|
||||||
cronName = mw.md5(mw.md5(str(time.time()) + '_mw'))
|
|
||||||
else:
|
|
||||||
cronName = param['echo']
|
|
||||||
file = cronPath + '/' + cronName
|
|
||||||
mw.writeFile(file, self.checkScript(shell))
|
|
||||||
mw.execShell('chmod 750 ' + file)
|
|
||||||
return cronName
|
|
||||||
|
|
||||||
# 检查脚本
|
|
||||||
def checkScript(self, shell):
|
|
||||||
keys = ['shutdown', 'init 0', 'mkfs', 'passwd',
|
|
||||||
'chpasswd', '--stdin', 'mkfs.ext', 'mke2fs']
|
|
||||||
for key in keys:
|
|
||||||
shell = shell.replace(key, '[***]')
|
|
||||||
return shell
|
|
||||||
|
|
||||||
# 将Shell脚本写到文件
|
|
||||||
def writeShell(self, config):
|
|
||||||
u_file = '/var/spool/cron/crontabs/root'
|
|
||||||
if not os.path.exists(u_file):
|
|
||||||
file = '/var/spool/cron/root'
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
file = '/etc/crontab'
|
|
||||||
else:
|
|
||||||
file = u_file
|
|
||||||
|
|
||||||
if not os.path.exists(file):
|
|
||||||
mw.writeFile(file, '')
|
|
||||||
conf = mw.readFile(file)
|
|
||||||
conf += str(config) + "\n"
|
|
||||||
if mw.writeFile(file, conf):
|
|
||||||
if not os.path.exists(u_file):
|
|
||||||
mw.execShell("chmod 600 '" + file +
|
|
||||||
"' && chown root.root " + file)
|
|
||||||
else:
|
|
||||||
mw.execShell("chmod 600 '" + file +
|
|
||||||
"' && chown root.crontab " + file)
|
|
||||||
return True
|
|
||||||
return mw.returnJson(False, '文件写入失败,请检查是否开启系统加固功能!')
|
|
||||||
|
|
||||||
# 重载配置
|
|
||||||
def crondReload(self):
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
if os.path.exists('/etc/crontab'):
|
|
||||||
pass
|
|
||||||
# mw.execShell('/usr/sbin/cron restart')
|
|
||||||
else:
|
|
||||||
if os.path.exists('/etc/init.d/crond'):
|
|
||||||
mw.execShell('/etc/init.d/crond reload')
|
|
||||||
elif os.path.exists('/etc/init.d/cron'):
|
|
||||||
mw.execShell('service cron restart')
|
|
||||||
else:
|
|
||||||
mw.execShell("systemctl reload crond")
|
|
||||||
|
|
||||||
# 从crond删除
|
|
||||||
def removeForCrond(self, echo):
|
|
||||||
u_file = '/var/spool/cron/crontabs/root'
|
|
||||||
if not os.path.exists(u_file):
|
|
||||||
file = '/var/spool/cron/root'
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
file = '/etc/crontab'
|
|
||||||
|
|
||||||
if not os.path.exists(file):
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
file = u_file
|
|
||||||
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return True
|
|
||||||
|
|
||||||
conf = mw.readFile(file)
|
|
||||||
rep = ".+" + str(echo) + ".+\n"
|
|
||||||
conf = re.sub(rep, "", conf)
|
|
||||||
if not mw.writeFile(file, conf):
|
|
||||||
return False
|
|
||||||
self.crondReload()
|
|
||||||
return True
|
|
||||||
|
|
||||||
def syncToCrond(self, cronInfo):
|
|
||||||
if 'status' in cronInfo:
|
|
||||||
if cronInfo['status'] == 0:
|
|
||||||
return False
|
|
||||||
if 'where_hour' in cronInfo:
|
|
||||||
cronInfo['hour'] = cronInfo['where_hour']
|
|
||||||
cronInfo['minute'] = cronInfo['where_minute']
|
|
||||||
cronInfo['week'] = cronInfo['where1']
|
|
||||||
cuonConfig, cronInfo, name = self.getCrondCycle(cronInfo)
|
|
||||||
cronPath = mw.getServerDir() + '/cron'
|
|
||||||
cronName = self.getShell(cronInfo)
|
|
||||||
if type(cronName) == dict:
|
|
||||||
return cronName
|
|
||||||
cuonConfig += ' ' + cronPath + '/' + cronName + \
|
|
||||||
' >> ' + cronPath + '/' + cronName + '.log 2>&1'
|
|
||||||
wRes = self.writeShell(cuonConfig)
|
|
||||||
if type(wRes) != bool:
|
|
||||||
return False
|
|
||||||
self.crondReload()
|
|
||||||
+29
-109
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
class Sql():
|
class Sql():
|
||||||
@@ -12,13 +11,12 @@ class Sql():
|
|||||||
#------------------------------
|
#------------------------------
|
||||||
__DB_FILE = None # 数据库文件
|
__DB_FILE = None # 数据库文件
|
||||||
__DB_CONN = None # 数据库连接对象
|
__DB_CONN = None # 数据库连接对象
|
||||||
__DB_TABLE = "" # 被操作的表名称
|
__DB_TABLE = "" # 被操作的表名称
|
||||||
__OPT_WHERE = "" # where条件
|
__OPT_WHERE = "" # where条件
|
||||||
__OPT_LIMIT = "" # limit条件
|
__OPT_LIMIT = "" # limit条件
|
||||||
__OPT_GROUP = "" # group条件
|
__OPT_ORDER = "" # order条件
|
||||||
__OPT_ORDER = "" # order条件
|
__OPT_FIELD = "*" # field条件
|
||||||
__OPT_FIELD = "*" # field条件
|
__OPT_PARAM = () # where值
|
||||||
__OPT_PARAM = () # where值
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__DB_FILE = 'data/default.db'
|
self.__DB_FILE = 'data/default.db'
|
||||||
@@ -28,26 +26,13 @@ class Sql():
|
|||||||
try:
|
try:
|
||||||
if self.__DB_CONN == None:
|
if self.__DB_CONN == None:
|
||||||
self.__DB_CONN = sqlite3.connect(self.__DB_FILE)
|
self.__DB_CONN = sqlite3.connect(self.__DB_FILE)
|
||||||
self.__DB_CONN.text_factory = str
|
except Exception, ex:
|
||||||
except Exception as ex:
|
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def autoTextFactory(self):
|
|
||||||
if sys.version_info[0] == 3:
|
|
||||||
self.__DB_CONN.text_factory = lambda x: str(
|
|
||||||
x, encoding="utf-8", errors='ignore')
|
|
||||||
else:
|
|
||||||
self.__DB_CONN.text_factory = lambda x: unicode(
|
|
||||||
x, "utf-8", "ignore")
|
|
||||||
|
|
||||||
def dbfile(self, name):
|
def dbfile(self, name):
|
||||||
self.__DB_FILE = 'data/' + name + '.db'
|
self.__DB_FILE = 'data/' + name + '.db'
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def dbPos(self, path, name):
|
|
||||||
self.__DB_FILE = path + '/' + name + '.db'
|
|
||||||
return self
|
|
||||||
|
|
||||||
def table(self, table):
|
def table(self, table):
|
||||||
# 设置表名
|
# 设置表名
|
||||||
self.__DB_TABLE = table
|
self.__DB_TABLE = table
|
||||||
@@ -60,36 +45,16 @@ class Sql():
|
|||||||
self.__OPT_PARAM = param
|
self.__OPT_PARAM = param
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def andWhere(self, where, param):
|
|
||||||
# WHERE条件
|
|
||||||
if where:
|
|
||||||
self.__OPT_WHERE = self.__OPT_WHERE + " and " + where
|
|
||||||
# print(param)
|
|
||||||
# print(self.__OPT_PARAM)
|
|
||||||
self.__OPT_PARAM = self.__OPT_PARAM + param
|
|
||||||
return self
|
|
||||||
|
|
||||||
def order(self, order):
|
def order(self, order):
|
||||||
# ORDER条件
|
# ORDER条件
|
||||||
if len(order):
|
if len(order):
|
||||||
self.__OPT_ORDER = " ORDER BY " + order
|
self.__OPT_ORDER = " ORDER BY " + order
|
||||||
else:
|
|
||||||
self.__OPT_ORDER = ""
|
|
||||||
return self
|
|
||||||
|
|
||||||
def group(self, group):
|
|
||||||
if len(group):
|
|
||||||
self.__OPT_GROUP = " GROUP BY " + group
|
|
||||||
else:
|
|
||||||
self.__OPT_GROUP = ""
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def limit(self, limit):
|
def limit(self, limit):
|
||||||
# LIMIT条件
|
# LIMIT条件
|
||||||
if len(limit):
|
if len(limit):
|
||||||
self.__OPT_LIMIT = " LIMIT " + limit
|
self.__OPT_LIMIT = " LIMIT " + limit
|
||||||
else:
|
|
||||||
self.__OPT_LIMIT = ""
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def field(self, field):
|
def field(self, field):
|
||||||
@@ -103,7 +68,7 @@ class Sql():
|
|||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
try:
|
try:
|
||||||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
||||||
self.__OPT_WHERE + self.__OPT_GROUP + self.__OPT_ORDER + self.__OPT_LIMIT
|
self.__OPT_WHERE + self.__OPT_ORDER + self.__OPT_LIMIT
|
||||||
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
|
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
|
||||||
data = result.fetchall()
|
data = result.fetchall()
|
||||||
# 构造字曲系列
|
# 构造字曲系列
|
||||||
@@ -127,45 +92,7 @@ class Sql():
|
|||||||
del(tmp)
|
del(tmp)
|
||||||
self.__close()
|
self.__close()
|
||||||
return data
|
return data
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
|
||||||
|
|
||||||
def inquiry(self, input_field=''):
|
|
||||||
# 查询数据集
|
|
||||||
# 不清空查询参数
|
|
||||||
self.__GetConn()
|
|
||||||
try:
|
|
||||||
sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \
|
|
||||||
self.__OPT_WHERE + self.__OPT_GROUP + self.__OPT_ORDER + self.__OPT_LIMIT
|
|
||||||
# print(sql, self.__OPT_PARAM)
|
|
||||||
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
|
|
||||||
data = result.fetchall()
|
|
||||||
# 构造字曲系列
|
|
||||||
if self.__OPT_FIELD != "*":
|
|
||||||
|
|
||||||
if input_field != "":
|
|
||||||
field = input_field.split(',')
|
|
||||||
else:
|
|
||||||
field = self.__OPT_FIELD.split(',')
|
|
||||||
|
|
||||||
tmp = []
|
|
||||||
for row in data:
|
|
||||||
i = 0
|
|
||||||
tmp1 = {}
|
|
||||||
for key in field:
|
|
||||||
tmp1[key] = row[i]
|
|
||||||
i += 1
|
|
||||||
tmp.append(tmp1)
|
|
||||||
del(tmp1)
|
|
||||||
data = tmp
|
|
||||||
del(tmp)
|
|
||||||
else:
|
|
||||||
# 将元组转换成列表
|
|
||||||
tmp = map(list, data)
|
|
||||||
data = tmp
|
|
||||||
del(tmp)
|
|
||||||
return data
|
|
||||||
except Exception as ex:
|
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def getField(self, keyName):
|
def getField(self, keyName):
|
||||||
@@ -198,6 +125,7 @@ class Sql():
|
|||||||
def add(self, keys, param):
|
def add(self, keys, param):
|
||||||
# 插入数据
|
# 插入数据
|
||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
|
self.__DB_CONN.text_factory = str
|
||||||
try:
|
try:
|
||||||
values = ""
|
values = ""
|
||||||
for key in keys.split(','):
|
for key in keys.split(','):
|
||||||
@@ -206,11 +134,11 @@ class Sql():
|
|||||||
sql = "INSERT INTO " + self.__DB_TABLE + \
|
sql = "INSERT INTO " + self.__DB_TABLE + \
|
||||||
"(" + keys + ") " + "VALUES(" + values + ")"
|
"(" + keys + ") " + "VALUES(" + values + ")"
|
||||||
result = self.__DB_CONN.execute(sql, param)
|
result = self.__DB_CONN.execute(sql, param)
|
||||||
last_id = result.lastrowid
|
id = result.lastrowid
|
||||||
self.__close()
|
self.__close()
|
||||||
self.__DB_CONN.commit()
|
self.__DB_CONN.commit()
|
||||||
return last_id
|
return id
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def checkInput(self, data):
|
def checkInput(self, data):
|
||||||
@@ -234,6 +162,7 @@ class Sql():
|
|||||||
def addAll(self, keys, param):
|
def addAll(self, keys, param):
|
||||||
# 插入数据
|
# 插入数据
|
||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
|
self.__DB_CONN.text_factory = str
|
||||||
try:
|
try:
|
||||||
values = ""
|
values = ""
|
||||||
for key in keys.split(','):
|
for key in keys.split(','):
|
||||||
@@ -243,7 +172,7 @@ class Sql():
|
|||||||
"(" + keys + ") " + "VALUES(" + values + ")"
|
"(" + keys + ") " + "VALUES(" + values + ")"
|
||||||
result = self.__DB_CONN.execute(sql, param)
|
result = self.__DB_CONN.execute(sql, param)
|
||||||
return True
|
return True
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def commit(self):
|
def commit(self):
|
||||||
@@ -253,6 +182,7 @@ class Sql():
|
|||||||
def save(self, keys, param):
|
def save(self, keys, param):
|
||||||
# 更新数据
|
# 更新数据
|
||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
|
self.__DB_CONN.text_factory = str
|
||||||
try:
|
try:
|
||||||
opt = ""
|
opt = ""
|
||||||
for key in keys.split(','):
|
for key in keys.split(','):
|
||||||
@@ -260,8 +190,8 @@ class Sql():
|
|||||||
opt = opt[0:len(opt) - 1]
|
opt = opt[0:len(opt) - 1]
|
||||||
sql = "UPDATE " + self.__DB_TABLE + " SET " + opt + self.__OPT_WHERE
|
sql = "UPDATE " + self.__DB_TABLE + " SET " + opt + self.__OPT_WHERE
|
||||||
|
|
||||||
# import mw
|
import public
|
||||||
# mw.writeFile('/tmp/test.pl', sql)
|
public.writeFile('/tmp/test.pl', sql)
|
||||||
|
|
||||||
# 处理拼接WHERE与UPDATE参数
|
# 处理拼接WHERE与UPDATE参数
|
||||||
tmp = list(param)
|
tmp = list(param)
|
||||||
@@ -272,7 +202,7 @@ class Sql():
|
|||||||
self.__close()
|
self.__close()
|
||||||
self.__DB_CONN.commit()
|
self.__DB_CONN.commit()
|
||||||
return result.rowcount
|
return result.rowcount
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def delete(self, id=None):
|
def delete(self, id=None):
|
||||||
@@ -287,27 +217,17 @@ class Sql():
|
|||||||
self.__close()
|
self.__close()
|
||||||
self.__DB_CONN.commit()
|
self.__DB_CONN.commit()
|
||||||
return result.rowcount
|
return result.rowcount
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def originExecute(self, sql, param=()):
|
def execute(self, sql, param):
|
||||||
self.__GetConn()
|
|
||||||
try:
|
|
||||||
result = self.__DB_CONN.execute(sql, param)
|
|
||||||
self.__DB_CONN.commit()
|
|
||||||
return result
|
|
||||||
except Exception as ex:
|
|
||||||
return "error: " + str(ex)
|
|
||||||
|
|
||||||
def execute(self, sql, param=()):
|
|
||||||
# 执行SQL语句返回受影响行
|
# 执行SQL语句返回受影响行
|
||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
# print sql, param
|
|
||||||
try:
|
try:
|
||||||
result = self.__DB_CONN.execute(sql, param)
|
result = self.__DB_CONN.execute(sql, param)
|
||||||
self.__DB_CONN.commit()
|
self.__DB_CONN.commit()
|
||||||
return result.rowcount
|
return result.rowcount
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def query(self, sql, param):
|
def query(self, sql, param):
|
||||||
@@ -316,16 +236,16 @@ class Sql():
|
|||||||
try:
|
try:
|
||||||
result = self.__DB_CONN.execute(sql, param)
|
result = self.__DB_CONN.execute(sql, param)
|
||||||
# 将元组转换成列表
|
# 将元组转换成列表
|
||||||
# data = map(list, result)
|
data = map(list, result)
|
||||||
return result
|
return data
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return "error: " + str(ex)
|
return "error: " + str(ex)
|
||||||
|
|
||||||
def create(self, name):
|
def create(self, name):
|
||||||
# 创建数据表
|
# 创建数据表
|
||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
import mw
|
import public
|
||||||
script = mw.readFile('data/' + name + '.sql')
|
script = public.readFile('data/' + name + '.sql')
|
||||||
result = self.__DB_CONN.executescript(script)
|
result = self.__DB_CONN.executescript(script)
|
||||||
self.__DB_CONN.commit()
|
self.__DB_CONN.commit()
|
||||||
return result.rowcount
|
return result.rowcount
|
||||||
@@ -333,8 +253,8 @@ class Sql():
|
|||||||
def fofile(self, filename):
|
def fofile(self, filename):
|
||||||
# 执行脚本
|
# 执行脚本
|
||||||
self.__GetConn()
|
self.__GetConn()
|
||||||
import mw
|
import public
|
||||||
script = mw.readFile(filename)
|
script = public.readFile(filename)
|
||||||
result = self.__DB_CONN.executescript(script)
|
result = self.__DB_CONN.executescript(script)
|
||||||
self.__DB_CONN.commit()
|
self.__DB_CONN.commit()
|
||||||
return result.rowcount
|
return result.rowcount
|
||||||
|
|||||||
@@ -1,878 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import mw
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import pwd
|
|
||||||
import shutil
|
|
||||||
|
|
||||||
from flask import request
|
|
||||||
from flask import send_file, send_from_directory
|
|
||||||
from flask import make_response
|
|
||||||
from flask import session
|
|
||||||
|
|
||||||
|
|
||||||
class files_api:
|
|
||||||
|
|
||||||
rPath = None
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.rPath = mw.getRootDir() + '/recycle_bin/'
|
|
||||||
|
|
||||||
##### ----- start ----- ###
|
|
||||||
def getBodyApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
return self.getBody(path)
|
|
||||||
|
|
||||||
def getLastBodyApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
line = request.form.get('line', '100')
|
|
||||||
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return mw.returnJson(False, '文件不存在', (path,))
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = mw.getNumLines(path, int(line))
|
|
||||||
return mw.returnJson(True, 'OK', data)
|
|
||||||
except Exception as ex:
|
|
||||||
return mw.returnJson(False, u'无法正确读取文件!' + str(ex))
|
|
||||||
|
|
||||||
def saveBodyApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
data = request.form.get('data', '')
|
|
||||||
encoding = request.form.get('encoding', '')
|
|
||||||
return self.saveBody(path, data, encoding)
|
|
||||||
|
|
||||||
def downloadApi(self):
|
|
||||||
filename = request.args.get('filename', '')
|
|
||||||
if not os.path.exists(filename):
|
|
||||||
return ''
|
|
||||||
response = make_response(send_from_directory(
|
|
||||||
os.path.dirname(filename), os.path.basename(filename), as_attachment=True))
|
|
||||||
return response
|
|
||||||
|
|
||||||
def zipApi(self):
|
|
||||||
sfile = request.form.get('sfile', '')
|
|
||||||
dfile = request.form.get('dfile', '')
|
|
||||||
stype = request.form.get('type', '')
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
return self.zip(sfile, dfile, stype, path)
|
|
||||||
|
|
||||||
def unzipApi(self):
|
|
||||||
sfile = request.form.get('sfile', '')
|
|
||||||
dfile = request.form.get('dfile', '')
|
|
||||||
stype = request.form.get('type', '')
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
return self.unzip(sfile, dfile, stype, path)
|
|
||||||
|
|
||||||
# 移动文件或目录
|
|
||||||
def mvFileApi(self):
|
|
||||||
sfile = request.form.get('sfile', '')
|
|
||||||
dfile = request.form.get('dfile', '')
|
|
||||||
if not self.checkFileName(dfile):
|
|
||||||
return mw.returnJson(False, '文件名中不能包含特殊字符!')
|
|
||||||
if not os.path.exists(sfile):
|
|
||||||
return mw.returnJson(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
if not self.checkDir(sfile):
|
|
||||||
return mw.returnJson(False, 'FILE_DANGER')
|
|
||||||
|
|
||||||
import shutil
|
|
||||||
try:
|
|
||||||
shutil.move(sfile, dfile)
|
|
||||||
msg = mw.getInfo('移动文件或目录[{1}]到[{2}]成功!', (sfile, dfile,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, '移动文件或目录成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '移动文件或目录失败!')
|
|
||||||
|
|
||||||
def deleteApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
return self.delete(path)
|
|
||||||
|
|
||||||
def fileAccessApi(self):
|
|
||||||
filename = request.form.get('filename', '')
|
|
||||||
data = self.getAccess(filename)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def setFileAccessApi(self):
|
|
||||||
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return mw.returnJson(True, '开发机不设置!')
|
|
||||||
|
|
||||||
filename = request.form.get('filename', '')
|
|
||||||
user = request.form.get('user', '')
|
|
||||||
access = request.form.get('access', '755')
|
|
||||||
sall = '-R'
|
|
||||||
try:
|
|
||||||
if not self.checkDir(filename):
|
|
||||||
return mw.returnJson(False, '请不要花样作死')
|
|
||||||
|
|
||||||
if not os.path.exists(filename):
|
|
||||||
return mw.returnJson(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
os.system('chmod ' + sall + ' ' + access + " '" + filename + "'")
|
|
||||||
os.system('chown ' + sall + ' ' + user +
|
|
||||||
':' + user + " '" + filename + "'")
|
|
||||||
msg = mw.getInfo(
|
|
||||||
'设置[{1}]权限为[{2}]所有者为[{3}]', (filename, access, user,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, '设置成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '设置失败!')
|
|
||||||
|
|
||||||
def getDirSizeApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
tmp = self.getDirSize(path)
|
|
||||||
return mw.returnJson(True, tmp[0].split()[0])
|
|
||||||
|
|
||||||
def getDirApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
if not os.path.exists(path):
|
|
||||||
path = mw.getRootDir() + "/wwwroot"
|
|
||||||
search = request.args.get('search', '').strip().lower()
|
|
||||||
page = request.args.get('p', '1').strip().lower()
|
|
||||||
row = request.args.get('showRow', '10')
|
|
||||||
disk = request.form.get('disk', '')
|
|
||||||
if disk == 'True':
|
|
||||||
row = 1000
|
|
||||||
|
|
||||||
return self.getDir(path, int(page), int(row), search)
|
|
||||||
|
|
||||||
def createFileApi(self):
|
|
||||||
file = request.form.get('path', '')
|
|
||||||
try:
|
|
||||||
if not self.checkFileName(file):
|
|
||||||
return mw.returnJson(False, '文件名中不能包含特殊字符!')
|
|
||||||
if os.path.exists(file):
|
|
||||||
return mw.returnJson(False, '指定文件已存在!')
|
|
||||||
_path = os.path.dirname(file)
|
|
||||||
if not os.path.exists(_path):
|
|
||||||
os.makedirs(_path)
|
|
||||||
open(file, 'w+').close()
|
|
||||||
self.setFileAccept(file)
|
|
||||||
msg = mw.getInfo('创建文件[{1}]成功!', (file,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, '文件创建成功!')
|
|
||||||
except Exception as e:
|
|
||||||
return mw.returnJson(True, '文件创建失败!')
|
|
||||||
|
|
||||||
def createDirApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
try:
|
|
||||||
if not self.checkFileName(path):
|
|
||||||
return mw.returnJson(False, '目录名中不能包含特殊字符!')
|
|
||||||
if os.path.exists(path):
|
|
||||||
return mw.returnJson(False, '指定目录已存在!')
|
|
||||||
os.makedirs(path)
|
|
||||||
self.setFileAccept(path)
|
|
||||||
msg = mw.getInfo('创建目录[{1}]成功!', (path,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, '目录创建成功!')
|
|
||||||
except Exception as e:
|
|
||||||
return mw.returnJson(False, '目录创建失败!')
|
|
||||||
|
|
||||||
def downloadFileApi(self):
|
|
||||||
import db
|
|
||||||
import time
|
|
||||||
url = request.form.get('url', '')
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
filename = request.form.get('filename', '')
|
|
||||||
execstr = url + '|mw|' + path + '/' + filename
|
|
||||||
execstr = execstr.strip()
|
|
||||||
mw.M('tasks').add('name,type,status,addtime,execstr',
|
|
||||||
('下载文件[' + filename + ']', 'download', '-1', time.strftime('%Y-%m-%d %H:%M:%S'), execstr))
|
|
||||||
|
|
||||||
# self.setFileAccept(path + '/' + filename)
|
|
||||||
mw.triggerTask()
|
|
||||||
return mw.returnJson(True, '已将下载任务添加到队列!')
|
|
||||||
|
|
||||||
# 删除进程下的所有进程
|
|
||||||
def removeTaskRecursion(self, pid):
|
|
||||||
cmd = "ps -ef|grep " + pid + \
|
|
||||||
" | grep -v grep |sed -n '2,1p' | awk '{print $2}'"
|
|
||||||
sub_pid = mw.execShell(cmd)
|
|
||||||
|
|
||||||
if sub_pid[0].strip() == '':
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
self.removeTaskRecursion(sub_pid[0].strip())
|
|
||||||
mw.execShell('kill -9 ' + sub_pid[0].strip())
|
|
||||||
return sub_pid[0].strip()
|
|
||||||
|
|
||||||
def removeTaskApi(self):
|
|
||||||
import system_api
|
|
||||||
mid = request.form.get('id', '')
|
|
||||||
try:
|
|
||||||
name = mw.M('tasks').where('id=?', (mid,)).getField('name')
|
|
||||||
status = mw.M('tasks').where('id=?', (mid,)).getField('status')
|
|
||||||
mw.M('tasks').delete(mid)
|
|
||||||
if status == '-1':
|
|
||||||
task_pid = mw.execShell(
|
|
||||||
"ps aux | grep 'task.py' | grep -v grep |awk '{print $2}'")
|
|
||||||
|
|
||||||
task_list = task_pid[0].strip().split("\n")
|
|
||||||
for i in range(len(task_list)):
|
|
||||||
self.removeTaskRecursion(task_list[i])
|
|
||||||
|
|
||||||
mw.triggerTask()
|
|
||||||
system_api.system_api().restartTask()
|
|
||||||
except:
|
|
||||||
system_api.system_api().restartTask()
|
|
||||||
return mw.returnJson(True, '任务已删除!')
|
|
||||||
|
|
||||||
# 上传文件
|
|
||||||
def uploadFileApi(self):
|
|
||||||
from werkzeug.utils import secure_filename
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
path = request.args.get('path', '')
|
|
||||||
|
|
||||||
if not os.path.exists(path):
|
|
||||||
os.makedirs(path)
|
|
||||||
f = request.files['zunfile']
|
|
||||||
filename = os.path.join(path, f.filename)
|
|
||||||
|
|
||||||
s_path = path
|
|
||||||
if os.path.exists(filename):
|
|
||||||
s_path = filename
|
|
||||||
p_stat = os.stat(s_path)
|
|
||||||
f.save(filename)
|
|
||||||
os.chown(filename, p_stat.st_uid, p_stat.st_gid)
|
|
||||||
os.chmod(filename, p_stat.st_mode)
|
|
||||||
|
|
||||||
msg = mw.getInfo('上传文件[{1}] 到 [{2}]成功!', (filename, path))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnMsg(True, '上传成功!')
|
|
||||||
|
|
||||||
def getRecycleBinApi(self):
|
|
||||||
rPath = self.rPath
|
|
||||||
if not os.path.exists(rPath):
|
|
||||||
os.system('mkdir -p ' + rPath)
|
|
||||||
data = {}
|
|
||||||
data['dirs'] = []
|
|
||||||
data['files'] = []
|
|
||||||
data['status'] = os.path.exists('data/recycle_bin.pl')
|
|
||||||
data['status_db'] = os.path.exists('data/recycle_bin_db.pl')
|
|
||||||
for file in os.listdir(rPath):
|
|
||||||
try:
|
|
||||||
tmp = {}
|
|
||||||
fname = rPath + file
|
|
||||||
tmp1 = file.split('_mw_')
|
|
||||||
tmp2 = tmp1[len(tmp1) - 1].split('_t_')
|
|
||||||
tmp['rname'] = file
|
|
||||||
tmp['dname'] = file.replace('_mw_', '/').split('_t_')[0]
|
|
||||||
tmp['name'] = tmp2[0]
|
|
||||||
tmp['time'] = int(float(tmp2[1]))
|
|
||||||
if os.path.islink(fname):
|
|
||||||
filePath = os.readlink(fname)
|
|
||||||
link = ' -> ' + filePath
|
|
||||||
if os.path.exists(filePath):
|
|
||||||
tmp['size'] = os.path.getsize(filePath)
|
|
||||||
else:
|
|
||||||
tmp['size'] = 0
|
|
||||||
else:
|
|
||||||
tmp['size'] = os.path.getsize(fname)
|
|
||||||
if os.path.isdir(fname):
|
|
||||||
data['dirs'].append(tmp)
|
|
||||||
else:
|
|
||||||
data['files'].append(tmp)
|
|
||||||
except Exception as e:
|
|
||||||
continue
|
|
||||||
return mw.returnJson(True, 'OK', data)
|
|
||||||
|
|
||||||
# 回收站开关
|
|
||||||
def recycleBinApi(self):
|
|
||||||
c = 'data/recycle_bin.pl'
|
|
||||||
db = request.form.get('db', '')
|
|
||||||
if db != '':
|
|
||||||
c = 'data/recycle_bin_db.pl'
|
|
||||||
if os.path.exists(c):
|
|
||||||
os.remove(c)
|
|
||||||
mw.writeLog('文件管理', '已关闭回收站功能!')
|
|
||||||
return mw.returnJson(True, '已关闭回收站功能!')
|
|
||||||
else:
|
|
||||||
mw.writeFile(c, 'True')
|
|
||||||
mw.writeLog('文件管理', '已开启回收站功能!')
|
|
||||||
return mw.returnJson(True, '已开启回收站功能!')
|
|
||||||
|
|
||||||
def reRecycleBinApi(self):
|
|
||||||
rPath = self.rPath
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
dFile = path.replace('_mw_', '/').split('_t_')[0]
|
|
||||||
try:
|
|
||||||
import shutil
|
|
||||||
shutil.move(rPath + path, dFile)
|
|
||||||
msg = mw.getInfo('移动文件[{1}]到回收站成功!', (dFile,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, '恢复成功!')
|
|
||||||
except Exception as e:
|
|
||||||
msg = mw.getInfo('从回收站恢复[{1}]失败!', (dFile,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(False, '恢复失败!')
|
|
||||||
|
|
||||||
def delRecycleBinApi(self):
|
|
||||||
rPath = self.rPath
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
empty = request.form.get('empty', '')
|
|
||||||
dFile = path.split('_t_')[0]
|
|
||||||
|
|
||||||
if not self.checkDir(path):
|
|
||||||
return mw.returnJson(False, '敏感目录,请不要花样作死!')
|
|
||||||
|
|
||||||
os.system('which chattr && chattr -R -i ' + rPath + path)
|
|
||||||
if os.path.isdir(rPath + path):
|
|
||||||
import shutil
|
|
||||||
shutil.rmtree(rPath + path)
|
|
||||||
else:
|
|
||||||
os.remove(rPath + path)
|
|
||||||
|
|
||||||
tfile = path.replace('_mw_', '/').split('_t_')[0]
|
|
||||||
msg = mw.getInfo('已彻底从回收站删除{1}!', (tfile,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, msg)
|
|
||||||
|
|
||||||
# 获取进度
|
|
||||||
def getSpeedApi(self):
|
|
||||||
data = mw.getSpeed()
|
|
||||||
return mw.returnJson(True, '已清空回收站!', data)
|
|
||||||
|
|
||||||
def closeRecycleBinApi(self):
|
|
||||||
rPath = self.rPath
|
|
||||||
os.system('which chattr && chattr -R -i ' + rPath)
|
|
||||||
rlist = os.listdir(rPath)
|
|
||||||
i = 0
|
|
||||||
l = len(rlist)
|
|
||||||
for name in rlist:
|
|
||||||
i += 1
|
|
||||||
path = rPath + name
|
|
||||||
mw.writeSpeed(name, i, l)
|
|
||||||
if os.path.isdir(path):
|
|
||||||
shutil.rmtree(path)
|
|
||||||
else:
|
|
||||||
os.remove(path)
|
|
||||||
mw.writeSpeed(None, 0, 0)
|
|
||||||
mw.writeLog('文件管理', '已清空回收站!')
|
|
||||||
return mw.returnJson(True, '已清空回收站!')
|
|
||||||
|
|
||||||
def deleteDirApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return mw.returnJson(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
# 检查是否为.user.ini
|
|
||||||
if path.find('.user.ini'):
|
|
||||||
os.system("which chattr && chattr -i '" + path + "'")
|
|
||||||
try:
|
|
||||||
if os.path.exists('data/recycle_bin.pl'):
|
|
||||||
if self.mvRecycleBin(path):
|
|
||||||
return mw.returnJson(True, '已将文件移动到回收站!')
|
|
||||||
mw.execShell('rm -rf ' + path)
|
|
||||||
mw.writeLog('文件管理', '删除文件成功!', (path,))
|
|
||||||
return mw.returnJson(True, '删除文件成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '删除文件失败!')
|
|
||||||
|
|
||||||
def closeLogsApi(self):
|
|
||||||
logPath = mw.getLogsDir()
|
|
||||||
os.system('rm -f ' + logPath + '/*')
|
|
||||||
os.system('kill -USR1 `cat ' + mw.getServerDir() +
|
|
||||||
'openresty/nginx/logs/nginx.pid`')
|
|
||||||
mw.writeLog('文件管理', '网站日志已被清空!')
|
|
||||||
tmp = self.getDirSize(logPath)
|
|
||||||
return mw.returnJson(True, tmp[0].split()[0])
|
|
||||||
|
|
||||||
def setBatchDataApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
stype = request.form.get('type', '')
|
|
||||||
access = request.form.get('access', '')
|
|
||||||
user = request.form.get('user', '')
|
|
||||||
data = request.form.get('data')
|
|
||||||
if stype == '1' or stype == '2':
|
|
||||||
session['selected'] = {
|
|
||||||
'path': path,
|
|
||||||
'type': stype,
|
|
||||||
'access': access,
|
|
||||||
'user': user,
|
|
||||||
'data': data
|
|
||||||
}
|
|
||||||
return mw.returnJson(True, '标记成功,请在目标目录点击粘贴所有按钮!')
|
|
||||||
elif stype == '3':
|
|
||||||
for key in json.loads(data):
|
|
||||||
try:
|
|
||||||
filename = path + '/' + key
|
|
||||||
if not self.checkDir(filename):
|
|
||||||
return mw.returnJson(False, 'FILE_DANGER')
|
|
||||||
os.system('chmod -R ' + access + " '" + filename + "'")
|
|
||||||
os.system('chown -R ' + user + ':' +
|
|
||||||
user + " '" + filename + "'")
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
mw.writeLog('文件管理', '批量设置权限成功!')
|
|
||||||
return mw.returnJson(True, '批量设置权限成功!')
|
|
||||||
else:
|
|
||||||
import shutil
|
|
||||||
isRecyle = os.path.exists('data/recycle_bin.pl')
|
|
||||||
data = json.loads(data)
|
|
||||||
l = len(data)
|
|
||||||
i = 0
|
|
||||||
for key in data:
|
|
||||||
try:
|
|
||||||
filename = path + '/' + key
|
|
||||||
topath = filename
|
|
||||||
if not os.path.exists(filename):
|
|
||||||
continue
|
|
||||||
|
|
||||||
i += 1
|
|
||||||
mw.writeSpeed(key, i, l)
|
|
||||||
if os.path.isdir(filename):
|
|
||||||
if not self.checkDir(filename):
|
|
||||||
return mw.returnJson(False, '请不要花样作死!')
|
|
||||||
if isRecyle:
|
|
||||||
self.mvRecycleBin(topath)
|
|
||||||
else:
|
|
||||||
shutil.rmtree(filename)
|
|
||||||
else:
|
|
||||||
if key == '.user.ini':
|
|
||||||
os.system('which chattr && chattr -i ' + filename)
|
|
||||||
if isRecyle:
|
|
||||||
self.mvRecycleBin(topath)
|
|
||||||
else:
|
|
||||||
os.remove(filename)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
mw.writeSpeed(None, 0, 0)
|
|
||||||
mw.writeLog('文件管理', '批量删除成功!')
|
|
||||||
return mw.returnJson(True, '批量删除成功!')
|
|
||||||
|
|
||||||
def checkExistsFilesApi(self):
|
|
||||||
dfile = request.form.get('dfile', '')
|
|
||||||
filename = request.form.get('filename', '')
|
|
||||||
data = []
|
|
||||||
filesx = []
|
|
||||||
if filename == '':
|
|
||||||
filesx = json.loads(session['selected']['data'])
|
|
||||||
else:
|
|
||||||
filesx.append(filename)
|
|
||||||
|
|
||||||
for fn in filesx:
|
|
||||||
if fn == '.':
|
|
||||||
continue
|
|
||||||
filename = dfile + '/' + fn
|
|
||||||
if os.path.exists(filename):
|
|
||||||
tmp = {}
|
|
||||||
stat = os.stat(filename)
|
|
||||||
tmp['filename'] = fn
|
|
||||||
tmp['size'] = os.path.getsize(filename)
|
|
||||||
tmp['mtime'] = str(int(stat.st_mtime))
|
|
||||||
data.append(tmp)
|
|
||||||
return mw.returnJson(True, 'ok', data)
|
|
||||||
|
|
||||||
def batchPasteApi(self):
|
|
||||||
path = request.form.get('path', '')
|
|
||||||
stype = request.form.get('type', '')
|
|
||||||
# filename = request.form.get('filename', '')
|
|
||||||
import shutil
|
|
||||||
if not self.checkDir(path):
|
|
||||||
return mw.returnJson(False, '请不要花样作死!')
|
|
||||||
i = 0
|
|
||||||
myfiles = json.loads(session['selected']['data'])
|
|
||||||
l = len(myfiles)
|
|
||||||
if stype == '1':
|
|
||||||
for key in myfiles:
|
|
||||||
i += 1
|
|
||||||
mw.writeSpeed(key, i, l)
|
|
||||||
try:
|
|
||||||
|
|
||||||
sfile = session['selected'][
|
|
||||||
'path'] + '/' + key
|
|
||||||
dfile = path + '/' + key
|
|
||||||
|
|
||||||
if os.path.isdir(sfile):
|
|
||||||
shutil.copytree(sfile, dfile)
|
|
||||||
else:
|
|
||||||
shutil.copyfile(sfile, dfile)
|
|
||||||
stat = os.stat(sfile)
|
|
||||||
os.chown(dfile, stat.st_uid, stat.st_gid)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
msg = mw.getInfo('从[{1}]批量复制到[{2}]成功',
|
|
||||||
(session['selected']['path'], path,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
else:
|
|
||||||
for key in myfiles:
|
|
||||||
try:
|
|
||||||
i += 1
|
|
||||||
mw.writeSpeed(key, i, l)
|
|
||||||
|
|
||||||
sfile = session['selected'][
|
|
||||||
'path'] + '/' + key
|
|
||||||
dfile = path + '/' + key
|
|
||||||
|
|
||||||
shutil.move(sfile, dfile)
|
|
||||||
except:
|
|
||||||
continue
|
|
||||||
msg = mw.getInfo('从[{1}]批量移动到[{2}]成功',
|
|
||||||
(session['selected']['path'], path,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
mw.writeSpeed(None, 0, 0)
|
|
||||||
errorCount = len(myfiles) - i
|
|
||||||
del(session['selected'])
|
|
||||||
msg = mw.getInfo('批量操作成功[{1}],失败[{2}]', (str(i), str(errorCount)))
|
|
||||||
return mw.returnJson(True, msg)
|
|
||||||
|
|
||||||
def copyFileApi(self):
|
|
||||||
sfile = request.form.get('sfile', '')
|
|
||||||
dfile = request.form.get('dfile', '')
|
|
||||||
|
|
||||||
if sfile == dfile:
|
|
||||||
return mw.returnJson(False, '源与目的一致!')
|
|
||||||
|
|
||||||
if not os.path.exists(sfile):
|
|
||||||
return mw.returnJson(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
if os.path.isdir(sfile):
|
|
||||||
return self.copyDir(sfile, dfile)
|
|
||||||
|
|
||||||
try:
|
|
||||||
import shutil
|
|
||||||
shutil.copyfile(sfile, dfile)
|
|
||||||
msg = mw.getInfo('复制文件[{1}]到[{2}]成功!', (sfile, dfile,))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
stat = os.stat(sfile)
|
|
||||||
os.chown(dfile, stat.st_uid, stat.st_gid)
|
|
||||||
return mw.returnJson(True, '文件复制成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '文件复制失败!')
|
|
||||||
|
|
||||||
##### ----- end ----- ###
|
|
||||||
|
|
||||||
def copyDir(self, sfile, dfile):
|
|
||||||
|
|
||||||
if not os.path.exists(sfile):
|
|
||||||
return mw.returnJson(False, '指定目录不存在!')
|
|
||||||
|
|
||||||
if os.path.exists(dfile):
|
|
||||||
return mw.returnJson(False, '指定目录已存在!')
|
|
||||||
import shutil
|
|
||||||
try:
|
|
||||||
shutil.copytree(sfile, dfile)
|
|
||||||
stat = os.stat(sfile)
|
|
||||||
os.chown(dfile, stat.st_uid, stat.st_gid)
|
|
||||||
msg = mw.getInfo('复制目录[{1}]到[{2}]成功!', (sfile, dfile))
|
|
||||||
mw.writeLog('文件管理', msg)
|
|
||||||
return mw.returnJson(True, '目录复制成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '目录复制失败!')
|
|
||||||
|
|
||||||
# 检查敏感目录
|
|
||||||
def checkDir(self, path):
|
|
||||||
# path = str(path, encoding='utf-8')
|
|
||||||
path = path.replace('//', '/')
|
|
||||||
if path[-1:] == '/':
|
|
||||||
path = path[:-1]
|
|
||||||
|
|
||||||
nDirs = ('',
|
|
||||||
'/',
|
|
||||||
'/*',
|
|
||||||
'/www',
|
|
||||||
'/root',
|
|
||||||
'/boot',
|
|
||||||
'/bin',
|
|
||||||
'/etc',
|
|
||||||
'/home',
|
|
||||||
'/dev',
|
|
||||||
'/sbin',
|
|
||||||
'/var',
|
|
||||||
'/usr',
|
|
||||||
'/tmp',
|
|
||||||
'/sys',
|
|
||||||
'/proc',
|
|
||||||
'/media',
|
|
||||||
'/mnt',
|
|
||||||
'/opt',
|
|
||||||
'/lib',
|
|
||||||
'/srv',
|
|
||||||
'/selinux',
|
|
||||||
'/www/server',
|
|
||||||
mw.getRootDir())
|
|
||||||
|
|
||||||
return not path in nDirs
|
|
||||||
|
|
||||||
def getDirSize(self, path):
|
|
||||||
if mw.getOs() == 'darwin':
|
|
||||||
tmp = mw.execShell('du -sh ' + path)
|
|
||||||
else:
|
|
||||||
tmp = mw.execShell('du -sbh ' + path)
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
def checkFileName(self, filename):
|
|
||||||
# 检测文件名
|
|
||||||
nots = ['\\', '&', '*', '|', ';']
|
|
||||||
if filename.find('/') != -1:
|
|
||||||
filename = filename.split('/')[-1]
|
|
||||||
for n in nots:
|
|
||||||
if n in filename:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
def setFileAccept(self, filename):
|
|
||||||
auth = 'www:www'
|
|
||||||
if mw.getOs() == 'darwin':
|
|
||||||
user = mw.execShell(
|
|
||||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
|
||||||
auth = user + ':staff'
|
|
||||||
os.system('chown -R ' + auth + ' ' + filename)
|
|
||||||
os.system('chmod -R 755 ' + filename)
|
|
||||||
|
|
||||||
# 移动到回收站
|
|
||||||
def mvRecycleBin(self, path):
|
|
||||||
rPath = self.rPath
|
|
||||||
if not os.path.exists(rPath):
|
|
||||||
os.system('mkdir -p ' + rPath)
|
|
||||||
|
|
||||||
rFile = rPath + path.replace('/', '_mw_') + '_t_' + str(time.time())
|
|
||||||
try:
|
|
||||||
import shutil
|
|
||||||
shutil.move(path, rFile)
|
|
||||||
mw.writeLog('文件管理', mw.getInfo(
|
|
||||||
'移动文件[{1}]到回收站成功!', (path)))
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
mw.writeLog('文件管理', mw.getInfo(
|
|
||||||
'移动文件[{1}]到回收站失败!', (path)))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getBody(self, path):
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return mw.returnJson(False, '文件不存在', (path,))
|
|
||||||
|
|
||||||
if os.path.getsize(path) > 2097152:
|
|
||||||
return mw.returnJson(False, u'不能在线编辑大于2MB的文件!')
|
|
||||||
|
|
||||||
fp = open(path, 'rb')
|
|
||||||
data = {}
|
|
||||||
data['status'] = True
|
|
||||||
try:
|
|
||||||
if fp:
|
|
||||||
from chardet.universaldetector import UniversalDetector
|
|
||||||
detector = UniversalDetector()
|
|
||||||
srcBody = b""
|
|
||||||
for line in fp.readlines():
|
|
||||||
detector.feed(line)
|
|
||||||
srcBody += line
|
|
||||||
detector.close()
|
|
||||||
char = detector.result
|
|
||||||
data['encoding'] = char['encoding']
|
|
||||||
if char['encoding'] == 'GB2312' or not char['encoding'] or char[
|
|
||||||
'encoding'] == 'TIS-620' or char['encoding'] == 'ISO-8859-9':
|
|
||||||
data['encoding'] = 'GBK'
|
|
||||||
if char['encoding'] == 'ascii' or char[
|
|
||||||
'encoding'] == 'ISO-8859-1':
|
|
||||||
data['encoding'] = 'utf-8'
|
|
||||||
if char['encoding'] == 'Big5':
|
|
||||||
data['encoding'] = 'BIG5'
|
|
||||||
if not char['encoding'] in ['GBK', 'utf-8', 'BIG5']:
|
|
||||||
data['encoding'] = 'utf-8'
|
|
||||||
try:
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
data['data'] = srcBody.decode(
|
|
||||||
data['encoding']).encode('utf-8', errors='ignore')
|
|
||||||
else:
|
|
||||||
data['data'] = srcBody.decode(data['encoding'])
|
|
||||||
except:
|
|
||||||
data['encoding'] = char['encoding']
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
data['data'] = srcBody.decode(
|
|
||||||
data['encoding']).encode('utf-8', errors='ignore')
|
|
||||||
else:
|
|
||||||
data['data'] = srcBody.decode(data['encoding'])
|
|
||||||
else:
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
data['data'] = srcBody.decode('utf-8').encode('utf-8')
|
|
||||||
else:
|
|
||||||
data['data'] = srcBody.decode('utf-8')
|
|
||||||
data['encoding'] = u'utf-8'
|
|
||||||
|
|
||||||
return mw.returnJson(True, 'OK', data)
|
|
||||||
except Exception as ex:
|
|
||||||
return mw.returnJson(False, u'文件编码不被兼容,无法正确读取文件!' + str(ex))
|
|
||||||
|
|
||||||
def saveBody(self, path, data, encoding='utf-8'):
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return mw.returnJson(False, '文件不存在')
|
|
||||||
try:
|
|
||||||
if encoding == 'ascii':
|
|
||||||
encoding = 'utf-8'
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
data = data.encode(encoding, errors='ignore')
|
|
||||||
fp = open(path, 'w+')
|
|
||||||
else:
|
|
||||||
data = data.encode(
|
|
||||||
encoding, errors='ignore').decode(encoding)
|
|
||||||
fp = open(path, 'w+', encoding=encoding)
|
|
||||||
fp.write(data)
|
|
||||||
fp.close()
|
|
||||||
|
|
||||||
if path.find("web_conf") > 0:
|
|
||||||
mw.restartWeb()
|
|
||||||
|
|
||||||
mw.writeLog('文件管理', '文件保存成功', (path,))
|
|
||||||
return mw.returnJson(True, '文件保存成功')
|
|
||||||
except Exception as ex:
|
|
||||||
return mw.returnJson(False, 'FILE_SAVE_ERR:' + str(ex))
|
|
||||||
|
|
||||||
def zip(self, sfile, dfile, stype, path):
|
|
||||||
if sfile.find(',') == -1:
|
|
||||||
if not os.path.exists(path + '/' + sfile):
|
|
||||||
return mw.returnMsg(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
try:
|
|
||||||
tmps = mw.getRunDir() + '/tmp/panelExec.log'
|
|
||||||
if stype == 'zip':
|
|
||||||
os.system("cd '" + path + "' && zip '" + dfile +
|
|
||||||
"' -r '" + sfile + "' > " + tmps + " 2>&1")
|
|
||||||
else:
|
|
||||||
sfiles = ''
|
|
||||||
for sfile in sfile.split(','):
|
|
||||||
if not sfile:
|
|
||||||
continue
|
|
||||||
sfiles += " '" + sfile + "'"
|
|
||||||
os.system("cd '" + path + "' && tar -zcvf '" +
|
|
||||||
dfile + "' " + sfiles + " > " + tmps + " 2>&1")
|
|
||||||
self.setFileAccept(dfile)
|
|
||||||
mw.writeLog("文件管理", '文件压缩成功!', (sfile, dfile))
|
|
||||||
return mw.returnJson(True, '文件压缩成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '文件压缩失败!')
|
|
||||||
|
|
||||||
def unzip(self, sfile, dfile, stype, path):
|
|
||||||
|
|
||||||
if not os.path.exists(sfile):
|
|
||||||
return mw.returnMsg(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
try:
|
|
||||||
tmps = mw.getRunDir() + '/tmp/panelExec.log'
|
|
||||||
if stype == 'zip':
|
|
||||||
os.system("cd " + path + " && unzip -d '" + dfile +
|
|
||||||
"' '" + sfile + "' > " + tmps + " 2>&1")
|
|
||||||
else:
|
|
||||||
sfiles = ''
|
|
||||||
for sfile in sfile.split(','):
|
|
||||||
if not sfile:
|
|
||||||
continue
|
|
||||||
sfiles += " '" + sfile + "'"
|
|
||||||
os.system("cd " + path + " && tar -zxvf " + sfiles +
|
|
||||||
" -C " + dfile + " > " + tmps + " 2>&1")
|
|
||||||
self.setFileAccept(dfile)
|
|
||||||
mw.writeLog("文件管理", '文件解压成功!', (sfile, dfile))
|
|
||||||
return mw.returnJson(True, '文件解压成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '文件解压失败!')
|
|
||||||
|
|
||||||
def delete(self, path):
|
|
||||||
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return mw.returnJson(False, '指定文件不存在!')
|
|
||||||
|
|
||||||
# 检查是否为.user.ini
|
|
||||||
if path.find('.user.ini') >= 0:
|
|
||||||
os.system("which chattr && chattr -i '" + path + "'")
|
|
||||||
|
|
||||||
try:
|
|
||||||
if os.path.exists('data/recycle_bin.pl'):
|
|
||||||
if self.mvRecycleBin(path):
|
|
||||||
return mw.returnJson(True, '已将文件移动到回收站!')
|
|
||||||
os.remove(path)
|
|
||||||
mw.writeLog('文件管理', mw.getInfo(
|
|
||||||
'删除文件[{1}]成功!', (path)))
|
|
||||||
return mw.returnJson(True, '删除文件成功!')
|
|
||||||
except:
|
|
||||||
return mw.returnJson(False, '删除文件失败!')
|
|
||||||
|
|
||||||
def getAccess(self, filename):
|
|
||||||
data = {}
|
|
||||||
try:
|
|
||||||
stat = os.stat(filename)
|
|
||||||
data['chmod'] = str(oct(stat.st_mode)[-3:])
|
|
||||||
data['chown'] = pwd.getpwuid(stat.st_uid).pw_name
|
|
||||||
except:
|
|
||||||
data['chmod'] = 755
|
|
||||||
data['chown'] = 'www'
|
|
||||||
return data
|
|
||||||
|
|
||||||
# 计算文件数量
|
|
||||||
def getCount(self, path, search):
|
|
||||||
i = 0
|
|
||||||
for name in os.listdir(path):
|
|
||||||
if search:
|
|
||||||
if name.lower().find(search) == -1:
|
|
||||||
continue
|
|
||||||
# if name[0:1] == '.':
|
|
||||||
# continue
|
|
||||||
i += 1
|
|
||||||
return i
|
|
||||||
|
|
||||||
def getDir(self, path, page=1, page_size=10, search=None):
|
|
||||||
data = {}
|
|
||||||
dirnames = []
|
|
||||||
filenames = []
|
|
||||||
|
|
||||||
info = {}
|
|
||||||
info['count'] = self.getCount(path, search)
|
|
||||||
info['row'] = page_size
|
|
||||||
info['p'] = page
|
|
||||||
info['tojs'] = 'getFiles'
|
|
||||||
pageObj = mw.getPageObject(info, '1,2,3,4,5,6,7,8')
|
|
||||||
data['PAGE'] = pageObj[0]
|
|
||||||
|
|
||||||
i = 0
|
|
||||||
n = 0
|
|
||||||
for filename in os.listdir(path):
|
|
||||||
if search:
|
|
||||||
if filename.lower().find(search) == -1:
|
|
||||||
continue
|
|
||||||
i += 1
|
|
||||||
if n >= pageObj[1].ROW:
|
|
||||||
break
|
|
||||||
if i < pageObj[1].SHIFT:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
filePath = path + '/' + filename
|
|
||||||
link = ''
|
|
||||||
if os.path.islink(filePath):
|
|
||||||
filePath = os.readlink(filePath)
|
|
||||||
link = ' -> ' + filePath
|
|
||||||
if not os.path.exists(filePath):
|
|
||||||
filePath = path + '/' + filePath
|
|
||||||
if not os.path.exists(filePath):
|
|
||||||
continue
|
|
||||||
|
|
||||||
stat = os.stat(filePath)
|
|
||||||
accept = str(oct(stat.st_mode)[-3:])
|
|
||||||
mtime = str(int(stat.st_mtime))
|
|
||||||
user = ''
|
|
||||||
try:
|
|
||||||
user = pwd.getpwuid(stat.st_uid).pw_name
|
|
||||||
except Exception as ee:
|
|
||||||
user = str(stat.st_uid)
|
|
||||||
|
|
||||||
size = str(stat.st_size)
|
|
||||||
if os.path.isdir(filePath):
|
|
||||||
dirnames.append(filename + ';' + size + ';' +
|
|
||||||
mtime + ';' + accept + ';' + user + ';' + link)
|
|
||||||
else:
|
|
||||||
filenames.append(filename + ';' + size + ';' +
|
|
||||||
mtime + ';' + accept + ';' + user + ';' + link)
|
|
||||||
n += 1
|
|
||||||
except Exception as e:
|
|
||||||
continue
|
|
||||||
data['DIR'] = sorted(dirnames)
|
|
||||||
data['FILES'] = sorted(filenames)
|
|
||||||
data['PATH'] = path.replace('//', '/')
|
|
||||||
|
|
||||||
return mw.getJson(data)
|
|
||||||
@@ -1,410 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import mw
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import pwd
|
|
||||||
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
|
|
||||||
class firewall_api:
|
|
||||||
|
|
||||||
__isFirewalld = False
|
|
||||||
__isUfw = False
|
|
||||||
__isMac = False
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
if os.path.exists('/usr/sbin/firewalld'):
|
|
||||||
self.__isFirewalld = True
|
|
||||||
if os.path.exists('/usr/sbin/ufw'):
|
|
||||||
self.__isUfw = True
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
self.__isMac = True
|
|
||||||
|
|
||||||
##### ----- start ----- ###
|
|
||||||
# 添加屏蔽IP
|
|
||||||
def addDropAddressApi(self):
|
|
||||||
import re
|
|
||||||
port = request.form.get('port', '').strip()
|
|
||||||
ps = request.form.get('ps', '').strip()
|
|
||||||
|
|
||||||
rep = "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(\/\d{1,2})?$"
|
|
||||||
if not re.search(rep, port):
|
|
||||||
return mw.returnJson(False, '您输入的IP地址不合法!')
|
|
||||||
address = port
|
|
||||||
if mw.M('firewall').where("port=?", (address,)).count() > 0:
|
|
||||||
return mw.returnJson(False, '您要放屏蔽的IP已存在屏蔽列表,无需重复处理!')
|
|
||||||
if self.__isUfw:
|
|
||||||
mw.execShell('ufw deny from ' + address + ' to any')
|
|
||||||
else:
|
|
||||||
if self.__isFirewalld:
|
|
||||||
cmd = 'firewall-cmd --permanent --add-rich-rule=\'rule family=ipv4 source address="' + \
|
|
||||||
address + '" drop\''
|
|
||||||
mw.execShell(cmd)
|
|
||||||
else:
|
|
||||||
cmd = 'iptables -I INPUT -s ' + address + ' -j DROP'
|
|
||||||
mw.execShell(cmd)
|
|
||||||
|
|
||||||
msg = mw.getInfo('屏蔽IP[{1}]成功!', (address,))
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
|
|
||||||
mw.M('firewall').add('port,ps,addtime', (address, ps, addtime))
|
|
||||||
self.firewallReload()
|
|
||||||
return mw.returnJson(True, '添加成功!')
|
|
||||||
|
|
||||||
# 添加放行端口
|
|
||||||
def addAcceptPortApi(self):
|
|
||||||
|
|
||||||
if not self.getFwStatus():
|
|
||||||
return mw.returnJson(False, '防火墙启动时,才能添加规则!')
|
|
||||||
|
|
||||||
import re
|
|
||||||
import time
|
|
||||||
port = request.form.get('port', '').strip()
|
|
||||||
ps = request.form.get('ps', '').strip()
|
|
||||||
stype = request.form.get('type', '').strip()
|
|
||||||
|
|
||||||
rep = "^\d{1,5}(:\d{1,5})?$"
|
|
||||||
if not re.search(rep, port):
|
|
||||||
return mw.returnJson(False, '端口范围不正确!')
|
|
||||||
|
|
||||||
if mw.M('firewall').where("port=?", (port,)).count() > 0:
|
|
||||||
return mw.returnJson(False, '您要放行的端口已存在,无需重复放行!')
|
|
||||||
|
|
||||||
msg = mw.getInfo('放行端口[{1}]成功', (port,))
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
|
|
||||||
mw.M('firewall').add('port,ps,addtime', (port, ps, addtime))
|
|
||||||
|
|
||||||
self.addAcceptPort(port)
|
|
||||||
self.firewallReload()
|
|
||||||
return mw.returnJson(True, '添加放行(' + port + ')端口成功!')
|
|
||||||
|
|
||||||
# 删除IP屏蔽
|
|
||||||
def delDropAddressApi(self):
|
|
||||||
if not self.getFwStatus():
|
|
||||||
return mw.returnJson(False, '防火墙启动时,才能删除规则!')
|
|
||||||
|
|
||||||
port = request.form.get('port', '').strip()
|
|
||||||
ps = request.form.get('ps', '').strip()
|
|
||||||
sid = request.form.get('id', '').strip()
|
|
||||||
address = port
|
|
||||||
if self.__isUfw:
|
|
||||||
mw.execShell('ufw delete deny from ' + address + ' to any')
|
|
||||||
else:
|
|
||||||
if self.__isFirewalld:
|
|
||||||
mw.execShell(
|
|
||||||
'firewall-cmd --permanent --remove-rich-rule=\'rule family=ipv4 source address="' + address + '" drop\'')
|
|
||||||
elif self.__isMac:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
cmd = 'iptables -D INPUT -s ' + address + ' -j DROP'
|
|
||||||
mw.execShell(cmd)
|
|
||||||
|
|
||||||
msg = mw.getInfo('解除IP[{1}]的屏蔽!', (address,))
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
mw.M('firewall').where("id=?", (sid,)).delete()
|
|
||||||
|
|
||||||
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:
|
|
||||||
mw.execShell('ufw delete allow ' + port + '/tcp')
|
|
||||||
else:
|
|
||||||
if self.__isFirewalld:
|
|
||||||
mw.execShell(
|
|
||||||
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
|
|
||||||
mw.execShell(
|
|
||||||
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
|
|
||||||
else:
|
|
||||||
mw.execShell(
|
|
||||||
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
|
|
||||||
msg = mw.getInfo('删除防火墙放行端口[{1}]成功!', (port,))
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
mw.M('firewall').where("id=?", (sid,)).delete()
|
|
||||||
|
|
||||||
self.firewallReload()
|
|
||||||
return mw.returnJson(True, '删除成功!')
|
|
||||||
except Exception as e:
|
|
||||||
return mw.returnJson(False, '删除失败!:' + str(e))
|
|
||||||
|
|
||||||
def getWwwPathApi(self):
|
|
||||||
path = mw.getLogsDir()
|
|
||||||
return mw.getJson({'path': path})
|
|
||||||
|
|
||||||
def getListApi(self):
|
|
||||||
p = request.form.get('p', '1').strip()
|
|
||||||
limit = request.form.get('limit', '10').strip()
|
|
||||||
return self.getList(int(p), int(limit))
|
|
||||||
|
|
||||||
def getLogListApi(self):
|
|
||||||
p = request.form.get('p', '1').strip()
|
|
||||||
limit = request.form.get('limit', '10').strip()
|
|
||||||
search = request.form.get('search', '').strip()
|
|
||||||
return self.getLogList(int(p), int(limit), search)
|
|
||||||
|
|
||||||
def getSshInfoApi(self):
|
|
||||||
file = '/etc/ssh/sshd_config'
|
|
||||||
conf = mw.readFile(file)
|
|
||||||
rep = "#*Port\s+([0-9]+)\s*\n"
|
|
||||||
port = re.search(rep, conf).groups(0)[0]
|
|
||||||
|
|
||||||
isPing = True
|
|
||||||
try:
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
isPing = True
|
|
||||||
else:
|
|
||||||
file = '/etc/sysctl.conf'
|
|
||||||
conf = mw.readFile(file)
|
|
||||||
rep = "#*net\.ipv4\.icmp_echo_ignore_all\s*=\s*([0-9]+)"
|
|
||||||
tmp = re.search(rep, conf).groups(0)[0]
|
|
||||||
if tmp == '1':
|
|
||||||
isPing = False
|
|
||||||
except:
|
|
||||||
isPing = True
|
|
||||||
|
|
||||||
import system_api
|
|
||||||
panelsys = system_api.system_api()
|
|
||||||
version = panelsys.getSystemVersion()
|
|
||||||
if os.path.exists('/usr/bin/apt-get'):
|
|
||||||
if os.path.exists('/etc/init.d/sshd'):
|
|
||||||
cmd = "service sshd status | grep -P '(dead|stop)'|grep -v grep"
|
|
||||||
status = mw.execShell(cmd)
|
|
||||||
else:
|
|
||||||
cmd = "service ssh status | grep -P '(dead|stop)'|grep -v grep"
|
|
||||||
status = mw.execShell(cmd)
|
|
||||||
else:
|
|
||||||
if version.find(' 7.') != -1:
|
|
||||||
cmd = "systemctl status sshd.service | grep 'dead'|grep -v grep"
|
|
||||||
status = mw.execShell(cmd)
|
|
||||||
else:
|
|
||||||
cmd = "/etc/init.d/sshd status | grep -e 'stopped' -e '已停'|grep -v grep"
|
|
||||||
status = mw.execShell(cmd)
|
|
||||||
if len(status[0]) > 3:
|
|
||||||
status = False
|
|
||||||
else:
|
|
||||||
status = True
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['port'] = port
|
|
||||||
|
|
||||||
data['status'] = status
|
|
||||||
data['ping'] = isPing
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
data['firewall_status'] = False
|
|
||||||
else:
|
|
||||||
data['firewall_status'] = self.getFwStatus()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def setSshPortApi(self):
|
|
||||||
port = request.form.get('port', '1').strip()
|
|
||||||
if int(port) < 22 or int(port) > 65535:
|
|
||||||
return mw.returnJson(False, '端口范围必需在22-65535之间!')
|
|
||||||
|
|
||||||
ports = ['21', '25', '80', '443', '7200', '8080', '888', '8888']
|
|
||||||
if port in ports:
|
|
||||||
return mw.returnJson(False, '(' + port + ')' + '特殊端口不可设置!')
|
|
||||||
|
|
||||||
file = '/etc/ssh/sshd_config'
|
|
||||||
conf = mw.readFile(file)
|
|
||||||
|
|
||||||
rep = "#*Port\s+([0-9]+)\s*\n"
|
|
||||||
conf = re.sub(rep, "Port " + port + "\n", conf)
|
|
||||||
mw.writeFile(file, conf)
|
|
||||||
|
|
||||||
if self.__isFirewalld:
|
|
||||||
mw.execShell('setenforce 0')
|
|
||||||
mw.execShell(
|
|
||||||
'sed -i "s#SELINUX=enforcing#SELINUX=disabled#" /etc/selinux/config')
|
|
||||||
mw.execShell("systemctl restart sshd.service")
|
|
||||||
elif self.__isUfw:
|
|
||||||
mw.execShell('ufw allow ' + port + '/tcp')
|
|
||||||
mw.execShell("service ssh restart")
|
|
||||||
else:
|
|
||||||
mw.execShell(
|
|
||||||
'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
|
|
||||||
mw.execShell("/etc/init.d/sshd restart")
|
|
||||||
|
|
||||||
self.firewallReload()
|
|
||||||
# mw.M('firewall').where(
|
|
||||||
# "ps=?", ('SSH远程管理服务',)).setField('port', port)
|
|
||||||
msg = mw.getInfo('改SSH端口为[{1}]成功!', port)
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
return mw.returnJson(True, '修改成功!')
|
|
||||||
|
|
||||||
def setSshStatusApi(self):
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return mw.returnJson(True, '开发机不能操作!')
|
|
||||||
|
|
||||||
status = request.form.get('status', '1').strip()
|
|
||||||
version = mw.readFile('/etc/redhat-release')
|
|
||||||
if int(status) == 1:
|
|
||||||
msg = 'SSH服务已停用'
|
|
||||||
act = 'stop'
|
|
||||||
else:
|
|
||||||
msg = 'SSH服务已启用'
|
|
||||||
act = 'start'
|
|
||||||
|
|
||||||
if not os.path.exists('/etc/redhat-release'):
|
|
||||||
mw.execShell('service ssh ' + act)
|
|
||||||
elif version.find(' 7.') != -1:
|
|
||||||
mw.execShell("systemctl " + act + " sshd.service")
|
|
||||||
else:
|
|
||||||
mw.execShell("/etc/init.d/sshd " + act)
|
|
||||||
|
|
||||||
mw.writeLog("防火墙管理", msg)
|
|
||||||
return mw.returnJson(True, '操作成功!')
|
|
||||||
|
|
||||||
def setPingApi(self):
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return mw.returnJson(True, '开发机不能操作!')
|
|
||||||
|
|
||||||
status = request.form.get('status')
|
|
||||||
filename = '/etc/sysctl.conf'
|
|
||||||
conf = mw.readFile(filename)
|
|
||||||
if conf.find('net.ipv4.icmp_echo') != -1:
|
|
||||||
rep = u"net\.ipv4\.icmp_echo.*"
|
|
||||||
conf = re.sub(rep, 'net.ipv4.icmp_echo_ignore_all=' + status, conf)
|
|
||||||
else:
|
|
||||||
conf += "\nnet.ipv4.icmp_echo_ignore_all=" + status
|
|
||||||
|
|
||||||
mw.writeFile(filename, conf)
|
|
||||||
mw.execShell('sysctl -p')
|
|
||||||
return mw.returnJson(True, '设置成功!')
|
|
||||||
|
|
||||||
def setFwApi(self):
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return mw.returnJson(True, '开发机不能设置!')
|
|
||||||
|
|
||||||
status = request.form.get('status', '1')
|
|
||||||
if status == '1':
|
|
||||||
if self.__isUfw:
|
|
||||||
mw.execShell('/usr/sbin/ufw disable')
|
|
||||||
if self.__isFirewalld:
|
|
||||||
mw.execShell('systemctl stop firewalld.service')
|
|
||||||
mw.execShell('systemctl disable firewalld.service')
|
|
||||||
elif self.__isMac:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
mw.execShell('/etc/init.d/iptables save')
|
|
||||||
mw.execShell('/etc/init.d/iptables stop')
|
|
||||||
else:
|
|
||||||
if self.__isUfw:
|
|
||||||
mw.execShell("echo 'y'|sudo ufw enable")
|
|
||||||
if self.__isFirewalld:
|
|
||||||
mw.execShell('systemctl start firewalld.service')
|
|
||||||
mw.execShell('systemctl enable firewalld.service')
|
|
||||||
elif self.__isMac:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
mw.execShell('/etc/init.d/iptables save')
|
|
||||||
mw.execShell('/etc/init.d/iptables restart')
|
|
||||||
|
|
||||||
return mw.returnJson(True, '设置成功!')
|
|
||||||
|
|
||||||
def delPanelLogsApi(self):
|
|
||||||
mw.M('logs').where('id>?', (0,)).delete()
|
|
||||||
mw.writeLog('面板设置', '面板操作日志已清空!')
|
|
||||||
return mw.returnJson(True, '面板操作日志已清空!')
|
|
||||||
|
|
||||||
##### ----- start ----- ###
|
|
||||||
|
|
||||||
def getList(self, page, limit):
|
|
||||||
|
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
_list = mw.M('firewall').field('id,port,ps,addtime').limit(
|
|
||||||
str(start) + ',' + str(limit)).order('id desc').select()
|
|
||||||
data = {}
|
|
||||||
data['data'] = _list
|
|
||||||
|
|
||||||
count = mw.M('firewall').count()
|
|
||||||
_page = {}
|
|
||||||
_page['count'] = count
|
|
||||||
_page['tojs'] = 'showAccept'
|
|
||||||
_page['p'] = page
|
|
||||||
|
|
||||||
data['page'] = mw.getPage(_page)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def getLogList(self, page, limit, search=''):
|
|
||||||
find_search = ''
|
|
||||||
if search != '':
|
|
||||||
find_search = "type like '%" + search + "%' or log like '%" + \
|
|
||||||
search + "%' or addtime like '%" + search + "%'"
|
|
||||||
|
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
_list = mw.M('logs').where(find_search, ()).field(
|
|
||||||
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
|
|
||||||
data = {}
|
|
||||||
data['data'] = _list
|
|
||||||
|
|
||||||
count = mw.M('logs').where(find_search, ()).count()
|
|
||||||
_page = {}
|
|
||||||
_page['count'] = count
|
|
||||||
_page['tojs'] = 'getLogs'
|
|
||||||
_page['p'] = page
|
|
||||||
|
|
||||||
data['page'] = mw.getPage(_page)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def addAcceptPort(self, port):
|
|
||||||
if self.__isUfw:
|
|
||||||
mw.execShell('ufw allow ' + port + '/tcp')
|
|
||||||
elif self.__isFirewalld:
|
|
||||||
port = port.replace(':', '-')
|
|
||||||
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
|
|
||||||
mw.execShell(cmd)
|
|
||||||
elif self.__isMac:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
|
|
||||||
mw.execShell(cmd)
|
|
||||||
|
|
||||||
def firewallReload(self):
|
|
||||||
if self.__isUfw:
|
|
||||||
mw.execShell('/usr/sbin/ufw reload')
|
|
||||||
return
|
|
||||||
if self.__isFirewalld:
|
|
||||||
mw.execShell('firewall-cmd --reload')
|
|
||||||
elif self.__isMac:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
mw.execShell('/etc/init.d/iptables save')
|
|
||||||
mw.execShell('/etc/init.d/iptables restart')
|
|
||||||
|
|
||||||
def getFwStatus(self):
|
|
||||||
if self.__isUfw:
|
|
||||||
cmd = "/usr/sbin/ufw status| grep Status | awk -F ':' '{print $2}'"
|
|
||||||
data = mw.execShell(cmd)
|
|
||||||
if data[0].strip() == 'inactive':
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
if self.__isFirewalld:
|
|
||||||
cmd = "ps -ef|grep firewalld |grep -v grep | awk '{print $2}'"
|
|
||||||
data = mw.execShell(cmd)
|
|
||||||
if data[0] == '':
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
elif self.__isMac:
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
cmd = "ps -ef|grep iptables |grep -v grep | awk '{print $2}'"
|
|
||||||
data = mw.execShell(cmd)
|
|
||||||
if data[0] == '':
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
-1066
File diff suppressed because it is too large
Load Diff
+26
-28
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
import string
|
import string
|
||||||
|
import public
|
||||||
|
|
||||||
|
|
||||||
class Page():
|
class Page():
|
||||||
@@ -28,7 +29,8 @@ class Page():
|
|||||||
__END_NUM = None # 结束行
|
__END_NUM = None # 结束行
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if False:
|
tmp = public.getMsg('PAGE')
|
||||||
|
if tmp:
|
||||||
self.__PREV = tmp['PREV']
|
self.__PREV = tmp['PREV']
|
||||||
self.__NEXT = tmp['NEXT']
|
self.__NEXT = tmp['NEXT']
|
||||||
self.__START = tmp['START']
|
self.__START = tmp['START']
|
||||||
@@ -53,6 +55,7 @@ class Page():
|
|||||||
self.SHIFT = self.__START_NUM - 1
|
self.SHIFT = self.__START_NUM - 1
|
||||||
|
|
||||||
keys = limit.split(',')
|
keys = limit.split(',')
|
||||||
|
|
||||||
pages = {}
|
pages = {}
|
||||||
# 起始页
|
# 起始页
|
||||||
pages['1'] = self.__GetStart()
|
pages['1'] = self.__GetStart()
|
||||||
@@ -67,16 +70,14 @@ class Page():
|
|||||||
|
|
||||||
# 当前显示页与总页数
|
# 当前显示页与总页数
|
||||||
pages['6'] = "<span class='Pnumber'>" + \
|
pages['6'] = "<span class='Pnumber'>" + \
|
||||||
str(self.__C_PAGE) + "/" + \
|
bytes(self.__C_PAGE) + "/" + bytes(self.__COUNT_PAGE) + "</span>"
|
||||||
str(self.__COUNT_PAGE) + "</span>"
|
|
||||||
|
|
||||||
# 本页显示开始与结束行
|
# 本页显示开始与结束行
|
||||||
pages['7'] = "<span class='Pline'>" + str(self.__FO) + \
|
pages['7'] = "<span class='Pline'>" + self.__FO + \
|
||||||
str(self.__START_NUM) + "-" + \
|
bytes(self.__START_NUM) + "-" + \
|
||||||
str(self.__END_NUM) + str(self.__LINE) + "</span>"
|
bytes(self.__END_NUM) + self.__LINE + "</span>"
|
||||||
# 行数
|
# 行数
|
||||||
pages['8'] = "<span class='Pcount'>" + str(self.__COUNT_START) + \
|
pages['8'] = "<span class='Pcount'>" + self.__COUNT_START + \
|
||||||
str(self.__COUNT_ROW) + str(self.__COUNT_END) + "</span>"
|
bytes(self.__COUNT_ROW) + self.__COUNT_END + "</span>"
|
||||||
|
|
||||||
# 构造返回数据
|
# 构造返回数据
|
||||||
retuls = '<div>'
|
retuls = '<div>'
|
||||||
@@ -95,11 +96,10 @@ class Page():
|
|||||||
else:
|
else:
|
||||||
if self.__RTURN_JS == "":
|
if self.__RTURN_JS == "":
|
||||||
endStr = "<a class='Pend' href='" + self.__URI + "p=" + \
|
endStr = "<a class='Pend' href='" + self.__URI + "p=" + \
|
||||||
str(self.__COUNT_PAGE) + "'>" + str(self.__END) + "</a>"
|
bytes(self.__COUNT_PAGE) + "'>" + self.__END + "</a>"
|
||||||
else:
|
else:
|
||||||
endStr = "<a class='Pend' onclick='" + self.__RTURN_JS + \
|
endStr = "<a class='Pend' onclick='" + self.__RTURN_JS + \
|
||||||
"(" + str(self.__COUNT_PAGE) + ")'>" + \
|
"(" + bytes(self.__COUNT_PAGE) + ")'>" + self.__END + "</a>"
|
||||||
str(self.__END) + "</a>"
|
|
||||||
return endStr
|
return endStr
|
||||||
|
|
||||||
def __GetNext(self):
|
def __GetNext(self):
|
||||||
@@ -110,11 +110,10 @@ class Page():
|
|||||||
else:
|
else:
|
||||||
if self.__RTURN_JS == "":
|
if self.__RTURN_JS == "":
|
||||||
nextStr = "<a class='Pnext' href='" + self.__URI + "p=" + \
|
nextStr = "<a class='Pnext' href='" + self.__URI + "p=" + \
|
||||||
str(self.__C_PAGE + 1) + "'>" + str(self.__NEXT) + "</a>"
|
bytes(self.__C_PAGE + 1) + "'>" + self.__NEXT + "</a>"
|
||||||
else:
|
else:
|
||||||
nextStr = "<a class='Pnext' onclick='" + self.__RTURN_JS + \
|
nextStr = "<a class='Pnext' onclick='" + self.__RTURN_JS + \
|
||||||
"(" + str(self.__C_PAGE + 1) + ")'>" + \
|
"(" + bytes(self.__C_PAGE + 1) + ")'>" + self.__NEXT + "</a>"
|
||||||
str(self.__NEXT) + "</a>"
|
|
||||||
|
|
||||||
return nextStr
|
return nextStr
|
||||||
|
|
||||||
@@ -135,15 +134,15 @@ class Page():
|
|||||||
if page > 0:
|
if page > 0:
|
||||||
if self.__RTURN_JS == "":
|
if self.__RTURN_JS == "":
|
||||||
pages += "<a class='Pnum' href='" + self.__URI + \
|
pages += "<a class='Pnum' href='" + self.__URI + \
|
||||||
"p=" + str(page) + "'>" + str(page) + "</a>"
|
"p=" + bytes(page) + "'>" + bytes(page) + "</a>"
|
||||||
else:
|
else:
|
||||||
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
|
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
|
||||||
"(" + str(page) + ")'>" + str(page) + "</a>"
|
"(" + bytes(page) + ")'>" + bytes(page) + "</a>"
|
||||||
|
|
||||||
# 当前页
|
# 当前页
|
||||||
if self.__C_PAGE > 0:
|
if self.__C_PAGE > 0:
|
||||||
pages += "<span class='Pcurrent'>" + \
|
pages += "<span class='Pcurrent'>" + \
|
||||||
str(self.__C_PAGE) + "</span>"
|
bytes(self.__C_PAGE) + "</span>"
|
||||||
|
|
||||||
# 当前页之后
|
# 当前页之后
|
||||||
if self.__C_PAGE <= self.__LIST_NUM:
|
if self.__C_PAGE <= self.__LIST_NUM:
|
||||||
@@ -158,10 +157,10 @@ class Page():
|
|||||||
break
|
break
|
||||||
if self.__RTURN_JS == "":
|
if self.__RTURN_JS == "":
|
||||||
pages += "<a class='Pnum' href='" + self.__URI + \
|
pages += "<a class='Pnum' href='" + self.__URI + \
|
||||||
"p=" + str(page) + "'>" + str(page) + "</a>"
|
"p=" + bytes(page) + "'>" + bytes(page) + "</a>"
|
||||||
else:
|
else:
|
||||||
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
|
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
|
||||||
"(" + str(page) + ")'>" + str(page) + "</a>"
|
"(" + bytes(page) + ")'>" + bytes(page) + "</a>"
|
||||||
|
|
||||||
return pages
|
return pages
|
||||||
|
|
||||||
@@ -173,11 +172,10 @@ class Page():
|
|||||||
else:
|
else:
|
||||||
if self.__RTURN_JS == "":
|
if self.__RTURN_JS == "":
|
||||||
startStr = "<a class='Ppren' href='" + self.__URI + "p=" + \
|
startStr = "<a class='Ppren' href='" + self.__URI + "p=" + \
|
||||||
str(self.__C_PAGE - 1) + "'>" + str(self.__PREV) + "</a>"
|
bytes(self.__C_PAGE - 1) + "'>" + self.__PREV + "</a>"
|
||||||
else:
|
else:
|
||||||
startStr = "<a class='Ppren' onclick='" + self.__RTURN_JS + \
|
startStr = "<a class='Ppren' onclick='" + self.__RTURN_JS + \
|
||||||
"(" + str(self.__C_PAGE - 1) + ")'>" + \
|
"(" + bytes(self.__C_PAGE - 1) + ")'>" + self.__PREV + "</a>"
|
||||||
str(self.__PREV) + "</a>"
|
|
||||||
return startStr
|
return startStr
|
||||||
|
|
||||||
def __GetStart(self):
|
def __GetStart(self):
|
||||||
@@ -188,10 +186,10 @@ class Page():
|
|||||||
else:
|
else:
|
||||||
if self.__RTURN_JS == "":
|
if self.__RTURN_JS == "":
|
||||||
startStr = "<a class='Pstart' href='" + \
|
startStr = "<a class='Pstart' href='" + \
|
||||||
self.__URI + "p=1'>" + str(self.__START) + "</a>"
|
self.__URI + "p=1'>" + self.__START + "</a>"
|
||||||
else:
|
else:
|
||||||
startStr = "<a class='Pstart' onclick='" + \
|
startStr = "<a class='Pstart' onclick='" + \
|
||||||
self.__RTURN_JS + "(1)'>" + str(self.__START) + "</a>"
|
self.__RTURN_JS + "(1)'>" + self.__START + "</a>"
|
||||||
return startStr
|
return startStr
|
||||||
|
|
||||||
def __GetCpage(self, p):
|
def __GetCpage(self, p):
|
||||||
@@ -214,11 +212,11 @@ class Page():
|
|||||||
# 取总页数
|
# 取总页数
|
||||||
return int(math.ceil(self.__COUNT_ROW / float(self.ROW)))
|
return int(math.ceil(self.__COUNT_ROW / float(self.ROW)))
|
||||||
|
|
||||||
def __SetUri(self, sinput):
|
def __SetUri(self, input):
|
||||||
# 构造URI
|
# 构造URI
|
||||||
uri = '?'
|
uri = '?'
|
||||||
for key in sinput:
|
for key in input:
|
||||||
if key == 'p':
|
if key == 'p':
|
||||||
continue
|
continue
|
||||||
uri += key + '=' + sinput[key] + '&'
|
uri += key + '=' + input[key] + '&'
|
||||||
return str(uri)
|
return str(uri)
|
||||||
|
|||||||
Executable
+291
@@ -0,0 +1,291 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import public
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class plugin_api:
|
||||||
|
__tasks = None
|
||||||
|
__plugin_dir = 'plugins'
|
||||||
|
__type = 'data/json/type.json'
|
||||||
|
__index = 'data/json/index.json'
|
||||||
|
setupPath = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.setupPath = 'server'
|
||||||
|
# self.__plugin_dir = public.getRunDir() + '/plugins'
|
||||||
|
|
||||||
|
# 进程是否存在
|
||||||
|
def processExists(self, pname, exe=None):
|
||||||
|
try:
|
||||||
|
if not self.pids:
|
||||||
|
self.pids = psutil.pids()
|
||||||
|
for pid in self.pids:
|
||||||
|
try:
|
||||||
|
p = psutil.Process(pid)
|
||||||
|
if p.name() == pname:
|
||||||
|
if not exe:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
if p.exe() == exe:
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
except:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 检查是否正在安装
|
||||||
|
def checkSetupTask(self, sName):
|
||||||
|
if not self.__tasks:
|
||||||
|
self.__tasks = public.M('tasks').where(
|
||||||
|
"status!=?", ('1',)).field('status,name').select()
|
||||||
|
|
||||||
|
if sName.find('php-') != -1:
|
||||||
|
tmp = sName.split('-')
|
||||||
|
sName = tmp[0]
|
||||||
|
version = tmp[1]
|
||||||
|
isTask = '1'
|
||||||
|
for task in self.__tasks:
|
||||||
|
tmpt = public.getStrBetween('[', ']', task['name'])
|
||||||
|
if not tmpt:
|
||||||
|
continue
|
||||||
|
tmp1 = tmpt.split('-')
|
||||||
|
name1 = tmp1[0].lower()
|
||||||
|
if sName == 'php':
|
||||||
|
if name1 == sName and tmp1[1] == version:
|
||||||
|
isTask = task['status']
|
||||||
|
else:
|
||||||
|
if name1 == 'pure':
|
||||||
|
name1 = 'pure-ftpd'
|
||||||
|
if name1 == sName:
|
||||||
|
isTask = task['status']
|
||||||
|
return isTask
|
||||||
|
|
||||||
|
def checkStatus(self, info):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def checkDisplayIndex(self, name, version):
|
||||||
|
if not os.path.exists(self.__index):
|
||||||
|
public.writeFile(self.__index, '[]')
|
||||||
|
|
||||||
|
indexList = json.loads(public.readFile(self.__index))
|
||||||
|
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
|
||||||
|
return False
|
||||||
|
|
||||||
|
def getVersion(self, path):
|
||||||
|
version_f = path + '/version.pl'
|
||||||
|
if os.path.exists(version_f):
|
||||||
|
return public.readFile(version_f).strip()
|
||||||
|
return ''
|
||||||
|
|
||||||
|
# 构造本地插件信息
|
||||||
|
def getPluginInfo(self, info):
|
||||||
|
checks = ''
|
||||||
|
path = ''
|
||||||
|
coexist = False
|
||||||
|
|
||||||
|
if info["checks"][0:1] == '/':
|
||||||
|
checks = info["checks"]
|
||||||
|
else:
|
||||||
|
checks = public.getRootDir() + '/' + info['checks']
|
||||||
|
|
||||||
|
if info.has_key('path'):
|
||||||
|
path = info['path']
|
||||||
|
|
||||||
|
if path[0:1] != '/':
|
||||||
|
path = public.getRootDir() + '/' + path
|
||||||
|
|
||||||
|
if info.has_key('coexist') and info['coexist']:
|
||||||
|
coexist = True
|
||||||
|
|
||||||
|
pluginInfo = {
|
||||||
|
"id": 10000,
|
||||||
|
"pid": info['pid'],
|
||||||
|
"type": 1000,
|
||||||
|
"name": info['name'],
|
||||||
|
"title": info['title'],
|
||||||
|
"ps": info['ps'],
|
||||||
|
"dependnet": "",
|
||||||
|
"mutex": "",
|
||||||
|
"path": path,
|
||||||
|
"install_checks": checks,
|
||||||
|
"uninsatll_checks": checks,
|
||||||
|
"coexist": coexist,
|
||||||
|
"versions": info['versions'],
|
||||||
|
# "updates": info['updates'],
|
||||||
|
"display": False,
|
||||||
|
"setup": False,
|
||||||
|
"setup_version": "",
|
||||||
|
"status": False,
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginInfo['task'] = self.checkSetupTask(pluginInfo['name'])
|
||||||
|
|
||||||
|
if checks.find('VERSION') > -1:
|
||||||
|
pluginInfo['install_checks'] = checks.replace(
|
||||||
|
'VERSION', info['versions'])
|
||||||
|
|
||||||
|
if path.find('VERSION') > -1:
|
||||||
|
pluginInfo['path'] = path.replace(
|
||||||
|
'VERSION', info['versions'])
|
||||||
|
|
||||||
|
pluginInfo['display'] = self.checkDisplayIndex(
|
||||||
|
info['name'], pluginInfo['versions'])
|
||||||
|
|
||||||
|
pluginInfo['setup'] = os.path.exists(pluginInfo['install_checks'])
|
||||||
|
|
||||||
|
if coexist and pluginInfo['setup']:
|
||||||
|
pluginInfo['setup_version'] = info['versions']
|
||||||
|
else:
|
||||||
|
pluginInfo['setup_version'] = self.getVersion(
|
||||||
|
pluginInfo['path'])
|
||||||
|
# pluginInfo['status'] = os.path.exists(pluginInfo['install_checks'])
|
||||||
|
return pluginInfo
|
||||||
|
|
||||||
|
def makeCoexist(self, data):
|
||||||
|
plugins_info = []
|
||||||
|
for index in range(len(data['versions'])):
|
||||||
|
tmp = data.copy()
|
||||||
|
tmp['title'] = tmp['title'] + \
|
||||||
|
'-' + data['versions'][index]
|
||||||
|
tmp['versions'] = data['versions'][index]
|
||||||
|
pg = self.getPluginInfo(tmp)
|
||||||
|
plugins_info.append(pg)
|
||||||
|
|
||||||
|
return plugins_info
|
||||||
|
|
||||||
|
def makeList(self, data, sType='0'):
|
||||||
|
plugins_info = []
|
||||||
|
|
||||||
|
if (data['pid'] == sType):
|
||||||
|
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
|
||||||
|
tmp_data = self.makeCoexist(data)
|
||||||
|
for index in range(len(tmp_data)):
|
||||||
|
plugins_info.append(tmp_data[index])
|
||||||
|
else:
|
||||||
|
pg = self.getPluginInfo(data)
|
||||||
|
plugins_info.append(pg)
|
||||||
|
return plugins_info
|
||||||
|
|
||||||
|
if sType == '0':
|
||||||
|
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
|
||||||
|
tmp_data = self.makeCoexist(data)
|
||||||
|
for index in range(len(tmp_data)):
|
||||||
|
plugins_info.append(tmp_data[index])
|
||||||
|
else:
|
||||||
|
pg = self.getPluginInfo(data)
|
||||||
|
plugins_info.append(pg)
|
||||||
|
|
||||||
|
# print plugins_info, data
|
||||||
|
return plugins_info
|
||||||
|
|
||||||
|
def getAllList(self, sType='0'):
|
||||||
|
ret = {}
|
||||||
|
ret['type'] = json.loads(public.readFile(self.__type))
|
||||||
|
plugins_info = []
|
||||||
|
|
||||||
|
for dirinfo in os.listdir(self.__plugin_dir):
|
||||||
|
if dirinfo[0:1] == '.':
|
||||||
|
continue
|
||||||
|
path = self.__plugin_dir + '/' + dirinfo
|
||||||
|
if os.path.isdir(path):
|
||||||
|
json_file = path + '/info.json'
|
||||||
|
if os.path.exists(json_file):
|
||||||
|
try:
|
||||||
|
data = json.loads(public.readFile(json_file))
|
||||||
|
tmp_data = self.makeList(data, sType)
|
||||||
|
for index in range(len(tmp_data)):
|
||||||
|
plugins_info.append(tmp_data[index])
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
return plugins_info
|
||||||
|
|
||||||
|
def getPluginList(self, sType, sPage=1, sPageSize=15):
|
||||||
|
|
||||||
|
ret = {}
|
||||||
|
ret['type'] = json.loads(public.readFile(self.__type))
|
||||||
|
plugins_info = self.getAllList(sType)
|
||||||
|
args = {}
|
||||||
|
args['count'] = len(plugins_info)
|
||||||
|
args['p1'] = sPage
|
||||||
|
|
||||||
|
ret['data'] = plugins_info
|
||||||
|
ret['list'] = public.getPage(args)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def getIndexList(self):
|
||||||
|
if not os.path.exists(self.__index):
|
||||||
|
public.writeFile(self.__index, '[]')
|
||||||
|
|
||||||
|
indexList = json.loads(public.readFile(self.__index))
|
||||||
|
|
||||||
|
plist = []
|
||||||
|
app = []
|
||||||
|
for i in indexList:
|
||||||
|
info = i.split('-')
|
||||||
|
if not info[0] in app:
|
||||||
|
app.append(info[0])
|
||||||
|
path = self.__plugin_dir + '/' + info[0]
|
||||||
|
if os.path.isdir(path):
|
||||||
|
json_file = path + '/info.json'
|
||||||
|
if os.path.exists(json_file):
|
||||||
|
try:
|
||||||
|
data = json.loads(public.readFile(json_file))
|
||||||
|
tmp_data = self.makeList(data)
|
||||||
|
for index in range(len(tmp_data)):
|
||||||
|
if tmp_data[index]['versions'] == info[1] or info[1] in tmp_data[index]['versions']:
|
||||||
|
tmp_data[index]['display'] = True
|
||||||
|
plist.append(tmp_data[index])
|
||||||
|
continue
|
||||||
|
except Exception, e:
|
||||||
|
print e
|
||||||
|
return plist
|
||||||
|
|
||||||
|
def setIndexSort(self, sort):
|
||||||
|
data = sort.split('|')
|
||||||
|
public.writeFile(self.__index, json.dumps(data))
|
||||||
|
return True
|
||||||
|
|
||||||
|
def addIndex(self, name, version):
|
||||||
|
if not os.path.exists(self.__index):
|
||||||
|
public.writeFile(self.__index, '[]')
|
||||||
|
|
||||||
|
indexList = json.loads(public.readFile(self.__index))
|
||||||
|
vname = name + '-' + version
|
||||||
|
|
||||||
|
if vname in indexList:
|
||||||
|
return public.returnJson(False, '请不要重复添加!')
|
||||||
|
if len(indexList) >= 12:
|
||||||
|
return public.returnJson(False, '首页最多只能显示12个软件!')
|
||||||
|
|
||||||
|
indexList.append(vname)
|
||||||
|
public.writeFile(self.__index, json.dumps(indexList))
|
||||||
|
return public.returnJson(True, '添加成功!')
|
||||||
|
|
||||||
|
def removeIndex(self, name, version):
|
||||||
|
if not os.path.exists(self.__index):
|
||||||
|
public.writeFile(self.__index, '[]')
|
||||||
|
|
||||||
|
indexList = json.loads(public.readFile(self.__index))
|
||||||
|
vname = name + '-' + version
|
||||||
|
if not vname in indexList:
|
||||||
|
return public.returnJson(True, '删除成功!')
|
||||||
|
indexList.remove(vname)
|
||||||
|
public.writeFile(self.__index, json.dumps(indexList))
|
||||||
|
return public.returnJson(True, '删除成功!')
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
pass
|
||||||
@@ -1,916 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import mw
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
|
|
||||||
import sys
|
|
||||||
# reload(sys)
|
|
||||||
# sys.setdefaultencoding('utf8')
|
|
||||||
|
|
||||||
import threading
|
|
||||||
import multiprocessing
|
|
||||||
|
|
||||||
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
|
|
||||||
class pa_thread(threading.Thread):
|
|
||||||
|
|
||||||
def __init__(self, func, args, name=''):
|
|
||||||
threading.Thread.__init__(self)
|
|
||||||
self.name = name
|
|
||||||
self.func = func
|
|
||||||
self.args = args
|
|
||||||
self.result = self.func(*self.args)
|
|
||||||
|
|
||||||
def getResult(self):
|
|
||||||
try:
|
|
||||||
return self.result
|
|
||||||
except Exception:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class plugins_api:
|
|
||||||
__tasks = None
|
|
||||||
__plugin_dir = 'plugins'
|
|
||||||
__type = 'data/json/type.json'
|
|
||||||
__index = 'data/json/index.json'
|
|
||||||
setupPath = None
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.setupPath = 'server'
|
|
||||||
self.__plugin_dir = mw.getRunDir() + '/plugins'
|
|
||||||
self.__type = mw.getRunDir() + '/data/json/type.json'
|
|
||||||
self.__index = mw.getRunDir() + '/data/json/index.json'
|
|
||||||
|
|
||||||
##### ----- start ----- ###
|
|
||||||
def listApi(self):
|
|
||||||
sType = request.args.get('type', '0')
|
|
||||||
sPage = request.args.get('p', '1')
|
|
||||||
|
|
||||||
if not mw.isNumber(sPage):
|
|
||||||
sPage = 1
|
|
||||||
|
|
||||||
if not mw.isNumber(sType):
|
|
||||||
sType = 0
|
|
||||||
|
|
||||||
# print sPage
|
|
||||||
data = self.getPluginList(sType, int(sPage))
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def fileApi(self):
|
|
||||||
name = request.args.get('name', '')
|
|
||||||
if name.strip() == '':
|
|
||||||
return ''
|
|
||||||
|
|
||||||
f = request.args.get('f', '')
|
|
||||||
if f.strip() == '':
|
|
||||||
return ''
|
|
||||||
|
|
||||||
file = mw.getPluginDir() + '/' + name + '/' + f
|
|
||||||
if not os.path.exists(file):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
c = open(file, 'rb').read()
|
|
||||||
return c
|
|
||||||
|
|
||||||
def indexListApi(self):
|
|
||||||
data = self.getIndexList()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def indexSortApi(self):
|
|
||||||
sort = request.form.get('ssort', '')
|
|
||||||
if sort.strip() == '':
|
|
||||||
return mw.returnJson(False, '排序数据不能为空!')
|
|
||||||
data = self.setIndexSort(sort)
|
|
||||||
if data:
|
|
||||||
return mw.returnJson(True, '成功!')
|
|
||||||
return mw.returnJson(False, '失败!')
|
|
||||||
|
|
||||||
def installApi(self):
|
|
||||||
rundir = mw.getRunDir()
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
version = request.form.get('version', '')
|
|
||||||
|
|
||||||
mmsg = '安装'
|
|
||||||
if hasattr(request.form, 'upgrade'):
|
|
||||||
mtype = 'update'
|
|
||||||
mmsg = 'upgrade'
|
|
||||||
|
|
||||||
if name.strip() == '':
|
|
||||||
return mw.returnJson(False, '缺少插件名称!', ())
|
|
||||||
|
|
||||||
if version.strip() == '':
|
|
||||||
return mw.returnJson(False, '缺少版本信息!', ())
|
|
||||||
|
|
||||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
|
||||||
# print infoJsonPos
|
|
||||||
|
|
||||||
if not os.path.exists(infoJsonPos):
|
|
||||||
return mw.returnJson(False, '配置文件不存在!', ())
|
|
||||||
|
|
||||||
pluginInfo = json.loads(mw.readFile(infoJsonPos))
|
|
||||||
self.hookInstall(pluginInfo)
|
|
||||||
|
|
||||||
execstr = "cd " + os.getcwd() + "/plugins/" + \
|
|
||||||
name + " && /bin/bash " + pluginInfo["shell"] \
|
|
||||||
+ " install " + version
|
|
||||||
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
print(execstr)
|
|
||||||
|
|
||||||
taskAdd = (None, mmsg + '[' + name + '-' + version + ']',
|
|
||||||
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
|
|
||||||
|
|
||||||
mw.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
|
|
||||||
|
|
||||||
# 任务执行相关
|
|
||||||
mw.triggerTask()
|
|
||||||
return mw.returnJson(True, '已将安装任务添加到队列!')
|
|
||||||
|
|
||||||
def hookInstallFile(self, hook_name, info):
|
|
||||||
hookPath = mw.getPanelDataDir() + "/hook_" + hook_name + ".json"
|
|
||||||
data = []
|
|
||||||
if os.path.exists(hookPath):
|
|
||||||
t = mw.readFile(hookPath)
|
|
||||||
data = json.loads(t)
|
|
||||||
|
|
||||||
isNeedAdd = True
|
|
||||||
for x in range(len(data)):
|
|
||||||
if data[x]['title'] == info['title'] and data[x]['name'] == info['name']:
|
|
||||||
isNeedAdd = False
|
|
||||||
|
|
||||||
if isNeedAdd:
|
|
||||||
tmp = {}
|
|
||||||
tmp['title'] = info['title']
|
|
||||||
tmp['name'] = info['name']
|
|
||||||
data.append(tmp)
|
|
||||||
mw.writeFile(hookPath, json.dumps(data))
|
|
||||||
|
|
||||||
def hookUninstallFile(self, hook_name, info):
|
|
||||||
hookPath = mw.getPanelDataDir() + "/hook_" + hook_name + ".json"
|
|
||||||
data = []
|
|
||||||
if os.path.exists(hookPath):
|
|
||||||
t = mw.readFile(hookPath)
|
|
||||||
data = json.loads(t)
|
|
||||||
|
|
||||||
for idx in range(len(data)):
|
|
||||||
if data[idx]['title'] == info['title'] and data[idx]['name'] == info['name']:
|
|
||||||
data.remove(data[idx])
|
|
||||||
mw.writeFile(hookPath, json.dumps(data))
|
|
||||||
|
|
||||||
def hookInstall(self, info):
|
|
||||||
if 'hook' in info:
|
|
||||||
hooks = info['hook']
|
|
||||||
for x in hooks:
|
|
||||||
if x in ['backup']:
|
|
||||||
self.hookInstallFile(x, info)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def hookUninstall(self, info):
|
|
||||||
if 'hook' in info:
|
|
||||||
hooks = info['hook']
|
|
||||||
for x in hooks:
|
|
||||||
if x in ['backup']:
|
|
||||||
self.hookUninstallFile(x, info)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def uninstallOldApi(self):
|
|
||||||
rundir = mw.getRunDir()
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
version = request.form.get('version', '')
|
|
||||||
if name.strip() == '':
|
|
||||||
return mw.returnJson(False, "缺少插件名称!", ())
|
|
||||||
|
|
||||||
if version.strip() == '':
|
|
||||||
return mw.returnJson(False, "缺少版本信息!", ())
|
|
||||||
|
|
||||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
|
||||||
|
|
||||||
if not os.path.exists(infoJsonPos):
|
|
||||||
return mw.returnJson(False, "配置文件不存在!", ())
|
|
||||||
|
|
||||||
pluginInfo = json.loads(mw.readFile(infoJsonPos))
|
|
||||||
execstr = "cd " + os.getcwd() + "/plugins/" + \
|
|
||||||
name + " && /bin/bash " + pluginInfo["shell"] \
|
|
||||||
+ " uninstall " + version
|
|
||||||
|
|
||||||
taskAdd = (None, '卸载[' + name + '-' + version + ']',
|
|
||||||
'execshell', '0', time.strftime('%Y-%m-%d %H:%M:%S'), execstr)
|
|
||||||
|
|
||||||
mw.M('tasks').add('id,name,type,status,addtime, execstr', taskAdd)
|
|
||||||
return mw.returnJson(True, '已将卸载任务添加到队列!')
|
|
||||||
|
|
||||||
# 卸载时间短,不加入任务中...
|
|
||||||
def uninstallApi(self):
|
|
||||||
rundir = mw.getRunDir()
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
version = request.form.get('version', '')
|
|
||||||
if name.strip() == '':
|
|
||||||
return mw.returnJson(False, "缺少插件名称!", ())
|
|
||||||
|
|
||||||
if version.strip() == '':
|
|
||||||
return mw.returnJson(False, "缺少版本信息!", ())
|
|
||||||
|
|
||||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
|
||||||
|
|
||||||
if not os.path.exists(infoJsonPos):
|
|
||||||
return mw.returnJson(False, "配置文件不存在!", ())
|
|
||||||
|
|
||||||
pluginInfo = json.loads(mw.readFile(infoJsonPos))
|
|
||||||
self.hookUninstall(pluginInfo)
|
|
||||||
execstr = "cd " + os.getcwd() + "/plugins/" + \
|
|
||||||
name + " && /bin/bash " + pluginInfo["shell"] \
|
|
||||||
+ " uninstall " + version
|
|
||||||
|
|
||||||
data = mw.execShell(execstr)
|
|
||||||
if mw.isDebugMode():
|
|
||||||
print(execstr)
|
|
||||||
print(data[0], data[1])
|
|
||||||
self.removeIndex(name, version)
|
|
||||||
return mw.returnJson(True, '卸载执行成功!')
|
|
||||||
# if data[1] == '':
|
|
||||||
# return mw.returnJson(True, '已将卸载成功!')
|
|
||||||
# else:
|
|
||||||
# return mw.returnJson(False, '卸载出现错误信息!' + data[1])
|
|
||||||
|
|
||||||
def checkApi(self):
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
if name.strip() == '':
|
|
||||||
return mw.returnJson(False, "缺少插件名称!", ())
|
|
||||||
|
|
||||||
infoJsonPos = self.__plugin_dir + '/' + name + '/' + 'info.json'
|
|
||||||
if not os.path.exists(infoJsonPos):
|
|
||||||
return mw.returnJson(False, "配置文件不存在!", ())
|
|
||||||
return mw.returnJson(True, "插件存在!", ())
|
|
||||||
|
|
||||||
def setIndexApi(self):
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
status = request.form.get('status', '0')
|
|
||||||
version = request.form.get('version', '')
|
|
||||||
if status == '1':
|
|
||||||
return self.addIndex(name, version)
|
|
||||||
return self.removeIndex(name, version)
|
|
||||||
|
|
||||||
def settingApi(self):
|
|
||||||
name = request.args.get('name', '')
|
|
||||||
html = self.__plugin_dir + '/' + name + '/index.html'
|
|
||||||
return mw.readFile(html)
|
|
||||||
|
|
||||||
def runApi(self):
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
func = request.form.get('func', '')
|
|
||||||
version = request.form.get('version', '')
|
|
||||||
args = request.form.get('args', '')
|
|
||||||
script = request.form.get('script', 'index')
|
|
||||||
|
|
||||||
data = self.run(name, func, version, args, script)
|
|
||||||
if data[1] == '':
|
|
||||||
r = mw.returnJson(True, "OK", data[0].strip())
|
|
||||||
else:
|
|
||||||
r = mw.returnJson(False, data[1].strip())
|
|
||||||
return r
|
|
||||||
|
|
||||||
def callbackApi(self):
|
|
||||||
name = request.form.get('name', '')
|
|
||||||
func = request.form.get('func', '')
|
|
||||||
args = request.form.get('args', '')
|
|
||||||
script = request.form.get('script', 'index')
|
|
||||||
|
|
||||||
data = self.callback(name, func, args, script)
|
|
||||||
if data[0]:
|
|
||||||
return mw.returnJson(True, "OK", data[1])
|
|
||||||
return mw.returnJson(False, data[1])
|
|
||||||
|
|
||||||
def updateZipApi(self):
|
|
||||||
tmp_path = mw.getRootDir() + '/temp'
|
|
||||||
if not os.path.exists(tmp_path):
|
|
||||||
os.makedirs(tmp_path)
|
|
||||||
mw.execShell("rm -rf " + tmp_path + '/*')
|
|
||||||
|
|
||||||
tmp_file = tmp_path + '/plugin_tmp.zip'
|
|
||||||
from werkzeug.utils import secure_filename
|
|
||||||
from flask import request
|
|
||||||
f = request.files['plugin_zip']
|
|
||||||
if f.filename[-4:] != '.zip':
|
|
||||||
return mw.returnJson(False, '仅支持zip文件!')
|
|
||||||
f.save(tmp_file)
|
|
||||||
mw.execShell('cd ' + tmp_path + ' && unzip ' + tmp_file)
|
|
||||||
os.remove(tmp_file)
|
|
||||||
|
|
||||||
p_info = tmp_path + '/info.json'
|
|
||||||
if not os.path.exists(p_info):
|
|
||||||
d_path = None
|
|
||||||
for df in os.walk(tmp_path):
|
|
||||||
if len(df[2]) < 3:
|
|
||||||
continue
|
|
||||||
if not 'info.json' in df[2]:
|
|
||||||
continue
|
|
||||||
if not 'install.sh' in df[2]:
|
|
||||||
continue
|
|
||||||
if not os.path.exists(df[0] + '/info.json'):
|
|
||||||
continue
|
|
||||||
d_path = df[0]
|
|
||||||
if d_path:
|
|
||||||
tmp_path = d_path
|
|
||||||
p_info = tmp_path + '/info.json'
|
|
||||||
try:
|
|
||||||
data = json.loads(mw.readFile(p_info))
|
|
||||||
data['size'] = mw.getPathSize(tmp_path)
|
|
||||||
if not 'author' in data:
|
|
||||||
data['author'] = '未知'
|
|
||||||
if not 'home' in data:
|
|
||||||
data['home'] = 'https://github.com/midoks/mdserver-web'
|
|
||||||
plugin_path = mw.getPluginDir() + data['name'] + '/info.json'
|
|
||||||
data['old_version'] = '0'
|
|
||||||
data['tmp_path'] = tmp_path
|
|
||||||
if os.path.exists(plugin_path):
|
|
||||||
try:
|
|
||||||
old_info = json.loads(mw.ReadFile(plugin_path))
|
|
||||||
data['old_version'] = old_info['versions']
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
except:
|
|
||||||
mw.execShell("rm -rf " + tmp_path)
|
|
||||||
return mw.returnJson(False, '在压缩包中没有找到插件信息,请检查插件包!')
|
|
||||||
protectPlist = ('openresty', 'mysql', 'php', 'redis', 'memcached'
|
|
||||||
'mongodb', 'swap', 'gogs', 'pureftp')
|
|
||||||
if data['name'] in protectPlist:
|
|
||||||
return mw.returnJson(False, '[' + data['name'] + '],重要插件不可修改!')
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def inputZipApi(self):
|
|
||||||
plugin_name = request.form.get('plugin_name', '')
|
|
||||||
tmp_path = request.form.get('tmp_path', '')
|
|
||||||
|
|
||||||
if not os.path.exists(tmp_path):
|
|
||||||
return mw.returnJson(False, '临时文件不存在,请重新上传!')
|
|
||||||
plugin_path = mw.getPluginDir() + '/' + plugin_name
|
|
||||||
if not os.path.exists(plugin_path):
|
|
||||||
print(mw.execShell('mkdir -p ' + plugin_path))
|
|
||||||
mw.execShell("\cp -rf " + tmp_path + '/* ' + plugin_path + '/')
|
|
||||||
mw.execShell('chmod -R 755 ' + plugin_path)
|
|
||||||
p_info = mw.readFile(plugin_path + '/info.json')
|
|
||||||
if p_info:
|
|
||||||
mw.writeLog('软件管理', '安装第三方插件[%s]' %
|
|
||||||
json.loads(p_info)['title'])
|
|
||||||
return mw.returnJson(True, '安装成功!')
|
|
||||||
mw.execShell("rm -rf " + plugin_path)
|
|
||||||
return mw.returnJson(False, '安装失败!')
|
|
||||||
##### ----- end ----- ###
|
|
||||||
|
|
||||||
# 进程是否存在
|
|
||||||
def processExists(self, pname, exe=None):
|
|
||||||
try:
|
|
||||||
if not self.pids:
|
|
||||||
self.pids = psutil.pids()
|
|
||||||
for pid in self.pids:
|
|
||||||
try:
|
|
||||||
p = psutil.Process(pid)
|
|
||||||
if p.name() == pname:
|
|
||||||
if not exe:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
if p.exe() == exe:
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return False
|
|
||||||
except:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# 检查是否正在安装
|
|
||||||
def checkSetupTask(self, sName, sVer, sCoexist):
|
|
||||||
if not self.__tasks:
|
|
||||||
self.__tasks = mw.M('tasks').where(
|
|
||||||
"status!=?", ('1',)).field('status,name').select()
|
|
||||||
isTask = '1'
|
|
||||||
for task in self.__tasks:
|
|
||||||
tmpt = mw.getStrBetween('[', ']', task['name'])
|
|
||||||
if not tmpt:
|
|
||||||
continue
|
|
||||||
task_sign = tmpt.split('-')
|
|
||||||
task_len = len(task_sign)
|
|
||||||
|
|
||||||
task_name = task_sign[0].lower()
|
|
||||||
task_ver = task_sign[1]
|
|
||||||
if task_len > 2:
|
|
||||||
nameArr = task_sign[0:task_len - 1]
|
|
||||||
task_name = '-'.join(nameArr).lower()
|
|
||||||
task_ver = task_sign[task_len - 1]
|
|
||||||
if sCoexist:
|
|
||||||
if task_name == sName and task_ver == sVer:
|
|
||||||
isTask = task['status']
|
|
||||||
else:
|
|
||||||
if task_name == sName:
|
|
||||||
isTask = task['status']
|
|
||||||
return isTask
|
|
||||||
|
|
||||||
def checkStatus(self, info):
|
|
||||||
if not info['setup']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
data = self.run(info['name'], 'status', info['setup_version'])
|
|
||||||
if data[0] == 'start':
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
def checkStatusProcess(self, info, i, return_dict):
|
|
||||||
if not info['setup']:
|
|
||||||
return_dict[i] = False
|
|
||||||
return
|
|
||||||
|
|
||||||
data = self.run(info['name'], 'status', info['setup_version'])
|
|
||||||
if data[0] == 'start':
|
|
||||||
return_dict[i] = True
|
|
||||||
else:
|
|
||||||
return_dict[i] = False
|
|
||||||
|
|
||||||
def checkStatusThreads(self, info, i):
|
|
||||||
if not info['setup']:
|
|
||||||
return False
|
|
||||||
data = self.run(info['name'], 'status', info['setup_version'])
|
|
||||||
if data[0] == 'start':
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# 还无法正常运行,先保留
|
|
||||||
def checkStatusThreadsCallback(self, info, i):
|
|
||||||
if not info['setup']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
try:
|
|
||||||
data = self.callback(info['name'], 'status', info['setup_version'])
|
|
||||||
except Exception as e:
|
|
||||||
data = self.callback(info['name'], 'status')
|
|
||||||
|
|
||||||
# data = self.run(info['name'], 'status', info['setup_version'])
|
|
||||||
if data[0] == 'start':
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def checkStatusMThreads(self, plugins_info):
|
|
||||||
try:
|
|
||||||
threads = []
|
|
||||||
ntmp_list = range(len(plugins_info))
|
|
||||||
for i in ntmp_list:
|
|
||||||
t = pa_thread(self.checkStatusThreads,
|
|
||||||
(plugins_info[i], i))
|
|
||||||
threads.append(t)
|
|
||||||
|
|
||||||
for i in ntmp_list:
|
|
||||||
threads[i].start()
|
|
||||||
for i in ntmp_list:
|
|
||||||
threads[i].join()
|
|
||||||
|
|
||||||
for i in ntmp_list:
|
|
||||||
t = threads[i].getResult()
|
|
||||||
plugins_info[i]['status'] = t
|
|
||||||
except Exception as e:
|
|
||||||
print('checkStatusMThreads:', str(e))
|
|
||||||
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def checkStatusMProcess(self, plugins_info):
|
|
||||||
manager = multiprocessing.Manager()
|
|
||||||
return_dict = manager.dict()
|
|
||||||
jobs = []
|
|
||||||
for i in range(len(plugins_info)):
|
|
||||||
p = multiprocessing.Process(
|
|
||||||
target=self.checkStatusProcess, args=(plugins_info[i], i, return_dict))
|
|
||||||
jobs.append(p)
|
|
||||||
p.start()
|
|
||||||
|
|
||||||
for proc in jobs:
|
|
||||||
proc.join()
|
|
||||||
|
|
||||||
returnData = return_dict.values()
|
|
||||||
for i in ntmp_list:
|
|
||||||
plugins_info[i]['status'] = returnData[i]
|
|
||||||
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def checkDisplayIndex(self, name, version):
|
|
||||||
if not os.path.exists(self.__index):
|
|
||||||
mw.writeFile(self.__index, '[]')
|
|
||||||
|
|
||||||
indexList = json.loads(mw.readFile(self.__index))
|
|
||||||
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
|
|
||||||
return False
|
|
||||||
|
|
||||||
def getVersion(self, path):
|
|
||||||
version_f = path + '/version.pl'
|
|
||||||
if os.path.exists(version_f):
|
|
||||||
return mw.readFile(version_f).strip()
|
|
||||||
return ''
|
|
||||||
|
|
||||||
# 构造本地插件信息
|
|
||||||
def getPluginInfo(self, info):
|
|
||||||
checks = ''
|
|
||||||
path = ''
|
|
||||||
coexist = False
|
|
||||||
|
|
||||||
if info["checks"][0:1] == '/':
|
|
||||||
checks = info["checks"]
|
|
||||||
else:
|
|
||||||
checks = mw.getRootDir() + '/' + info['checks']
|
|
||||||
|
|
||||||
if 'path' in info:
|
|
||||||
path = info['path']
|
|
||||||
|
|
||||||
if path[0:1] != '/':
|
|
||||||
path = mw.getRootDir() + '/' + path
|
|
||||||
|
|
||||||
if 'coexist' in info and info['coexist']:
|
|
||||||
coexist = True
|
|
||||||
|
|
||||||
pInfo = {
|
|
||||||
"id": 10000,
|
|
||||||
"pid": info['pid'],
|
|
||||||
"type": 1000,
|
|
||||||
"name": info['name'],
|
|
||||||
"title": info['title'],
|
|
||||||
"ps": info['ps'],
|
|
||||||
"dependnet": "",
|
|
||||||
"mutex": "",
|
|
||||||
"path": path,
|
|
||||||
"install_checks": checks,
|
|
||||||
"uninsatll_checks": checks,
|
|
||||||
"coexist": coexist,
|
|
||||||
"versions": info['versions'],
|
|
||||||
# "updates": info['updates'],
|
|
||||||
"display": False,
|
|
||||||
"setup": False,
|
|
||||||
"setup_version": "",
|
|
||||||
"status": False,
|
|
||||||
"install_pre_inspection": False,
|
|
||||||
"uninstall_pre_inspection": False,
|
|
||||||
}
|
|
||||||
|
|
||||||
if checks.find('VERSION') > -1:
|
|
||||||
pInfo['install_checks'] = checks.replace(
|
|
||||||
'VERSION', info['versions'])
|
|
||||||
|
|
||||||
if path.find('VERSION') > -1:
|
|
||||||
pInfo['path'] = path.replace(
|
|
||||||
'VERSION', info['versions'])
|
|
||||||
|
|
||||||
pInfo['task'] = self.checkSetupTask(
|
|
||||||
pInfo['name'], info['versions'], coexist)
|
|
||||||
pInfo['display'] = self.checkDisplayIndex(
|
|
||||||
info['name'], pInfo['versions'])
|
|
||||||
|
|
||||||
pInfo['setup'] = os.path.exists(pInfo['install_checks'])
|
|
||||||
|
|
||||||
if coexist and pInfo['setup']:
|
|
||||||
pInfo['setup_version'] = info['versions']
|
|
||||||
else:
|
|
||||||
pInfo['setup_version'] = self.getVersion(pInfo['install_checks'])
|
|
||||||
# pluginInfo['status'] = self.checkStatus(pluginInfo)
|
|
||||||
|
|
||||||
if 'install_pre_inspection' in info:
|
|
||||||
pInfo['install_pre_inspection'] = info['install_pre_inspection']
|
|
||||||
if 'uninstall_pre_inspection' in info:
|
|
||||||
pInfo['uninstall_pre_inspection'] = info[
|
|
||||||
'uninstall_pre_inspection']
|
|
||||||
|
|
||||||
pInfo['status'] = False
|
|
||||||
return pInfo
|
|
||||||
|
|
||||||
def makeCoexist(self, data):
|
|
||||||
plugins_info = []
|
|
||||||
for index in range(len(data['versions'])):
|
|
||||||
tmp = data.copy()
|
|
||||||
tmp['title'] = tmp['title'] + \
|
|
||||||
'-' + data['versions'][index]
|
|
||||||
tmp['versions'] = data['versions'][index]
|
|
||||||
pg = self.getPluginInfo(tmp)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def makeList(self, data, sType='0'):
|
|
||||||
plugins_info = []
|
|
||||||
|
|
||||||
if (data['pid'] == sType):
|
|
||||||
if type(data['versions']) == list and 'coexist' in data and data['coexist']:
|
|
||||||
tmp_data = self.makeCoexist(data)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
else:
|
|
||||||
pg = self.getPluginInfo(data)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
if sType == '0':
|
|
||||||
if type(data['versions']) == list and 'coexist' in data and data['coexist']:
|
|
||||||
tmp_data = self.makeCoexist(data)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
else:
|
|
||||||
pg = self.getPluginInfo(data)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
|
|
||||||
# print plugins_info, data
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def getAllList(self, sType='0'):
|
|
||||||
plugins_info = []
|
|
||||||
for dirinfo in os.listdir(self.__plugin_dir):
|
|
||||||
if dirinfo[0:1] == '.':
|
|
||||||
continue
|
|
||||||
path = self.__plugin_dir + '/' + dirinfo
|
|
||||||
json_file = path + '/info.json'
|
|
||||||
if os.path.exists(json_file):
|
|
||||||
try:
|
|
||||||
data = json.loads(mw.readFile(json_file))
|
|
||||||
tmp_data = self.makeList(data, sType)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def getAllListPage(self, sType='0', page=1, pageSize=10):
|
|
||||||
plugins_info = []
|
|
||||||
for dirinfo in os.listdir(self.__plugin_dir):
|
|
||||||
if dirinfo[0:1] == '.':
|
|
||||||
continue
|
|
||||||
path = self.__plugin_dir + '/' + dirinfo
|
|
||||||
if os.path.isdir(path):
|
|
||||||
json_file = path + '/info.json'
|
|
||||||
if os.path.exists(json_file):
|
|
||||||
try:
|
|
||||||
data = json.loads(mw.readFile(json_file))
|
|
||||||
tmp_data = self.makeList(data, sType)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
|
|
||||||
start = (page - 1) * pageSize
|
|
||||||
end = start + pageSize
|
|
||||||
_plugins_info = plugins_info[start:end]
|
|
||||||
|
|
||||||
_plugins_info = self.checkStatusMThreads(_plugins_info)
|
|
||||||
return (_plugins_info, len(plugins_info))
|
|
||||||
|
|
||||||
def makeListThread(self, data, sType='0'):
|
|
||||||
plugins_info = []
|
|
||||||
|
|
||||||
if (data['pid'] == sType):
|
|
||||||
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
|
|
||||||
tmp_data = self.makeCoexist(data)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
else:
|
|
||||||
pg = self.getPluginInfo(data)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
if sType == '0':
|
|
||||||
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
|
|
||||||
tmp_data = self.makeCoexist(data)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
else:
|
|
||||||
pg = self.getPluginInfo(data)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
|
|
||||||
# print plugins_info, data
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def getAllListThread(self, sType='0'):
|
|
||||||
plugins_info = []
|
|
||||||
tmp_list = []
|
|
||||||
threads = []
|
|
||||||
for dirinfo in os.listdir(self.__plugin_dir):
|
|
||||||
if dirinfo[0:1] == '.':
|
|
||||||
continue
|
|
||||||
path = self.__plugin_dir + '/' + dirinfo
|
|
||||||
if os.path.isdir(path):
|
|
||||||
json_file = path + '/info.json'
|
|
||||||
if os.path.exists(json_file):
|
|
||||||
data = json.loads(mw.readFile(json_file))
|
|
||||||
if sType == '0':
|
|
||||||
tmp_list.append(data)
|
|
||||||
|
|
||||||
if (data['pid'] == sType):
|
|
||||||
tmp_list.append(data)
|
|
||||||
|
|
||||||
ntmp_list = range(len(tmp_list))
|
|
||||||
for i in ntmp_list:
|
|
||||||
t = pa_thread(self.makeListThread, (tmp_list[i], sType))
|
|
||||||
threads.append(t)
|
|
||||||
for i in ntmp_list:
|
|
||||||
threads[i].start()
|
|
||||||
for i in ntmp_list:
|
|
||||||
threads[i].join()
|
|
||||||
|
|
||||||
for i in ntmp_list:
|
|
||||||
t = threads[i].getResult()
|
|
||||||
for index in range(len(t)):
|
|
||||||
plugins_info.append(t[index])
|
|
||||||
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def makeListProcess(self, data, sType, i, return_dict):
|
|
||||||
plugins_info = []
|
|
||||||
|
|
||||||
if (data['pid'] == sType):
|
|
||||||
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
|
|
||||||
tmp_data = self.makeCoexist(data)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
else:
|
|
||||||
pg = self.getPluginInfo(data)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
# return plugins_info
|
|
||||||
|
|
||||||
if sType == '0':
|
|
||||||
if type(data['versions']) == list and data.has_key('coexist') and data['coexist']:
|
|
||||||
tmp_data = self.makeCoexist(data)
|
|
||||||
for index in range(len(tmp_data)):
|
|
||||||
plugins_info.append(tmp_data[index])
|
|
||||||
else:
|
|
||||||
pg = self.getPluginInfo(data)
|
|
||||||
plugins_info.append(pg)
|
|
||||||
|
|
||||||
return_dict[i] = plugins_info
|
|
||||||
# return plugins_info
|
|
||||||
|
|
||||||
def getAllListProcess(self, sType='0'):
|
|
||||||
plugins_info = []
|
|
||||||
tmp_list = []
|
|
||||||
manager = multiprocessing.Manager()
|
|
||||||
return_dict = manager.dict()
|
|
||||||
jobs = []
|
|
||||||
for dirinfo in os.listdir(self.__plugin_dir):
|
|
||||||
if dirinfo[0:1] == '.':
|
|
||||||
continue
|
|
||||||
path = self.__plugin_dir + '/' + dirinfo
|
|
||||||
if os.path.isdir(path):
|
|
||||||
json_file = path + '/info.json'
|
|
||||||
if os.path.exists(json_file):
|
|
||||||
data = json.loads(mw.readFile(json_file))
|
|
||||||
if sType == '0':
|
|
||||||
tmp_list.append(data)
|
|
||||||
|
|
||||||
if (data['pid'] == sType):
|
|
||||||
tmp_list.append(data)
|
|
||||||
|
|
||||||
ntmp_list = range(len(tmp_list))
|
|
||||||
for i in ntmp_list:
|
|
||||||
p = multiprocessing.Process(
|
|
||||||
target=self.makeListProcess, args=(tmp_list[i], sType, i, return_dict))
|
|
||||||
jobs.append(p)
|
|
||||||
p.start()
|
|
||||||
|
|
||||||
for proc in jobs:
|
|
||||||
proc.join()
|
|
||||||
|
|
||||||
returnData = return_dict.values()
|
|
||||||
for i in ntmp_list:
|
|
||||||
for index in range(len(returnData[i])):
|
|
||||||
plugins_info.append(returnData[i][index])
|
|
||||||
|
|
||||||
return plugins_info
|
|
||||||
|
|
||||||
def getPluginList(self, sType, sPage=1, sPageSize=10):
|
|
||||||
# print sType, sPage, sPageSize
|
|
||||||
|
|
||||||
ret = {}
|
|
||||||
ret['type'] = json.loads(mw.readFile(self.__type))
|
|
||||||
# plugins_info = self.getAllListThread(sType)
|
|
||||||
# plugins_info = self.getAllListProcess(sType)
|
|
||||||
data = self.getAllListPage(sType, sPage, sPageSize)
|
|
||||||
ret['data'] = data[0]
|
|
||||||
|
|
||||||
args = {}
|
|
||||||
args['count'] = data[1]
|
|
||||||
args['p'] = sPage
|
|
||||||
args['tojs'] = 'getSList'
|
|
||||||
args['row'] = sPageSize
|
|
||||||
|
|
||||||
ret['list'] = mw.getPage(args)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def getIndexList(self):
|
|
||||||
if not os.path.exists(self.__index):
|
|
||||||
mw.writeFile(self.__index, '[]')
|
|
||||||
|
|
||||||
indexList = json.loads(mw.readFile(self.__index))
|
|
||||||
plist = []
|
|
||||||
for i in indexList:
|
|
||||||
tmp = i.split('-')
|
|
||||||
tmp_len = len(tmp)
|
|
||||||
plugin_name = tmp[0]
|
|
||||||
plugin_ver = tmp[1]
|
|
||||||
if tmp_len > 2:
|
|
||||||
tmpArr = tmp[0:tmp_len - 1]
|
|
||||||
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)
|
|
||||||
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']:
|
|
||||||
data[index]['display'] = True
|
|
||||||
plist.append(data[index])
|
|
||||||
continue
|
|
||||||
except Exception as e:
|
|
||||||
print('getIndexList:', e)
|
|
||||||
|
|
||||||
# 使用gevent模式时,无法使用多进程
|
|
||||||
# plist = self.checkStatusMProcess(plist)
|
|
||||||
plist = self.checkStatusMThreads(plist)
|
|
||||||
return plist
|
|
||||||
|
|
||||||
def setIndexSort(self, sort):
|
|
||||||
data = sort.split('|')
|
|
||||||
mw.writeFile(self.__index, json.dumps(data))
|
|
||||||
return True
|
|
||||||
|
|
||||||
def addIndex(self, name, version):
|
|
||||||
if not os.path.exists(self.__index):
|
|
||||||
mw.writeFile(self.__index, '[]')
|
|
||||||
|
|
||||||
indexList = json.loads(mw.readFile(self.__index))
|
|
||||||
vname = name + '-' + version
|
|
||||||
|
|
||||||
if vname in indexList:
|
|
||||||
return mw.returnJson(False, '请不要重复添加!')
|
|
||||||
if len(indexList) > 12:
|
|
||||||
return mw.returnJson(False, '首页最多只能显示12个软件!')
|
|
||||||
|
|
||||||
indexList.append(vname)
|
|
||||||
mw.writeFile(self.__index, json.dumps(indexList))
|
|
||||||
return mw.returnJson(True, '添加成功!')
|
|
||||||
|
|
||||||
def removeIndex(self, name, version):
|
|
||||||
if not os.path.exists(self.__index):
|
|
||||||
mw.writeFile(self.__index, '[]')
|
|
||||||
|
|
||||||
indexList = json.loads(mw.readFile(self.__index))
|
|
||||||
vname = name + '-' + version
|
|
||||||
if not vname in indexList:
|
|
||||||
return mw.returnJson(True, '删除成功!')
|
|
||||||
indexList.remove(vname)
|
|
||||||
mw.writeFile(self.__index, json.dumps(indexList))
|
|
||||||
return mw.returnJson(True, '删除成功!')
|
|
||||||
|
|
||||||
# shell 调用
|
|
||||||
def run(self, name, func, version='', args='', script='index'):
|
|
||||||
path = self.__plugin_dir + \
|
|
||||||
'/' + name + '/' + script + '.py'
|
|
||||||
py = 'python3 ' + path
|
|
||||||
|
|
||||||
if args == '':
|
|
||||||
py_cmd = py + ' ' + func + ' ' + version
|
|
||||||
else:
|
|
||||||
py_cmd = py + ' ' + func + ' ' + version + ' ' + args
|
|
||||||
|
|
||||||
if not os.path.exists(path):
|
|
||||||
return ('', '')
|
|
||||||
data = mw.execShell(py_cmd)
|
|
||||||
|
|
||||||
if mw.isDebugMode():
|
|
||||||
print('run', py_cmd)
|
|
||||||
print(data)
|
|
||||||
# print os.path.exists(py_cmd)
|
|
||||||
|
|
||||||
return (data[0].strip(), data[1].strip())
|
|
||||||
|
|
||||||
# 映射包调用
|
|
||||||
def callback(self, name, func, args='', script='index'):
|
|
||||||
package = self.__plugin_dir + '/' + name
|
|
||||||
if not os.path.exists(package):
|
|
||||||
return (False, "插件不存在!")
|
|
||||||
|
|
||||||
sys.path.append(package)
|
|
||||||
eval_str = "__import__('" + script + "')." + func + '(' + args + ')'
|
|
||||||
newRet = eval(eval_str)
|
|
||||||
if mw.isDebugMode():
|
|
||||||
print('callback', eval_str)
|
|
||||||
|
|
||||||
return (True, newRet)
|
|
||||||
Executable
+733
@@ -0,0 +1,733 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import string
|
||||||
|
import json
|
||||||
|
import hashlib
|
||||||
|
import shlex
|
||||||
|
import datetime
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
import db
|
||||||
|
|
||||||
|
from random import Random
|
||||||
|
|
||||||
|
|
||||||
|
def execShell(cmdstring, cwd=None, timeout=None, shell=True):
|
||||||
|
|
||||||
|
if shell:
|
||||||
|
cmdstring_list = cmdstring
|
||||||
|
else:
|
||||||
|
cmdstring_list = shlex.split(cmdstring)
|
||||||
|
if timeout:
|
||||||
|
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
|
||||||
|
|
||||||
|
sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE,
|
||||||
|
shell=shell, bufsize=4096, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
|
||||||
|
while sub.poll() is None:
|
||||||
|
time.sleep(0.1)
|
||||||
|
if timeout:
|
||||||
|
if end_time <= datetime.datetime.now():
|
||||||
|
raise Exception("Timeout:%s" % cmdstring)
|
||||||
|
|
||||||
|
return sub.communicate()
|
||||||
|
|
||||||
|
|
||||||
|
def getRunDir():
|
||||||
|
return os.getcwd()
|
||||||
|
|
||||||
|
|
||||||
|
def getRootDir():
|
||||||
|
return os.path.dirname(os.path.dirname(getRunDir()))
|
||||||
|
|
||||||
|
|
||||||
|
def getOs():
|
||||||
|
os = execShell('uname')
|
||||||
|
return os[0].lower().strip()
|
||||||
|
|
||||||
|
|
||||||
|
def M(table):
|
||||||
|
sql = db.Sql()
|
||||||
|
return sql.table(table)
|
||||||
|
|
||||||
|
|
||||||
|
def getPage(args, result='1,2,3,4,5,8'):
|
||||||
|
# 取分页
|
||||||
|
import page
|
||||||
|
# 实例化分页类
|
||||||
|
page = page.Page()
|
||||||
|
info = {}
|
||||||
|
|
||||||
|
info['count'] = 0
|
||||||
|
if args.has_key('count'):
|
||||||
|
info['count'] = int(args['count'])
|
||||||
|
|
||||||
|
info['row'] = 10
|
||||||
|
if args.has_key('row'):
|
||||||
|
info['row'] = args['row']
|
||||||
|
|
||||||
|
info['p'] = 1
|
||||||
|
if args.has_key('p'):
|
||||||
|
info['p'] = int(args['p'])
|
||||||
|
info['uri'] = {}
|
||||||
|
info['return_js'] = ''
|
||||||
|
if args.has_key('tojs'):
|
||||||
|
info['return_js'] = args['tojs']
|
||||||
|
|
||||||
|
return page.GetPage(info, result)
|
||||||
|
|
||||||
|
|
||||||
|
def md5(str):
|
||||||
|
# 生成MD5
|
||||||
|
try:
|
||||||
|
m = hashlib.md5()
|
||||||
|
m.update(str)
|
||||||
|
return m.hexdigest()
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def getFileMd5(filename):
|
||||||
|
# 文件的MD5值
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
return False
|
||||||
|
|
||||||
|
myhash = hashlib.md5()
|
||||||
|
f = file(filename, 'rb')
|
||||||
|
while True:
|
||||||
|
b = f.read(8096)
|
||||||
|
if not b:
|
||||||
|
break
|
||||||
|
myhash.update(b)
|
||||||
|
f.close()
|
||||||
|
return myhash.hexdigest()
|
||||||
|
|
||||||
|
|
||||||
|
def getRandomString(length):
|
||||||
|
# 取随机字符串
|
||||||
|
str = ''
|
||||||
|
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
|
||||||
|
chrlen = len(chars) - 1
|
||||||
|
random = Random()
|
||||||
|
for i in range(length):
|
||||||
|
str += chars[random.randint(0, chrlen)]
|
||||||
|
return str
|
||||||
|
|
||||||
|
|
||||||
|
def getJson(data):
|
||||||
|
import json
|
||||||
|
return json.dumps(data)
|
||||||
|
|
||||||
|
|
||||||
|
def returnJson(status, msg, args=()):
|
||||||
|
# 取通用Json返回
|
||||||
|
return getJson(returnMsg(status, msg, args))
|
||||||
|
|
||||||
|
|
||||||
|
def returnMsg(status, msg, args=()):
|
||||||
|
# 取通用字曲返回
|
||||||
|
logMessage = json.loads(
|
||||||
|
readFile('static/language/' + getLanguage() + '/public.json'))
|
||||||
|
keys = logMessage.keys()
|
||||||
|
|
||||||
|
if msg in keys:
|
||||||
|
msg = logMessage[msg]
|
||||||
|
for i in range(len(args)):
|
||||||
|
rep = '{' + str(i + 1) + '}'
|
||||||
|
msg = msg.replace(rep, args[i])
|
||||||
|
return {'status': status, 'msg': msg, 'data': args}
|
||||||
|
|
||||||
|
|
||||||
|
def getInfo(msg, args=()):
|
||||||
|
# 取提示消息
|
||||||
|
for i in range(len(args)):
|
||||||
|
rep = '{' + str(i + 1) + '}'
|
||||||
|
msg = msg.replace(rep, args[i])
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def getMsg(key, args=()):
|
||||||
|
# 取提示消息
|
||||||
|
try:
|
||||||
|
logMessage = json.loads(
|
||||||
|
readFile('static/language/' + getLanguage() + '/public.json'))
|
||||||
|
keys = logMessage.keys()
|
||||||
|
msg = None
|
||||||
|
if key in keys:
|
||||||
|
msg = logMessage[key]
|
||||||
|
for i in range(len(args)):
|
||||||
|
rep = '{' + str(i + 1) + '}'
|
||||||
|
msg = msg.replace(rep, args[i])
|
||||||
|
return msg
|
||||||
|
except:
|
||||||
|
return key
|
||||||
|
|
||||||
|
|
||||||
|
def getLan(key):
|
||||||
|
# 取提示消息
|
||||||
|
logMessage = json.loads(
|
||||||
|
readFile('static/language/' + getLanguage() + '/template.json'))
|
||||||
|
keys = logMessage.keys()
|
||||||
|
msg = None
|
||||||
|
if key in keys:
|
||||||
|
msg = logMessage[key]
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
|
def readFile(filename):
|
||||||
|
# 读文件内容
|
||||||
|
try:
|
||||||
|
fp = open(filename, 'r')
|
||||||
|
fBody = fp.read()
|
||||||
|
fp.close()
|
||||||
|
return fBody
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def getDate():
|
||||||
|
# 取格式时间
|
||||||
|
import time
|
||||||
|
return time.strftime('%Y-%m-%d %X', time.localtime())
|
||||||
|
|
||||||
|
|
||||||
|
def getLanguage():
|
||||||
|
path = 'data/language.pl'
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return 'Simplified_Chinese'
|
||||||
|
return readFile(path).strip()
|
||||||
|
|
||||||
|
|
||||||
|
def writeLog(type, logMsg, args=()):
|
||||||
|
# 写日志
|
||||||
|
try:
|
||||||
|
import time
|
||||||
|
import db
|
||||||
|
import json
|
||||||
|
logMessage = json.loads(
|
||||||
|
readFile('static/language/' + getLanguage() + '/log.json'))
|
||||||
|
keys = logMessage.keys()
|
||||||
|
if logMsg in keys:
|
||||||
|
logMsg = logMessage[logMsg]
|
||||||
|
for i in range(len(args)):
|
||||||
|
rep = '{' + str(i + 1) + '}'
|
||||||
|
logMsg = logMsg.replace(rep, args[i])
|
||||||
|
if type in keys:
|
||||||
|
type = logMessage[type]
|
||||||
|
sql = db.Sql()
|
||||||
|
mDate = time.strftime('%Y-%m-%d %X', time.localtime())
|
||||||
|
data = (type, logMsg, mDate)
|
||||||
|
result = sql.table('logs').add('type,log,addtime', data)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def writeFile(filename, str):
|
||||||
|
# 写文件内容
|
||||||
|
try:
|
||||||
|
fp = open(filename, 'w+')
|
||||||
|
fp.write(str)
|
||||||
|
fp.close()
|
||||||
|
return True
|
||||||
|
except:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def httpGet(url, timeout=30):
|
||||||
|
# 发送GET请求
|
||||||
|
try:
|
||||||
|
import urllib2
|
||||||
|
import ssl
|
||||||
|
try:
|
||||||
|
ssl._create_default_https_context = ssl._create_unverified_context
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
response = urllib2.urlopen(url, timeout=timeout)
|
||||||
|
return response.read()
|
||||||
|
except Exception, ex:
|
||||||
|
# WriteLog('网络诊断',str(ex) + '['+url+']');
|
||||||
|
return str(ex)
|
||||||
|
|
||||||
|
|
||||||
|
def httpPost(url, data, timeout=30):
|
||||||
|
# 发送POST请求
|
||||||
|
try:
|
||||||
|
import urllib
|
||||||
|
import urllib2
|
||||||
|
import ssl
|
||||||
|
try:
|
||||||
|
ssl._create_default_https_context = ssl._create_unverified_context
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
data = urllib.urlencode(data)
|
||||||
|
req = urllib2.Request(url, data)
|
||||||
|
response = urllib2.urlopen(req, timeout=timeout)
|
||||||
|
return response.read()
|
||||||
|
except Exception, ex:
|
||||||
|
# WriteLog('网络诊断',str(ex) + '['+url+']');
|
||||||
|
return str(ex)
|
||||||
|
|
||||||
|
|
||||||
|
def writeSpeed(title, used, total, speed=0):
|
||||||
|
# 写进度
|
||||||
|
if not title:
|
||||||
|
data = {'title': None, 'progress': 0,
|
||||||
|
'total': 0, 'used': 0, 'speed': 0}
|
||||||
|
else:
|
||||||
|
progress = int((100.0 * used / total))
|
||||||
|
data = {'title': title, 'progress': progress,
|
||||||
|
'total': total, 'used': used, 'speed': speed}
|
||||||
|
writeFile('/tmp/panelSpeed.pl', json.dumps(data))
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def getSpeed():
|
||||||
|
# 取进度
|
||||||
|
data = readFile('/tmp/panelSpeed.pl')
|
||||||
|
if not data:
|
||||||
|
data = json.dumps({'title': None, 'progress': 0,
|
||||||
|
'total': 0, 'used': 0, 'speed': 0})
|
||||||
|
writeFile('/tmp/panelSpeed.pl', data)
|
||||||
|
return json.loads(data)
|
||||||
|
|
||||||
|
|
||||||
|
def getLastLine(inputfile, lineNum):
|
||||||
|
# 读文件指定倒数行数
|
||||||
|
try:
|
||||||
|
fp = open(inputfile, 'r')
|
||||||
|
lastLine = ""
|
||||||
|
|
||||||
|
lines = fp.readlines()
|
||||||
|
count = len(lines)
|
||||||
|
if count > lineNum:
|
||||||
|
num = lineNum
|
||||||
|
else:
|
||||||
|
num = count
|
||||||
|
i = 1
|
||||||
|
lastre = []
|
||||||
|
for i in range(1, (num + 1)):
|
||||||
|
if lines:
|
||||||
|
n = -i
|
||||||
|
lastLine = lines[n].strip()
|
||||||
|
fp.close()
|
||||||
|
lastre.append(lastLine)
|
||||||
|
|
||||||
|
result = ''
|
||||||
|
num -= 1
|
||||||
|
while num >= 0:
|
||||||
|
result += lastre[num] + "\n"
|
||||||
|
num -= 1
|
||||||
|
return result
|
||||||
|
except:
|
||||||
|
return getMsg('TASK_SLEEP')
|
||||||
|
|
||||||
|
|
||||||
|
def serviceReload():
|
||||||
|
# 重载Web服务配置
|
||||||
|
if os.path.exists('/www/server/nginx/sbin/nginx'):
|
||||||
|
result = execShell('/etc/init.d/nginx reload')
|
||||||
|
if result[1].find('nginx.pid') != -1:
|
||||||
|
execShell('pkill -9 nginx && sleep 1')
|
||||||
|
execShell('/etc/init.d/nginx start')
|
||||||
|
else:
|
||||||
|
result = execShell('/etc/init.d/httpd reload')
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def phpReload(version):
|
||||||
|
# 重载PHP配置
|
||||||
|
import os
|
||||||
|
if os.path.exists('/www/server/php/' + version + '/libphp5.so'):
|
||||||
|
execShell('/etc/init.d/httpd reload')
|
||||||
|
else:
|
||||||
|
execShell('/etc/init.d/php-fpm-' + version + ' reload')
|
||||||
|
|
||||||
|
|
||||||
|
def downloadFile(url, filename):
|
||||||
|
import urllib
|
||||||
|
urllib.urlretrieve(url, filename=filename, reporthook=downloadHook)
|
||||||
|
|
||||||
|
|
||||||
|
def downloadHook(count, blockSize, totalSize):
|
||||||
|
speed = {'total': totalSize, 'block': blockSize, 'count': count}
|
||||||
|
print speed
|
||||||
|
print '%02d%%' % (100.0 * count * blockSize / totalSize)
|
||||||
|
|
||||||
|
|
||||||
|
def GetLocalIp():
|
||||||
|
# 取本地外网IP
|
||||||
|
try:
|
||||||
|
import re
|
||||||
|
filename = 'data/iplist.txt'
|
||||||
|
ipaddress = readFile(filename)
|
||||||
|
if not ipaddress:
|
||||||
|
import urllib2
|
||||||
|
url = 'http://pv.sohu.com/cityjson?ie=utf-8'
|
||||||
|
opener = urllib2.urlopen(url)
|
||||||
|
str = opener.read()
|
||||||
|
ipaddress = re.search('\d+.\d+.\d+.\d+', str).group(0)
|
||||||
|
writeFile(filename, ipaddress)
|
||||||
|
|
||||||
|
ipaddress = re.search('\d+.\d+.\d+.\d+', ipaddress).group(0)
|
||||||
|
return ipaddress
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
# try:
|
||||||
|
# url = web.ctx.session.home + '/Api/getIpAddress'
|
||||||
|
# opener = urllib2.urlopen(url)
|
||||||
|
# return opener.read()
|
||||||
|
# except:
|
||||||
|
# return web.ctx.host.split(':')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def inArray(arrays, searchStr):
|
||||||
|
# 搜索数据中是否存在
|
||||||
|
for key in arrays:
|
||||||
|
if key == searchStr:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def checkWebConfig():
|
||||||
|
# 检查Web服务器配置文件是否有错误
|
||||||
|
if get_webserver() == 'nginx':
|
||||||
|
result = ExecShell(
|
||||||
|
"ulimit -n 10240 && /www/server/nginx/sbin/nginx -t -c /www/server/nginx/conf/nginx.conf")
|
||||||
|
searchStr = 'successful'
|
||||||
|
else:
|
||||||
|
result = ExecShell(
|
||||||
|
"ulimit -n 10240 && /www/server/apache/bin/apachectl -t")
|
||||||
|
searchStr = 'Syntax OK'
|
||||||
|
|
||||||
|
if result[1].find(searchStr) == -1:
|
||||||
|
WriteLog("TYPE_SOFT", 'CONF_CHECK_ERR', (result[1],))
|
||||||
|
return result[1]
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def checkIp(ip):
|
||||||
|
# 检查是否为IPv4地址
|
||||||
|
import re
|
||||||
|
p = re.compile(
|
||||||
|
'^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$')
|
||||||
|
if p.match(ip):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def checkPort(port):
|
||||||
|
# 检查端口是否合法
|
||||||
|
ports = ['21', '25', '443', '8080', '888', '8888', '8443']
|
||||||
|
if port in ports:
|
||||||
|
return False
|
||||||
|
intport = int(port)
|
||||||
|
if intport < 1 or intport > 65535:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def getStrBetween(startStr, endStr, srcStr):
|
||||||
|
# 字符串取中间
|
||||||
|
start = srcStr.find(startStr)
|
||||||
|
if start == -1:
|
||||||
|
return None
|
||||||
|
end = srcStr.find(endStr)
|
||||||
|
if end == -1:
|
||||||
|
return None
|
||||||
|
return srcStr[start + 1:end]
|
||||||
|
|
||||||
|
|
||||||
|
def getCpuType():
|
||||||
|
# 取CPU类型
|
||||||
|
cpuinfo = open('/proc/cpuinfo', 'r').read()
|
||||||
|
rep = "model\s+name\s+:\s+(.+)"
|
||||||
|
tmp = re.search(rep, cpuinfo)
|
||||||
|
cpuType = None
|
||||||
|
if tmp:
|
||||||
|
cpuType = tmp.groups()[0]
|
||||||
|
return cpuType
|
||||||
|
|
||||||
|
|
||||||
|
def isRestart():
|
||||||
|
# 检查是否允许重启
|
||||||
|
num = M('tasks').where('status!=?', ('1',)).count()
|
||||||
|
if num > 0:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def hasPwd(password):
|
||||||
|
# 加密密码字符
|
||||||
|
import crypt
|
||||||
|
return crypt.crypt(password, password)
|
||||||
|
|
||||||
|
|
||||||
|
def get_url(timeout=0.5):
|
||||||
|
import json
|
||||||
|
try:
|
||||||
|
nodeFile = '/www/server/panel/data/node.json'
|
||||||
|
node_list = json.loads(readFile(nodeFile))
|
||||||
|
mnode = None
|
||||||
|
for node in node_list:
|
||||||
|
node['ping'] = get_timeout(
|
||||||
|
node['protocol'] + node['address'] + ':' + node['port'] + '/check.txt')
|
||||||
|
if not node['ping']:
|
||||||
|
continue
|
||||||
|
if not mnode:
|
||||||
|
mnode = node
|
||||||
|
if node['ping'] < mnode['ping']:
|
||||||
|
mnode = node
|
||||||
|
return mnode['protocol'] + mnode['address'] + ':' + mnode['port']
|
||||||
|
except:
|
||||||
|
return 'http://download.bt.cn'
|
||||||
|
|
||||||
|
|
||||||
|
def get_timeout(url):
|
||||||
|
start = time.time()
|
||||||
|
result = httpGet(url)
|
||||||
|
if result != 'True':
|
||||||
|
return False
|
||||||
|
return int((time.time() - start) * 1000)
|
||||||
|
|
||||||
|
|
||||||
|
def auth_decode(data):
|
||||||
|
# 解密数据
|
||||||
|
token = GetToken()
|
||||||
|
# 是否有生成Token
|
||||||
|
if not token:
|
||||||
|
return returnMsg(False, 'REQUEST_ERR')
|
||||||
|
|
||||||
|
# 校验access_key是否正确
|
||||||
|
if token['access_key'] != data['btauth_key']:
|
||||||
|
return returnMsg(False, 'REQUEST_ERR')
|
||||||
|
|
||||||
|
# 解码数据
|
||||||
|
import binascii
|
||||||
|
import hashlib
|
||||||
|
import urllib
|
||||||
|
import hmac
|
||||||
|
import json
|
||||||
|
tdata = binascii.unhexlify(data['data'])
|
||||||
|
|
||||||
|
# 校验signature是否正确
|
||||||
|
signature = binascii.hexlify(
|
||||||
|
hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest())
|
||||||
|
if signature != data['signature']:
|
||||||
|
return returnMsg(False, 'REQUEST_ERR')
|
||||||
|
|
||||||
|
# 返回
|
||||||
|
return json.loads(urllib.unquote(tdata))
|
||||||
|
|
||||||
|
|
||||||
|
# 数据加密
|
||||||
|
def auth_encode(data):
|
||||||
|
token = GetToken()
|
||||||
|
pdata = {}
|
||||||
|
|
||||||
|
# 是否有生成Token
|
||||||
|
if not token:
|
||||||
|
return returnMsg(False, 'REQUEST_ERR')
|
||||||
|
|
||||||
|
# 生成signature
|
||||||
|
import binascii
|
||||||
|
import hashlib
|
||||||
|
import urllib
|
||||||
|
import hmac
|
||||||
|
import json
|
||||||
|
tdata = urllib.quote(json.dumps(data))
|
||||||
|
# 公式 hex(hmac_sha256(data))
|
||||||
|
pdata['signature'] = binascii.hexlify(
|
||||||
|
hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest())
|
||||||
|
|
||||||
|
# 加密数据
|
||||||
|
pdata['btauth_key'] = token['access_key']
|
||||||
|
pdata['data'] = binascii.hexlify(tdata)
|
||||||
|
pdata['timestamp'] = time.time()
|
||||||
|
|
||||||
|
# 返回
|
||||||
|
return pdata
|
||||||
|
|
||||||
|
|
||||||
|
def checkToken(get):
|
||||||
|
# 检查Token
|
||||||
|
tempFile = 'data/tempToken.json'
|
||||||
|
if not os.path.exists(tempFile):
|
||||||
|
return False
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
tempToken = json.loads(readFile(tempFile))
|
||||||
|
if time.time() > tempToken['timeout']:
|
||||||
|
return False
|
||||||
|
if get.token != tempToken['token']:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_webserver():
|
||||||
|
# 获取Web服务器
|
||||||
|
webserver = 'nginx'
|
||||||
|
if not os.path.exists('/www/server/nginx/sbin/nginx'):
|
||||||
|
webserver = 'apache'
|
||||||
|
return webserver
|
||||||
|
|
||||||
|
|
||||||
|
def checkInput(data):
|
||||||
|
# 过滤输入
|
||||||
|
if not data:
|
||||||
|
return data
|
||||||
|
if type(data) != str:
|
||||||
|
return data
|
||||||
|
checkList = [
|
||||||
|
{'d': '<', 'r': '<'},
|
||||||
|
{'d': '>', 'r': '>'},
|
||||||
|
{'d': '\'', 'r': '‘'},
|
||||||
|
{'d': '"', 'r': '“'},
|
||||||
|
{'d': '&', 'r': '&'},
|
||||||
|
{'d': '#', 'r': '#'},
|
||||||
|
{'d': '<', 'r': '<'}
|
||||||
|
]
|
||||||
|
for v in checkList:
|
||||||
|
data = data.replace(v['d'], v['r'])
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def getNumLines(path, num, p=1):
|
||||||
|
# 取文件指定尾行数
|
||||||
|
try:
|
||||||
|
import cgi
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return ""
|
||||||
|
start_line = (p - 1) * num
|
||||||
|
count = start_line + num
|
||||||
|
fp = open(path)
|
||||||
|
buf = ""
|
||||||
|
fp.seek(-1, 2)
|
||||||
|
if fp.read(1) == "\n":
|
||||||
|
fp.seek(-1, 2)
|
||||||
|
data = []
|
||||||
|
b = True
|
||||||
|
n = 0
|
||||||
|
for i in range(count):
|
||||||
|
while True:
|
||||||
|
newline_pos = string.rfind(buf, "\n")
|
||||||
|
pos = fp.tell()
|
||||||
|
if newline_pos != -1:
|
||||||
|
if n >= start_line:
|
||||||
|
line = buf[newline_pos + 1:]
|
||||||
|
try:
|
||||||
|
data.insert(0, cgi.escape(line))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
buf = buf[:newline_pos]
|
||||||
|
n += 1
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
if pos == 0:
|
||||||
|
b = False
|
||||||
|
break
|
||||||
|
to_read = min(4096, pos)
|
||||||
|
fp.seek(-to_read, 1)
|
||||||
|
buf = fp.read(to_read) + buf
|
||||||
|
fp.seek(-to_read, 1)
|
||||||
|
if pos - to_read == 0:
|
||||||
|
buf = "\n" + buf
|
||||||
|
if not b:
|
||||||
|
break
|
||||||
|
fp.close()
|
||||||
|
except:
|
||||||
|
data = []
|
||||||
|
return "\n".join(data)
|
||||||
|
|
||||||
|
|
||||||
|
def checkCert(certPath='ssl/certificate.pem'):
|
||||||
|
# 验证证书
|
||||||
|
openssl = '/usr/local/openssl/bin/openssl'
|
||||||
|
if not os.path.exists(openssl):
|
||||||
|
openssl = 'openssl'
|
||||||
|
certPem = readFile(certPath)
|
||||||
|
s = "\n-----BEGIN CERTIFICATE-----"
|
||||||
|
tmp = certPem.strip().split(s)
|
||||||
|
for tmp1 in tmp:
|
||||||
|
if tmp1.find('-----BEGIN CERTIFICATE-----') == -1:
|
||||||
|
tmp1 = s + tmp1
|
||||||
|
writeFile(certPath, tmp1)
|
||||||
|
result = execShell(openssl + " x509 -in " +
|
||||||
|
certPath + " -noout -subject")
|
||||||
|
if result[1].find('-bash:') != -1:
|
||||||
|
return True
|
||||||
|
if len(result[1]) > 2:
|
||||||
|
return False
|
||||||
|
if result[0].find('error:') != -1:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 获取面板地址
|
||||||
|
|
||||||
|
|
||||||
|
# def getPanelAddr():
|
||||||
|
# import web
|
||||||
|
# protocol = 'https://' if os.path.exists("data/ssl.pl") else 'http://'
|
||||||
|
# h = web.ctx.host.split(':')
|
||||||
|
# try:
|
||||||
|
# result = protocol + h[0] + ':' + h[1]
|
||||||
|
# except:
|
||||||
|
# result = protocol + h[0] + ':' + readFile('data/port.pl').strip()
|
||||||
|
# return result
|
||||||
|
|
||||||
|
|
||||||
|
def to_size(size):
|
||||||
|
# 字节单位转换
|
||||||
|
d = ('b', 'KB', 'MB', 'GB', 'TB')
|
||||||
|
s = d[0]
|
||||||
|
for b in d:
|
||||||
|
if size < 1024:
|
||||||
|
return str(size) + ' ' + b
|
||||||
|
size = size / 1024
|
||||||
|
s = b
|
||||||
|
return str(size) + ' ' + b
|
||||||
|
|
||||||
|
|
||||||
|
def get_string(t):
|
||||||
|
if t != -1:
|
||||||
|
max = 126
|
||||||
|
m_types = [{'m': 122, 'n': 97}, {'m': 90, 'n': 65}, {'m': 57, 'n': 48}, {
|
||||||
|
'm': 47, 'n': 32}, {'m': 64, 'n': 58}, {'m': 96, 'n': 91}, {'m': 125, 'n': 123}]
|
||||||
|
else:
|
||||||
|
max = 256
|
||||||
|
t = 0
|
||||||
|
m_types = [{'m': 255, 'n': 0}]
|
||||||
|
arr = []
|
||||||
|
for i in range(max):
|
||||||
|
if i < m_types[t]['n'] or i > m_types[t]['m']:
|
||||||
|
continue
|
||||||
|
arr.append(chr(i))
|
||||||
|
return arr
|
||||||
|
|
||||||
|
|
||||||
|
def get_string_find(t):
|
||||||
|
if type(t) != list:
|
||||||
|
t = [t]
|
||||||
|
return_str = ''
|
||||||
|
for s1 in t:
|
||||||
|
return_str += get_string(int(s1[0]))[int(s1[1:])]
|
||||||
|
return return_str
|
||||||
|
|
||||||
|
|
||||||
|
def get_string_arr(t):
|
||||||
|
s_arr = {}
|
||||||
|
t_arr = []
|
||||||
|
for s1 in t:
|
||||||
|
for i in range(6):
|
||||||
|
if not i in s_arr:
|
||||||
|
s_arr[i] = get_string(i)
|
||||||
|
for j in range(len(s_arr[i])):
|
||||||
|
if s1 == s_arr[i][j]:
|
||||||
|
t_arr.append(str(i) + str(j))
|
||||||
|
return t_arr
|
||||||
File diff suppressed because it is too large
Load Diff
+115
-282
@@ -5,27 +5,12 @@ import time
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import math
|
import math
|
||||||
import sys
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from flask import Flask, session
|
from flask import Flask, session
|
||||||
from flask import request
|
|
||||||
|
|
||||||
import db
|
import db
|
||||||
import mw
|
import public
|
||||||
|
|
||||||
import config_api
|
|
||||||
import requests
|
|
||||||
|
|
||||||
from threading import Thread
|
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
|
|
||||||
def mw_async(f):
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
thr = Thread(target=f, args=args, kwargs=kwargs)
|
|
||||||
thr.start()
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class system_api:
|
class system_api:
|
||||||
@@ -33,93 +18,9 @@ class system_api:
|
|||||||
pids = None
|
pids = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.setupPath = mw.getServerDir()
|
self.setupPath = '/www/server'
|
||||||
|
|
||||||
##### ----- start ----- ###
|
# 名取PID
|
||||||
def networkApi(self):
|
|
||||||
data = self.getNetWork()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def updateServerApi(self):
|
|
||||||
stype = request.args.get('type', 'check')
|
|
||||||
version = request.args.get('version', '')
|
|
||||||
return self.updateServer(stype, version)
|
|
||||||
|
|
||||||
def systemTotalApi(self):
|
|
||||||
data = self.getSystemTotal()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def diskInfoApi(self):
|
|
||||||
diskInfo = self.getDiskInfo()
|
|
||||||
return mw.getJson(diskInfo)
|
|
||||||
|
|
||||||
def setControlApi(self):
|
|
||||||
stype = request.form.get('type', '')
|
|
||||||
day = request.form.get('day', '')
|
|
||||||
data = self.setControl(stype, day)
|
|
||||||
return data
|
|
||||||
|
|
||||||
def getLoadAverageApi(self):
|
|
||||||
start = request.args.get('start', '')
|
|
||||||
end = request.args.get('end', '')
|
|
||||||
data = self.getLoadAverageData(start, end)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def getCpuIoApi(self):
|
|
||||||
start = request.args.get('start', '')
|
|
||||||
end = request.args.get('end', '')
|
|
||||||
data = self.getCpuIoData(start, end)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def getDiskIoApi(self):
|
|
||||||
start = request.args.get('start', '')
|
|
||||||
end = request.args.get('end', '')
|
|
||||||
data = self.getDiskIoData(start, end)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def getNetworkIoApi(self):
|
|
||||||
start = request.args.get('start', '')
|
|
||||||
end = request.args.get('end', '')
|
|
||||||
data = self.getNetWorkIoData(start, end)
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
def rememoryApi(self):
|
|
||||||
os.system('sync')
|
|
||||||
scriptFile = mw.getRunDir() + '/script/rememory.sh'
|
|
||||||
mw.execShell("/bin/bash " + scriptFile)
|
|
||||||
data = self.getMemInfo()
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
# 重启面板
|
|
||||||
def restartApi(self):
|
|
||||||
self.restartMw()
|
|
||||||
return mw.returnJson(True, '面板已重启!')
|
|
||||||
|
|
||||||
def restartServerApi(self):
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return mw.returnJson(False, "开发环境不可重起")
|
|
||||||
self.restartServer()
|
|
||||||
return mw.returnJson(True, '正在重启服务器!')
|
|
||||||
##### ----- end ----- ###
|
|
||||||
|
|
||||||
def restartTask(self):
|
|
||||||
initd = mw.getRunDir() + '/scripts/init.d/mw'
|
|
||||||
if os.path.exists(initd):
|
|
||||||
os.system(initd + ' ' + 'restart_task')
|
|
||||||
return True
|
|
||||||
|
|
||||||
def restartMw(self):
|
|
||||||
mw.writeFile('data/restart.pl', 'True')
|
|
||||||
return True
|
|
||||||
|
|
||||||
@mw_async
|
|
||||||
def restartServer(self):
|
|
||||||
if not mw.isRestart():
|
|
||||||
return mw.returnJson(False, '请等待所有安装任务完成再执行!')
|
|
||||||
mw.execShell("sync && init 6 &")
|
|
||||||
return mw.returnJson(True, '命令发送成功!')
|
|
||||||
|
|
||||||
# 名取PID
|
|
||||||
def getPid(self, pname):
|
def getPid(self, pname):
|
||||||
try:
|
try:
|
||||||
if not self.pids:
|
if not self.pids:
|
||||||
@@ -155,30 +56,30 @@ class system_api:
|
|||||||
|
|
||||||
def getPanelInfo(self, get=None):
|
def getPanelInfo(self, get=None):
|
||||||
# 取面板配置
|
# 取面板配置
|
||||||
address = mw.GetLocalIp()
|
address = public.GetLocalIp()
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
port = web.ctx.host.split(':')[1]
|
port = web.ctx.host.split(':')[1]
|
||||||
except:
|
except:
|
||||||
port = mw.readFile('data/port.pl')
|
port = public.readFile('data/port.pl')
|
||||||
except:
|
except:
|
||||||
port = '8888'
|
port = '8888'
|
||||||
domain = ''
|
domain = ''
|
||||||
if os.path.exists('data/domain.conf'):
|
if os.path.exists('data/domain.conf'):
|
||||||
domain = mw.readFile('data/domain.conf')
|
domain = public.readFile('data/domain.conf')
|
||||||
|
|
||||||
autoUpdate = ''
|
autoUpdate = ''
|
||||||
if os.path.exists('data/autoUpdate.pl'):
|
if os.path.exists('data/autoUpdate.pl'):
|
||||||
autoUpdate = 'checked'
|
autoUpdate = 'checked'
|
||||||
limitip = ''
|
limitip = ''
|
||||||
if os.path.exists('data/limitip.conf'):
|
if os.path.exists('data/limitip.conf'):
|
||||||
limitip = mw.readFile('data/limitip.conf')
|
limitip = public.readFile('data/limitip.conf')
|
||||||
|
|
||||||
templates = []
|
templates = []
|
||||||
for template in os.listdir('templates/'):
|
for template in os.listdir('templates/'):
|
||||||
if os.path.isdir('templates/' + template):
|
if os.path.isdir('templates/' + template):
|
||||||
templates.append(template)
|
templates.append(template)
|
||||||
template = mw.readFile('data/templates.pl')
|
template = public.readFile('data/templates.pl')
|
||||||
|
|
||||||
check502 = ''
|
check502 = ''
|
||||||
if os.path.exists('data/502Task.pl'):
|
if os.path.exists('data/502Task.pl'):
|
||||||
@@ -193,12 +94,12 @@ class system_api:
|
|||||||
data['cpuRealUsed'] = cpu[0]
|
data['cpuRealUsed'] = cpu[0]
|
||||||
data['time'] = self.getBootTime()
|
data['time'] = self.getBootTime()
|
||||||
data['system'] = self.getSystemVersion()
|
data['system'] = self.getSystemVersion()
|
||||||
data['isuser'] = mw.M('users').where(
|
data['isuser'] = public.M('users').where(
|
||||||
'username=?', ('admin',)).count()
|
'username=?', ('admin',)).count()
|
||||||
data['version'] = '0.0.1'
|
data['version'] = '0.0.1'
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def getLoadAverage(self):
|
def getLoadAverage(self, get=None):
|
||||||
c = os.getloadavg()
|
c = os.getloadavg()
|
||||||
data = {}
|
data = {}
|
||||||
data['one'] = float(c[0])
|
data['one'] = float(c[0])
|
||||||
@@ -215,7 +116,7 @@ class system_api:
|
|||||||
data['title'] = self.GetTitle()
|
data['title'] = self.GetTitle()
|
||||||
data['network'] = self.GetNetWorkApi(get)
|
data['network'] = self.GetNetWorkApi(get)
|
||||||
data['panel_status'] = not os.path.exists(
|
data['panel_status'] = not os.path.exists(
|
||||||
'/www/server/mdserver-web/data/close.pl')
|
'/www/server/panel/data/close.pl')
|
||||||
import firewalls
|
import firewalls
|
||||||
ssh_info = firewalls.firewalls().GetSshInfo(None)
|
ssh_info = firewalls.firewalls().GetSshInfo(None)
|
||||||
data['enable_ssh_status'] = ssh_info['status']
|
data['enable_ssh_status'] = ssh_info['status']
|
||||||
@@ -228,50 +129,42 @@ class system_api:
|
|||||||
|
|
||||||
def getTitle(self):
|
def getTitle(self):
|
||||||
titlePl = 'data/title.pl'
|
titlePl = 'data/title.pl'
|
||||||
title = 'Linux面板'
|
title = '宝塔Linux面板'
|
||||||
if os.path.exists(titlePl):
|
if os.path.exists(titlePl):
|
||||||
title = mw.readFile(titlePl).strip()
|
title = public.readFile(titlePl).strip()
|
||||||
return title
|
return title
|
||||||
|
|
||||||
def getSystemVersion(self):
|
def getSystemVersion(self):
|
||||||
# 取操作系统版本
|
# 取操作系统版本
|
||||||
if mw.getOs() == 'darwin':
|
os = public.getOs()
|
||||||
data = mw.execShell('sw_vers')[0]
|
if os == 'darwin':
|
||||||
|
data = public.execShell('sw_vers')[0]
|
||||||
data_list = data.strip().split("\n")
|
data_list = data.strip().split("\n")
|
||||||
mac_version = ''
|
mac_version = ''
|
||||||
for x in data_list:
|
for x in data_list:
|
||||||
mac_version += x.split("\t")[1] + ' '
|
mac_version += x.split("\t")[1] + ' '
|
||||||
return mac_version
|
return mac_version
|
||||||
|
|
||||||
redhat_series = '/etc/redhat-release'
|
version = public.readFile('/etc/redhat-release')
|
||||||
if os.path.exists(redhat_series):
|
if not version:
|
||||||
version = mw.readFile('/etc/redhat-release')
|
version = public.readFile(
|
||||||
|
'/etc/issue').strip().split("\n")[0].replace('\\n', '').replace('\l', '').strip()
|
||||||
|
else:
|
||||||
version = version.replace('release ', '').strip()
|
version = version.replace('release ', '').strip()
|
||||||
return version
|
return version
|
||||||
|
|
||||||
os_series = '/etc/os-release'
|
|
||||||
if os.path.exists(os_series):
|
|
||||||
version = mw.execShell(
|
|
||||||
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
|
|
||||||
return version[0].strip()
|
|
||||||
|
|
||||||
return '未识别系统信息'
|
|
||||||
|
|
||||||
def getBootTime(self):
|
def getBootTime(self):
|
||||||
# 取系统启动时间
|
# 取系统启动时间
|
||||||
uptime = mw.readFile('/proc/uptime')
|
start_time = psutil.boot_time()
|
||||||
if uptime == False:
|
run_time = time.time() - start_time
|
||||||
start_time = psutil.boot_time()
|
# conf = public.readFile('/proc/uptime').split()
|
||||||
run_time = time.time() - start_time
|
|
||||||
else:
|
|
||||||
run_time = uptime.split()[0]
|
|
||||||
tStr = float(run_time)
|
tStr = float(run_time)
|
||||||
min = tStr / 60
|
min = tStr / 60
|
||||||
hours = min / 60
|
hours = min / 60
|
||||||
days = math.floor(hours / 24)
|
days = math.floor(hours / 24)
|
||||||
hours = math.floor(hours - (days * 24))
|
hours = math.floor(hours - (days * 24))
|
||||||
min = math.floor(min - (days * 60 * 24) - (hours * 60))
|
min = math.floor(min - (days * 60 * 24) - (hours * 60))
|
||||||
return mw.getInfo('已不间断运行: {1}天{2}小时{3}分钟', (str(int(days)), str(int(hours)), str(int(min))))
|
return public.getInfo('已不间断运行: {1}天{2}小时{3}分钟', (str(int(days)), str(int(hours)), str(int(min))))
|
||||||
|
|
||||||
def getCpuInfo(self, interval=1):
|
def getCpuInfo(self, interval=1):
|
||||||
# 取CPU信息
|
# 取CPU信息
|
||||||
@@ -279,10 +172,10 @@ class system_api:
|
|||||||
used = psutil.cpu_percent(interval=interval)
|
used = psutil.cpu_percent(interval=interval)
|
||||||
return used, cpuCount
|
return used, cpuCount
|
||||||
|
|
||||||
def getMemInfo(self):
|
def getMemInfo(self, get=None):
|
||||||
# 取内存信息
|
# 取内存信息
|
||||||
mem = psutil.virtual_memory()
|
mem = psutil.virtual_memory()
|
||||||
if mw.getOs() == 'darwin':
|
if public.getOs() == 'darwin':
|
||||||
memInfo = {
|
memInfo = {
|
||||||
'memTotal': mem.total / 1024 / 1024
|
'memTotal': mem.total / 1024 / 1024
|
||||||
}
|
}
|
||||||
@@ -306,7 +199,7 @@ class system_api:
|
|||||||
import psutil
|
import psutil
|
||||||
mem = psutil.virtual_memory()
|
mem = psutil.virtual_memory()
|
||||||
|
|
||||||
if mw.getOs() == 'darwin':
|
if public.getOs() == 'darwin':
|
||||||
return mem.percent
|
return mem.percent
|
||||||
|
|
||||||
memInfo = {'memTotal': mem.total / 1024 / 1024, 'memFree': mem.free / 1024 / 1024,
|
memInfo = {'memTotal': mem.total / 1024 / 1024, 'memFree': mem.free / 1024 / 1024,
|
||||||
@@ -315,14 +208,11 @@ class system_api:
|
|||||||
memInfo['memBuffers'] - memInfo['memCached']
|
memInfo['memBuffers'] - memInfo['memCached']
|
||||||
tmp1 = memInfo['memTotal'] / 100
|
tmp1 = memInfo['memTotal'] / 100
|
||||||
return (tmp / tmp1)
|
return (tmp / tmp1)
|
||||||
except Exception as ex:
|
except Exception, ex:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def getDiskInfo(self):
|
def getDiskInfo(self, get=None):
|
||||||
info = self.getDiskInfo2()
|
return self.getDiskInfo2()
|
||||||
if len(info) != 0:
|
|
||||||
return info
|
|
||||||
|
|
||||||
# 取磁盘分区信息
|
# 取磁盘分区信息
|
||||||
diskIo = psutil.disk_partitions()
|
diskIo = psutil.disk_partitions()
|
||||||
diskInfo = []
|
diskInfo = []
|
||||||
@@ -334,24 +224,22 @@ class system_api:
|
|||||||
continue
|
continue
|
||||||
tmp = {}
|
tmp = {}
|
||||||
tmp['path'] = disk[1]
|
tmp['path'] = disk[1]
|
||||||
size_tmp = psutil.disk_usage(disk[1])
|
tmp['size'] = psutil.disk_usage(disk[1])
|
||||||
tmp['size'] = [mw.toSize(size_tmp[0]), mw.toSize(
|
|
||||||
size_tmp[1]), mw.toSize(size_tmp[2]), str(size_tmp[3]) + '%']
|
|
||||||
diskInfo.append(tmp)
|
diskInfo.append(tmp)
|
||||||
return diskInfo
|
return diskInfo
|
||||||
|
|
||||||
def getDiskInfo2(self):
|
def getDiskInfo2(self):
|
||||||
# 取磁盘分区信息
|
# 取磁盘分区信息
|
||||||
temp = mw.execShell(
|
temp = public.execShell(
|
||||||
"df -h -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
|
"df -h -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
|
||||||
tempInodes = mw.execShell(
|
tempInodes = public.execShell(
|
||||||
"df -i -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
|
"df -i -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
|
||||||
temp1 = temp.split('\n')
|
temp1 = temp.split('\n')
|
||||||
tempInodes1 = tempInodes.split('\n')
|
tempInodes1 = tempInodes.split('\n')
|
||||||
diskInfo = []
|
diskInfo = []
|
||||||
n = 0
|
n = 0
|
||||||
cuts = ['/mnt/cdrom', '/boot', '/boot/efi', '/dev',
|
cuts = ['/mnt/cdrom', '/boot', '/boot/efi', '/dev',
|
||||||
'/dev/shm', '/zroot', '/run/lock', '/run', '/run/shm', '/run/user']
|
'/dev/shm', '/run/lock', '/run', '/run/shm', '/run/user']
|
||||||
for tmp in temp1:
|
for tmp in temp1:
|
||||||
n += 1
|
n += 1
|
||||||
inodes = tempInodes1[n - 1].split()
|
inodes = tempInodes1[n - 1].split()
|
||||||
@@ -371,7 +259,16 @@ class system_api:
|
|||||||
tmp1 = [disk[1], disk[2], disk[3], disk[4]]
|
tmp1 = [disk[1], disk[2], disk[3], disk[4]]
|
||||||
arr['size'] = tmp1
|
arr['size'] = tmp1
|
||||||
arr['inodes'] = [inodes[1], inodes[2], inodes[3], inodes[4]]
|
arr['inodes'] = [inodes[1], inodes[2], inodes[3], inodes[4]]
|
||||||
diskInfo.append(arr)
|
if disk[5] == '/':
|
||||||
|
bootLog = os.getcwd() + '/tmp/panelBoot.pl'
|
||||||
|
if disk[2].find('M') != -1:
|
||||||
|
if os.path.exists(bootLog):
|
||||||
|
os.system('rm -f ' + bootLog)
|
||||||
|
else:
|
||||||
|
if not os.path.exists(bootLog):
|
||||||
|
pass
|
||||||
|
if inodes[2] != '0':
|
||||||
|
diskInfo.append(arr)
|
||||||
return diskInfo
|
return diskInfo
|
||||||
|
|
||||||
# 清理系统垃圾
|
# 清理系统垃圾
|
||||||
@@ -405,7 +302,7 @@ class system_api:
|
|||||||
shutil.rmtree(filename)
|
shutil.rmtree(filename)
|
||||||
else:
|
else:
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
print('mail clear ok')
|
print '\t\033[1;32m[OK]\033[0m'
|
||||||
num += 1
|
num += 1
|
||||||
total += size
|
total += size
|
||||||
count += num
|
count += num
|
||||||
@@ -414,10 +311,10 @@ class system_api:
|
|||||||
# 清理其它
|
# 清理其它
|
||||||
def clearOther(self):
|
def clearOther(self):
|
||||||
clearPath = [
|
clearPath = [
|
||||||
{'path': '/www/server/mdserver-web', 'find': 'testDisk_'},
|
{'path': '/www/server/panel', 'find': 'testDisk_'},
|
||||||
{'path': '/www/wwwlogs', 'find': 'log'},
|
{'path': '/www/wwwlogs', 'find': 'log'},
|
||||||
{'path': '/tmp', 'find': 'panelBoot.pl'},
|
{'path': '/tmp', 'find': 'panelBoot.pl'},
|
||||||
{'path': '/www/server/mdserver-web/install', 'find': '.rpm'}
|
{'path': '/www/server/panel/install', 'find': '.rpm'}
|
||||||
]
|
]
|
||||||
|
|
||||||
total = count = 0
|
total = count = 0
|
||||||
@@ -433,11 +330,11 @@ class system_api:
|
|||||||
else:
|
else:
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
count += 1
|
count += 1
|
||||||
mw.serviceReload()
|
public.serviceReload()
|
||||||
os.system('echo > /tmp/panelBoot.pl')
|
os.system('echo > /tmp/panelBoot.pl')
|
||||||
return total, count
|
return total, count
|
||||||
|
|
||||||
def getNetWork(self):
|
def getNetWork(self, get=None):
|
||||||
# return self.GetNetWorkApi(get);
|
# return self.GetNetWorkApi(get);
|
||||||
# 取网络流量信息
|
# 取网络流量信息
|
||||||
try:
|
try:
|
||||||
@@ -465,25 +362,25 @@ class system_api:
|
|||||||
session['otime'] = time.time()
|
session['otime'] = time.time()
|
||||||
|
|
||||||
networkInfo['cpu'] = self.getCpuInfo()
|
networkInfo['cpu'] = self.getCpuInfo()
|
||||||
networkInfo['load'] = self.getLoadAverage()
|
networkInfo['load'] = self.getLoadAverage(get)
|
||||||
networkInfo['mem'] = self.getMemInfo()
|
networkInfo['mem'] = self.getMemInfo(get)
|
||||||
|
|
||||||
return networkInfo
|
return networkInfo
|
||||||
except Exception as e:
|
except Exception, e:
|
||||||
# print(e)
|
print e
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getNetWorkApi(self):
|
def getNetWorkApi(self, get=None):
|
||||||
# 取网络流量信息
|
# 取网络流量信息
|
||||||
try:
|
try:
|
||||||
tmpfile = 'data/network.temp'
|
tmpfile = 'data/network.temp'
|
||||||
networkIo = psutil.net_io_counters()[:4]
|
networkIo = psutil.net_io_counters()[:4]
|
||||||
|
|
||||||
if not os.path.exists(tmpfile):
|
if not os.path.exists(tmpfile):
|
||||||
mw.writeFile(tmpfile, str(
|
public.writeFile(tmpfile, str(
|
||||||
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
|
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
|
||||||
|
|
||||||
lastValue = mw.readFile(tmpfile).split('|')
|
lastValue = public.readFile(tmpfile).split('|')
|
||||||
|
|
||||||
ntime = time.time()
|
ntime = time.time()
|
||||||
networkInfo = {}
|
networkInfo = {}
|
||||||
@@ -496,7 +393,7 @@ class system_api:
|
|||||||
networkInfo['downPackets'] = networkIo[3]
|
networkInfo['downPackets'] = networkIo[3]
|
||||||
networkInfo['upPackets'] = networkIo[2]
|
networkInfo['upPackets'] = networkIo[2]
|
||||||
|
|
||||||
mw.writeFile(tmpfile, str(
|
public.writeFile(tmpfile, str(
|
||||||
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
|
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
|
||||||
|
|
||||||
# networkInfo['cpu'] = self.GetCpuInfo(0.1)
|
# networkInfo['cpu'] = self.GetCpuInfo(0.1)
|
||||||
@@ -504,26 +401,43 @@ class system_api:
|
|||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def restartServer(self, get):
|
||||||
|
if not public.IsRestart():
|
||||||
|
return public.returnMsg(False, 'EXEC_ERR_TASK')
|
||||||
|
public.ExecShell("sync && /etc/init.d/bt stop && init 6 &")
|
||||||
|
return public.returnMsg(True, 'SYS_REBOOT')
|
||||||
|
|
||||||
|
# 释放内存
|
||||||
|
def reMemory(self, get):
|
||||||
|
os.system('sync')
|
||||||
|
scriptFile = 'script/rememory.sh'
|
||||||
|
if not os.path.exists(scriptFile):
|
||||||
|
public.downloadFile(web.ctx.session.home +
|
||||||
|
'/script/rememory.sh', scriptFile)
|
||||||
|
public.ExecShell("/bin/bash " + self.setupPath +
|
||||||
|
'/panel/' + scriptFile)
|
||||||
|
return self.GetMemInfo()
|
||||||
|
|
||||||
def getNetWorkIoData(self, start, end):
|
def getNetWorkIoData(self, start, end):
|
||||||
# 取指定时间段的网络Io
|
# 取指定时间段的网络Io
|
||||||
data = mw.M('network').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
|
data = public.M('network').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
|
||||||
'id,up,down,total_up,total_down,down_packets,up_packets,addtime').order('id asc').select()
|
'id,up,down,total_up,total_down,down_packets,up_packets,addtime').order('id asc').select()
|
||||||
return self.toAddtime(data)
|
return self.toAddtime(data)
|
||||||
|
|
||||||
def getDiskIoData(self, start, end):
|
def getDiskIoData(self, start, end):
|
||||||
# 取指定时间段的磁盘Io
|
# 取指定时间段的磁盘Io
|
||||||
data = mw.M('diskio').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
|
data = public.M('diskio').dbfile('system').where("addtime>=? AND addtime<=?", (start, end)).field(
|
||||||
'id,read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime').order('id asc').select()
|
'id,read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime').order('id asc').select()
|
||||||
return self.toAddtime(data)
|
return self.toAddtime(data)
|
||||||
|
|
||||||
def getCpuIoData(self, start, end):
|
def getCpuIoData(self, start, end):
|
||||||
# 取指定时间段的CpuIo
|
# 取指定时间段的CpuIo
|
||||||
data = mw.M('cpuio').dbfile('system').where("addtime>=? AND addtime<=?",
|
data = public.M('cpuio').dbfile('system').where("addtime>=? AND addtime<=?",
|
||||||
(start, end)).field('id,pro,mem,addtime').order('id asc').select()
|
(start, end)).field('id,pro,mem,addtime').order('id asc').select()
|
||||||
return self.toAddtime(data, True)
|
return self.toAddtime(data, True)
|
||||||
|
|
||||||
def getLoadAverageData(self, start, end):
|
def getLoadAverageData(self, start, end):
|
||||||
data = mw.M('load_average').dbfile('system').where("addtime>=? AND addtime<=?", (
|
data = public.M('load_average').dbfile('system').where("addtime>=? AND addtime<=?", (
|
||||||
start, end)).field('id,pro,one,five,fifteen,addtime').order('id asc').select()
|
start, end)).field('id,pro,one,five,fifteen,addtime').order('id asc').select()
|
||||||
return self.toAddtime(data)
|
return self.toAddtime(data)
|
||||||
|
|
||||||
@@ -569,151 +483,70 @@ class system_api:
|
|||||||
filename = 'data/control.conf'
|
filename = 'data/control.conf'
|
||||||
|
|
||||||
if stype == '0':
|
if stype == '0':
|
||||||
mw.execShell("rm -f " + filename)
|
public.execShell("rm -f " + filename)
|
||||||
elif stype == '1':
|
elif stype == '1':
|
||||||
_day = int(day)
|
_day = int(day)
|
||||||
if _day < 1:
|
if _day < 1:
|
||||||
return mw.returnJson(False, "设置失败!")
|
return public.returnJson(False, "设置失败!")
|
||||||
mw.writeFile(filename, day)
|
public.writeFile(filename, day)
|
||||||
elif stype == 'del':
|
elif stype == 'del':
|
||||||
if not mw.isRestart():
|
if not public.isRestart():
|
||||||
return mw.returnJson(False, '请等待所有安装任务完成再执行')
|
return public.returnJson(False, '请等待所有安装任务完成再执行')
|
||||||
os.remove("data/system.db")
|
os.remove("data/system.db")
|
||||||
|
|
||||||
sql = db.Sql().dbfile('system')
|
sql = db.Sql().dbfile('system')
|
||||||
csql = mw.readFile('data/sql/system.sql')
|
csql = public.readFile('data/sql/system.sql')
|
||||||
csql_list = csql.split(';')
|
csql_list = csql.split(';')
|
||||||
for index in range(len(csql_list)):
|
for index in range(len(csql_list)):
|
||||||
sql.execute(csql_list[index], ())
|
sql.execute(csql_list[index], ())
|
||||||
return mw.returnJson(True, "监控服务已关闭")
|
return public.returnJson(True, "监控服务已关闭")
|
||||||
else:
|
else:
|
||||||
data = {}
|
data = {}
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
try:
|
try:
|
||||||
data['day'] = int(mw.readFile(filename))
|
data['day'] = int(public.readFile(filename))
|
||||||
except:
|
except:
|
||||||
data['day'] = 30
|
data['day'] = 30
|
||||||
data['status'] = True
|
data['status'] = True
|
||||||
else:
|
else:
|
||||||
data['day'] = 30
|
data['day'] = 30
|
||||||
data['status'] = False
|
data['status'] = False
|
||||||
return mw.getJson(data)
|
return public.getJson(data)
|
||||||
|
|
||||||
return mw.returnJson(True, "设置成功!")
|
return public.returnJson(True, "设置成功!")
|
||||||
|
|
||||||
def versionDiff(self, old, new):
|
# 更新服务
|
||||||
'''
|
def updateServer(self, stype):
|
||||||
test 测试
|
|
||||||
new 有新版本
|
|
||||||
none 没有新版本
|
|
||||||
'''
|
|
||||||
new_list = new.split('.')
|
|
||||||
if len(new_list) > 3:
|
|
||||||
return 'test'
|
|
||||||
|
|
||||||
old_list = old.split('.')
|
|
||||||
ret = 'none'
|
|
||||||
|
|
||||||
isHasNew = True
|
|
||||||
if int(new_list[0]) == int(old_list[0]) and int(new_list[1]) == int(old_list[1]) and int(new_list[2]) == int(old_list[2]):
|
|
||||||
isHasNew = False
|
|
||||||
|
|
||||||
if isHasNew:
|
|
||||||
return 'new'
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def getServerInfo(self):
|
|
||||||
import urllib.request
|
|
||||||
import ssl
|
|
||||||
upAddr = 'https://api.github.com/repos/midoks/mdserver-web/releases/latest'
|
|
||||||
try:
|
try:
|
||||||
context = ssl._create_unverified_context()
|
if not public.isRestart():
|
||||||
req = urllib.request.urlopen(upAddr, context=context, timeout=3)
|
return public.returnMsg(False, '请等待所有安装任务完成再执行!')
|
||||||
result = req.read().decode('utf-8')
|
|
||||||
version = json.loads(result)
|
|
||||||
return version
|
|
||||||
except Exception as e:
|
|
||||||
print('getServerInfo', e)
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def updateServer(self, stype, version=''):
|
|
||||||
# 更新服务
|
|
||||||
try:
|
|
||||||
if not mw.isRestart():
|
|
||||||
return mw.returnJson(False, '请等待所有安装任务完成再执行!')
|
|
||||||
|
|
||||||
version_new_info = self.getServerInfo()
|
|
||||||
version_now = config_api.config_api().getVersion()
|
|
||||||
|
|
||||||
new_ver = version_new_info['name']
|
|
||||||
|
|
||||||
if stype == 'check':
|
if stype == 'check':
|
||||||
if not 'name' in version_new_info:
|
public.httpGet('')
|
||||||
return mw.returnJson(False, '服务器数据或网络有问题!')
|
|
||||||
|
|
||||||
diff = self.versionDiff(version_now, new_ver)
|
|
||||||
if diff == 'new':
|
|
||||||
return mw.returnJson(True, '有新版本!', new_ver)
|
|
||||||
elif diff == 'test':
|
|
||||||
return mw.returnJson(True, '有测试版本!', new_ver)
|
|
||||||
else:
|
|
||||||
return mw.returnJson(False, '已经是最新,无需更新!')
|
|
||||||
|
|
||||||
if stype == 'info':
|
|
||||||
if not 'name' in version_new_info:
|
|
||||||
return mw.returnJson(False, '服务器数据有问题!')
|
|
||||||
diff = self.versionDiff(version_now, new_ver)
|
|
||||||
data = {}
|
|
||||||
data['version'] = new_ver
|
|
||||||
data['content'] = version_new_info[
|
|
||||||
'body'].replace("\n", "<br/>")
|
|
||||||
return mw.returnJson(True, '更新信息!', data)
|
|
||||||
|
|
||||||
if stype == 'update':
|
|
||||||
if version == '':
|
|
||||||
return mw.returnJson(False, '缺少版本信息!')
|
|
||||||
|
|
||||||
if new_ver != version:
|
|
||||||
return mw.returnJson(False, '更新失败,请重试!')
|
|
||||||
|
|
||||||
toPath = mw.getRootDir() + '/temp'
|
|
||||||
if not os.path.exists(toPath):
|
|
||||||
mw.execShell('mkdir -p ' + toPath)
|
|
||||||
|
|
||||||
newUrl = "https://github.com/midoks/mdserver-web/archive/refs/tags/" + version + ".zip"
|
|
||||||
|
|
||||||
dist_mw = toPath + '/mw.zip'
|
|
||||||
if not os.path.exists(dist_mw):
|
|
||||||
mw.execShell(
|
|
||||||
'wget --no-check-certificate -O ' + dist_mw + ' ' + newUrl)
|
|
||||||
|
|
||||||
dist_to = toPath + "/mdserver-web-" + version
|
|
||||||
if not os.path.exists(dist_to):
|
|
||||||
os.system('unzip -o ' + toPath +
|
|
||||||
'/mw.zip' + ' -d ' + toPath)
|
|
||||||
|
|
||||||
cmd_cp = 'cp -rf ' + toPath + '/mdserver-web-' + \
|
|
||||||
version + '/* ' + mw.getServerDir() + '/mdserver-web'
|
|
||||||
mw.execShell(cmd_cp)
|
|
||||||
|
|
||||||
mw.execShell('rm -rf ' + toPath + '/mdserver-web-' + version)
|
|
||||||
mw.execShell('rm -rf ' + toPath + '/mw.zip')
|
|
||||||
|
|
||||||
self.restartMw()
|
|
||||||
return mw.returnJson(True, '安装更新成功!')
|
|
||||||
|
|
||||||
return mw.returnJson(False, '已经是最新,无需更新!')
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
# print('updateServer', ex)
|
return public.returnJson(False, "连接服务器失败!")
|
||||||
return mw.returnJson(False, "连接服务器失败!" + str(ex))
|
|
||||||
|
# 重启面板
|
||||||
|
def reWeb(self, get):
|
||||||
|
# if not public.IsRestart(): return
|
||||||
|
# public.returnMsg(False,'EXEC_ERR_TASK');
|
||||||
|
# public.ExecShell('/etc/init.d/bt restart &')
|
||||||
|
return True
|
||||||
|
|
||||||
# 修复面板
|
# 修复面板
|
||||||
def repPanel(self, get):
|
def repPanel(self, get):
|
||||||
vp = ''
|
vp = ''
|
||||||
if mw.readFile('/www/server/mdserver-web/class/common.py').find('checkSafe') != -1:
|
if public.readFile('/www/server/panel/class/common.py').find('checkSafe') != -1:
|
||||||
vp = '_pro'
|
vp = '_pro'
|
||||||
mw.ExecShell("wget -O update.sh " + mw.get_url() +
|
public.ExecShell("wget -O update.sh " + public.get_url() +
|
||||||
"/install/update" + vp + ".sh && bash update.sh")
|
"/install/update" + vp + ".sh && bash update.sh")
|
||||||
|
if hasattr(web.ctx.session, 'getCloudPlugin'):
|
||||||
|
del(web.ctx.session['getCloudPlugin'])
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 升级到专业版
|
||||||
|
def updatePro(self, get):
|
||||||
|
public.ExecShell("wget -O update.sh " + public.get_url() +
|
||||||
|
"/install/update_pro.sh && bash update.sh pro")
|
||||||
if hasattr(web.ctx.session, 'getCloudPlugin'):
|
if hasattr(web.ctx.session, 'getCloudPlugin'):
|
||||||
del(web.ctx.session['getCloudPlugin'])
|
del(web.ctx.session['getCloudPlugin'])
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import mw
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
import pwd
|
|
||||||
|
|
||||||
|
|
||||||
from flask import request
|
|
||||||
|
|
||||||
|
|
||||||
class task_api:
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def countApi(self):
|
|
||||||
c = mw.M('tasks').where("status!=?", ('1',)).count()
|
|
||||||
return str(c)
|
|
||||||
|
|
||||||
def listApi(self):
|
|
||||||
|
|
||||||
p = request.form.get('p', '1')
|
|
||||||
limit = request.form.get('limit', '10').strip()
|
|
||||||
search = request.form.get('search', '').strip()
|
|
||||||
|
|
||||||
start = (int(p) - 1) * int(limit)
|
|
||||||
limit_str = str(start) + ',' + str(limit)
|
|
||||||
|
|
||||||
_list = mw.M('tasks').where('', ()).field(
|
|
||||||
'id,name,type,status,addtime,start,end').limit(limit_str).order('id desc').select()
|
|
||||||
_ret = {}
|
|
||||||
_ret['data'] = _list
|
|
||||||
|
|
||||||
count = mw.M('tasks').where('', ()).count()
|
|
||||||
_page = {}
|
|
||||||
_page['count'] = count
|
|
||||||
_page['tojs'] = 'remind'
|
|
||||||
_page['p'] = p
|
|
||||||
|
|
||||||
# return data
|
|
||||||
_ret['count'] = count
|
|
||||||
_ret['page'] = mw.getPage(_page)
|
|
||||||
return mw.getJson(_ret)
|
|
||||||
|
|
||||||
def getExecLogApi(self):
|
|
||||||
file = os.getcwd() + "/tmp/panelExec.log"
|
|
||||||
v = mw.getLastLine(file, 100)
|
|
||||||
return v
|
|
||||||
|
|
||||||
def getTaskSpeedApi(self):
|
|
||||||
tempFile = mw.getRunDir() + '/tmp/panelExec.log'
|
|
||||||
freshFile = mw.getRunDir() + '/tmp/panelFresh'
|
|
||||||
|
|
||||||
find = mw.M('tasks').where('status=? OR status=?',
|
|
||||||
('-1', '0')).field('id,type,name,execstr').find()
|
|
||||||
if not len(find):
|
|
||||||
return mw.returnJson(False, '当前没有任务队列在执行-2!')
|
|
||||||
|
|
||||||
mw.triggerTask()
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['name'] = find['name']
|
|
||||||
data['execstr'] = find['execstr']
|
|
||||||
if find['type'] == 'download':
|
|
||||||
readLine = ""
|
|
||||||
for i in range(3):
|
|
||||||
try:
|
|
||||||
readLine = mw.readFile(tempFile)
|
|
||||||
if len(readLine) > 10:
|
|
||||||
data['msg'] = json.loads(readLine)
|
|
||||||
data['isDownload'] = True
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
if i == 2:
|
|
||||||
mw.M('tasks').where("id=?", (find['id'],)).save(
|
|
||||||
'status', ('0',))
|
|
||||||
return mw.returnJson(False, '当前没有任务队列在执行-4:' + str(e))
|
|
||||||
time.sleep(0.5)
|
|
||||||
else:
|
|
||||||
data['msg'] = mw.getLastLine(tempFile, 10)
|
|
||||||
data['isDownload'] = False
|
|
||||||
|
|
||||||
data['task'] = mw.M('tasks').where("status!=?", ('1',)).field(
|
|
||||||
'id,status,name,type').order("id asc").select()
|
|
||||||
return mw.getJson(data)
|
|
||||||
@@ -75,7 +75,7 @@ class vieCode:
|
|||||||
if not self.__inNoise:
|
if not self.__inNoise:
|
||||||
return
|
return
|
||||||
font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5))
|
font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5))
|
||||||
for i in range(5):
|
for i in xrange(5):
|
||||||
# 杂点颜色
|
# 杂点颜色
|
||||||
noiseColor = (random.randint(150, 200), random.randint(
|
noiseColor = (random.randint(150, 200), random.randint(
|
||||||
150, 200), random.randint(150, 200))
|
150, 200), random.randint(150, 200))
|
||||||
@@ -104,9 +104,9 @@ class vieCode:
|
|||||||
# 画曲线
|
# 画曲线
|
||||||
color = (random.randint(30, 150), random.randint(
|
color = (random.randint(30, 150), random.randint(
|
||||||
30, 150), random.randint(30, 150))
|
30, 150), random.randint(30, 150))
|
||||||
for x in range(xend):
|
for x in xrange(xend):
|
||||||
if w != 0:
|
if w != 0:
|
||||||
for k in range(int(self.__heigth / 10)):
|
for k in xrange(int(self.__heigth / 10)):
|
||||||
y = a * math.sin(w * x + f) + b + self.__heigth / 2
|
y = a * math.sin(w * x + f) + b + self.__heigth / 2
|
||||||
i = int(self.__fontSize / 5)
|
i = int(self.__fontSize / 5)
|
||||||
while i > 0:
|
while i > 0:
|
||||||
@@ -120,7 +120,7 @@ class vieCode:
|
|||||||
font = ImageFont.truetype(self.__fontPatn, self.__fontSize)
|
font = ImageFont.truetype(self.__fontPatn, self.__fontSize)
|
||||||
x = 0
|
x = 0
|
||||||
# 打印字符到画板
|
# 打印字符到画板
|
||||||
for i in range(self.__length):
|
for i in xrange(self.__length):
|
||||||
# 设置字体随机颜色
|
# 设置字体随机颜色
|
||||||
color = (random.randint(30, 150), random.randint(
|
color = (random.randint(30, 150), random.randint(
|
||||||
30, 150), random.randint(30, 150))
|
30, 150), random.randint(30, 150))
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
- fcgi-client.py
|
|
||||||
```
|
|
||||||
https://pypi.org/project/flup6/1.1.1/#files
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,408 +0,0 @@
|
|||||||
# Copyright (c) 2006 Allan Saddi <allan@saddi.com>
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# Redistribution and use in source and binary forms, with or without
|
|
||||||
# modification, are permitted provided that the following conditions
|
|
||||||
# are met:
|
|
||||||
# 1. Redistributions of source code must retain the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer.
|
|
||||||
# 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
# notice, this list of conditions and the following disclaimer in the
|
|
||||||
# documentation and/or other materials provided with the distribution.
|
|
||||||
#
|
|
||||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
# SUCH DAMAGE.
|
|
||||||
#
|
|
||||||
# $Id$
|
|
||||||
#
|
|
||||||
# Copyright (c) 2011 Vladimir Rusinov <vladimir@greenmice.info>
|
|
||||||
|
|
||||||
__author__ = 'Allan Saddi <allan@saddi.com>'
|
|
||||||
__version__ = '$Revision$'
|
|
||||||
import sys
|
|
||||||
import select
|
|
||||||
import struct
|
|
||||||
import socket
|
|
||||||
import errno
|
|
||||||
import types
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['FCGIApp']
|
|
||||||
|
|
||||||
# Constants from the spec.
|
|
||||||
FCGI_LISTENSOCK_FILENO = 0
|
|
||||||
|
|
||||||
FCGI_HEADER_LEN = 8
|
|
||||||
|
|
||||||
FCGI_VERSION_1 = 1
|
|
||||||
|
|
||||||
FCGI_BEGIN_REQUEST = 1
|
|
||||||
FCGI_ABORT_REQUEST = 2
|
|
||||||
FCGI_END_REQUEST = 3
|
|
||||||
FCGI_PARAMS = 4
|
|
||||||
FCGI_STDIN = 5
|
|
||||||
FCGI_STDOUT = 6
|
|
||||||
FCGI_STDERR = 7
|
|
||||||
FCGI_DATA = 8
|
|
||||||
FCGI_GET_VALUES = 9
|
|
||||||
FCGI_GET_VALUES_RESULT = 10
|
|
||||||
FCGI_UNKNOWN_TYPE = 11
|
|
||||||
FCGI_MAXTYPE = FCGI_UNKNOWN_TYPE
|
|
||||||
|
|
||||||
FCGI_NULL_REQUEST_ID = 0
|
|
||||||
|
|
||||||
FCGI_KEEP_CONN = 1
|
|
||||||
|
|
||||||
FCGI_RESPONDER = 1
|
|
||||||
FCGI_AUTHORIZER = 2
|
|
||||||
FCGI_FILTER = 3
|
|
||||||
|
|
||||||
FCGI_REQUEST_COMPLETE = 0
|
|
||||||
FCGI_CANT_MPX_CONN = 1
|
|
||||||
FCGI_OVERLOADED = 2
|
|
||||||
FCGI_UNKNOWN_ROLE = 3
|
|
||||||
|
|
||||||
FCGI_MAX_CONNS = 'FCGI_MAX_CONNS'
|
|
||||||
FCGI_MAX_REQS = 'FCGI_MAX_REQS'
|
|
||||||
FCGI_MPXS_CONNS = 'FCGI_MPXS_CONNS'
|
|
||||||
|
|
||||||
FCGI_Header = '!BBHHBx'
|
|
||||||
FCGI_BeginRequestBody = '!HB5x'
|
|
||||||
FCGI_EndRequestBody = '!LB3x'
|
|
||||||
FCGI_UnknownTypeBody = '!B7x'
|
|
||||||
|
|
||||||
FCGI_BeginRequestBody_LEN = struct.calcsize(FCGI_BeginRequestBody)
|
|
||||||
FCGI_EndRequestBody_LEN = struct.calcsize(FCGI_EndRequestBody)
|
|
||||||
FCGI_UnknownTypeBody_LEN = struct.calcsize(FCGI_UnknownTypeBody)
|
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
import time
|
|
||||||
|
|
||||||
# Set non-zero to write debug output to a file.
|
|
||||||
DEBUG = 0
|
|
||||||
DEBUGLOG = '/www/server/mdserver-web/logs/fastcgi.log'
|
|
||||||
|
|
||||||
def _debug(level, msg):
|
|
||||||
if DEBUG < level:
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
f = open(DEBUGLOG, 'a')
|
|
||||||
f.write('%sfcgi: %s\n' % (time.ctime()[4:-4], msg))
|
|
||||||
f.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def decode_pair(s, pos=0):
|
|
||||||
"""
|
|
||||||
Decodes a name/value pair.
|
|
||||||
|
|
||||||
The number of bytes decoded as well as the name/value pair
|
|
||||||
are returned.
|
|
||||||
"""
|
|
||||||
nameLength = ord(s[pos])
|
|
||||||
if nameLength & 128:
|
|
||||||
nameLength = struct.unpack('!L', s[pos:pos + 4])[0] & 0x7fffffff
|
|
||||||
pos += 4
|
|
||||||
else:
|
|
||||||
pos += 1
|
|
||||||
|
|
||||||
valueLength = ord(s[pos])
|
|
||||||
if valueLength & 128:
|
|
||||||
valueLength = struct.unpack('!L', s[pos:pos + 4])[0] & 0x7fffffff
|
|
||||||
pos += 4
|
|
||||||
else:
|
|
||||||
pos += 1
|
|
||||||
|
|
||||||
name = s[pos:pos + nameLength]
|
|
||||||
pos += nameLength
|
|
||||||
value = s[pos:pos + valueLength]
|
|
||||||
pos += valueLength
|
|
||||||
|
|
||||||
return (pos, (name, value))
|
|
||||||
|
|
||||||
|
|
||||||
def encode_pair(name, value):
|
|
||||||
"""
|
|
||||||
Encodes a name/value pair.
|
|
||||||
|
|
||||||
The encoded string is returned.
|
|
||||||
"""
|
|
||||||
nameLength = len(name)
|
|
||||||
if nameLength < 128:
|
|
||||||
s = chr(nameLength).encode()
|
|
||||||
else:
|
|
||||||
s = struct.pack('!L', nameLength | 0x80000000)
|
|
||||||
|
|
||||||
valueLength = len(value)
|
|
||||||
if valueLength < 128:
|
|
||||||
s += chr(valueLength).encode()
|
|
||||||
else:
|
|
||||||
s += struct.pack('!L', valueLength | 0x80000000)
|
|
||||||
|
|
||||||
return s + name + value
|
|
||||||
|
|
||||||
|
|
||||||
class Record(object):
|
|
||||||
"""
|
|
||||||
A FastCGI Record.
|
|
||||||
|
|
||||||
Used for encoding/decoding records.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, type=FCGI_UNKNOWN_TYPE, requestId=FCGI_NULL_REQUEST_ID):
|
|
||||||
self.version = FCGI_VERSION_1
|
|
||||||
self.type = type
|
|
||||||
self.requestId = requestId
|
|
||||||
self.contentLength = 0
|
|
||||||
self.paddingLength = 0
|
|
||||||
self.contentData = ''
|
|
||||||
|
|
||||||
def _recvall(sock, length):
|
|
||||||
"""
|
|
||||||
Attempts to receive length bytes from a socket, blocking if necessary.
|
|
||||||
(Socket may be blocking or non-blocking.)
|
|
||||||
"""
|
|
||||||
dataList = []
|
|
||||||
recvLen = 0
|
|
||||||
while length:
|
|
||||||
try:
|
|
||||||
data = sock.recv(length)
|
|
||||||
except socket.error as e:
|
|
||||||
if e[0] == errno.EAGAIN:
|
|
||||||
select.select([sock], [], [])
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
if not data: # EOF
|
|
||||||
break
|
|
||||||
dataList.append(data)
|
|
||||||
dataLen = len(data)
|
|
||||||
recvLen += dataLen
|
|
||||||
length -= dataLen
|
|
||||||
return b''.join(dataList), recvLen
|
|
||||||
_recvall = staticmethod(_recvall)
|
|
||||||
|
|
||||||
def read(self, sock):
|
|
||||||
"""Read and decode a Record from a socket."""
|
|
||||||
try:
|
|
||||||
header, length = self._recvall(sock, FCGI_HEADER_LEN)
|
|
||||||
except:
|
|
||||||
raise EOFError
|
|
||||||
|
|
||||||
if length < FCGI_HEADER_LEN:
|
|
||||||
raise EOFError
|
|
||||||
|
|
||||||
self.version, self.type, self.requestId, self.contentLength, \
|
|
||||||
self.paddingLength = struct.unpack(FCGI_Header, header)
|
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
_debug(9, 'read: fd = %d, type = %d, requestId = %d, '
|
|
||||||
'contentLength = %d' %
|
|
||||||
(sock.fileno(), self.type, self.requestId,
|
|
||||||
self.contentLength))
|
|
||||||
|
|
||||||
if self.contentLength:
|
|
||||||
try:
|
|
||||||
self.contentData, length = self._recvall(sock,
|
|
||||||
self.contentLength)
|
|
||||||
except:
|
|
||||||
raise EOFError
|
|
||||||
|
|
||||||
if length < self.contentLength:
|
|
||||||
raise EOFError
|
|
||||||
|
|
||||||
if self.paddingLength:
|
|
||||||
try:
|
|
||||||
self._recvall(sock, self.paddingLength)
|
|
||||||
except:
|
|
||||||
raise EOFError
|
|
||||||
|
|
||||||
def _sendall(sock, data):
|
|
||||||
"""
|
|
||||||
Writes data to a socket and does not return until all the data is sent.
|
|
||||||
"""
|
|
||||||
length = len(data)
|
|
||||||
while length:
|
|
||||||
try:
|
|
||||||
sent = sock.send(data)
|
|
||||||
except socket.error as e:
|
|
||||||
if e[0] == errno.EAGAIN:
|
|
||||||
select.select([], [sock], [])
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
data = data[sent:]
|
|
||||||
length -= sent
|
|
||||||
_sendall = staticmethod(_sendall)
|
|
||||||
|
|
||||||
def write(self, sock):
|
|
||||||
"""Encode and write a Record to a socket."""
|
|
||||||
self.paddingLength = -self.contentLength & 7
|
|
||||||
|
|
||||||
if __debug__:
|
|
||||||
_debug(9, 'write: fd = %d, type = %d, requestId = %d, '
|
|
||||||
'contentLength = %d' %
|
|
||||||
(sock.fileno(), self.type, self.requestId,
|
|
||||||
self.contentLength))
|
|
||||||
|
|
||||||
header = struct.pack(FCGI_Header, self.version, self.type,
|
|
||||||
self.requestId, self.contentLength,
|
|
||||||
self.paddingLength)
|
|
||||||
self._sendall(sock, header)
|
|
||||||
if self.contentLength:
|
|
||||||
self._sendall(sock, self.contentData)
|
|
||||||
if self.paddingLength:
|
|
||||||
self._sendall(sock, b'\x00' * self.paddingLength)
|
|
||||||
|
|
||||||
|
|
||||||
class FCGIApp(object):
|
|
||||||
|
|
||||||
def __init__(self, connect=None, host=None, port=None, filterEnviron=True):
|
|
||||||
if host is not None:
|
|
||||||
assert port is not None
|
|
||||||
connect = (host, port)
|
|
||||||
|
|
||||||
self._connect = connect
|
|
||||||
self._filterEnviron = filterEnviron
|
|
||||||
|
|
||||||
def __call__(self, environ, io, start_response=None):
|
|
||||||
# For sanity's sake, we don't care about FCGI_MPXS_CONN
|
|
||||||
# (connection multiplexing). For every request, we obtain a new
|
|
||||||
# transport socket, perform the request, then discard the socket.
|
|
||||||
# This is, I believe, how mod_fastcgi does things...
|
|
||||||
|
|
||||||
sock = self._getConnection()
|
|
||||||
|
|
||||||
# Since this is going to be the only request on this connection,
|
|
||||||
# set the request ID to 1.
|
|
||||||
requestId = 1
|
|
||||||
|
|
||||||
# Begin the request
|
|
||||||
rec = Record(FCGI_BEGIN_REQUEST, requestId)
|
|
||||||
rec.contentData = struct.pack(FCGI_BeginRequestBody, FCGI_RESPONDER, 0)
|
|
||||||
rec.contentLength = FCGI_BeginRequestBody_LEN
|
|
||||||
rec.write(sock)
|
|
||||||
|
|
||||||
# Filter WSGI environ and send it as FCGI_PARAMS
|
|
||||||
if self._filterEnviron:
|
|
||||||
params = self._defaultFilterEnviron(environ)
|
|
||||||
else:
|
|
||||||
params = self._lightFilterEnviron(environ)
|
|
||||||
# TODO: Anything not from environ that needs to be sent also?
|
|
||||||
# return '200 OK',[],str(params),''
|
|
||||||
self._fcgiParams(sock, requestId, params)
|
|
||||||
self._fcgiParams(sock, requestId, {})
|
|
||||||
|
|
||||||
# Transfer wsgi.input to FCGI_STDIN
|
|
||||||
content_length = int(environ.get('CONTENT_LENGTH') or 0)
|
|
||||||
s = ''
|
|
||||||
#io = StringIO(stdin)
|
|
||||||
while True:
|
|
||||||
if not io:
|
|
||||||
break
|
|
||||||
chunk_size = min(content_length, 4096)
|
|
||||||
s = io.read(chunk_size)
|
|
||||||
content_length -= len(s)
|
|
||||||
rec = Record(FCGI_STDIN, requestId)
|
|
||||||
rec.contentData = s
|
|
||||||
rec.contentLength = len(s)
|
|
||||||
rec.write(sock)
|
|
||||||
if not s:
|
|
||||||
break
|
|
||||||
# Empty FCGI_DATA stream
|
|
||||||
rec = Record(FCGI_DATA, requestId)
|
|
||||||
rec.write(sock)
|
|
||||||
return sock
|
|
||||||
|
|
||||||
def _getConnection(self):
|
|
||||||
if self._connect is not None:
|
|
||||||
# The simple case. Create a socket and connect to the
|
|
||||||
# application.
|
|
||||||
if isinstance(self._connect, str):
|
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
||||||
sock.connect(self._connect)
|
|
||||||
elif hasattr(socket, 'create_connection'):
|
|
||||||
sock = socket.create_connection(self._connect)
|
|
||||||
else:
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
||||||
sock.connect(self._connect)
|
|
||||||
return sock
|
|
||||||
|
|
||||||
# To be done when I have more time...
|
|
||||||
# , 'Launching and managing FastCGI programs not yet implemented'
|
|
||||||
raise NotImplementedError
|
|
||||||
|
|
||||||
def _fcgiGetValues(self, sock, vars):
|
|
||||||
# Construct FCGI_GET_VALUES record
|
|
||||||
outrec = Record(FCGI_GET_VALUES)
|
|
||||||
data = []
|
|
||||||
for name in vars:
|
|
||||||
data.append(encode_pair(name, ''))
|
|
||||||
data = ''.join(data)
|
|
||||||
outrec.contentData = data
|
|
||||||
outrec.contentLength = len(data)
|
|
||||||
outrec.write(sock)
|
|
||||||
|
|
||||||
# Await response
|
|
||||||
inrec = Record()
|
|
||||||
inrec.read(sock)
|
|
||||||
result = {}
|
|
||||||
if inrec.type == FCGI_GET_VALUES_RESULT:
|
|
||||||
pos = 0
|
|
||||||
while pos < inrec.contentLength:
|
|
||||||
pos, (name, value) = decode_pair(inrec.contentData, pos)
|
|
||||||
result[name] = value
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _fcgiParams(self, sock, requestId, params):
|
|
||||||
rec = Record(FCGI_PARAMS, requestId)
|
|
||||||
data = []
|
|
||||||
for name, value in params.items():
|
|
||||||
data.append(encode_pair(name.encode(
|
|
||||||
'latin-1'), value.encode('latin-1')))
|
|
||||||
data = b''.join(data)
|
|
||||||
rec.contentData = data
|
|
||||||
rec.contentLength = len(data)
|
|
||||||
rec.write(sock)
|
|
||||||
|
|
||||||
_environPrefixes = ['SERVER_', 'HTTP_', 'REQUEST_', 'REMOTE_', 'PATH_',
|
|
||||||
'CONTENT_', 'DOCUMENT_', 'SCRIPT_']
|
|
||||||
_environCopies = ['SCRIPT_NAME', 'QUERY_STRING', 'AUTH_TYPE']
|
|
||||||
_environRenames = []
|
|
||||||
|
|
||||||
def _defaultFilterEnviron(self, environ):
|
|
||||||
result = {}
|
|
||||||
for n in environ.keys():
|
|
||||||
iv = False
|
|
||||||
for p in self._environPrefixes:
|
|
||||||
if n.startswith(p):
|
|
||||||
result[n] = environ[n]
|
|
||||||
iv = True
|
|
||||||
if n in self._environCopies:
|
|
||||||
result[n] = environ[n]
|
|
||||||
iv = True
|
|
||||||
if n in self._environRenames:
|
|
||||||
result[self._environRenames[n]] = environ[n]
|
|
||||||
iv = True
|
|
||||||
if not iv:
|
|
||||||
result[n] = environ[n]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _lightFilterEnviron(self, environ):
|
|
||||||
result = {}
|
|
||||||
for n in environ.keys():
|
|
||||||
if n.upper() == n:
|
|
||||||
result[n] = environ[n]
|
|
||||||
return result
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
# coding:utf-8
|
|
||||||
|
|
||||||
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
import struct
|
|
||||||
import fcgi_client
|
|
||||||
|
|
||||||
FCGI_Header = '!BBHHBx'
|
|
||||||
|
|
||||||
if sys.version_info[0] == 2:
|
|
||||||
try:
|
|
||||||
from cStringIO import StringIO
|
|
||||||
except:
|
|
||||||
from StringIO import StringIO
|
|
||||||
else:
|
|
||||||
from io import BytesIO as StringIO
|
|
||||||
|
|
||||||
|
|
||||||
def get_header_data(sock):
|
|
||||||
'''
|
|
||||||
@name 获取头部32KB数据
|
|
||||||
@param sock socketobject(fastcgi套接字对象)
|
|
||||||
@return bytes
|
|
||||||
'''
|
|
||||||
headers_data = b''
|
|
||||||
total_len = 0
|
|
||||||
header_len = 1024 * 128
|
|
||||||
while True:
|
|
||||||
fastcgi_header = sock.recv(8)
|
|
||||||
if not fastcgi_header:
|
|
||||||
break
|
|
||||||
if len(fastcgi_header) != 8:
|
|
||||||
headers_data += fastcgi_header
|
|
||||||
break
|
|
||||||
fast_pack = struct.unpack(FCGI_Header, fastcgi_header)
|
|
||||||
if fast_pack[1] == 3:
|
|
||||||
break
|
|
||||||
|
|
||||||
tlen = fast_pack[3]
|
|
||||||
while tlen > 0:
|
|
||||||
sd = sock.recv(tlen)
|
|
||||||
if not sd:
|
|
||||||
break
|
|
||||||
headers_data += sd
|
|
||||||
tlen -= len(sd)
|
|
||||||
|
|
||||||
total_len += fast_pack[3]
|
|
||||||
if fast_pack[4]:
|
|
||||||
sock.recv(fast_pack[4])
|
|
||||||
if total_len > header_len:
|
|
||||||
break
|
|
||||||
return headers_data
|
|
||||||
|
|
||||||
|
|
||||||
def format_header_data(headers_data):
|
|
||||||
'''
|
|
||||||
@name 格式化响应头
|
|
||||||
@param headers_data bytes(fastcgi头部32KB数据)
|
|
||||||
@return status int(响应状态), headers dict(响应头), bdata bytes(格式化响应头后的多余数据)
|
|
||||||
'''
|
|
||||||
status = '200 OK'
|
|
||||||
headers = {}
|
|
||||||
pos = 0
|
|
||||||
while True:
|
|
||||||
eolpos = headers_data.find(b'\n', pos)
|
|
||||||
if eolpos < 0:
|
|
||||||
break
|
|
||||||
line = headers_data[pos:eolpos - 1]
|
|
||||||
pos = eolpos + 1
|
|
||||||
line = line.strip()
|
|
||||||
if len(line) < 2:
|
|
||||||
break
|
|
||||||
if line.find(b':') == -1:
|
|
||||||
continue
|
|
||||||
header, value = line.split(b':', 1)
|
|
||||||
header = header.strip()
|
|
||||||
value = value.strip()
|
|
||||||
if isinstance(header, bytes):
|
|
||||||
header = header.decode()
|
|
||||||
value = value.decode()
|
|
||||||
if header == 'Status':
|
|
||||||
status = value
|
|
||||||
if status.find(' ') < 0:
|
|
||||||
status += ' BTPanel'
|
|
||||||
else:
|
|
||||||
headers[header] = value
|
|
||||||
bdata = headers_data[pos:]
|
|
||||||
status = int(status.split(' ')[0])
|
|
||||||
return status, headers, bdata
|
|
||||||
|
|
||||||
|
|
||||||
def resp_sock(sock, bdata):
|
|
||||||
'''
|
|
||||||
@name 以流的方式发送剩余数据
|
|
||||||
@param sock socketobject(fastcgi套接字对象)
|
|
||||||
@param bdata bytes(格式化响应头后的多余数据)
|
|
||||||
@return yield bytes
|
|
||||||
'''
|
|
||||||
# 发送除响应头以外的多余头部数据
|
|
||||||
yield bdata
|
|
||||||
while True:
|
|
||||||
fastcgi_header = sock.recv(8)
|
|
||||||
if not fastcgi_header:
|
|
||||||
break
|
|
||||||
if len(fastcgi_header) != 8:
|
|
||||||
yield fastcgi_header
|
|
||||||
break
|
|
||||||
fast_pack = struct.unpack(FCGI_Header, fastcgi_header)
|
|
||||||
if fast_pack[1] == 3:
|
|
||||||
break
|
|
||||||
tlen = fast_pack[3]
|
|
||||||
while tlen > 0:
|
|
||||||
sd = sock.recv(tlen)
|
|
||||||
if not sd:
|
|
||||||
break
|
|
||||||
tlen -= len(sd)
|
|
||||||
if sd:
|
|
||||||
yield sd
|
|
||||||
|
|
||||||
if fast_pack[4]:
|
|
||||||
sock.recv(fast_pack[4])
|
|
||||||
sock.close()
|
|
||||||
|
|
||||||
|
|
||||||
class fpm(object):
|
|
||||||
|
|
||||||
def __init__(self, sock=None, document_root='', last_path=''):
|
|
||||||
'''
|
|
||||||
@name 实例化FPM对象
|
|
||||||
@param sock string(unixsocket路径)
|
|
||||||
@param document_root string(PHP文档根目录)
|
|
||||||
@return FPM
|
|
||||||
'''
|
|
||||||
if sock:
|
|
||||||
self.fcgi_sock = sock
|
|
||||||
if document_root[-1:] != '/':
|
|
||||||
document_root += '/'
|
|
||||||
self.document_root = document_root
|
|
||||||
self.last_path = last_path
|
|
||||||
|
|
||||||
def load_url_public(self, url, content=b'', method='GET', content_type='application/x-www-form-urlencoded'):
|
|
||||||
'''
|
|
||||||
@name 转发URL到PHP-FPM 公共
|
|
||||||
@param url string(URI地址)
|
|
||||||
@param content stream(POST数据io对象)
|
|
||||||
@return fastcgi-socket
|
|
||||||
'''
|
|
||||||
fcgi = fcgi_client.FCGIApp(connect=self.fcgi_sock)
|
|
||||||
try:
|
|
||||||
script_name, query_string = url.split('?')
|
|
||||||
except ValueError:
|
|
||||||
script_name = url
|
|
||||||
query_string = ''
|
|
||||||
|
|
||||||
content_length = len(content)
|
|
||||||
if content:
|
|
||||||
content = StringIO(content)
|
|
||||||
|
|
||||||
env = {
|
|
||||||
'SCRIPT_FILENAME': '%s%s' % (self.document_root, script_name),
|
|
||||||
'QUERY_STRING': query_string,
|
|
||||||
'REQUEST_METHOD': method,
|
|
||||||
'SCRIPT_NAME': self.last_path + script_name,
|
|
||||||
'REQUEST_URI': url,
|
|
||||||
'GATEWAY_INTERFACE': 'CGI/1.1',
|
|
||||||
'SERVER_SOFTWARE': 'MW-Panel',
|
|
||||||
'REDIRECT_STATUS': '200',
|
|
||||||
'CONTENT_TYPE': content_type,
|
|
||||||
'CONTENT_LENGTH': str(content_length),
|
|
||||||
'DOCUMENT_URI': script_name,
|
|
||||||
'DOCUMENT_ROOT': self.document_root,
|
|
||||||
'SERVER_PROTOCOL': 'HTTP/1.1',
|
|
||||||
'REMOTE_ADDR': '127.0.0.1',
|
|
||||||
'REMOTE_PORT': '7200',
|
|
||||||
'SERVER_ADDR': '127.0.0.1',
|
|
||||||
'SERVER_PORT': '80',
|
|
||||||
'SERVER_NAME': 'MW-Panel'
|
|
||||||
}
|
|
||||||
|
|
||||||
fpm_sock = fcgi(env, content)
|
|
||||||
|
|
||||||
_data = b''
|
|
||||||
while True:
|
|
||||||
fastcgi_header = fpm_sock.recv(8)
|
|
||||||
if not fastcgi_header:
|
|
||||||
break
|
|
||||||
if len(fastcgi_header) != 8:
|
|
||||||
_data += fastcgi_header
|
|
||||||
break
|
|
||||||
fast_pack = struct.unpack(FCGI_Header, fastcgi_header)
|
|
||||||
if fast_pack[1] == 3:
|
|
||||||
break
|
|
||||||
tlen = fast_pack[3]
|
|
||||||
while tlen > 0:
|
|
||||||
sd = fpm_sock.recv(tlen)
|
|
||||||
if not sd:
|
|
||||||
break
|
|
||||||
tlen -= len(sd)
|
|
||||||
_data += sd
|
|
||||||
if fast_pack[4]:
|
|
||||||
fpm_sock.recv(fast_pack[4])
|
|
||||||
status, headers, data = format_header_data(_data)
|
|
||||||
return data
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import pymysql.cursors
|
|
||||||
|
|
||||||
|
|
||||||
class ORM:
|
|
||||||
__DB_PASS = None
|
|
||||||
__DB_USER = 'root'
|
|
||||||
__DB_PORT = 3306
|
|
||||||
__DB_NAME = ''
|
|
||||||
__DB_HOST = 'localhost'
|
|
||||||
__DB_CONN = None
|
|
||||||
__DB_CUR = None
|
|
||||||
__DB_ERR = None
|
|
||||||
__DB_CNF = '/etc/my.cnf'
|
|
||||||
__DB_SOCKET = '/www/server/mysql/mysql.sock'
|
|
||||||
|
|
||||||
__DB_CHARSET = "utf8"
|
|
||||||
|
|
||||||
def __Conn(self):
|
|
||||||
'''连接数据库'''
|
|
||||||
try:
|
|
||||||
|
|
||||||
if os.path.exists(self.__DB_SOCKET):
|
|
||||||
try:
|
|
||||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
database=self.__DB_NAME,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
|
||||||
unix_socket=self.__DB_SOCKET, cursorclass=pymysql.cursors.DictCursor)
|
|
||||||
except Exception as e:
|
|
||||||
self.__DB_HOST = '127.0.0.1'
|
|
||||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
database=self.__DB_NAME,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
|
||||||
unix_socket=self.__DB_SOCKET, cursorclass=pymysql.cursors.DictCursor)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
database=self.__DB_NAME,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
|
||||||
cursorclass=pymysql.cursors.DictCursor)
|
|
||||||
except Exception as e:
|
|
||||||
self.__DB_HOST = '127.0.0.1'
|
|
||||||
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
database=self.__DB_NAME,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
|
|
||||||
cursorclass=pymysql.cursors.DictCursor)
|
|
||||||
|
|
||||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
|
||||||
return True
|
|
||||||
except Exception as e:
|
|
||||||
self.__DB_ERR = e
|
|
||||||
return False
|
|
||||||
|
|
||||||
def setDbConf(self, conf):
|
|
||||||
self.__DB_CNF = conf
|
|
||||||
|
|
||||||
def setSocket(self, sock):
|
|
||||||
self.__DB_SOCKET = sock
|
|
||||||
|
|
||||||
def setCharset(self, charset):
|
|
||||||
self.__DB_CHARSET = charset
|
|
||||||
|
|
||||||
def setPort(self, port):
|
|
||||||
self.__DB_PORT = port
|
|
||||||
|
|
||||||
def setPwd(self, pwd):
|
|
||||||
self.__DB_PASS = pwd
|
|
||||||
|
|
||||||
def getPwd(self):
|
|
||||||
return self.__DB_PASS
|
|
||||||
|
|
||||||
def setDbName(self, name):
|
|
||||||
self.__DB_NAME = name
|
|
||||||
|
|
||||||
def execute(self, sql):
|
|
||||||
# 执行SQL语句返回受影响行
|
|
||||||
if not self.__Conn():
|
|
||||||
return self.__DB_ERR
|
|
||||||
try:
|
|
||||||
result = self.__DB_CUR.execute(sql)
|
|
||||||
self.__DB_CONN.commit()
|
|
||||||
self.__Close()
|
|
||||||
return result
|
|
||||||
except Exception as ex:
|
|
||||||
return ex
|
|
||||||
|
|
||||||
def query(self, sql):
|
|
||||||
# 执行SQL语句返回数据集
|
|
||||||
if not self.__Conn():
|
|
||||||
return self.__DB_ERR
|
|
||||||
try:
|
|
||||||
self.__DB_CUR.execute(sql)
|
|
||||||
result = self.__DB_CUR.fetchall()
|
|
||||||
# print(result)
|
|
||||||
# 将元组转换成列表
|
|
||||||
# data = map(list, result)
|
|
||||||
self.__Close()
|
|
||||||
return result
|
|
||||||
except Exception as ex:
|
|
||||||
return ex
|
|
||||||
|
|
||||||
def __Close(self):
|
|
||||||
# 关闭连接
|
|
||||||
self.__DB_CUR.close()
|
|
||||||
self.__DB_CONN.close()
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
class ORM:
|
|
||||||
__DB_PASS = None
|
|
||||||
__DB_USER = 'root'
|
|
||||||
__DB_PORT = 3306
|
|
||||||
__DB_HOST = 'localhost'
|
|
||||||
__DB_CONN = None
|
|
||||||
__DB_CUR = None
|
|
||||||
__DB_ERR = None
|
|
||||||
__DB_CNF = '/etc/my.cnf'
|
|
||||||
|
|
||||||
__DB_SOCKET = '/www/server/mysql/mysql.sock'
|
|
||||||
__DB_CHARSET = 'utf8'
|
|
||||||
|
|
||||||
def __Conn(self):
|
|
||||||
'''连接MYSQL数据库'''
|
|
||||||
try:
|
|
||||||
|
|
||||||
try:
|
|
||||||
import MySQLdb
|
|
||||||
except Exception as ex:
|
|
||||||
self.__DB_ERR = ex
|
|
||||||
return False
|
|
||||||
|
|
||||||
# print(self.__DB_HOST)
|
|
||||||
# print(self.__DB_USER)
|
|
||||||
# print(self.__DB_PASS)
|
|
||||||
# print(self.__DB_PORT)
|
|
||||||
# print(self.__DB_CHARSET)
|
|
||||||
# print(self.__DB_SOCKET)
|
|
||||||
if os.path.exists(self.__DB_SOCKET):
|
|
||||||
try:
|
|
||||||
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1, unix_socket=self.__DB_SOCKET)
|
|
||||||
except Exception as e:
|
|
||||||
print(e)
|
|
||||||
self.__DB_HOST = '127.0.0.1'
|
|
||||||
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1, unix_socket=self.__DB_SOCKET)
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1)
|
|
||||||
except Exception as e:
|
|
||||||
self.__DB_HOST = '127.0.0.1'
|
|
||||||
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1)
|
|
||||||
|
|
||||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
|
||||||
|
|
||||||
return True
|
|
||||||
except MySQLdb.Error as e:
|
|
||||||
self.__DB_ERR = e
|
|
||||||
return False
|
|
||||||
|
|
||||||
def setDbConf(self, conf):
|
|
||||||
self.__DB_CNF = conf
|
|
||||||
|
|
||||||
def setSocket(self, sock):
|
|
||||||
self.__DB_SOCKET = sock
|
|
||||||
|
|
||||||
def setCharset(self, charset):
|
|
||||||
self.__DB_CHARSET = charset
|
|
||||||
|
|
||||||
def setPort(self, port):
|
|
||||||
self.__DB_PORT = port
|
|
||||||
|
|
||||||
def setPwd(self, pwd):
|
|
||||||
self.__DB_PASS = pwd
|
|
||||||
|
|
||||||
def getPwd(self):
|
|
||||||
return self.__DB_PASS
|
|
||||||
|
|
||||||
def execute(self, sql):
|
|
||||||
# 执行SQL语句返回受影响行
|
|
||||||
if not self.__Conn():
|
|
||||||
return self.__DB_ERR
|
|
||||||
try:
|
|
||||||
result = self.__DB_CUR.execute(sql)
|
|
||||||
self.__DB_CONN.commit()
|
|
||||||
self.__Close()
|
|
||||||
return result
|
|
||||||
except Exception as ex:
|
|
||||||
return ex
|
|
||||||
|
|
||||||
def query(self, sql):
|
|
||||||
# 执行SQL语句返回数据集
|
|
||||||
if not self.__Conn():
|
|
||||||
return self.__DB_ERR
|
|
||||||
try:
|
|
||||||
self.__DB_CUR.execute(sql)
|
|
||||||
result = self.__DB_CUR.fetchall()
|
|
||||||
# 将元组转换成列表
|
|
||||||
data = map(list, result)
|
|
||||||
self.__Close()
|
|
||||||
return data
|
|
||||||
except Exception as ex:
|
|
||||||
return ex
|
|
||||||
|
|
||||||
# 关闭连接
|
|
||||||
def __Close(self):
|
|
||||||
self.__DB_CUR.close()
|
|
||||||
self.__DB_CONN.close()
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/usr/local/lib/python2.7/bin
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
find . -name .DS_Store | xargs rm -rf
|
|
||||||
find . -type d -name "*.pyc" | xargs rm -rf
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
DIR=$(cd "$(dirname "$0")"; pwd)
|
|
||||||
MDIR=$(dirname "$DIR")
|
|
||||||
|
|
||||||
|
|
||||||
PATH=$PATH:$DIR/bin
|
|
||||||
if [ -f bin/activate ];then
|
|
||||||
source bin/activate
|
|
||||||
fi
|
|
||||||
|
|
||||||
# export LC_ALL="en_US.UTF-8"
|
|
||||||
|
|
||||||
|
|
||||||
mw_start_task()
|
|
||||||
{
|
|
||||||
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
|
|
||||||
if [ "$isStart" == '' ];then
|
|
||||||
echo -e "Starting mw-tasks... \c"
|
|
||||||
cd $DIR && python3 task.py >> ${DIR}/logs/task.log 2>&1 &
|
|
||||||
sleep 0.3
|
|
||||||
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
|
|
||||||
if [ "$isStart" == '' ];then
|
|
||||||
echo -e "\033[31mfailed\033[0m"
|
|
||||||
echo '------------------------------------------------------'
|
|
||||||
tail -n 20 $DIR/logs/task.log
|
|
||||||
echo '------------------------------------------------------'
|
|
||||||
echo -e "\033[31mError: mw-tasks service startup failed.\033[0m"
|
|
||||||
return;
|
|
||||||
fi
|
|
||||||
echo -e "\033[32mdone\033[0m"
|
|
||||||
else
|
|
||||||
echo "Starting mw-tasks... mw-tasks (pid $(echo $isStart)) already running"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
mw_start(){
|
|
||||||
gunicorn -c setting.py app:app
|
|
||||||
#安全启动
|
|
||||||
mw_start_task
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mw_start_debug(){
|
|
||||||
python3 task.py >> $DIR/logs/task.log 2>&1 &
|
|
||||||
gunicorn -b :7200 -k gevent -w 1 app:app
|
|
||||||
}
|
|
||||||
|
|
||||||
mw_start_debug2(){
|
|
||||||
python3 task.py >> $DIR/logs/task.log 2>&1 &
|
|
||||||
gunicorn -b :7200 -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 app:app
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mw_stop()
|
|
||||||
{
|
|
||||||
PLIST=`ps -ef|grep app:app |grep -v grep|awk '{print $2}'`
|
|
||||||
for i in $PLIST
|
|
||||||
do
|
|
||||||
kill -9 $i
|
|
||||||
done
|
|
||||||
|
|
||||||
pids=`ps -ef|grep task.py | grep -v grep |awk '{print $2}'`
|
|
||||||
arr=($pids)
|
|
||||||
for p in ${arr[@]}
|
|
||||||
do
|
|
||||||
kill -9 $p
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
'start') mw_start;;
|
|
||||||
'stop') mw_stop;;
|
|
||||||
'restart')
|
|
||||||
mw_stop
|
|
||||||
mw_start
|
|
||||||
;;
|
|
||||||
'debug')
|
|
||||||
mw_stop
|
|
||||||
mw_start_debug
|
|
||||||
;;
|
|
||||||
'debug2')
|
|
||||||
mw_stop
|
|
||||||
mw_start_debug2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
### 常用命令说明
|
|
||||||
|
|
||||||
|
|
||||||
- 面板相关命令
|
|
||||||
|
|
||||||
```
|
|
||||||
/etc/init.d/mw default
|
|
||||||
|
|
||||||
service mw [start|stop|reload|restart|status]
|
|
||||||
```
|
|
||||||
|
|
||||||
- OpenResty
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] openresty
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- MySQL
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] mysql
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- MariaDB
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] mariadb
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- PHP
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] php[54-81]
|
|
||||||
|
|
||||||
sytemctl start php71
|
|
||||||
```
|
|
||||||
|
|
||||||
- Redis
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] redis
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
- Memcached
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] memcached
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
- sphinx
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
sytemctl [start|stop|reload|restart|status] sphinx
|
|
||||||
|
|
||||||
```
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
### 兼容性测试报告
|
|
||||||
|
|
||||||
快速测试命令
|
|
||||||
|
|
||||||
```
|
|
||||||
cd /www/server/mdserver-web/scripts/quick && bash debug.sh
|
|
||||||
cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
| 系统名称 | 面板 | OpenResty |
|
|
||||||
| ----------------- |---------------|---------------|
|
|
||||||
| CentOS 7.9 |✅ |✅ |
|
|
||||||
| CentOS 8.4 |✅ |✅ |
|
|
||||||
| CentOS 8 Stream |✅ |✅ |
|
|
||||||
| CentOS 9 Stream |✅ |✅ |
|
|
||||||
| Debian 10.3 |✅ |✅ |
|
|
||||||
| Debian 11.3 |✅ |✅ |
|
|
||||||
| Ubuntu 18.04 |✅ |✅ |
|
|
||||||
| Ubuntu 20.04 |✅ |✅ |
|
|
||||||
| Ubuntu 22.04 |✅ |✅ |
|
|
||||||
| Fedora 31 |✅ |✅ |
|
|
||||||
| Fedora 32 |✅ |✅ |
|
|
||||||
| AlmaLinux 9 |✅ |✅ |
|
|
||||||
| RockyLinux 8.6 |✅ |✅ |
|
|
||||||
| Arch Linux |✅ |✅ |
|
|
||||||
| openSUSE 15.4 |✅ |✅ |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |
|
|
||||||
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
|
|
||||||
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
| 系统名称 | MySQL55|MySQL56|MySQL57|MySQL80|
|
|
||||||
| ----------------- |-------|--------|-------|-------|
|
|
||||||
| CentOS 7.9 |✅ |✅ |✅ |✅ |
|
|
||||||
| CentOS 8.4 |✅ |✅ |✅ |✅ |
|
|
||||||
| CentOS 8 Stream |✅ |✅ |✅ |✅ |
|
|
||||||
| CentOS 9 Stream |✅ |✅ |✅ |✅ |
|
|
||||||
| Debian 10.3 |✅ |✅ |✅ |✅ |
|
|
||||||
| Debian 11.3 |✅ |✅ |✅ |✅ |
|
|
||||||
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |
|
|
||||||
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |
|
|
||||||
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |
|
|
||||||
| Fedora 31 |✅ |✅ |✅ |✅ |
|
|
||||||
| Fedora 32 |✅ |✅ |✅ |✅ |
|
|
||||||
| AlmaLinux 9 |✅ |✅ |✅ |✅ |
|
|
||||||
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |
|
|
||||||
| Arch Linux |✅ |✅ |✅ |✅ |
|
|
||||||
| openSUSE 15.4 |✅ |✅ |✅ |✅ |
|
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
30
|
||||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
+1
-6
@@ -10,7 +10,7 @@
|
|||||||
"ps":""
|
"ps":""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"title":"数据软件",
|
"title":"缓存软件",
|
||||||
"type":2,
|
"type":2,
|
||||||
"ps":""
|
"ps":""
|
||||||
},
|
},
|
||||||
@@ -28,10 +28,5 @@
|
|||||||
"title":"其他插件",
|
"title":"其他插件",
|
||||||
"type":5,
|
"type":5,
|
||||||
"ps":""
|
"ps":""
|
||||||
},
|
|
||||||
{
|
|
||||||
"title":"辅助插件",
|
|
||||||
"type":6,
|
|
||||||
"ps":""
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1 +0,0 @@
|
|||||||
True
|
|
||||||
+41
-31
@@ -19,6 +19,19 @@ CREATE TABLE IF NOT EXISTS `binding` (
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `config` (
|
||||||
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`webserver` TEXT,
|
||||||
|
`backup_path` TEXT,
|
||||||
|
`sites_path` TEXT,
|
||||||
|
`status` INTEGER,
|
||||||
|
`mysql_root` TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO `config` (`id`, `webserver`, `backup_path`, `sites_path`, `status`, `mysql_root`) VALUES
|
||||||
|
(1, 'nginx', '/www/backup', '/www/wwwroot', 0, 'admin');
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `crontab` (
|
CREATE TABLE IF NOT EXISTS `crontab` (
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
`name` TEXT,
|
`name` TEXT,
|
||||||
@@ -27,14 +40,18 @@ CREATE TABLE IF NOT EXISTS `crontab` (
|
|||||||
`where_hour` INTEGER,
|
`where_hour` INTEGER,
|
||||||
`where_minute` INTEGER,
|
`where_minute` INTEGER,
|
||||||
`echo` TEXT,
|
`echo` TEXT,
|
||||||
`addtime` TEXT,
|
`addtime` TEXT
|
||||||
`status` INTEGER DEFAULT '1',
|
);
|
||||||
`save` INTEGER DEFAULT '3',
|
|
||||||
`backup_to` TEXT DEFAULT 'off',
|
CREATE TABLE IF NOT EXISTS `databases` (
|
||||||
`sname` TEXT,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
`sbody` TEXT,
|
`pid` INTEGER,
|
||||||
'stype' TEXT,
|
`name` TEXT,
|
||||||
`urladdress` TEXT
|
`username` TEXT,
|
||||||
|
`password` TEXT,
|
||||||
|
`accept` TEXT,
|
||||||
|
`ps` TEXT,
|
||||||
|
`addtime` TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `firewall` (
|
CREATE TABLE IF NOT EXISTS `firewall` (
|
||||||
@@ -45,13 +62,23 @@ CREATE TABLE IF NOT EXISTS `firewall` (
|
|||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
|
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
|
||||||
(1, '80', '网站默认端口', '0000-00-00 00:00:00'),
|
(2, '80', '网站默认端口', '0000-00-00 00:00:00'),
|
||||||
(2, '7200', 'WEB面板', '0000-00-00 00:00:00'),
|
(3, '8888', 'WEB面板', '0000-00-00 00:00:00'),
|
||||||
(3, '22', 'SSH远程管理服务', '0000-00-00 00:00:00'),
|
(4, '21', 'FTP服务', '0000-00-00 00:00:00'),
|
||||||
(4, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00'),
|
(5, '22', 'SSH远程管理服务', '0000-00-00 00:00:00');
|
||||||
(5, '443', 'HTTPS', '0000-00-00 00:00:00');
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `ftps` (
|
||||||
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
`pid` INTEGER,
|
||||||
|
`name` TEXT,
|
||||||
|
`password` TEXT,
|
||||||
|
`path` TEXT,
|
||||||
|
`status` TEXT,
|
||||||
|
`ps` TEXT,
|
||||||
|
`addtime` TEXT
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `logs` (
|
CREATE TABLE IF NOT EXISTS `logs` (
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
@@ -66,17 +93,10 @@ CREATE TABLE IF NOT EXISTS `sites` (
|
|||||||
`path` TEXT,
|
`path` TEXT,
|
||||||
`status` TEXT,
|
`status` TEXT,
|
||||||
`index` TEXT,
|
`index` TEXT,
|
||||||
`type_id` INTEGER,
|
|
||||||
`ps` TEXT,
|
`ps` TEXT,
|
||||||
`edate` TEXT,
|
|
||||||
`addtime` TEXT
|
`addtime` TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `site_types` (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`name` TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `domain` (
|
CREATE TABLE IF NOT EXISTS `domain` (
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
`pid` INTEGER,
|
`pid` INTEGER,
|
||||||
@@ -96,7 +116,7 @@ CREATE TABLE IF NOT EXISTS `users` (
|
|||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO `users` (`id`, `username`, `password`, `login_ip`, `login_time`, `phone`, `email`) VALUES
|
INSERT INTO `users` (`id`, `username`, `password`, `login_ip`, `login_time`, `phone`, `email`) VALUES
|
||||||
(1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '192.168.0.10', '2022-02-02 00:00:00', 0, 'midoks@163.com');
|
(1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '192.168.0.10', '2016-12-10 15:12:56', 0, '287962566@qq.com');
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `tasks` (
|
CREATE TABLE IF NOT EXISTS `tasks` (
|
||||||
@@ -109,13 +129,3 @@ CREATE TABLE IF NOT EXISTS `tasks` (
|
|||||||
`end` INTEGER,
|
`end` INTEGER,
|
||||||
`execstr` TEXT
|
`execstr` TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `panel` (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`title` TEXT,
|
|
||||||
`url` TEXT,
|
|
||||||
`username` TEXT,
|
|
||||||
`password` TEXT,
|
|
||||||
`click` INTEGER,
|
|
||||||
`addtime` INTEGER
|
|
||||||
);
|
|
||||||
|
|||||||
@@ -1,57 +0,0 @@
|
|||||||
server
|
|
||||||
{
|
|
||||||
listen {$PORT};
|
|
||||||
server_name {$SERVER_NAME};
|
|
||||||
index index.php index.html index.htm default.php default.htm default.html;
|
|
||||||
root {$ROOT_DIR};
|
|
||||||
|
|
||||||
#SSL-START
|
|
||||||
#error_page 404/404.html;
|
|
||||||
#SSL-END
|
|
||||||
|
|
||||||
#301-START
|
|
||||||
|
|
||||||
#PROXY-START
|
|
||||||
|
|
||||||
#ERROR-PAGE-START
|
|
||||||
error_page 404 /404.html;
|
|
||||||
error_page 502 /502.html;
|
|
||||||
#ERROR-PAGE-END
|
|
||||||
|
|
||||||
#PHP-INFO-START
|
|
||||||
include {$PHP_DIR}/conf/enable-php-{$PHPVER}.conf;
|
|
||||||
#PHP-INFO-END
|
|
||||||
|
|
||||||
#REWRITE-START
|
|
||||||
include {$OR_REWRITE}/{$SERVER_NAME}.conf;
|
|
||||||
#REWRITE-END
|
|
||||||
|
|
||||||
|
|
||||||
#禁止访问的文件或目录
|
|
||||||
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
|
|
||||||
{
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
|
|
||||||
#一键申请SSL证书验证目录相关设置
|
|
||||||
location ~ \.well-known{
|
|
||||||
allow all;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
|
|
||||||
{
|
|
||||||
expires 30d;
|
|
||||||
error_log off;
|
|
||||||
access_log /dev/null;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ .*\\.(js|css)?$
|
|
||||||
{
|
|
||||||
expires 12h;
|
|
||||||
error_log off;
|
|
||||||
access_log /dev/null;
|
|
||||||
}
|
|
||||||
|
|
||||||
access_log {$LOGPATH}/{$SERVER_NAME}.log main;
|
|
||||||
error_log {$LOGPATH}/{$SERVER_NAME}.error.log;
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
|
|
||||||
#BINDING-{$DIRBIND}-START
|
|
||||||
server
|
|
||||||
{
|
|
||||||
listen {$PORT};
|
|
||||||
server_name {$DIRBIND};
|
|
||||||
index index.php index.html index.htm default.php default.htm default.html;
|
|
||||||
root {$ROOT_DIR};
|
|
||||||
|
|
||||||
#SSL-START
|
|
||||||
#error_page 404/404.html;
|
|
||||||
#SSL-END
|
|
||||||
|
|
||||||
#ERROR-PAGE-START
|
|
||||||
error_page 404 /404.html;
|
|
||||||
error_page 502 /502.html;
|
|
||||||
#ERROR-PAGE-END
|
|
||||||
|
|
||||||
#PHP-INFO-START
|
|
||||||
include enable-php-{$PHPVER}.conf;
|
|
||||||
#PHP-INFO-END
|
|
||||||
|
|
||||||
#REWRITE-START
|
|
||||||
include {$OR_REWRITE}/{$SERVER_MAIN}.conf;
|
|
||||||
#REWRITE-END
|
|
||||||
|
|
||||||
#禁止访问的文件或目录
|
|
||||||
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
|
|
||||||
{
|
|
||||||
return 404;
|
|
||||||
}
|
|
||||||
|
|
||||||
#一键申请SSL证书验证目录相关设置
|
|
||||||
location ~ \.well-known{
|
|
||||||
allow all;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
|
|
||||||
{
|
|
||||||
expires 30d;
|
|
||||||
error_log off;
|
|
||||||
access_log /dev/null;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~ .*\\.(js|css)?$
|
|
||||||
{
|
|
||||||
expires 12h;
|
|
||||||
error_log off;
|
|
||||||
access_log /dev/null;
|
|
||||||
}
|
|
||||||
|
|
||||||
access_log {$LOGPATH}/{$SERVER_MAIN}_{$DIRBIND}.log;
|
|
||||||
error_log {$LOGPATH}/{$SERVER_MAIN}_{$DIRBIND}.error.log;
|
|
||||||
}
|
|
||||||
#BINDING-{$DIRBIND}-END
|
|
||||||
Executable
+6
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
rm -rf ./*.pyc
|
||||||
|
rm -rf ./*/*.pyc
|
||||||
|
|
||||||
|
#open "http://127.0.0.1:7200"
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
FROM debian:10.12-slim
|
|
||||||
|
|
||||||
STOPSIGNAL SIGRTMIN+3
|
|
||||||
|
|
||||||
RUN rm -f /lib/systemd/system/multi-user.target.wants/* \
|
|
||||||
/etc/systemd/system/*.wants/* \
|
|
||||||
/lib/systemd/system/local-fs.target.wants/* \
|
|
||||||
/lib/systemd/system/sockets.target.wants/*udev* \
|
|
||||||
/lib/systemd/system/sockets.target.wants/*initctl* \
|
|
||||||
/lib/systemd/system/sysinit.target.wants/systemd-tmpfiles-setup* \
|
|
||||||
/lib/systemd/system/systemd-update-utmp*
|
|
||||||
|
|
||||||
RUN apt update -y && \
|
|
||||||
apt install -y devscripts && \
|
|
||||||
apt install -y wget zip unzip && \
|
|
||||||
apt-get install -y locales && \
|
|
||||||
localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8 && \
|
|
||||||
locale-gen en_US.UTF-8 && \
|
|
||||||
export LC_ALL=en_US.UTF-8 && \
|
|
||||||
export LANG=en_US.UTF-8 && \
|
|
||||||
export LANGUAGE=en_US.UTF-8 && \
|
|
||||||
localedef -i en_US -f UTF-8 en_US.UTF-8 && \
|
|
||||||
mkdir -p /www/server && \
|
|
||||||
mkdir -p /www/wwwroot && \
|
|
||||||
mkdir -p /www/wwwlogs && \
|
|
||||||
mkdir -p /www/backup/database && \
|
|
||||||
mkdir -p /www/backup/site && \
|
|
||||||
wget -O /tmp/dev.zip https://github.com/midoks/mdserver-web/archive/refs/heads/dev.zip && \
|
|
||||||
cd /tmp && unzip /tmp/dev.zip && \
|
|
||||||
mv -f /tmp/mdserver-web-dev /www/server/mdserver-web && \
|
|
||||||
rm -rf /tmp/dev.zip && \
|
|
||||||
rm -rf /tmp/mdserver-web-dev && \
|
|
||||||
cd /www/server/mdserver-web && \
|
|
||||||
bash scripts/install/debian.sh && \
|
|
||||||
cd /www/server/mdserver-web/ && \
|
|
||||||
/www/server/mdserver-web/bin/python tools.py username username && \
|
|
||||||
cd /www/server/mdserver-web/ && \
|
|
||||||
/www/server/mdserver-web/bin/python tools.py panel password
|
|
||||||
|
|
||||||
RUN cd /www/server/mdserver-web/plugins/php && \
|
|
||||||
bash install.sh install 74 && \
|
|
||||||
cd /www/server/mdserver-web/plugins/openresty && \
|
|
||||||
bash install.sh install 1.21.4.1 && \
|
|
||||||
cd /www/server/mdserver-web/plugins/mysql && \
|
|
||||||
bash install.sh install 5.6 && \
|
|
||||||
cd /www/server/mdserver-web/plugins/phpmyadmin && \
|
|
||||||
bash install.sh install 4.4.15 && \
|
|
||||||
systemctl enable openresty && \
|
|
||||||
systemctl enable php74 && \
|
|
||||||
systemctl enable mysql
|
|
||||||
|
|
||||||
RUN rm -rf /www/server/mysql/data
|
|
||||||
|
|
||||||
ADD ./start.sh /start.sh
|
|
||||||
ADD start.service /usr/lib/systemd/system/start.service
|
|
||||||
#RUN systemctl enable start
|
|
||||||
|
|
||||||
CMD [ "/lib/systemd/systemd", "log-level=info", "unit=sysinit.target" ]
|
|
||||||
|
|
||||||
EXPOSE 7200 80 443 888
|
|
||||||
|
|
||||||
VOLUME [ "/www" ]
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Customize the script
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart=/start.sh
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
#!/www/server/mdserver-web/bin/python
|
|
||||||
# description: mdserver-web cli tools
|
|
||||||
# ln -s /www/server/mdserver-web/mw-cli /usr/bin/mw-cli
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def mw_start():
|
|
||||||
"""
|
|
||||||
Start mdserver-web
|
|
||||||
"""
|
|
||||||
os.system('systemctl start mw')
|
|
||||||
print("服务已启动")
|
|
||||||
|
|
||||||
|
|
||||||
def mw_stop():
|
|
||||||
"""
|
|
||||||
stop mdserver-web
|
|
||||||
"""
|
|
||||||
os.system('systemctl stop mw')
|
|
||||||
print("服务已停止")
|
|
||||||
|
|
||||||
|
|
||||||
def mw_restart():
|
|
||||||
"""
|
|
||||||
restart mdserver-web
|
|
||||||
"""
|
|
||||||
os.system('systemctl restart mw')
|
|
||||||
print("服务已重启")
|
|
||||||
|
|
||||||
|
|
||||||
def mw_reset_username():
|
|
||||||
"""
|
|
||||||
reset mdserver-web username
|
|
||||||
"""
|
|
||||||
from tools import set_panel_username
|
|
||||||
user_name = input("请输入新的用户名: ")
|
|
||||||
set_panel_username(user_name)
|
|
||||||
|
|
||||||
|
|
||||||
def mw_reset_pwd():
|
|
||||||
"""
|
|
||||||
reset mdserver-web password
|
|
||||||
"""
|
|
||||||
from tools import set_panel_pwd
|
|
||||||
pwd = input("请输入新的密码: ")
|
|
||||||
set_panel_pwd(pwd, True)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
|
|
||||||
if os.geteuid() != 0:
|
|
||||||
print("请使用root账户执行该命令.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
os.chdir("/www/server/mdserver-web")
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
|
|
||||||
try:
|
|
||||||
str = '''
|
|
||||||
==== mdserver-web cli tools ====
|
|
||||||
1. 启动服务 2. 停止服务
|
|
||||||
3. 重启服务 4. 修改用户名
|
|
||||||
5. 修改密码
|
|
||||||
=================================
|
|
||||||
'''
|
|
||||||
if len(sys.argv) == 2:
|
|
||||||
sw = sys.argv[1]
|
|
||||||
else:
|
|
||||||
print(str)
|
|
||||||
sw = input("请输入您要进行的操作: ")
|
|
||||||
|
|
||||||
if sw == '1':
|
|
||||||
mw_start()
|
|
||||||
elif sw == '2':
|
|
||||||
mw_stop()
|
|
||||||
elif sw == '3':
|
|
||||||
mw_restart()
|
|
||||||
elif sw == '4':
|
|
||||||
mw_reset_username()
|
|
||||||
elif sw == '5':
|
|
||||||
mw_reset_pwd()
|
|
||||||
else:
|
|
||||||
print("操作不存在")
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("\n操作已终止")
|
|
||||||
Executable
+85
@@ -0,0 +1,85 @@
|
|||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
# 使用示例:
|
||||||
|
# 1、将此文件重命名为btkill.py , 然后上传到服务器/root目录
|
||||||
|
# 2、执行 python /root/btkill.py
|
||||||
|
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
sys.path.append("/usr/local/lib/python2.7/site-packages")
|
||||||
|
import psutil
|
||||||
|
|
||||||
|
|
||||||
|
class btkill:
|
||||||
|
__limit = 10 # Cpu使用率触发上限
|
||||||
|
__vmsize = 1048576 / 4 # 虚拟内存触发上限(字节)
|
||||||
|
|
||||||
|
def checkMain(self):
|
||||||
|
pids = psutil.pids()
|
||||||
|
print pids
|
||||||
|
num = 0
|
||||||
|
for pid in pids:
|
||||||
|
try:
|
||||||
|
p = psutil.Process(pid)
|
||||||
|
if p.exe() == "":
|
||||||
|
continue
|
||||||
|
name = p.name()
|
||||||
|
if self.whiteList(name):
|
||||||
|
continue
|
||||||
|
cputimes = p.cpu_times()
|
||||||
|
if cputimes.user < 0.1:
|
||||||
|
continue
|
||||||
|
print p
|
||||||
|
percent = p.cpu_percent(interval=0.1)
|
||||||
|
vm = p.memory_info().vms
|
||||||
|
if percent > self.__limit or vm > self.__vmsize:
|
||||||
|
log = time.strftime('%Y-%m-%d %X', time.localtime()) + " (PID=" + str(
|
||||||
|
pid) + ", NAME=" + name + ", VMS=" + str(vm) + ", PERCENT=" + str(percent) + "%)"
|
||||||
|
p.kill()
|
||||||
|
num += 1
|
||||||
|
print log + " >> killed\n"
|
||||||
|
except Exception as ex:
|
||||||
|
print str(ex)
|
||||||
|
return num
|
||||||
|
|
||||||
|
# 检查白名单
|
||||||
|
def whiteList(self, name):
|
||||||
|
wlist = ['yum', 'apt-get', 'apt', 'redis-cli', 'memcached', 'sshd', 'vm', 'vim', 'htop', 'top', 'sh', 'bash', 'zip', 'gzip', 'rsync',
|
||||||
|
'tar', 'unzip', 'php', 'composer', 'pkill', 'mongo', 'mongod', 'php-fpm', 'nginx', 'httpd', 'lsof', 'ps', 'redis-server',
|
||||||
|
'mysqld', 'mysqld_safe', 'mysql', 'pure-ftpd', 'sparse_dd', 'stunnel', 'squeezed', 'vncterm', 'awk', 'ruby', 'postgres',
|
||||||
|
'mpathalert', 'vncterm', 'multipathd', 'fe', 'elasticsyslog', 'syslogd', 'v6d', 'xapi', 'screen', 'runsvdir', 'svlogd',
|
||||||
|
'java', 'udevd', 'ntpd', 'irqbalance', 'qmgr', 'wpa_supplicant', 'mysqld_safe', 'sftp-server', 'lvmetad', 'gitlab-web',
|
||||||
|
'pure-ftpd', 'auditd', 'master', 'dbus-daemon', 'tapdisk', 'sshd', 'init', 'ksoftirqd', 'kworker', 'kmpathd',
|
||||||
|
'kmpath_handlerd', 'python', 'kdmflush', 'bioset', 'crond', 'kthreadd', 'migration', 'rcu_sched', 'kjournald',
|
||||||
|
'gcc', 'gcc++', 'nginx', 'mysqld', 'php-cgi', 'login', 'firewalld', 'iptables', 'systemd', 'network', 'dhclient',
|
||||||
|
'systemd-journald', 'NetworkManager', 'systemd-logind', 'systemd-udevd', 'polkitd', 'tuned', 'rsyslogd', 'AliYunDunUpdate', 'AliYunDun', 'sendmail']
|
||||||
|
wslist = ['vif', 'qemu', 'scsi_eh', 'xcp',
|
||||||
|
'xen', 'docker', 'yunsuo', 'aliyun', 'PM2']
|
||||||
|
|
||||||
|
for key in wlist:
|
||||||
|
if key == name:
|
||||||
|
return True
|
||||||
|
|
||||||
|
for key in wslist:
|
||||||
|
if name.find(key) != -1:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 开始处理
|
||||||
|
def start(self):
|
||||||
|
num = 0
|
||||||
|
while True:
|
||||||
|
num += self.checkMain()
|
||||||
|
print "查杀完成, 共查杀[" + str(num) + "]个异常进程!"
|
||||||
|
time.sleep(3)
|
||||||
|
print '======================================='
|
||||||
|
print "查杀完成, 共查杀[" + str(num) + "]个异常进程!"
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print "正在检测异常进程..."
|
||||||
|
print '======================================='
|
||||||
|
c = btkill()
|
||||||
|
c.start()
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 254 B |
@@ -1,24 +0,0 @@
|
|||||||
<div class="bt-form">
|
|
||||||
<div class="bt-w-main">
|
|
||||||
<div class="bt-w-menu">
|
|
||||||
<p class="bgw" onclick="pluginService('clean');">服务</p>
|
|
||||||
<p onclick="pluginConfig('clean');">配置修改</p>
|
|
||||||
<p onclick="pRead()">说明</p>
|
|
||||||
</div>
|
|
||||||
<div class="bt-w-con pd15">
|
|
||||||
<div class="soft-man-con"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
pluginService('clean');
|
|
||||||
|
|
||||||
|
|
||||||
function pRead(){
|
|
||||||
var readme = '<ul class="help-info-text c7">';
|
|
||||||
readme += '<li>cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/clean/index.py clean</li>';
|
|
||||||
readme += '</ul>';
|
|
||||||
|
|
||||||
$('.soft-man-con').html(readme);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
@@ -1,200 +0,0 @@
|
|||||||
# coding:utf-8
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
import mw
|
|
||||||
|
|
||||||
app_debug = False
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
app_debug = True
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginName():
|
|
||||||
return 'clean'
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginDir():
|
|
||||||
return mw.getPluginDir() + '/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getServerDir():
|
|
||||||
return mw.getServerDir() + '/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getInitDFile():
|
|
||||||
if app_debug:
|
|
||||||
return '/tmp/' + getPluginName()
|
|
||||||
return '/etc/init.d/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getConf():
|
|
||||||
path = getServerDir() + "/clean.conf"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getArgs():
|
|
||||||
args = sys.argv[2:]
|
|
||||||
tmp = {}
|
|
||||||
args_len = len(args)
|
|
||||||
|
|
||||||
if args_len == 1:
|
|
||||||
t = args[0].strip('{').strip('}')
|
|
||||||
t = t.split(':')
|
|
||||||
tmp[t[0]] = t[1]
|
|
||||||
elif args_len > 1:
|
|
||||||
for i in range(len(args)):
|
|
||||||
t = args[i].split(':')
|
|
||||||
tmp[t[0]] = t[1]
|
|
||||||
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
def status():
|
|
||||||
if os.path.exists(getConf()):
|
|
||||||
return "start"
|
|
||||||
return 'stop'
|
|
||||||
|
|
||||||
|
|
||||||
def start():
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(file + ' start')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(file + ' stop')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
|
|
||||||
def reload():
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(file + ' reload')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
|
|
||||||
def get_filePath_fileName_fileExt(filename):
|
|
||||||
(filepath, tempfilename) = os.path.split(filename)
|
|
||||||
(shotname, extension) = os.path.splitext(tempfilename)
|
|
||||||
return filepath, shotname, extension
|
|
||||||
|
|
||||||
|
|
||||||
def cleanFileLog(path):
|
|
||||||
filepath, shotname, extension = get_filePath_fileName_fileExt(path)
|
|
||||||
if extension == ".log":
|
|
||||||
cmd = "echo \"\" > " + path
|
|
||||||
print(cmd)
|
|
||||||
print(mw.execShell(cmd))
|
|
||||||
|
|
||||||
|
|
||||||
def cleanSelfFileLog(path):
|
|
||||||
filepath, shotname, extension = get_filePath_fileName_fileExt(path)
|
|
||||||
cmd = "echo \"\" > " + path
|
|
||||||
print(cmd)
|
|
||||||
print(mw.execShell(cmd))
|
|
||||||
|
|
||||||
|
|
||||||
def cleanDirLog(path):
|
|
||||||
l = os.listdir(path)
|
|
||||||
for x in range(len(l)):
|
|
||||||
abspath = path + "/" + l[x]
|
|
||||||
if os.path.isfile(abspath):
|
|
||||||
cleanFileLog(abspath)
|
|
||||||
if os.path.isdir(abspath):
|
|
||||||
cleanDirLog(abspath)
|
|
||||||
|
|
||||||
|
|
||||||
def cleanLog():
|
|
||||||
# 清理日志
|
|
||||||
rootDir = "/var/log"
|
|
||||||
print("clean start")
|
|
||||||
|
|
||||||
clog = [
|
|
||||||
"rm -rf /var/log/cron-*",
|
|
||||||
"rm -rf /var/log/maillog-*",
|
|
||||||
"rm -rf /var/log/secure-*",
|
|
||||||
"rm -rf /var/log/spooler-*",
|
|
||||||
"rm -rf /var/log/yum.log-*",
|
|
||||||
"rm -rf /var/log/messages-*",
|
|
||||||
"rm -rf /var/log/btmp-*",
|
|
||||||
"rm -rf /var/log/audit/audit.log.*",
|
|
||||||
"rm -rf /var/log/rhsm/rhsm.log-*",
|
|
||||||
"rm -rf /var/log/rhsm/rhsmcertd.log-*",
|
|
||||||
"rm -rf /tmp/yum_save_*",
|
|
||||||
"rm -rf /tmp/tmp.*",
|
|
||||||
]
|
|
||||||
|
|
||||||
for i in clog:
|
|
||||||
print(i)
|
|
||||||
mw.execShell(i)
|
|
||||||
|
|
||||||
# 常用日志
|
|
||||||
clogcom = [
|
|
||||||
"/var/log/messages",
|
|
||||||
"/var/log/btmp",
|
|
||||||
"/var/log/wtmp",
|
|
||||||
"/var/log/secure",
|
|
||||||
"/var/log/lastlog",
|
|
||||||
"/var/log/cron",
|
|
||||||
]
|
|
||||||
for i in clogcom:
|
|
||||||
if os.path.exists(i):
|
|
||||||
mw.execShell("echo \"\" > " + i)
|
|
||||||
|
|
||||||
l = os.listdir(rootDir)
|
|
||||||
for x in range(len(l)):
|
|
||||||
abspath = rootDir + "/" + l[x]
|
|
||||||
if os.path.isfile(abspath):
|
|
||||||
cleanFileLog(abspath)
|
|
||||||
|
|
||||||
if os.path.isdir(abspath):
|
|
||||||
cleanDirLog(abspath)
|
|
||||||
|
|
||||||
print("conf clean")
|
|
||||||
|
|
||||||
confFile = getServerDir()
|
|
||||||
# mw.readFile()
|
|
||||||
confFile = confFile + "/clean.conf"
|
|
||||||
clist = mw.readFile(confFile).strip()
|
|
||||||
clist = clist.split("\n")
|
|
||||||
|
|
||||||
for x in clist:
|
|
||||||
abspath = x.strip()
|
|
||||||
if os.path.exists(abspath):
|
|
||||||
if os.path.isfile(abspath):
|
|
||||||
cleanSelfFileLog(abspath)
|
|
||||||
|
|
||||||
if os.path.isdir(abspath):
|
|
||||||
cleanDirLog(abspath)
|
|
||||||
print("conf clean end")
|
|
||||||
|
|
||||||
print("clean end")
|
|
||||||
|
|
||||||
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 == 'conf':
|
|
||||||
print(getConf())
|
|
||||||
elif func == 'clean':
|
|
||||||
cleanLog()
|
|
||||||
else:
|
|
||||||
print('error')
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"title":"日志清理",
|
|
||||||
"tip":"soft",
|
|
||||||
"name":"clean",
|
|
||||||
"type":"运行环境",
|
|
||||||
"ps":"日志清理",
|
|
||||||
"versions":"1.0",
|
|
||||||
"updates":"1.0",
|
|
||||||
"shell":"install.sh",
|
|
||||||
"checks":"server/clean",
|
|
||||||
"path": "server/clean",
|
|
||||||
"author":"clean",
|
|
||||||
"home":"https://github.com/midoks",
|
|
||||||
"date":"2021-11-23",
|
|
||||||
"pid": "5"
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
|
||||||
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
|
|
||||||
|
|
||||||
curPath=`pwd`
|
|
||||||
rootPath=$(dirname "$curPath")
|
|
||||||
rootPath=$(dirname "$rootPath")
|
|
||||||
serverPath=$(dirname "$rootPath")
|
|
||||||
|
|
||||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
|
||||||
VERSION=$2
|
|
||||||
|
|
||||||
|
|
||||||
Install_app()
|
|
||||||
{
|
|
||||||
echo '正在安装脚本文件...' > $install_tmp
|
|
||||||
mkdir -p $serverPath/clean
|
|
||||||
|
|
||||||
echo "" > $serverPath/clean/clean.conf
|
|
||||||
|
|
||||||
echo "${VERSION}" > $serverPath/clean/version.pl
|
|
||||||
echo '安装完成' > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
Uninstall_app()
|
|
||||||
{
|
|
||||||
rm -rf $serverPath/clean
|
|
||||||
echo "Uninstall_clean" > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
if [ "${1}" == 'install' ];then
|
|
||||||
Install_app
|
|
||||||
else
|
|
||||||
Uninstall_app
|
|
||||||
fi
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Executable
+550
@@ -0,0 +1,550 @@
|
|||||||
|
<style>
|
||||||
|
|
||||||
|
|
||||||
|
/*危险按钮*/
|
||||||
|
.bts-danger:hover{
|
||||||
|
color: #fff;
|
||||||
|
background-color: #c9302c;
|
||||||
|
border-color: #ac2925;
|
||||||
|
}
|
||||||
|
#whiteList a{
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*弹窗*/
|
||||||
|
.Add_view{
|
||||||
|
height: 100px;
|
||||||
|
padding-left: 35px;
|
||||||
|
padding-top: 35px;
|
||||||
|
}
|
||||||
|
.Add_view label{
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 100;
|
||||||
|
}
|
||||||
|
.Add_view input{
|
||||||
|
width: 230px;
|
||||||
|
}
|
||||||
|
.Add_view .error{
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
.Add_view .correct{
|
||||||
|
border: 1px solid #20a53a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*日志管理*/
|
||||||
|
.btnTitle{
|
||||||
|
font-weight: 100;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 34px;
|
||||||
|
height: 34px;
|
||||||
|
margin-right: 15px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
.whiteList-table{
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
/*登录日志表单*/
|
||||||
|
.viewTwo .whiteList-table{
|
||||||
|
overflow-x: hidden;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
.maks{
|
||||||
|
background: rgba(39, 39, 39, 0.4);
|
||||||
|
position: absolute;
|
||||||
|
width: 700px;
|
||||||
|
height: 555px;
|
||||||
|
z-index: 999;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.boxshow{
|
||||||
|
position: absolute;
|
||||||
|
height: 150px;
|
||||||
|
width: 400px;
|
||||||
|
margin-left: -200px;
|
||||||
|
margin-top: -75px;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
z-index: 1000;
|
||||||
|
background: #fff;
|
||||||
|
padding: 25px 20px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.btPayment {
|
||||||
|
float: left;
|
||||||
|
padding: 8px 10px;
|
||||||
|
width: 190px;
|
||||||
|
height: 100px;
|
||||||
|
line-height: 33px;
|
||||||
|
text-align: center;
|
||||||
|
border-left: 1px solid #ececec;
|
||||||
|
}
|
||||||
|
.btPayment .t2{
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.btPayment .price{
|
||||||
|
color: #20A53A;
|
||||||
|
font-size: 22px;
|
||||||
|
margin: 0 5px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.bt-form{
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.boxtext{
|
||||||
|
line-height: 32px;
|
||||||
|
margin-top: -17px;
|
||||||
|
text-align: center;
|
||||||
|
border-bottom: #eee 1px solid;
|
||||||
|
height: 39px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="maks" style="display: none"></div>
|
||||||
|
<div class="boxshow" style="display: none;">
|
||||||
|
<div>
|
||||||
|
<div class="boxtext">
|
||||||
|
<span>未开通此服务,如需使用请开通企业运维版。</span>
|
||||||
|
</div>
|
||||||
|
<div class="btvipinfo" style="width: 170px;padding-left: 20px">
|
||||||
|
<p style="height: 25px">1、一对一运维人员对接</p>
|
||||||
|
<p style="height: 25px">2、提供每月3次运维服务</p>
|
||||||
|
<p style="height: 25px">3、双重安全隔离登录</p>
|
||||||
|
</div>
|
||||||
|
<div class="btPayment">
|
||||||
|
<span class="t2">企业运维版<span class="price">98</span>元/月</span>
|
||||||
|
<button class="btn btn-success btn-sm" style="width:80%" onclick="window.open('https://www.bt.cn/admin/index.html')">立即开通</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bt-form">
|
||||||
|
<div class="bt-w-main">
|
||||||
|
<div class="bt-w-menu">
|
||||||
|
<p class="bgw">密钥</p>
|
||||||
|
<p>面板设置</p>
|
||||||
|
<p>面板登录日志</p>
|
||||||
|
<p>SSH设置</p>
|
||||||
|
<p>SSH日志管理</p>
|
||||||
|
</div>
|
||||||
|
<div class="bt-w-con pd15">
|
||||||
|
<div class="soft-man-con viewZoo">
|
||||||
|
<p class="status" style="margin-top:10px;margin-left:10px;height: 80px;margin-bottom:15px;">
|
||||||
|
<span style="float:left;margin-top:-5px">密钥:</span>
|
||||||
|
<textarea class="bt-input-text" name="token" readonly="readonly" style="background-color: #eee;width:400px;height:80px;padding: 8px 15px;" placeholder="密钥已隐藏..."></textarea>
|
||||||
|
</p>
|
||||||
|
<input type="button" class="btn btn-success btn-sm" name="ButtonShow" style="margin-left:52px;width:100px" onclick="sagelogin.tokenShow()" value="显示密钥" />
|
||||||
|
<ul style="margin: 15px 5px;padding-left: 70px;list-style-type: disc;line-height: 25px;">
|
||||||
|
<li>宝塔企业运维后台连接您的服务器需要此密钥,请妥善记录并保存</li>
|
||||||
|
<li>一但密钥丢失,可能导致您无法登录服务器</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="soft-man-con viewOne" style="display: none;">
|
||||||
|
<p class="status">当前状态:
|
||||||
|
<span>开启</span>
|
||||||
|
<span style="color: #20a53a; margin-left: 3px;" class="glyphicon glyphicon glyphicon-play"></span>
|
||||||
|
<span style="color: red; margin-left: 3px; display: none" class="glyphicon glyphicon-pause"></span>
|
||||||
|
</p>
|
||||||
|
<div class="sfm-opt">
|
||||||
|
<button class="btn btn-default btn-sm bts-danger" onclick="sagelogin.Panel_Admin()">清除面板登录限制IP</button>
|
||||||
|
<button class="btn btn-default btn-sm bts-safety" onclick="sagelogin.Add_view('面板白名单',true)">添加白名单</button>
|
||||||
|
</div>
|
||||||
|
<div class="whiteList-table divtable" style="overflow-x: hidden;height: 420px">
|
||||||
|
<table class="table table-hover" style="max-height: 380px; overflow: auto;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>IP地址</th>
|
||||||
|
<th style="text-align: right;">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="whiteListOne"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="soft-man-con viewTwo" style="display: none">
|
||||||
|
<div class="whiteList-table divtable">
|
||||||
|
<table class="table table-hover" style=" max-height: 380px; overflow: auto;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>操作记录</th>
|
||||||
|
<th>操作时间</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="whiteListTwo"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="soft-man-con viewThree" style="display: none">
|
||||||
|
<p class="status">当前状态:
|
||||||
|
<span>开启</span>
|
||||||
|
<span style="color: #20a53a; margin-left: 3px;" class="glyphicon glyphicon glyphicon-play">
|
||||||
|
</span>
|
||||||
|
<span style="color: red; margin-left: 3px; display: none" class="glyphicon glyphicon-pause"></span>
|
||||||
|
</p>
|
||||||
|
<div class="sfm-opt">
|
||||||
|
<button class="btn btn-default btn-sm bts-danger" onclick="sagelogin.Panel_Admin()">清除SSH登录限制IP</button>
|
||||||
|
<button class="btn btn-default btn-sm bts-safety" onclick="sagelogin.Add_view('SSH白名单',false)">添加白名单</button>
|
||||||
|
</div>
|
||||||
|
<div class="whiteList-table divtable" style="overflow-x: hidden;height: 420px">
|
||||||
|
<table class="table table-hover" style="max-height: 380px; overflow: auto;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>IP地址</th>
|
||||||
|
<th style="text-align: right;">操作</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="whiteListThree"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="soft-man-con viewFour" style="display: none">
|
||||||
|
<div class="btnclick">
|
||||||
|
<label class="btnTitle">日志分类</label>
|
||||||
|
<div class="btn-group">
|
||||||
|
<input type="submit" name="btnOne" class="btn btn-success" onclick="sagelogin.SSH_Defense_List(0)" value="已防御" />
|
||||||
|
<input type="submit" name="btnTwo" class="btn btn-default" onclick="sagelogin.SSH_Defense_List(1)" value="入侵日志"/>
|
||||||
|
<input type="submit" name="btnThree" class="btn btn-default" onclick="sagelogin.SSH_Defense_List(2)" value="登录日志"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="whiteList-table divtable" style="overflow-x: hidden;height: 470px;">
|
||||||
|
<table class="table table-hover" style="max-height: 380px; overflow: auto;">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>源IP地址</th>
|
||||||
|
<th>用户</th>
|
||||||
|
<th style="text-align: right;">登录时间</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="whiteListFour"></tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script type="javascript/text">
|
||||||
|
//宝塔安全登录
|
||||||
|
$(function(){
|
||||||
|
$(".bt-w-menu p").click(function(){
|
||||||
|
$(this).addClass("bgw").siblings().removeClass("bgw");
|
||||||
|
$('.bt-w-con .soft-man-con').hide().eq($(this).index()).show();
|
||||||
|
switch($(this).index()) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sagelogin.Panel_White_List();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sagelogin.Panel_journal();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sagelogin.SSH_White_List();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sagelogin.SSH_Defense_List(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
layer.load();
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=GetServerInfo',function(data) {
|
||||||
|
layer.closeAll('loading');
|
||||||
|
if (data.status) {
|
||||||
|
$('.boxshow').hide();
|
||||||
|
$('.maks').hide();
|
||||||
|
}else{
|
||||||
|
$('.boxshow').show();
|
||||||
|
$('.maks').show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var sagelogin = new Object();
|
||||||
|
sagelogin = {
|
||||||
|
Addview:'',
|
||||||
|
SSHlogList:'',
|
||||||
|
PanelLogList:'',
|
||||||
|
// SSH管理
|
||||||
|
SSH_Admin:function(){
|
||||||
|
var confirm = layer.confirm('确定清除面板登录限制IP地址?',{icon: 1}, {
|
||||||
|
btn: ['确认','取消'],
|
||||||
|
}, function(){
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=close_ssh_limit',function(data) {
|
||||||
|
if (data.status) {
|
||||||
|
layer.msg(data.msg,{icon:1});
|
||||||
|
sagelogin.SSH_White_List();
|
||||||
|
}else{
|
||||||
|
layer.msg(data.msg,{icon:2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function(){
|
||||||
|
layer.close(confirm);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
tokenShow:function(){
|
||||||
|
var inputPwd = layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: '验证面板密码',
|
||||||
|
shadeClose: true,
|
||||||
|
shade: 0.3,
|
||||||
|
area: ['380px', '190px'],
|
||||||
|
btn:['确定','取消'],
|
||||||
|
content:'<div class="Add_view" style="height:90px"><label>面板密码:</label><input name="panel_pwd" class=" bt-input-text" type="password"></div>',
|
||||||
|
yes:function(){
|
||||||
|
var passwordStr = $("input[name='panel_pwd']").val();
|
||||||
|
var index = layer.load(0, {shade: false});
|
||||||
|
$.post('/plugin?action=a&name=safelogin&s=GetServerToken',{password:passwordStr},function(token) {
|
||||||
|
layer.close(index);
|
||||||
|
if(token.status === false){
|
||||||
|
layer.msg(token.msg,{icon:2});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layer.close(inputPwd);
|
||||||
|
$("textarea[name='token']").val(token);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
btn2:function(){
|
||||||
|
layer.close(inputPwd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// SSH白名单——列表
|
||||||
|
SSH_White_List:function(){
|
||||||
|
var index = layer.load(0, {shade: false});
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=get_ssh_limit','',function(data){
|
||||||
|
$('#whiteListThree').empty();
|
||||||
|
var List = '';
|
||||||
|
if (data.length == 0){
|
||||||
|
$('.viewThree .status span:eq(0)').html('关闭');
|
||||||
|
$('.viewThree .glyphicon-pause').show();
|
||||||
|
$('.viewThree .glyphicon-play').hide();
|
||||||
|
}else {
|
||||||
|
$('.viewThree .status span:eq(0)').html('开启');
|
||||||
|
$('.viewThree .glyphicon-pause').hide();
|
||||||
|
$('.viewThree .glyphicon-play').show();
|
||||||
|
}
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
List = List + '<tr><td>'+ data[i] +'</td><td style="text-align:right;"><a href="javascript:;" ip-val="'+ data[i] +'" onclick="sagelogin.SSH_Del_White_List(event)" style="color:red">删除</a></td></tr>'
|
||||||
|
}
|
||||||
|
$('#whiteListThree').append(List);
|
||||||
|
layer.close(index);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// SSH白名单——删除
|
||||||
|
SSH_Del_White_List:function(ev){
|
||||||
|
var ip = ev.currentTarget.getAttribute('ip-val');
|
||||||
|
var confirm = layer.confirm('确定删除IP['+ ip +']限制地址?', {
|
||||||
|
btn: ['确认','取消'] //按钮
|
||||||
|
}, function(){
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=remove_ssh_limit',{ip:ip},function(data){
|
||||||
|
if (data.status) {
|
||||||
|
sagelogin.SSH_White_List();
|
||||||
|
layer.msg(data.msg,{icon:1});
|
||||||
|
}else {
|
||||||
|
layer.msg(data.msg,{icon:2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function(){
|
||||||
|
layer.close(confirm);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// SSH白名单——添加
|
||||||
|
SSH_Add_White_List:function(ip){
|
||||||
|
$.post('/plugin?action=a&name=safelogin&s=add_ssh_limit',{ip:ip},function(data){
|
||||||
|
layer.close(sagelogin.Addview);
|
||||||
|
if (data.status) {
|
||||||
|
sagelogin.SSH_White_List();
|
||||||
|
layer.msg(data.msg,{icon:1});
|
||||||
|
}else{
|
||||||
|
layer.msg(data.msg,{icon:2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// SSH日志管理
|
||||||
|
SSH_Defense_List:function(status){
|
||||||
|
$('.btnclick input').removeClass('btn-success').addClass('btn-default');
|
||||||
|
$('.btnclick input').eq(status).addClass('btn-success').removeClass('btn-default');
|
||||||
|
if (sagelogin.SSHlogList == '') {
|
||||||
|
$.get('/plugin?action=a&s=get_ssh_errorlogin&name=safelogin',function(data){
|
||||||
|
sagelogin.SSHlogList = data;
|
||||||
|
sagelogin.DefenseFor(sagelogin.SSHlogList.defense);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
switch(status) {
|
||||||
|
case 0:
|
||||||
|
sagelogin.DefenseFor(sagelogin.SSHlogList.defense);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sagelogin.DefenseFor(sagelogin.SSHlogList.intrusion);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
sagelogin.DefenseFor(sagelogin.SSHlogList.success);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// SSH日志渲染模板
|
||||||
|
DefenseFor:function(data){
|
||||||
|
var List = '';
|
||||||
|
$('#whiteListFour').empty();
|
||||||
|
for (var i = data.length - 1; i >= 0; i--) {
|
||||||
|
List = List + '<tr><td>'+data[i].address+'</td><td>' + data[i].user + '</td><td style="text-align:right">'+ data[i].date+'</td></tr>'
|
||||||
|
}
|
||||||
|
$('#whiteListFour').append(List);
|
||||||
|
},
|
||||||
|
// 面板管理
|
||||||
|
Panel_Admin:function(){
|
||||||
|
var confirm = layer.confirm('确定清除面板登录限制IP地址?', {
|
||||||
|
btn: ['确认','取消'] //按钮
|
||||||
|
}, function(){
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=close_panel_limit',function(data) {
|
||||||
|
if (data.status) {
|
||||||
|
layer.msg(data.msg,{icon:1});
|
||||||
|
sagelogin.Panel_White_List();
|
||||||
|
}else{
|
||||||
|
layer.msg(data.msg,{icon:2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function(){
|
||||||
|
layer.close(confirm);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
// 面板白名单——列表
|
||||||
|
Panel_White_List:function(){
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=get_panel_limit','',function(data){
|
||||||
|
$('#whiteListOne').empty();
|
||||||
|
var List = '';
|
||||||
|
if (data.length == 0){
|
||||||
|
$('.viewOne .status span:eq(0)').html('关闭');
|
||||||
|
$('.viewOne .glyphicon-pause').show();
|
||||||
|
$('.viewOne .glyphicon-play').hide();
|
||||||
|
}else {
|
||||||
|
$('.viewOne .status span:eq(0)').html('开启');
|
||||||
|
$('.viewOne .glyphicon-pause').hide();
|
||||||
|
$('.viewOne .glyphicon-play').show();
|
||||||
|
}
|
||||||
|
for (var i = 0; i < data.length; i++) {
|
||||||
|
List = List + '<tr><td>'+ data[i] +'</td><td style="text-align:right;"><a href="javascript:;" ip-val="'+ data[i] +'" onclick="sagelogin.Panel_Del_White_List(event)" style="color:red">删除</a></td></tr>'
|
||||||
|
}
|
||||||
|
$('#whiteListOne').append(List);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 面板白名单——删除
|
||||||
|
Panel_Del_White_List:function(ev){
|
||||||
|
var ip = ev.currentTarget.getAttribute('ip-val');
|
||||||
|
var confirm = layer.confirm('确定删除IP['+ ip +']限制地址?', {
|
||||||
|
btn: ['确认','取消'] //按钮
|
||||||
|
}, function(){
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=remove_ssh_limit',{ip:ip},function(data){
|
||||||
|
if (data.status) {
|
||||||
|
sagelogin.Panel_White_List();
|
||||||
|
layer.msg(data.msg,{icon:1});
|
||||||
|
}else {
|
||||||
|
layer.msg(data.msg,{icon:2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function(){
|
||||||
|
layer.close(confirm);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 面板白名单——添加
|
||||||
|
Panel_Add_White_List:function(ip){
|
||||||
|
$.post('/plugin?action=a&name=safelogin&s=add_panel_limit', {ip: ip}, function(data) {
|
||||||
|
layer.close(sagelogin.Addview);
|
||||||
|
if (data.status) {
|
||||||
|
sagelogin.Panel_White_List();
|
||||||
|
layer.msg(data.msg,{icon:1});
|
||||||
|
}else{
|
||||||
|
layer.msg(data.msg,{icon:2});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 面板日志——列表
|
||||||
|
Panel_journal:function(){
|
||||||
|
var index = layer.load(0, {shade: false});
|
||||||
|
$.get('/plugin?action=a&name=safelogin&s=get_login_log',function(data){
|
||||||
|
$('#whiteListTwo').empty();
|
||||||
|
var List = '';
|
||||||
|
sagelogin.PanelLogList = data;
|
||||||
|
for (var i = sagelogin.PanelLogList.length - 1; i >= 0; i--) {
|
||||||
|
List = List + '<tr><td>'+ sagelogin.PanelLogList[i].log +'</td><td style="text-align:right;">'+ sagelogin.PanelLogList[i].addtime +'</tr>';
|
||||||
|
}
|
||||||
|
$('#whiteListTwo').append(List);
|
||||||
|
layer.close(index);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// IP正则:192.168.1.0/24
|
||||||
|
CheckIP:function(ip) {
|
||||||
|
var reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\/\d{1,2})?$/;
|
||||||
|
return reg.test(ip);
|
||||||
|
},
|
||||||
|
CheckIPTwo:function(ip) {
|
||||||
|
var reg = /^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$/gi;
|
||||||
|
return reg.test(ip);
|
||||||
|
},
|
||||||
|
// 添加表单效验
|
||||||
|
addViewVul:function(status){
|
||||||
|
var ip = $('.addViewVul');
|
||||||
|
if (status) {
|
||||||
|
console.log(sagelogin.CheckIP(ip.val()));
|
||||||
|
if(sagelogin.CheckIPTwo(ip.val())){
|
||||||
|
ip.addClass('correct').removeClass('error');
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
ip.addClass('error').removeClass('correct');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
|
||||||
|
if(sagelogin.CheckIP(ip.val())){
|
||||||
|
ip.addClass('correct').removeClass('error');
|
||||||
|
return true;
|
||||||
|
}else {
|
||||||
|
ip.addClass('error').removeClass('correct');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 添加界面
|
||||||
|
Add_view:function(title,status){
|
||||||
|
var _this = this;
|
||||||
|
var text = ''
|
||||||
|
var statuss = true;
|
||||||
|
if (status) {
|
||||||
|
text = '';
|
||||||
|
statuss = true;
|
||||||
|
}else{
|
||||||
|
text = '<p style="color:red;margin: 5px 0px 0px 67px;font-size: 14px;">支持IP段,如:192.168.1.0/24</p>';
|
||||||
|
statuss = false;
|
||||||
|
}
|
||||||
|
sagelogin.Addview = layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: title,
|
||||||
|
shadeClose: true,
|
||||||
|
shade: 0.1,
|
||||||
|
area: ['380px', '200px'],
|
||||||
|
btn:['确定','取消'],
|
||||||
|
content:'<div class="Add_view"><label>IP地址:</label><input class="addViewVul bt-input-text" onchange="sagelogin.addViewVul('+ statuss +')" type="text">'+ text +'</div>',
|
||||||
|
yes:function(){
|
||||||
|
if (sagelogin.addViewVul(statuss)) {
|
||||||
|
if(status){
|
||||||
|
sagelogin.Panel_Add_White_List($('.addViewVul').val());
|
||||||
|
}else{
|
||||||
|
sagelogin.SSH_Add_White_List($('.addViewVul').val());
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
layer.msg('请输入合法的IP地址',{icon:2})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
btn2:function(){
|
||||||
|
layer.close(sagelogin.Addview);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$('.addViewVul').focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
import psutil
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
|
import urllib
|
||||||
|
import binascii
|
||||||
import json
|
import json
|
||||||
|
import public
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
import mw
|
|
||||||
|
|
||||||
|
|
||||||
def status():
|
def status():
|
||||||
@@ -17,4 +17,4 @@ def status():
|
|||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
func = sys.argv[1]
|
func = sys.argv[1]
|
||||||
if func == 'status':
|
if func == 'status':
|
||||||
print(status())
|
print status()
|
||||||
Executable
+16
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"sort": 7,
|
||||||
|
"ps": "最流行的SVN代码共享管理软件",
|
||||||
|
"shell": "install.sh",
|
||||||
|
"name": "csvn",
|
||||||
|
"title": "CSVN",
|
||||||
|
"versions": ["5.1"],
|
||||||
|
"updates":["5.1.4"],
|
||||||
|
"tip": "soft",
|
||||||
|
"checks": "server/csvn",
|
||||||
|
"author": "midoks",
|
||||||
|
"date": "2017-04-01",
|
||||||
|
"home": "https://www.collab.net",
|
||||||
|
"type": "SVN代码共享管理软件",
|
||||||
|
"pid": "3"
|
||||||
|
}
|
||||||
Executable
+43
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
curPath=`pwd`
|
||||||
|
rootPath=$(dirname "$curPath")
|
||||||
|
rootPath=$(dirname "$rootPath")
|
||||||
|
serverPath=$(dirname "$rootPath")
|
||||||
|
|
||||||
|
install_tmp=${rootPath}/tmp/bt_install.pl
|
||||||
|
|
||||||
|
|
||||||
|
CSVN_SOURCE='https://github.com/midoks/mdserver-web/releases/download/init/CollabNetSubversionEdge-5.1.4_linux-x86_64.tar.xz'
|
||||||
|
|
||||||
|
Install_csvn()
|
||||||
|
{
|
||||||
|
mkdir -p $serverPath/tmp
|
||||||
|
|
||||||
|
echo '正在安装脚本文件...' > $install_tmp
|
||||||
|
|
||||||
|
if [ ! -f $serverPath/tmp/csvn.tar.xz ];then
|
||||||
|
wget -O $serverPath/so/csvn.tar.xz ${CSVN_SOURCE}
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd $serverPath/tmp && tar -Jxf $serverPath/tmp/csvn.tar.xz
|
||||||
|
mv $serverPath/tmp/csvn $serverPath/csvn
|
||||||
|
|
||||||
|
echo '安装完成' > $install_tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
Uninstall_csvn()
|
||||||
|
{
|
||||||
|
rm -rf $serverPath/csvn
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
action=$1
|
||||||
|
host=$2
|
||||||
|
if [ "${1}" == 'install' ];then
|
||||||
|
Install_csvn
|
||||||
|
else
|
||||||
|
Uninstall_csvn
|
||||||
|
fi
|
||||||
@@ -1,704 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
import mw
|
|
||||||
|
|
||||||
|
|
||||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
|
||||||
info = mw.execShell(cmd)
|
|
||||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
|
||||||
sys.path.append(p)
|
|
||||||
import psutil
|
|
||||||
|
|
||||||
|
|
||||||
app_debug = False
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
app_debug = True
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginName():
|
|
||||||
return 'gogs'
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginDir():
|
|
||||||
return mw.getPluginDir() + '/' + getPluginName()
|
|
||||||
|
|
||||||
sys.path.append(getPluginDir() + "/class")
|
|
||||||
import mysqlDb
|
|
||||||
|
|
||||||
|
|
||||||
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(':', 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 getInitdConfTpl():
|
|
||||||
path = getPluginDir() + "/init.d/gogs.tpl"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getInitdConf():
|
|
||||||
path = getServerDir() + "/init.d/gogs"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getConf():
|
|
||||||
path = getServerDir() + "/custom/conf/app.ini"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getConfTpl():
|
|
||||||
path = getPluginDir() + "/conf/app.ini"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def status():
|
|
||||||
data = mw.execShell(
|
|
||||||
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
|
||||||
if data[0] == '':
|
|
||||||
return 'stop'
|
|
||||||
return 'start'
|
|
||||||
|
|
||||||
|
|
||||||
def getHomeDir():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
user = mw.execShell(
|
|
||||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
|
||||||
return '/Users/' + user
|
|
||||||
else:
|
|
||||||
return '/root'
|
|
||||||
|
|
||||||
|
|
||||||
def getRunUser():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
user = mw.execShell(
|
|
||||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
|
||||||
return user
|
|
||||||
else:
|
|
||||||
return 'root'
|
|
||||||
|
|
||||||
__SR = '''#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
export USER=%s
|
|
||||||
export HOME=%s && ''' % ( getRunUser(), getHomeDir())
|
|
||||||
|
|
||||||
|
|
||||||
def contentReplace(content):
|
|
||||||
|
|
||||||
service_path = mw.getServerDir()
|
|
||||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
|
||||||
content = content.replace('{$SERVER_PATH}', service_path)
|
|
||||||
content = content.replace('{$RUN_USER}', getRunUser())
|
|
||||||
content = content.replace('{$HOME_DIR}', getHomeDir())
|
|
||||||
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def initDreplace():
|
|
||||||
|
|
||||||
file_tpl = getInitdConfTpl()
|
|
||||||
service_path = mw.getServerDir()
|
|
||||||
|
|
||||||
initD_path = getServerDir() + '/init.d'
|
|
||||||
if not os.path.exists(initD_path):
|
|
||||||
os.mkdir(initD_path)
|
|
||||||
file_bin = initD_path + '/' + getPluginName()
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
conf_bin = getConf()
|
|
||||||
if not os.path.exists(conf_bin):
|
|
||||||
mw.execShell('mkdir -p ' + getServerDir() + '/custom/conf')
|
|
||||||
conf_tpl = getConfTpl()
|
|
||||||
content = mw.readFile(conf_tpl)
|
|
||||||
content = contentReplace(content)
|
|
||||||
mw.writeFile(conf_bin, content)
|
|
||||||
|
|
||||||
log_path = getServerDir() + '/log'
|
|
||||||
if not os.path.exists(log_path):
|
|
||||||
os.mkdir(log_path)
|
|
||||||
|
|
||||||
return file_bin
|
|
||||||
|
|
||||||
|
|
||||||
def getRootUrl():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'ROOT_URL\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getSshPort():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'SSH_PORT\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getHttpPort():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'HTTP_PORT\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getRootPath():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'ROOT\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getDbConfValue():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
|
|
||||||
rep_scope = "\[database\](.*?)\["
|
|
||||||
tmp = re.findall(rep_scope, content, re.S)
|
|
||||||
|
|
||||||
rep = '(\w*)\s*=\s*(.*)'
|
|
||||||
tmp = re.findall(rep, tmp[0])
|
|
||||||
r = {}
|
|
||||||
for x in range(len(tmp)):
|
|
||||||
k = tmp[x][0]
|
|
||||||
v = tmp[x][1]
|
|
||||||
r[k] = v
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
def pMysqlDb():
|
|
||||||
conf = getDbConfValue()
|
|
||||||
|
|
||||||
host = conf['HOST'].split(':')
|
|
||||||
conn = mysqlDb.mysqlDb()
|
|
||||||
|
|
||||||
conn.setHost(host[0])
|
|
||||||
conn.setUser(conf['USER'])
|
|
||||||
conn.setPwd(conf['PASSWD'])
|
|
||||||
conn.setPort(int(host[1]))
|
|
||||||
conn.setDb(conf['NAME'])
|
|
||||||
return conn
|
|
||||||
|
|
||||||
|
|
||||||
def isSqlError(mysqlMsg):
|
|
||||||
# 检测数据库执行错误
|
|
||||||
_mysqlMsg = str(mysqlMsg)
|
|
||||||
# print _mysqlMsg
|
|
||||||
if "MySQLdb" in _mysqlMsg:
|
|
||||||
return mw.returnData(False, 'MySQLdb组件缺失! <br>进入SSH命令行输入: pip install mysql-python')
|
|
||||||
if "2002," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库连接失败,请检查数据库服务是否启动!')
|
|
||||||
if "using password:" in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库管理密码错误!')
|
|
||||||
if "Connection refused" in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库连接失败,请检查数据库服务是否启动!')
|
|
||||||
if "1133," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库用户不存在!')
|
|
||||||
if "1007," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库已经存在!')
|
|
||||||
if "1044," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, mysqlMsg[1])
|
|
||||||
if "2003," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, "Can't connect to MySQL server on '127.0.0.1' (61)")
|
|
||||||
return mw.returnData(True, 'OK')
|
|
||||||
|
|
||||||
|
|
||||||
def start():
|
|
||||||
|
|
||||||
is_frist = True
|
|
||||||
conf_bin = getConf()
|
|
||||||
if os.path.exists(conf_bin):
|
|
||||||
is_frist = False
|
|
||||||
|
|
||||||
file = initDreplace()
|
|
||||||
|
|
||||||
if is_frist:
|
|
||||||
return "第一次启动Gogs,默认使用MySQL连接!<br>可以在配置文件中重新设置,再启动!"
|
|
||||||
|
|
||||||
conn = pMysqlDb()
|
|
||||||
list_table = conn.query('show tables')
|
|
||||||
data = isSqlError(list_table)
|
|
||||||
if not data['status']:
|
|
||||||
return data['msg']
|
|
||||||
|
|
||||||
data = mw.execShell(__SR + file + ' start')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return data[0]
|
|
||||||
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(__SR + file + ' stop')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return data[1]
|
|
||||||
|
|
||||||
|
|
||||||
def restart():
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(__SR + file + ' restart')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return data[1]
|
|
||||||
|
|
||||||
|
|
||||||
def reload():
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(__SR + file + ' reload')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return data[1]
|
|
||||||
|
|
||||||
|
|
||||||
def initdStatus():
|
|
||||||
if not app_debug:
|
|
||||||
os_name = mw.getOs()
|
|
||||||
if os_name == 'darwin':
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
initd_bin = getInitDFile()
|
|
||||||
if os.path.exists(initd_bin):
|
|
||||||
return 'ok'
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
|
|
||||||
def initdInstall():
|
|
||||||
import shutil
|
|
||||||
if not app_debug:
|
|
||||||
os_name = mw.getOs()
|
|
||||||
if os_name == 'darwin':
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
|
|
||||||
mem_bin = initDreplace()
|
|
||||||
initd_bin = getInitDFile()
|
|
||||||
shutil.copyfile(mem_bin, initd_bin)
|
|
||||||
mw.execShell('chmod +x ' + initd_bin)
|
|
||||||
mw.execShell('chkconfig --add ' + getPluginName())
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def initdUinstall():
|
|
||||||
if not app_debug:
|
|
||||||
os_name = mw.getOs()
|
|
||||||
if os_name == 'darwin':
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
initd_bin = getInitDFile()
|
|
||||||
os.remove(initd_bin)
|
|
||||||
mw.execShell('chkconfig --del ' + getPluginName())
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def runLog():
|
|
||||||
log_path = getServerDir() + '/log/gogs.log'
|
|
||||||
return log_path
|
|
||||||
|
|
||||||
|
|
||||||
def postReceiveLog():
|
|
||||||
log_path = getServerDir() + '/log/hooks/post-receive.log'
|
|
||||||
return log_path
|
|
||||||
|
|
||||||
|
|
||||||
def getGogsConf():
|
|
||||||
gets = [
|
|
||||||
{'name': 'DOMAIN', 'type': -1, 'ps': '服务器域名'},
|
|
||||||
{'name': 'ROOT_URL', 'type': -1, 'ps': '公开的完整URL路径'},
|
|
||||||
{'name': 'HTTP_ADDR', 'type': -1, 'ps': '应用HTTP监听地址'},
|
|
||||||
{'name': 'HTTP_PORT', 'type': -1, 'ps': '应用 HTTP 监听端口号'},
|
|
||||||
|
|
||||||
{'name': 'START_SSH_SERVER', 'type': 2, 'ps': '启动内置SSH服务器'},
|
|
||||||
{'name': 'SSH_PORT', 'type': -1, 'ps': 'SSH 端口号'},
|
|
||||||
|
|
||||||
{'name': 'REQUIRE_SIGNIN_VIEW', 'type': 2, 'ps': '强制登录浏览'},
|
|
||||||
{'name': 'ENABLE_CAPTCHA', 'type': 2, 'ps': '启用验证码服务'},
|
|
||||||
{'name': 'DISABLE_REGISTRATION', 'type': 2, 'ps': '禁止注册,只能由管理员创建帐号'},
|
|
||||||
{'name': 'ENABLE_NOTIFY_MAIL', 'type': 2, 'ps': '是否开启邮件通知'},
|
|
||||||
|
|
||||||
{'name': 'FORCE_PRIVATE', 'type': 2, 'ps': '强制要求所有新建的仓库都是私有'},
|
|
||||||
|
|
||||||
{'name': 'SHOW_FOOTER_BRANDING', 'type': 2, 'ps': 'Gogs推广信息'},
|
|
||||||
{'name': 'SHOW_FOOTER_VERSION', 'type': 2, 'ps': 'Gogs版本信息'},
|
|
||||||
{'name': 'SHOW_FOOTER_TEMPLATE_LOAD_TIME', 'type': 2, 'ps': 'Gogs模板加载时间'},
|
|
||||||
]
|
|
||||||
conf = mw.readFile(getConf())
|
|
||||||
result = []
|
|
||||||
|
|
||||||
for g in gets:
|
|
||||||
rep = g['name'] + '\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, conf)
|
|
||||||
if not tmp:
|
|
||||||
continue
|
|
||||||
g['value'] = tmp.groups()[0]
|
|
||||||
result.append(g)
|
|
||||||
return mw.getJson(result)
|
|
||||||
|
|
||||||
|
|
||||||
def submitGogsConf():
|
|
||||||
gets = ['DOMAIN',
|
|
||||||
'ROOT_URL',
|
|
||||||
'HTTP_ADDR',
|
|
||||||
'HTTP_PORT',
|
|
||||||
'START_SSH_SERVER',
|
|
||||||
'SSH_PORT',
|
|
||||||
'REQUIRE_SIGNIN_VIEW',
|
|
||||||
'FORCE_PRIVATE',
|
|
||||||
'ENABLE_CAPTCHA',
|
|
||||||
'DISABLE_REGISTRATION',
|
|
||||||
'ENABLE_NOTIFY_MAIL',
|
|
||||||
'SHOW_FOOTER_BRANDING',
|
|
||||||
'SHOW_FOOTER_VERSION',
|
|
||||||
'SHOW_FOOTER_TEMPLATE_LOAD_TIME']
|
|
||||||
args = getArgs()
|
|
||||||
filename = getConf()
|
|
||||||
conf = mw.readFile(filename)
|
|
||||||
for g in gets:
|
|
||||||
if g in args:
|
|
||||||
rep = g + '\s*=\s*(.*)'
|
|
||||||
val = g + ' = ' + args[g]
|
|
||||||
conf = re.sub(rep, val, conf)
|
|
||||||
mw.writeFile(filename, conf)
|
|
||||||
reload()
|
|
||||||
return mw.returnJson(True, '设置成功')
|
|
||||||
|
|
||||||
|
|
||||||
def userList():
|
|
||||||
import math
|
|
||||||
args = getArgs()
|
|
||||||
|
|
||||||
page = 1
|
|
||||||
page_size = 10
|
|
||||||
search = ''
|
|
||||||
if 'page' in args:
|
|
||||||
page = int(args['page'])
|
|
||||||
|
|
||||||
if 'page_size' in args:
|
|
||||||
page_size = int(args['page_size'])
|
|
||||||
|
|
||||||
if 'search' in args:
|
|
||||||
search = args['search']
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
data['root_url'] = getRootUrl()
|
|
||||||
|
|
||||||
pm = pMysqlDb()
|
|
||||||
start = (page - 1) * page_size
|
|
||||||
list_count = pm.query('select count(id) as num from user')
|
|
||||||
count = list_count[0][0]
|
|
||||||
|
|
||||||
list_data = pm.query(
|
|
||||||
'select id,name,email from user order by id desc limit ' + str(start) + ',' + str(page_size))
|
|
||||||
|
|
||||||
page_info = {'count': count, 'p': page,
|
|
||||||
'row': page_size, 'tojs': 'gogsUserList'}
|
|
||||||
data['list'] = mw.getPage(page_info)
|
|
||||||
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 getAllUserProject(user, search=''):
|
|
||||||
path = getRootPath() + '/' + user
|
|
||||||
dlist = []
|
|
||||||
if os.path.exists(path):
|
|
||||||
for filename in os.listdir(path):
|
|
||||||
tmp = {}
|
|
||||||
filePath = path + '/' + filename
|
|
||||||
if os.path.isdir(filePath):
|
|
||||||
if search == '':
|
|
||||||
tmp['name'] = filename.replace('.git', '')
|
|
||||||
dlist.append(tmp)
|
|
||||||
else:
|
|
||||||
if filename.find(search) != -1:
|
|
||||||
tmp['name'] = filename.replace('.git', '')
|
|
||||||
dlist.append(tmp)
|
|
||||||
return dlist
|
|
||||||
|
|
||||||
|
|
||||||
def checkProjectListIsHasScript(user, data):
|
|
||||||
path = getRootPath() + '/' + user
|
|
||||||
for x in range(len(data)):
|
|
||||||
name = data[x]['name'] + '.git'
|
|
||||||
path_tmp = path + '/' + name + '/custom_hooks/post-receive'
|
|
||||||
if os.path.exists(path_tmp):
|
|
||||||
data[x]['has_hook'] = True
|
|
||||||
else:
|
|
||||||
data[x]['has_hook'] = False
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def userProjectList():
|
|
||||||
import math
|
|
||||||
args = getArgs()
|
|
||||||
# print args
|
|
||||||
|
|
||||||
page = 1
|
|
||||||
page_size = 5
|
|
||||||
search = ''
|
|
||||||
|
|
||||||
if not 'name' in args:
|
|
||||||
return mw.returnJson(False, '缺少参数name')
|
|
||||||
if 'page' in args:
|
|
||||||
page = int(args['page'])
|
|
||||||
|
|
||||||
if 'page_size' in args:
|
|
||||||
page_size = int(args['page_size'])
|
|
||||||
|
|
||||||
if 'search' in args:
|
|
||||||
search = args['search']
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
ulist = getAllUserProject(args['name'])
|
|
||||||
dlist_sum = len(ulist)
|
|
||||||
|
|
||||||
start = (page - 1) * page_size
|
|
||||||
ret_data = ulist[start:start + page_size]
|
|
||||||
ret_data = checkProjectListIsHasScript(args['name'], ret_data)
|
|
||||||
|
|
||||||
data['root_url'] = getRootUrl()
|
|
||||||
data['data'] = ret_data
|
|
||||||
data['args'] = args
|
|
||||||
data['list'] = mw.getPage(
|
|
||||||
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectList'})
|
|
||||||
|
|
||||||
return mw.returnJson(True, 'OK', data)
|
|
||||||
|
|
||||||
|
|
||||||
def projectScriptEdit():
|
|
||||||
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')
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
post_receive = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/commit'
|
|
||||||
if os.path.exists(post_receive):
|
|
||||||
return mw.returnJson(True, 'OK', {'path': post_receive})
|
|
||||||
else:
|
|
||||||
return mw.returnJson(False, 'file does not exist')
|
|
||||||
|
|
||||||
|
|
||||||
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')
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
|
|
||||||
path = getRootPath() + '/' + user + '/' + name
|
|
||||||
post_receive_tpl = getPluginDir() + '/hook/post-receive.tpl'
|
|
||||||
post_receive = path + '/custom_hooks/post-receive'
|
|
||||||
|
|
||||||
if not os.path.exists(path + '/custom_hooks'):
|
|
||||||
mw.execShell('mkdir -p ' + path + '/custom_hooks')
|
|
||||||
|
|
||||||
pct_content = mw.readFile(post_receive_tpl)
|
|
||||||
pct_content = pct_content.replace('{$PATH}', path + '/custom_hooks')
|
|
||||||
mw.writeFile(post_receive, pct_content)
|
|
||||||
mw.execShell('chmod 777 ' + post_receive)
|
|
||||||
|
|
||||||
commit_tpl = getPluginDir() + '/hook/commit.tpl'
|
|
||||||
commit = path + '/custom_hooks/commit'
|
|
||||||
|
|
||||||
codeDir = mw.getRootDir() + '/git'
|
|
||||||
|
|
||||||
cc_content = mw.readFile(commit_tpl)
|
|
||||||
|
|
||||||
sshUrl = 'http://127.0.0.1:' + getHttpPort()
|
|
||||||
cc_content = cc_content.replace('{$GITROOTURL}', sshUrl)
|
|
||||||
cc_content = cc_content.replace('{$CODE_DIR}', codeDir)
|
|
||||||
cc_content = cc_content.replace('{$USERNAME}', user)
|
|
||||||
cc_content = cc_content.replace('{$PROJECT}', args['name'])
|
|
||||||
cc_content = cc_content.replace('{$WEB_ROOT}', mw.getWwwDir())
|
|
||||||
mw.writeFile(commit, cc_content)
|
|
||||||
mw.execShell('chmod 777 ' + commit)
|
|
||||||
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def projectScriptUnload():
|
|
||||||
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')
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
|
|
||||||
post_receive = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/post-receive'
|
|
||||||
mw.execShell('rm -f ' + post_receive)
|
|
||||||
|
|
||||||
commit = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/commit'
|
|
||||||
mw.execShell('rm -f ' + commit)
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def projectScriptDebug():
|
|
||||||
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')
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
commit_log = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/sh.log'
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
if os.path.exists(commit_log):
|
|
||||||
data['status'] = True
|
|
||||||
data['path'] = commit_log
|
|
||||||
else:
|
|
||||||
data['status'] = False
|
|
||||||
data['msg'] = '没有日志文件'
|
|
||||||
|
|
||||||
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 getRsaPublic():
|
|
||||||
path = getHomeDir()
|
|
||||||
path += '/.ssh/id_rsa.pub'
|
|
||||||
|
|
||||||
content = mw.readFile(path)
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['mw'] = content
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
|
|
||||||
def getTotalStatistics():
|
|
||||||
st = status()
|
|
||||||
data = {}
|
|
||||||
if st.strip() == 'start':
|
|
||||||
pm = pMysqlDb()
|
|
||||||
list_count = pm.query('select count(id) as num from repository')
|
|
||||||
|
|
||||||
if list_count.find("error") > -1:
|
|
||||||
data['status'] = False
|
|
||||||
data['count'] = 0
|
|
||||||
return mw.returnJson(False, 'fail', data)
|
|
||||||
|
|
||||||
data['status'] = True
|
|
||||||
data['count'] = count
|
|
||||||
data['ver'] = mw.readFile(getServerDir() + '/version.pl').strip()
|
|
||||||
return mw.returnJson(True, 'ok', data)
|
|
||||||
|
|
||||||
data['status'] = False
|
|
||||||
data['count'] = 0
|
|
||||||
return mw.returnJson(False, 'fail', data)
|
|
||||||
|
|
||||||
|
|
||||||
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_log':
|
|
||||||
print(runLog())
|
|
||||||
elif func == 'post_receive_log':
|
|
||||||
print(postReceiveLog())
|
|
||||||
elif func == 'conf':
|
|
||||||
print(getConf())
|
|
||||||
elif func == 'init_conf':
|
|
||||||
print(getInitdConf())
|
|
||||||
elif func == 'get_gogs_conf':
|
|
||||||
print(getGogsConf())
|
|
||||||
elif func == 'submit_gogs_conf':
|
|
||||||
print(submitGogsConf())
|
|
||||||
elif func == 'user_list':
|
|
||||||
print(userList())
|
|
||||||
elif func == 'user_project_list':
|
|
||||||
print(userProjectList())
|
|
||||||
elif func == 'project_script_edit':
|
|
||||||
print(projectScriptEdit())
|
|
||||||
elif func == 'project_script_load':
|
|
||||||
print(projectScriptLoad())
|
|
||||||
elif func == 'project_script_unload':
|
|
||||||
print(projectScriptUnload())
|
|
||||||
elif func == 'project_script_debug':
|
|
||||||
print(projectScriptDebug())
|
|
||||||
elif func == 'gogs_edit':
|
|
||||||
print(gogsEdit())
|
|
||||||
elif func == 'get_rsa_public':
|
|
||||||
print(getRsaPublic())
|
|
||||||
elif func == 'get_total_statistics':
|
|
||||||
print(getTotalStatistics())
|
|
||||||
else:
|
|
||||||
print('fail')
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# sys.path.append("/usr/local/lib/python3.6/site-packages")
|
|
||||||
|
|
||||||
|
|
||||||
class mysqlDb:
|
|
||||||
__DB_PASS = None
|
|
||||||
__DB_USER = 'root'
|
|
||||||
__DB_PORT = 3306
|
|
||||||
__DB_HOST = 'localhost'
|
|
||||||
__DB_NAME = 'test'
|
|
||||||
__DB_CONN = None
|
|
||||||
__DB_CUR = None
|
|
||||||
__DB_ERR = None
|
|
||||||
__DB_CNF = '/etc/my.cnf'
|
|
||||||
|
|
||||||
def __Conn(self):
|
|
||||||
'''连接MYSQL数据库'''
|
|
||||||
try:
|
|
||||||
socket = '/www/server/mysql/mysql.sock'
|
|
||||||
try:
|
|
||||||
import MySQLdb
|
|
||||||
except Exception as ex:
|
|
||||||
self.__DB_ERR = ex
|
|
||||||
return False
|
|
||||||
try:
|
|
||||||
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
port=self.__DB_PORT, db=self.__DB_NAME, charset="utf8", connect_timeout=10, unix_socket=socket)
|
|
||||||
except MySQLdb.Error as e:
|
|
||||||
self.__DB_HOST = '127.0.0.1'
|
|
||||||
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
|
|
||||||
port=self.__DB_PORT, db=self.__DB_NAME, charset="utf8", connect_timeout=10, unix_socket=socket)
|
|
||||||
self.__DB_CUR = self.__DB_CONN.cursor()
|
|
||||||
return True
|
|
||||||
|
|
||||||
except MySQLdb.Error as e:
|
|
||||||
self.__DB_ERR = e
|
|
||||||
return False
|
|
||||||
|
|
||||||
def setHost(self, host):
|
|
||||||
self.__DB_HOST = host
|
|
||||||
|
|
||||||
def setPwd(self, pwd):
|
|
||||||
self.__DB_PASS = pwd
|
|
||||||
|
|
||||||
def setUser(self, user):
|
|
||||||
self.__DB_USER = user
|
|
||||||
|
|
||||||
def setPort(self, port):
|
|
||||||
self.__DB_PORT = port
|
|
||||||
|
|
||||||
def setDb(self, name):
|
|
||||||
self.__DB_NAME = name
|
|
||||||
|
|
||||||
def getPwd(self):
|
|
||||||
return self.__DB_PASS
|
|
||||||
|
|
||||||
def execute(self, sql):
|
|
||||||
# 执行SQL语句返回受影响行
|
|
||||||
if not self.__Conn():
|
|
||||||
return self.__DB_ERR
|
|
||||||
try:
|
|
||||||
result = self.__DB_CUR.execute(sql)
|
|
||||||
self.__DB_CONN.commit()
|
|
||||||
self.__Close()
|
|
||||||
return result
|
|
||||||
except Exception as ex:
|
|
||||||
return ex
|
|
||||||
|
|
||||||
def query(self, sql):
|
|
||||||
# 执行SQL语句返回数据集
|
|
||||||
if not self.__Conn():
|
|
||||||
return self.__DB_ERR
|
|
||||||
try:
|
|
||||||
self.__DB_CUR.execute(sql)
|
|
||||||
result = self.__DB_CUR.fetchall()
|
|
||||||
# 将元组转换成列表
|
|
||||||
# data = map(list, result)
|
|
||||||
self.__Close()
|
|
||||||
return result
|
|
||||||
except Exception as ex:
|
|
||||||
return "error: " + str(ex)
|
|
||||||
|
|
||||||
# 关闭连接
|
|
||||||
def __Close(self):
|
|
||||||
self.__DB_CUR.close()
|
|
||||||
self.__DB_CONN.close()
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
APP_NAME = Gogs
|
|
||||||
RUN_USER = {$RUN_USER}
|
|
||||||
RUN_MODE = prod
|
|
||||||
|
|
||||||
[database]
|
|
||||||
DB_TYPE = mysql
|
|
||||||
HOST = 127.0.0.1:3306
|
|
||||||
NAME = gogs
|
|
||||||
USER = gogs
|
|
||||||
PASSWD = gogs
|
|
||||||
SSL_MODE = disable
|
|
||||||
PATH = data/gogs.db
|
|
||||||
|
|
||||||
[repository]
|
|
||||||
ROOT = {$ROOT_PATH}/gogs-repositories
|
|
||||||
FORCE_PRIVATE = true
|
|
||||||
|
|
||||||
[server]
|
|
||||||
DOMAIN = 127.0.0.1
|
|
||||||
HTTP_PORT = 3000
|
|
||||||
ROOT_URL = http://127.0.0.1:3000/
|
|
||||||
DISABLE_SSH = true
|
|
||||||
SSH_PORT = 2000
|
|
||||||
START_SSH_SERVER = false
|
|
||||||
OFFLINE_MODE = false
|
|
||||||
LANDING_PAGE = home
|
|
||||||
|
|
||||||
[mailer]
|
|
||||||
ENABLED = false
|
|
||||||
HOST = smtp.163.com:465
|
|
||||||
USER = midoks@163.com
|
|
||||||
PASSWD = ***
|
|
||||||
USE_PLAIN_TEXT = true
|
|
||||||
|
|
||||||
[service]
|
|
||||||
REGISTER_EMAIL_CONFIRM = false
|
|
||||||
ENABLE_NOTIFY_MAIL = false
|
|
||||||
DISABLE_REGISTRATION = true
|
|
||||||
ENABLE_CAPTCHA = true
|
|
||||||
REQUIRE_SIGNIN_VIEW = true
|
|
||||||
|
|
||||||
[picture]
|
|
||||||
DISABLE_GRAVATAR = false
|
|
||||||
ENABLE_FEDERATED_AVATAR = false
|
|
||||||
|
|
||||||
[session]
|
|
||||||
PROVIDER = file
|
|
||||||
|
|
||||||
[log]
|
|
||||||
MODE = console, file
|
|
||||||
LEVEL = Info
|
|
||||||
ROOT_PATH = {$SERVER_PATH}/gogs/log
|
|
||||||
|
|
||||||
[security]
|
|
||||||
INSTALL_LOCK = true
|
|
||||||
SECRET_KEY = jmGSJXDBH5Ng4wt
|
|
||||||
|
|
||||||
|
|
||||||
[other]
|
|
||||||
SHOW_FOOTER_BRANDING = false
|
|
||||||
SHOW_FOOTER_VERSION = false
|
|
||||||
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
|
|
||||||
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo `date`
|
|
||||||
|
|
||||||
GITADDR="{$GITROOTURL}/{$USERNAME}/{$PROJECT}.git"
|
|
||||||
GIT_SDIR="{$CODE_DIR}"
|
|
||||||
|
|
||||||
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
|
|
||||||
GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
|
|
||||||
|
|
||||||
|
|
||||||
git config --global credential.helper store
|
|
||||||
|
|
||||||
# echo $GIT_PROJECT_DIR
|
|
||||||
if [ ! -d $GIT_PROJECT_DIR ];then
|
|
||||||
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
|
|
||||||
git clone $GITADDR
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset GIT_DIR
|
|
||||||
cd $GIT_PROJECT_DIR && git pull
|
|
||||||
|
|
||||||
# func 2
|
|
||||||
# cd $GIT_PROJECT_DIR && env -i git pull origin master
|
|
||||||
|
|
||||||
|
|
||||||
#更新的目的地址
|
|
||||||
WEB_PATH={$WEB_ROOT}/{$USERNAME}/{$PROJECT}
|
|
||||||
mkdir -p $WEB_PATH
|
|
||||||
|
|
||||||
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
|
||||||
|
|
||||||
sysName=`uname`
|
|
||||||
if [ $sysName == 'Darwin' ]; then
|
|
||||||
USER=$(who | sed -n "2,1p" |awk '{print $1}')
|
|
||||||
chown -R $USER:staff $WEB_PATH
|
|
||||||
else
|
|
||||||
chown -R www:www $WEB_PATH
|
|
||||||
fi
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
echo `date`
|
|
||||||
|
|
||||||
GITADDR="{$GITROOTURL}/{$USERNAME}/{$PROJECT}"
|
|
||||||
GIT_SDIR="{$CODE_DIR}"
|
|
||||||
|
|
||||||
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
|
|
||||||
GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
|
|
||||||
|
|
||||||
# echo $GIT_PROJECT_DIR
|
|
||||||
if [ ! -d $GIT_PROJECT_DIR ];then
|
|
||||||
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
|
|
||||||
git clone $GITADDR
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset GIT_DIR
|
|
||||||
cd $GIT_PROJECT_DIR && git pull
|
|
||||||
|
|
||||||
# func 2
|
|
||||||
# cd $GIT_PROJECT_DIR && env -i git pull origin master
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
WEB_PATH={$WEB_ROOT}/{$USERNAME}/{$PROJECT}
|
|
||||||
mkdir -p $WEB_PATH
|
|
||||||
|
|
||||||
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
|
|
||||||
|
|
||||||
sysName=`uname`
|
|
||||||
if [ $sysName == 'Darwin' ]; then
|
|
||||||
USER=$(who | sed -n "2,1p" |awk '{print $1}')
|
|
||||||
chown -R $USER:staff $WEB_PATH
|
|
||||||
else
|
|
||||||
chown -R www:www $WEB_PATH
|
|
||||||
fi
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
sh -x {$PATH}/commit 2>{$PATH}/sh.log
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,23 +0,0 @@
|
|||||||
<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="pluginConfig('gogs',null, 'conf');">配置文件</p>
|
|
||||||
<p onclick="gogsSetConfig();">配置修改</p>
|
|
||||||
<p onclick="gogsUserList();">用户列表</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>
|
|
||||||
</div>
|
|
||||||
<div class="bt-w-con pd15">
|
|
||||||
<div class="soft-man-con"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
$.getScript( "/plugins/file?name=gogs&f=js/gogs.js");
|
|
||||||
pluginService('gogs');
|
|
||||||
</script>
|
|
||||||
@@ -1,749 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
|
|
||||||
import time
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
import mw
|
|
||||||
|
|
||||||
|
|
||||||
# cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
|
||||||
# info = mw.execShell(cmd)
|
|
||||||
# p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
|
||||||
# sys.path.append(p)
|
|
||||||
|
|
||||||
import psutil
|
|
||||||
|
|
||||||
|
|
||||||
app_debug = False
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
app_debug = True
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginName():
|
|
||||||
return 'gogs'
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginDir():
|
|
||||||
return mw.getPluginDir() + '/' + getPluginName()
|
|
||||||
|
|
||||||
sys.path.append(getPluginDir() + "/class")
|
|
||||||
import mysqlDb
|
|
||||||
|
|
||||||
|
|
||||||
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(':', 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 getInitdConfTpl():
|
|
||||||
path = getPluginDir() + "/init.d/gogs.tpl"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getInitdConf():
|
|
||||||
path = getServerDir() + "/init.d/gogs"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getConf():
|
|
||||||
path = getServerDir() + "/custom/conf/app.ini"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getConfTpl():
|
|
||||||
path = getPluginDir() + "/conf/app.ini"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def status():
|
|
||||||
data = mw.execShell(
|
|
||||||
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
|
||||||
if data[0] == '':
|
|
||||||
return 'stop'
|
|
||||||
return 'start'
|
|
||||||
|
|
||||||
|
|
||||||
def getHomeDir():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
user = mw.execShell(
|
|
||||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
|
||||||
return '/Users/' + user
|
|
||||||
else:
|
|
||||||
return '/root'
|
|
||||||
|
|
||||||
|
|
||||||
def getRunUser():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
user = mw.execShell(
|
|
||||||
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
|
|
||||||
return user
|
|
||||||
else:
|
|
||||||
return 'root'
|
|
||||||
|
|
||||||
__SR = '''#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
export USER=%s
|
|
||||||
export HOME=%s && ''' % ( getRunUser(), getHomeDir())
|
|
||||||
|
|
||||||
|
|
||||||
def contentReplace(content):
|
|
||||||
|
|
||||||
service_path = mw.getServerDir()
|
|
||||||
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
|
|
||||||
content = content.replace('{$SERVER_PATH}', service_path)
|
|
||||||
content = content.replace('{$RUN_USER}', getRunUser())
|
|
||||||
content = content.replace('{$HOME_DIR}', getHomeDir())
|
|
||||||
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def initDreplace():
|
|
||||||
|
|
||||||
file_tpl = getInitdConfTpl()
|
|
||||||
service_path = mw.getServerDir()
|
|
||||||
|
|
||||||
initD_path = getServerDir() + '/init.d'
|
|
||||||
if not os.path.exists(initD_path):
|
|
||||||
os.mkdir(initD_path)
|
|
||||||
file_bin = initD_path + '/' + getPluginName()
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
# conf_bin = getConf()
|
|
||||||
# if not os.path.exists(conf_bin):
|
|
||||||
# mw.execShell('mkdir -p ' + getServerDir() + '/custom/conf')
|
|
||||||
# conf_tpl = getConfTpl()
|
|
||||||
# content = mw.readFile(conf_tpl)
|
|
||||||
# content = contentReplace(content)
|
|
||||||
# mw.writeFile(conf_bin, content)
|
|
||||||
|
|
||||||
# systemd
|
|
||||||
systemDir = mw.systemdCfgDir()
|
|
||||||
systemService = systemDir + '/gogs.service'
|
|
||||||
systemServiceTpl = getPluginDir() + '/init.d/gogs.service.tpl'
|
|
||||||
if os.path.exists(systemDir) and not os.path.exists(systemService):
|
|
||||||
service_path = mw.getServerDir()
|
|
||||||
se_content = mw.readFile(systemServiceTpl)
|
|
||||||
se_content = se_content.replace('{$SERVER_PATH}', service_path)
|
|
||||||
mw.writeFile(systemService, se_content)
|
|
||||||
mw.execShell('systemctl daemon-reload')
|
|
||||||
|
|
||||||
log_path = getServerDir() + '/log'
|
|
||||||
if not os.path.exists(log_path):
|
|
||||||
os.mkdir(log_path)
|
|
||||||
|
|
||||||
return file_bin
|
|
||||||
|
|
||||||
|
|
||||||
def getRootUrl():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'ROOT_URL\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if tmp:
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
rep = 'EXTERNAL_URL\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if tmp:
|
|
||||||
return tmp.groups()[0]
|
|
||||||
return ''
|
|
||||||
|
|
||||||
|
|
||||||
def getSshPort():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'SSH_PORT\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getHttpPort():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'HTTP_PORT\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getRootPath():
|
|
||||||
content = mw.readFile(getConf())
|
|
||||||
rep = 'ROOT\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
if not tmp:
|
|
||||||
return ''
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getDbConfValue():
|
|
||||||
conf = getConf()
|
|
||||||
if not os.path.exists(conf):
|
|
||||||
return {}
|
|
||||||
|
|
||||||
content = mw.readFile(conf)
|
|
||||||
rep_scope = "\[database\](.*?)\["
|
|
||||||
tmp = re.findall(rep_scope, content, re.S)
|
|
||||||
|
|
||||||
rep = '(\w*)\s*=\s*(.*)'
|
|
||||||
tmp = re.findall(rep, tmp[0])
|
|
||||||
r = {}
|
|
||||||
for x in range(len(tmp)):
|
|
||||||
k = tmp[x][0]
|
|
||||||
v = tmp[x][1]
|
|
||||||
r[k] = v
|
|
||||||
return r
|
|
||||||
|
|
||||||
|
|
||||||
def pMysqlDb(conf):
|
|
||||||
|
|
||||||
host = conf['HOST'].split(':')
|
|
||||||
conn = mysqlDb.mysqlDb()
|
|
||||||
|
|
||||||
conn.setHost(host[0])
|
|
||||||
conn.setUser(conf['USER'])
|
|
||||||
conn.setPwd(conf['PASSWD'])
|
|
||||||
conn.setPort(int(host[1]))
|
|
||||||
conn.setDb(conf['NAME'])
|
|
||||||
return conn
|
|
||||||
|
|
||||||
|
|
||||||
def pSqliteDb(conf):
|
|
||||||
# print(conf)
|
|
||||||
import db
|
|
||||||
psDb = db.Sql()
|
|
||||||
|
|
||||||
# 默认
|
|
||||||
gsdir = getServerDir() + '/data'
|
|
||||||
dbname = 'gogs'
|
|
||||||
if conf['PATH'][0] == '/':
|
|
||||||
# 绝对路径
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
path = conf['PATH'].split('/')
|
|
||||||
gsdir = getServerDir() + '/' + path[0]
|
|
||||||
dbname = path[1].split('.')[0]
|
|
||||||
|
|
||||||
# print(gsdir, dbname)
|
|
||||||
psDb.dbPos(gsdir, dbname)
|
|
||||||
return psDb
|
|
||||||
|
|
||||||
|
|
||||||
def getGogsDbType(conf):
|
|
||||||
|
|
||||||
if 'DB_TYPE' in conf:
|
|
||||||
return conf['DB_TYPE']
|
|
||||||
|
|
||||||
if 'TYPE' in conf:
|
|
||||||
return conf['TYPE']
|
|
||||||
|
|
||||||
return 'NONE'
|
|
||||||
|
|
||||||
|
|
||||||
def pQuery(sql):
|
|
||||||
conf = getDbConfValue()
|
|
||||||
gtype = getGogsDbType(conf)
|
|
||||||
if gtype == 'sqlite3':
|
|
||||||
db = pSqliteDb(conf)
|
|
||||||
data = db.query(sql, []).fetchall()
|
|
||||||
return data
|
|
||||||
elif gtype == 'mysql':
|
|
||||||
db = pMysqlDb(conf)
|
|
||||||
return db.query(sql)
|
|
||||||
|
|
||||||
print("仅支持mysql|sqlite3配置")
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
|
|
||||||
def isSqlError(mysqlMsg):
|
|
||||||
# 检测数据库执行错误
|
|
||||||
_mysqlMsg = str(mysqlMsg)
|
|
||||||
# print _mysqlMsg
|
|
||||||
if "MySQLdb" in _mysqlMsg:
|
|
||||||
return mw.returnData(False, 'MySQLdb组件缺失! <br>进入SSH命令行输入: pip install mysql-python')
|
|
||||||
if "2002," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库连接失败,请检查数据库服务是否启动!')
|
|
||||||
if "using password:" in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库管理密码错误!')
|
|
||||||
if "Connection refused" in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库连接失败,请检查数据库服务是否启动!')
|
|
||||||
if "1133," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库用户不存在!')
|
|
||||||
if "1007," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, '数据库已经存在!')
|
|
||||||
if "1044," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, mysqlMsg[1])
|
|
||||||
if "2003," in _mysqlMsg:
|
|
||||||
return mw.returnData(False, "Can't connect to MySQL server on '127.0.0.1' (61)")
|
|
||||||
return mw.returnData(True, 'OK')
|
|
||||||
|
|
||||||
|
|
||||||
def gogsOp(method):
|
|
||||||
file = initDreplace()
|
|
||||||
|
|
||||||
if not mw.isAppleSystem():
|
|
||||||
data = mw.execShell('systemctl ' + method + ' gogs')
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
data = mw.execShell(__SR + file + ' ' + method)
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return data[0]
|
|
||||||
|
|
||||||
|
|
||||||
def start():
|
|
||||||
return gogsOp('start')
|
|
||||||
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
return gogsOp('stop')
|
|
||||||
|
|
||||||
|
|
||||||
def restart():
|
|
||||||
return gogsOp('restart')
|
|
||||||
|
|
||||||
|
|
||||||
def reload():
|
|
||||||
return gogsOp('reload')
|
|
||||||
|
|
||||||
|
|
||||||
def initdStatus():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
|
|
||||||
shell_cmd = 'systemctl status gogs | grep loaded | grep "enabled;"'
|
|
||||||
data = mw.execShell(shell_cmd)
|
|
||||||
if data[0] == '':
|
|
||||||
return 'fail'
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def initdInstall():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
|
|
||||||
mw.execShell('systemctl enable gogs')
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def initdUinstall():
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
|
|
||||||
mw.execShell('systemctl disable gogs')
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def runLog():
|
|
||||||
log_path = getServerDir() + '/log/gogs.log'
|
|
||||||
return log_path
|
|
||||||
|
|
||||||
|
|
||||||
def postReceiveLog():
|
|
||||||
log_path = getServerDir() + '/log/hooks/post-receive.log'
|
|
||||||
return log_path
|
|
||||||
|
|
||||||
|
|
||||||
def getGogsConf():
|
|
||||||
conf = getConf()
|
|
||||||
if not os.path.exists(conf):
|
|
||||||
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
|
|
||||||
|
|
||||||
gets = [
|
|
||||||
{'name': 'DOMAIN', 'type': -1, 'ps': '服务器域名'},
|
|
||||||
{'name': 'ROOT_URL', 'type': -1, 'ps': '公开的完整URL路径'},
|
|
||||||
{'name': 'HTTP_ADDR', 'type': -1, 'ps': '应用HTTP监听地址'},
|
|
||||||
{'name': 'HTTP_PORT', 'type': -1, 'ps': '应用 HTTP 监听端口号'},
|
|
||||||
|
|
||||||
{'name': 'START_SSH_SERVER', 'type': 2, 'ps': '启动内置SSH服务器'},
|
|
||||||
{'name': 'SSH_PORT', 'type': -1, 'ps': 'SSH 端口号'},
|
|
||||||
|
|
||||||
{'name': 'REQUIRE_SIGNIN_VIEW', 'type': 2, 'ps': '强制登录浏览'},
|
|
||||||
{'name': 'ENABLE_CAPTCHA', 'type': 2, 'ps': '启用验证码服务'},
|
|
||||||
{'name': 'DISABLE_REGISTRATION', 'type': 2, 'ps': '禁止注册,只能由管理员创建帐号'},
|
|
||||||
{'name': 'ENABLE_NOTIFY_MAIL', 'type': 2, 'ps': '是否开启邮件通知'},
|
|
||||||
|
|
||||||
{'name': 'FORCE_PRIVATE', 'type': 2, 'ps': '强制要求所有新建的仓库都是私有'},
|
|
||||||
|
|
||||||
{'name': 'SHOW_FOOTER_BRANDING', 'type': 2, 'ps': 'Gogs推广信息'},
|
|
||||||
{'name': 'SHOW_FOOTER_VERSION', 'type': 2, 'ps': 'Gogs版本信息'},
|
|
||||||
{'name': 'SHOW_FOOTER_TEMPLATE_LOAD_TIME', 'type': 2, 'ps': 'Gogs模板加载时间'},
|
|
||||||
]
|
|
||||||
conf = mw.readFile(conf)
|
|
||||||
result = []
|
|
||||||
|
|
||||||
for g in gets:
|
|
||||||
rep = g['name'] + '\s*=\s*(.*)'
|
|
||||||
tmp = re.search(rep, conf)
|
|
||||||
if not tmp:
|
|
||||||
continue
|
|
||||||
g['value'] = tmp.groups()[0]
|
|
||||||
result.append(g)
|
|
||||||
return mw.returnJson(True, 'OK', result)
|
|
||||||
|
|
||||||
|
|
||||||
def submitGogsConf():
|
|
||||||
gets = ['DOMAIN',
|
|
||||||
'ROOT_URL',
|
|
||||||
'HTTP_ADDR',
|
|
||||||
'HTTP_PORT',
|
|
||||||
'START_SSH_SERVER',
|
|
||||||
'SSH_PORT',
|
|
||||||
'REQUIRE_SIGNIN_VIEW',
|
|
||||||
'FORCE_PRIVATE',
|
|
||||||
'ENABLE_CAPTCHA',
|
|
||||||
'DISABLE_REGISTRATION',
|
|
||||||
'ENABLE_NOTIFY_MAIL',
|
|
||||||
'SHOW_FOOTER_BRANDING',
|
|
||||||
'SHOW_FOOTER_VERSION',
|
|
||||||
'SHOW_FOOTER_TEMPLATE_LOAD_TIME']
|
|
||||||
args = getArgs()
|
|
||||||
filename = getConf()
|
|
||||||
conf = mw.readFile(filename)
|
|
||||||
for g in gets:
|
|
||||||
if g in args:
|
|
||||||
rep = g + '\s*=\s*(.*)'
|
|
||||||
val = g + ' = ' + args[g]
|
|
||||||
conf = re.sub(rep, val, conf)
|
|
||||||
mw.writeFile(filename, conf)
|
|
||||||
reload()
|
|
||||||
return mw.returnJson(True, '设置成功')
|
|
||||||
|
|
||||||
|
|
||||||
def userList():
|
|
||||||
|
|
||||||
conf = getConf()
|
|
||||||
if not os.path.exists(conf):
|
|
||||||
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
|
|
||||||
|
|
||||||
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']
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
data['root_url'] = getRootUrl()
|
|
||||||
|
|
||||||
start = (page - 1) * page_size
|
|
||||||
list_count = pQuery('select count(id) as num from user')
|
|
||||||
count = list_count[0][0]
|
|
||||||
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': '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 getAllUserProject(user, search=''):
|
|
||||||
path = getRootPath() + '/' + user
|
|
||||||
dlist = []
|
|
||||||
if os.path.exists(path):
|
|
||||||
for filename in os.listdir(path):
|
|
||||||
tmp = {}
|
|
||||||
filePath = path + '/' + filename
|
|
||||||
if os.path.isdir(filePath):
|
|
||||||
if search == '':
|
|
||||||
tmp['name'] = filename.replace('.git', '')
|
|
||||||
dlist.append(tmp)
|
|
||||||
else:
|
|
||||||
if filename.find(search) != -1:
|
|
||||||
tmp['name'] = filename.replace('.git', '')
|
|
||||||
dlist.append(tmp)
|
|
||||||
return dlist
|
|
||||||
|
|
||||||
|
|
||||||
def checkProjectListIsHasScript(user, data):
|
|
||||||
path = getRootPath() + '/' + user
|
|
||||||
for x in range(len(data)):
|
|
||||||
name = data[x]['name'] + '.git'
|
|
||||||
path_tmp = path + '/' + name + '/custom_hooks/post-receive'
|
|
||||||
if os.path.exists(path_tmp):
|
|
||||||
data[x]['has_hook'] = True
|
|
||||||
else:
|
|
||||||
data[x]['has_hook'] = False
|
|
||||||
return data
|
|
||||||
|
|
||||||
|
|
||||||
def userProjectList():
|
|
||||||
import math
|
|
||||||
args = getArgs()
|
|
||||||
# print args
|
|
||||||
|
|
||||||
page = 1
|
|
||||||
page_size = 5
|
|
||||||
search = ''
|
|
||||||
|
|
||||||
if not 'name' in args:
|
|
||||||
return mw.returnJson(False, '缺少参数name')
|
|
||||||
if 'page' in args:
|
|
||||||
page = int(args['page'])
|
|
||||||
|
|
||||||
if 'page_size' in args:
|
|
||||||
page_size = int(args['page_size'])
|
|
||||||
|
|
||||||
if 'search' in args:
|
|
||||||
search = args['search']
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
|
|
||||||
ulist = getAllUserProject(args['name'])
|
|
||||||
dlist_sum = len(ulist)
|
|
||||||
|
|
||||||
start = (page - 1) * page_size
|
|
||||||
ret_data = ulist[start:start + page_size]
|
|
||||||
ret_data = checkProjectListIsHasScript(args['name'], ret_data)
|
|
||||||
|
|
||||||
data['root_url'] = getRootUrl()
|
|
||||||
data['data'] = ret_data
|
|
||||||
data['args'] = args
|
|
||||||
data['list'] = mw.getPage(
|
|
||||||
{'count': dlist_sum, 'p': page, 'row': page_size, 'tojs': 'userProjectList'})
|
|
||||||
|
|
||||||
return mw.returnJson(True, 'OK', data)
|
|
||||||
|
|
||||||
|
|
||||||
def projectScriptEdit():
|
|
||||||
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')
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
post_receive = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/commit'
|
|
||||||
if os.path.exists(post_receive):
|
|
||||||
return mw.returnJson(True, 'OK', {'path': post_receive})
|
|
||||||
else:
|
|
||||||
return mw.returnJson(False, 'file does not exist')
|
|
||||||
|
|
||||||
|
|
||||||
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')
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
|
|
||||||
path = getRootPath() + '/' + user + '/' + name
|
|
||||||
post_receive_tpl = getPluginDir() + '/hook/post-receive.tpl'
|
|
||||||
post_receive = path + '/custom_hooks/post-receive'
|
|
||||||
|
|
||||||
if not os.path.exists(path + '/custom_hooks'):
|
|
||||||
mw.execShell('mkdir -p ' + path + '/custom_hooks')
|
|
||||||
|
|
||||||
pct_content = mw.readFile(post_receive_tpl)
|
|
||||||
pct_content = pct_content.replace('{$PATH}', path + '/custom_hooks')
|
|
||||||
mw.writeFile(post_receive, pct_content)
|
|
||||||
mw.execShell('chmod 777 ' + post_receive)
|
|
||||||
|
|
||||||
commit_tpl = getPluginDir() + '/hook/commit.tpl'
|
|
||||||
commit = path + '/custom_hooks/commit'
|
|
||||||
|
|
||||||
codeDir = mw.getRootDir() + '/git'
|
|
||||||
|
|
||||||
cc_content = mw.readFile(commit_tpl)
|
|
||||||
|
|
||||||
gitPath = getRootPath()
|
|
||||||
cc_content = cc_content.replace('{$GITROOTURL}', gitPath)
|
|
||||||
cc_content = cc_content.replace('{$CODE_DIR}', codeDir)
|
|
||||||
cc_content = cc_content.replace('{$USERNAME}', user)
|
|
||||||
cc_content = cc_content.replace('{$PROJECT}', args['name'])
|
|
||||||
cc_content = cc_content.replace('{$WEB_ROOT}', mw.getWwwDir())
|
|
||||||
mw.writeFile(commit, cc_content)
|
|
||||||
mw.execShell('chmod 777 ' + commit)
|
|
||||||
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def projectScriptUnload():
|
|
||||||
args = getArgs()
|
|
||||||
data = checkArgs(args, ['user', 'name'])
|
|
||||||
if not data[0]:
|
|
||||||
return data[1]
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
|
|
||||||
post_receive = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/post-receive'
|
|
||||||
mw.execShell('rm -f ' + post_receive)
|
|
||||||
|
|
||||||
commit = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/commit'
|
|
||||||
mw.execShell('rm -f ' + commit)
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def projectScriptDebug():
|
|
||||||
args = getArgs()
|
|
||||||
data = checkArgs(args, ['user', 'name'])
|
|
||||||
if not data[0]:
|
|
||||||
return data[1]
|
|
||||||
|
|
||||||
user = args['user']
|
|
||||||
name = args['name'] + '.git'
|
|
||||||
commit_log = getRootPath() + '/' + user + '/' + name + \
|
|
||||||
'/custom_hooks/sh.log'
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
if os.path.exists(commit_log):
|
|
||||||
data['status'] = True
|
|
||||||
data['path'] = commit_log
|
|
||||||
else:
|
|
||||||
data['status'] = False
|
|
||||||
data['msg'] = '没有日志文件'
|
|
||||||
|
|
||||||
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 getRsaPublic():
|
|
||||||
path = getHomeDir()
|
|
||||||
path += '/.ssh/id_rsa.pub'
|
|
||||||
|
|
||||||
content = mw.readFile(path)
|
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['mw'] = content
|
|
||||||
return mw.getJson(data)
|
|
||||||
|
|
||||||
|
|
||||||
def getTotalStatistics():
|
|
||||||
st = status()
|
|
||||||
data = {}
|
|
||||||
if st.strip() == 'start':
|
|
||||||
list_count = pQuery('select count(id) as num from repository')
|
|
||||||
|
|
||||||
if list_count.find("error") > -1:
|
|
||||||
data['status'] = False
|
|
||||||
data['count'] = 0
|
|
||||||
return mw.returnJson(False, 'fail', data)
|
|
||||||
|
|
||||||
data['status'] = True
|
|
||||||
data['count'] = count
|
|
||||||
data['ver'] = mw.readFile(getServerDir() + '/version.pl').strip()
|
|
||||||
return mw.returnJson(True, 'ok', data)
|
|
||||||
|
|
||||||
data['status'] = False
|
|
||||||
data['count'] = 0
|
|
||||||
return mw.returnJson(False, 'fail', data)
|
|
||||||
|
|
||||||
|
|
||||||
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_log':
|
|
||||||
print(runLog())
|
|
||||||
elif func == 'post_receive_log':
|
|
||||||
print(postReceiveLog())
|
|
||||||
elif func == 'conf':
|
|
||||||
print(getConf())
|
|
||||||
elif func == 'init_conf':
|
|
||||||
print(getInitdConf())
|
|
||||||
elif func == 'get_gogs_conf':
|
|
||||||
print(getGogsConf())
|
|
||||||
elif func == 'submit_gogs_conf':
|
|
||||||
print(submitGogsConf())
|
|
||||||
elif func == 'user_list':
|
|
||||||
print(userList())
|
|
||||||
elif func == 'user_project_list':
|
|
||||||
print(userProjectList())
|
|
||||||
elif func == 'project_script_edit':
|
|
||||||
print(projectScriptEdit())
|
|
||||||
elif func == 'project_script_load':
|
|
||||||
print(projectScriptLoad())
|
|
||||||
elif func == 'project_script_unload':
|
|
||||||
print(projectScriptUnload())
|
|
||||||
elif func == 'project_script_debug':
|
|
||||||
print(projectScriptDebug())
|
|
||||||
elif func == 'gogs_edit':
|
|
||||||
print(gogsEdit())
|
|
||||||
elif func == 'get_rsa_public':
|
|
||||||
print(getRsaPublic())
|
|
||||||
elif func == 'get_total_statistics':
|
|
||||||
print(getTotalStatistics())
|
|
||||||
else:
|
|
||||||
print('fail')
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"ps": "Gogs是一款极易搭建的自助Git服务",
|
|
||||||
"name": "gogs",
|
|
||||||
"title": "Gogs",
|
|
||||||
"versions": ["0.11.86","0.12.9"],
|
|
||||||
"tip": "soft",
|
|
||||||
"checks": "server/gogs",
|
|
||||||
"path":"server/gogs",
|
|
||||||
"author": "midoks",
|
|
||||||
"date": "2018-04-01",
|
|
||||||
"home": "https://gogs.io",
|
|
||||||
"type": "Git服务器",
|
|
||||||
"shell": "install.sh",
|
|
||||||
"pid": "3",
|
|
||||||
"sort": 7
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Gogs
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
# Modify these two values and uncomment them if you have
|
|
||||||
# repos with lots of files and get an HTTP error 500 because
|
|
||||||
# of that
|
|
||||||
###
|
|
||||||
#LimitMEMLOCK=infinity
|
|
||||||
#LimitNOFILE=65535
|
|
||||||
Type=simple
|
|
||||||
User=git
|
|
||||||
Group=git
|
|
||||||
WorkingDirectory={$SERVER_PATH}/gogs
|
|
||||||
ExecStart={$SERVER_PATH}/gogs/gogs web
|
|
||||||
ExecReload=/bin/kill -USR2 $MAINPID
|
|
||||||
Restart=always
|
|
||||||
Environment=USER=git HOME=/home/git
|
|
||||||
|
|
||||||
# Some distributions may not support these hardening directives. If you cannot start the service due
|
|
||||||
# to an unknown option, comment out the ones not supported by your version of systemd.
|
|
||||||
ProtectSystem=full
|
|
||||||
PrivateDevices=yes
|
|
||||||
PrivateTmp=yes
|
|
||||||
NoNewPrivileges=true
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Gogs
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=forking
|
|
||||||
ExecStart={$SERVER_PATH}/gogs/init.d/gogs start
|
|
||||||
ExecStop={$SERVER_PATH}/gogs/init.d/gogs stop
|
|
||||||
RemainAfterExit=yes
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# /etc/rc.d/init.d/gogs
|
|
||||||
#
|
|
||||||
# Runs the Gogs
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# chkconfig: - 85 15
|
|
||||||
#
|
|
||||||
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: gogs
|
|
||||||
# Required-Start: $remote_fs $syslog
|
|
||||||
# Required-Stop: $remote_fs $syslog
|
|
||||||
# Should-Start: mysql postgresql
|
|
||||||
# Should-Stop: mysql postgresql
|
|
||||||
# Default-Start: 2 3 4 5
|
|
||||||
# Default-Stop: 0 1 6
|
|
||||||
# Short-Description: Start gogs at boot time.
|
|
||||||
# Description: Control gogs.
|
|
||||||
### END INIT INFO
|
|
||||||
|
|
||||||
# Source function library.
|
|
||||||
if [ -f /etc/init.d/functions ];then
|
|
||||||
. /etc/init.d/functions
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f /etc/rc.d/init.d/functions ];then
|
|
||||||
. /etc/rc.d/init.d/functions
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Default values
|
|
||||||
export HOME={$HOME_DIR}
|
|
||||||
export USER={$RUN_USER}
|
|
||||||
NAME=gogs
|
|
||||||
GOGS_HOME={$SERVER_PATH}/gogs
|
|
||||||
GOGS_PATH=${GOGS_HOME}/$NAME
|
|
||||||
GOGS_USER={$RUN_USER}
|
|
||||||
SERVICENAME="Gogs"
|
|
||||||
LOCKFILE=/tmp/gogs.lock
|
|
||||||
LOGPATH=${GOGS_HOME}/log
|
|
||||||
LOGFILE=${LOGPATH}/gogs.log
|
|
||||||
RETVAL=0
|
|
||||||
|
|
||||||
|
|
||||||
[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME
|
|
||||||
DAEMON_OPTS="--check $NAME"
|
|
||||||
[ ! -z "$GOGS_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${GOGS_USER}"
|
|
||||||
|
|
||||||
|
|
||||||
status(){
|
|
||||||
isStart=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
|
|
||||||
if [ "$isStart" == '' ];then
|
|
||||||
echo -e "${SERVICENAME} not running"
|
|
||||||
else
|
|
||||||
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
start() {
|
|
||||||
isStart=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
|
|
||||||
if [ "$isStart" != '' ];then
|
|
||||||
echo "${SERVICENAME}(pid $(echo $isStart)) already running"
|
|
||||||
return $RETVAL
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ${GOGS_HOME}
|
|
||||||
echo -e "Starting ${SERVICENAME}: \c"
|
|
||||||
${GOGS_PATH} web > ${LOGFILE} 2>&1 &
|
|
||||||
RETVAL=$?
|
|
||||||
[ $RETVAL = 0 ] && touch ${LOCKFILE} && echo -e "\033[32mdone\033[0m"
|
|
||||||
return $RETVAL
|
|
||||||
}
|
|
||||||
|
|
||||||
stop() {
|
|
||||||
|
|
||||||
pids=`ps -ef|grep 'gogs web' |grep -v grep|awk '{print $2}'`
|
|
||||||
arr=($pids)
|
|
||||||
echo -e "Stopping gogs... \c"
|
|
||||||
for p in ${arr[@]}
|
|
||||||
do
|
|
||||||
kill -9 $p
|
|
||||||
done
|
|
||||||
echo -e "\033[32mdone\033[0m"
|
|
||||||
}
|
|
||||||
|
|
||||||
case "$1" in
|
|
||||||
start)
|
|
||||||
start
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
stop
|
|
||||||
;;
|
|
||||||
status)
|
|
||||||
status
|
|
||||||
;;
|
|
||||||
restart)
|
|
||||||
stop
|
|
||||||
start
|
|
||||||
;;
|
|
||||||
reload)
|
|
||||||
stop
|
|
||||||
start
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Usage: ${NAME} {start|stop|status|restart}"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
exit $RETVAL
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
curPath=`pwd`
|
|
||||||
rootPath=$(dirname "$curPath")
|
|
||||||
rootPath=$(dirname "$rootPath")
|
|
||||||
serverPath=$(dirname "$rootPath")
|
|
||||||
|
|
||||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
|
||||||
|
|
||||||
|
|
||||||
GOGS_DOWNLOAD='https://dl.gogs.io'
|
|
||||||
|
|
||||||
getOs(){
|
|
||||||
os=`uname`
|
|
||||||
if [ "Darwin" == "$os" ];then
|
|
||||||
echo 'darwin'
|
|
||||||
else
|
|
||||||
echo 'linux'
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
getBit(){
|
|
||||||
echo `getconf LONG_BIT`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Install_gogs()
|
|
||||||
{
|
|
||||||
mkdir -p $serverPath/source/gogs
|
|
||||||
|
|
||||||
echo '正在安装脚本文件...' > $install_tmp
|
|
||||||
version=$1
|
|
||||||
os=`getOs`
|
|
||||||
|
|
||||||
# if id git &> /dev/null ;then
|
|
||||||
# echo "git uid is `id -u git`"
|
|
||||||
# echo "git shell is `grep "^git:" /etc/passwd |cut -d':' -f7 `"
|
|
||||||
# else
|
|
||||||
# groupadd git
|
|
||||||
# useradd -g git git
|
|
||||||
# fi
|
|
||||||
|
|
||||||
git config --global push.default simple
|
|
||||||
|
|
||||||
if [ "darwin" == "$os" ];then
|
|
||||||
file=gogs_${version}_darwin_amd64.zip
|
|
||||||
else
|
|
||||||
file=gogs_${version}_linux_amd64.zip
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -f $serverPath/source/gogs/$file ];then
|
|
||||||
wget -O $serverPath/source/gogs/$file ${GOGS_DOWNLOAD}/${version}/${file}
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd $serverPath/source/gogs && unzip -o $file -d gogs_${version}
|
|
||||||
mv $serverPath/source/gogs/gogs_${version}/gogs/ $serverPath/gogs
|
|
||||||
|
|
||||||
|
|
||||||
if [ -d $serverPath/gogs ];then
|
|
||||||
echo $version > $serverPath/gogs/version.pl
|
|
||||||
|
|
||||||
cd ${rootPath} && python3 ${rootPath}/plugins/gogs/index.py start
|
|
||||||
cd ${rootPath} && python3 ${rootPath}/plugins/gogs/index.py initd_install
|
|
||||||
fi
|
|
||||||
# if id -u gogs > /dev/null 2>&1; then
|
|
||||||
# echo "gogs user exists"
|
|
||||||
# else
|
|
||||||
# useradd gogs
|
|
||||||
# cp /etc/sudoers{,.`date +"%Y-%m-%d_%H-%M-%S"`}
|
|
||||||
# echo "gogs ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
|
||||||
# fi
|
|
||||||
|
|
||||||
echo 'install success' > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
Uninstall_gogs()
|
|
||||||
{
|
|
||||||
|
|
||||||
if [ -f /usr/lib/systemd/system/gogs.service ];then
|
|
||||||
systemctl stop gogs
|
|
||||||
systemctl disable gogs
|
|
||||||
rm -rf /usr/lib/systemd/system/gogs.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f $serverPath/gogs/initd/gogs ];then
|
|
||||||
$serverPath/gogs/initd/gogs stop
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf $serverPath/gogs
|
|
||||||
echo 'uninstall success' > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
version=$2
|
|
||||||
if [ "${1}" == 'install' ];then
|
|
||||||
Install_gogs $version
|
|
||||||
else
|
|
||||||
Uninstall_gogs $version
|
|
||||||
fi
|
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
|
|
||||||
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));
|
|
||||||
} else {
|
|
||||||
_args = JSON.stringify(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
var _title = '正在获取...';
|
|
||||||
if (typeof(title) != 'undefined'){
|
|
||||||
_title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
|
|
||||||
$.post('/plugins/run', {name:'gogs', 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 gogsSetConfig(){
|
|
||||||
gogsPost('get_gogs_conf', '', function(data){
|
|
||||||
var rrdata = $.parseJSON(data.data);
|
|
||||||
if (!rrdata.status){
|
|
||||||
layer.msg(rrdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var rdata = rrdata.data;
|
|
||||||
var mlist = '';
|
|
||||||
for (var i = 0; i < rdata.length; i++) {
|
|
||||||
var w = '140';
|
|
||||||
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;
|
|
||||||
case 2:
|
|
||||||
var selected_1 = (rdata[i].value == 'true') ? 'selected' : '';
|
|
||||||
var selected_0 = (rdata[i].value == 'false') ? 'selected' : '';
|
|
||||||
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
|
|
||||||
<option value="true" ' + selected_1 + '>开启</option>\
|
|
||||||
<option value="false" ' + selected_0 + '>关闭</option></select>'
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
mlist += '<p><span>' + rdata[i].name + '</span>' + ibody + ', <font>' + rdata[i].ps + '</font></p>'
|
|
||||||
}
|
|
||||||
var html = '<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="gogsSetConfig()">刷新</button>\
|
|
||||||
<button class="btn btn-success btn-sm" onclick="submitGogsConf()">保存</button></div>\
|
|
||||||
</div>';
|
|
||||||
$(".soft-man-con").html(html);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//提交PHP配置
|
|
||||||
function submitGogsConf() {
|
|
||||||
var data = {
|
|
||||||
DOMAIN: $("input[name='DOMAIN']").val(),
|
|
||||||
ROOT_URL: $("input[name='ROOT_URL']").val(),
|
|
||||||
HTTP_ADDR: $("select[name='HTTP_ADDR']").val(),
|
|
||||||
HTTP_PORT: $("input[name='HTTP_PORT']").val(),
|
|
||||||
START_SSH_SERVER: $("select[name='START_SSH_SERVER']").val() || 'false',
|
|
||||||
SSH_PORT: $("input[name='SSH_PORT']").val(),
|
|
||||||
REQUIRE_SIGNIN_VIEW: $("select[name='REQUIRE_SIGNIN_VIEW']").val() || 'false',
|
|
||||||
ENABLE_CAPTCHA: $("select[name='ENABLE_CAPTCHA']").val() || 'true',
|
|
||||||
DISABLE_REGISTRATION: $("select[name='DISABLE_REGISTRATION']").val() || 'false',
|
|
||||||
ENABLE_NOTIFY_MAIL: $("select[name='ENABLE_NOTIFY_MAIL']").val() || 'false',
|
|
||||||
FORCE_PRIVATE: $("select[name='FORCE_PRIVATE']").val() || 'false',
|
|
||||||
SHOW_FOOTER_BRANDING: $("select[name='SHOW_FOOTER_BRANDING']").val() || 'false',
|
|
||||||
SHOW_FOOTER_VERSION: $("select[name='SHOW_FOOTER_VERSION']").val() || 'false',
|
|
||||||
SHOW_FOOTER_TEMPLATE_LOAD_TIME: $("select[name='SHOW_FOOTER_TEMPLATE_LOAD_TIME']").val() || 'false',
|
|
||||||
};
|
|
||||||
|
|
||||||
gogsPost('submit_gogs_conf', data, function(ret_data){
|
|
||||||
var rdata = $.parseJSON(ret_data.data);
|
|
||||||
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
|
|
||||||
gogsSetConfig();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function gogsEdit(){
|
|
||||||
|
|
||||||
gogsPost('gogs_edit',{} , function(data){
|
|
||||||
// console.log(data);
|
|
||||||
var rdata = $.parseJSON(data.data);
|
|
||||||
var edit = '<p class="status">通用的手动编辑:</p>';
|
|
||||||
edit +='<div class="sfm-opt">\
|
|
||||||
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['post_receive']+'\');">post-receive.tpl</button>\
|
|
||||||
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['commit']+'\');">commit.tpl</button>\
|
|
||||||
</div>';
|
|
||||||
$(".soft-man-con").html(edit);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function gogsUserList(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('user_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;
|
|
||||||
}
|
|
||||||
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 += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
|
|
||||||
content += '<thead><tr>';
|
|
||||||
content += '<th>序号</th>';
|
|
||||||
content += '<th>用户或组织</th>';
|
|
||||||
content += '<th>邮件地址</th>';
|
|
||||||
content += '<th>操作(<a href="'+rdata['data']['root_url']+'" class="btlink" target="_blank">WEB管理</a>)</th>';
|
|
||||||
content += '</tr></thead>';
|
|
||||||
|
|
||||||
content += '<tbody>';
|
|
||||||
|
|
||||||
ulist = rdata['data']['data'];
|
|
||||||
for (i in ulist){
|
|
||||||
email = ulist[i][2] == '' ? '无' : ulist[i][2];
|
|
||||||
content += '<tr><td>'+ulist[i][0]+'</td>'+
|
|
||||||
'<td>'+ulist[i][1]+'</td>'+
|
|
||||||
'<td>'+email+'</td>'+
|
|
||||||
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i][1]+'\')">项目管理</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>';
|
|
||||||
|
|
||||||
content += page;
|
|
||||||
|
|
||||||
$(".soft-man-con").html(content);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function userProjectList(user, search){
|
|
||||||
var req = {};
|
|
||||||
if (!isNaN(user)){
|
|
||||||
req['page'] = user;
|
|
||||||
req['name'] = user = getCookie('gogsUserSelected');
|
|
||||||
} else {
|
|
||||||
req['page'] = 1;
|
|
||||||
req['name'] = user;
|
|
||||||
setCookie('gogsUserSelected', user);
|
|
||||||
}
|
|
||||||
|
|
||||||
req['page_size'] = 5;
|
|
||||||
req['search'] = '';
|
|
||||||
if(typeof(search) != 'undefined'){
|
|
||||||
req['search'] = search;
|
|
||||||
}
|
|
||||||
|
|
||||||
$('.layui-layer-close1').click();
|
|
||||||
gogsPost('user_project_list', req, function(data){
|
|
||||||
var rdata = [];
|
|
||||||
try {
|
|
||||||
rdata = $.parseJSON(data.data);
|
|
||||||
} catch(e){}
|
|
||||||
|
|
||||||
if (!rdata['status']){
|
|
||||||
layer.msg(rdata['msg'], { icon: 2 });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var list = '';
|
|
||||||
// console.log(rdata);
|
|
||||||
var project_list = rdata['data']['data'];
|
|
||||||
for (i in project_list) {
|
|
||||||
var name = project_list[i]['name'];
|
|
||||||
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>\
|
|
||||||
</td>\
|
|
||||||
</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>';
|
|
||||||
|
|
||||||
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>"
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function projectScript(user, name,has_hook){
|
|
||||||
// console.log(user,name,has_hook);
|
|
||||||
var html = '';
|
|
||||||
if (has_hook){
|
|
||||||
html += '<button onclick="projectScriptEdit(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">手动编辑</button>';
|
|
||||||
html += '<button onclick="projectScriptDebug(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">调试日志</button>';
|
|
||||||
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">重新加载</button>';
|
|
||||||
html += '<button onclick="projectScriptUnload(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">卸载脚本</button>';
|
|
||||||
} else {
|
|
||||||
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">加载脚本</button>';
|
|
||||||
}
|
|
||||||
|
|
||||||
var loadOpen = layer.open({
|
|
||||||
type: 1,
|
|
||||||
title: '['+user+']['+name+']脚本设置',
|
|
||||||
area: '240px',
|
|
||||||
content:'<div class="change-default pd20">'+html+'</div>'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function projectScriptEdit(user,name){
|
|
||||||
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']});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function projectScriptLoad(user,name){
|
|
||||||
gogsPost('project_script_load', {'user':user,'name':name}, function(data){
|
|
||||||
if (data.data != 'ok'){
|
|
||||||
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.msg('加载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
|
|
||||||
setTimeout(function(){
|
|
||||||
userProjectList(1);
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function projectScriptUnload(user,name){
|
|
||||||
gogsPost('project_script_unload', {'user':user,'name':name}, function(data){
|
|
||||||
if (data.data != 'ok'){
|
|
||||||
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.msg('卸载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
|
|
||||||
setTimeout(function(){
|
|
||||||
userProjectList(1);
|
|
||||||
}, 2000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function projectScriptDebug(user,name){
|
|
||||||
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']});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRsaPublic(){
|
|
||||||
gogsPost('get_rsa_public', {}, function(data){
|
|
||||||
var rdata = $.parseJSON(data.data);
|
|
||||||
var con = '<div class="tab-con">\
|
|
||||||
<div class="myKeyCon ptb15">\
|
|
||||||
<textarea style="margin:0px;width:580px;height:110px;outline:none;" spellcheck="false">'+rdata.mw+'</textarea>\
|
|
||||||
</div>\
|
|
||||||
<ul class="help-info-text c7 pull-left"></ul>\
|
|
||||||
</div>'
|
|
||||||
layer.open({
|
|
||||||
type: 1,
|
|
||||||
area: "600px",
|
|
||||||
title: '本机公钥',
|
|
||||||
closeBtn: 2,
|
|
||||||
shift: 5,
|
|
||||||
shadeClose: false,
|
|
||||||
content:con
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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><a href="#" onclick="getRsaPublic();">点击查看本机公钥</></li>';
|
|
||||||
readme += '</ul>';
|
|
||||||
|
|
||||||
$('.soft-man-con').html(readme);
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
[mysqld]
|
|
||||||
# SHOW GLOBAL VARIABLES LIKE '%gtid%'
|
|
||||||
gtid_mode=ON
|
|
||||||
enforce_gtid_consistency=ON
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
CREATE TABLE IF NOT EXISTS `config` (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`mysql_root` TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
INSERT INTO `config` (`id`, `mysql_root`) VALUES (1, 'admin');
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `databases` (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`pid` INTEGER,
|
|
||||||
`name` TEXT,
|
|
||||||
`username` TEXT,
|
|
||||||
`password` TEXT,
|
|
||||||
`accept` TEXT,
|
|
||||||
`rw` TEXT DEFAULT 'rw',
|
|
||||||
`ps` TEXT,
|
|
||||||
`addtime` TEXT
|
|
||||||
);
|
|
||||||
-- ALTER TABLE `databases` ADD COLUMN `rw` TEXT DEFAULT 'rw';
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `master_replication_user` (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`username` TEXT,
|
|
||||||
`password` TEXT,
|
|
||||||
`accept` TEXT,
|
|
||||||
`ps` TEXT,
|
|
||||||
`addtime` TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
-- 从库配置主库的[ssh private key]
|
|
||||||
-- drop table `slave_id_rsa`;
|
|
||||||
CREATE TABLE IF NOT EXISTS `slave_id_rsa` (
|
|
||||||
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
`ip` TEXT,
|
|
||||||
`port` TEXT,
|
|
||||||
`user` TEXT,
|
|
||||||
`db_user` TEXT,
|
|
||||||
`id_rsa` TEXT,
|
|
||||||
`ps` TEXT,
|
|
||||||
`addtime` TEXT
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
[client]
|
|
||||||
user = root
|
|
||||||
#password = your_password
|
|
||||||
port = 33106
|
|
||||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
|
||||||
|
|
||||||
[mysqld]
|
|
||||||
|
|
||||||
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
|
|
||||||
|
|
||||||
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
|
|
||||||
user = mysql
|
|
||||||
port = 33106
|
|
||||||
socket = {$SERVER_APP_PATH}/mysql.sock
|
|
||||||
basedir = {$SERVER_APP_PATH}
|
|
||||||
datadir = {$SERVER_APP_PATH}/data
|
|
||||||
log-error = {$SERVER_APP_PATH}/data/error.log
|
|
||||||
server-id = {$SERVER_ID}
|
|
||||||
|
|
||||||
default_storage_engine = InnoDB
|
|
||||||
|
|
||||||
key_buffer_size = 8M
|
|
||||||
max_allowed_packet = 100M
|
|
||||||
table_open_cache = 32
|
|
||||||
sort_buffer_size = 256K
|
|
||||||
net_buffer_length = 4K
|
|
||||||
read_buffer_size = 128K
|
|
||||||
read_rnd_buffer_size = 256K
|
|
||||||
myisam_sort_buffer_size = 4M
|
|
||||||
thread_cache_size = 4
|
|
||||||
lower_case_table_names=1
|
|
||||||
query_cache_size = 4M
|
|
||||||
tmp_table_size = 8M
|
|
||||||
|
|
||||||
max_connections = 500
|
|
||||||
max_connect_errors = 100
|
|
||||||
open_files_limit = 65535
|
|
||||||
|
|
||||||
skip-name-resolve = on
|
|
||||||
#skip-networking
|
|
||||||
#skip-external-locking
|
|
||||||
#loose-skip-innodb
|
|
||||||
#skip-grant-tables
|
|
||||||
|
|
||||||
|
|
||||||
log-bin=mysql-bin
|
|
||||||
binlog_format=mixed
|
|
||||||
slow_query_log=1
|
|
||||||
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
|
|
||||||
long_query_time=3
|
|
||||||
#log_queries_not_using_indexes=on
|
|
||||||
binlog-expire-logs-seconds = 2592000
|
|
||||||
|
|
||||||
relay-log=mdserver
|
|
||||||
relay-log-index=mdserver
|
|
||||||
|
|
||||||
#master
|
|
||||||
#binlog-do-db
|
|
||||||
binlog-ignore-db = test
|
|
||||||
binlog-ignore-db = mysql
|
|
||||||
binlog-ignore-db = information_schema
|
|
||||||
binlog-ignore-db = performance_schema
|
|
||||||
|
|
||||||
#slave
|
|
||||||
log-slave-updates
|
|
||||||
#replicate-do-db
|
|
||||||
replicate-ignore-db = information_schema
|
|
||||||
replicate-ignore-db = performance_schema
|
|
||||||
replicate-ignore-db = mysql
|
|
||||||
replicate-ignore-db = test
|
|
||||||
|
|
||||||
|
|
||||||
innodb_data_home_dir = {$SERVER_APP_PATH}/data
|
|
||||||
innodb_data_file_path = ibdata1:10M:autoextend
|
|
||||||
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
|
|
||||||
innodb_buffer_pool_size = 16M
|
|
||||||
innodb_log_file_size = 5M
|
|
||||||
innodb_log_buffer_size = 8M
|
|
||||||
innodb_flush_log_at_trx_commit = 1
|
|
||||||
innodb_lock_wait_timeout = 120
|
|
||||||
innodb_max_dirty_pages_pct = 90
|
|
||||||
innodb_read_io_threads = 1
|
|
||||||
innodb_write_io_threads = 2
|
|
||||||
innodb_file_per_table=1
|
|
||||||
|
|
||||||
|
|
||||||
secure-file-priv={$SERVER_APP_PATH}/tmp
|
|
||||||
|
|
||||||
[mysqldump]
|
|
||||||
quick
|
|
||||||
max_allowed_packet = 16M
|
|
||||||
|
|
||||||
[mysql]
|
|
||||||
no-auto-rehash
|
|
||||||
|
|
||||||
[myisamchk]
|
|
||||||
key_buffer_size = 20M
|
|
||||||
sort_buffer_size = 20M
|
|
||||||
read_buffer = 2M
|
|
||||||
write_buffer = 2M
|
|
||||||
|
|
||||||
[mysqlhotcopy]
|
|
||||||
interactive-timeout
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
@@ -1,61 +0,0 @@
|
|||||||
<div class="bt-form">
|
|
||||||
<div class='plugin_version'></div>
|
|
||||||
<div class="bt-w-main">
|
|
||||||
<div class="bt-w-menu">
|
|
||||||
<script type="text/javascript">console.log($('.plugin_version').attr('version'));</script>
|
|
||||||
<p class="bgw" onclick="pluginService('mariadb', $('.plugin_version').attr('version'));">服务</p>
|
|
||||||
<p onclick="pluginInitD('mariadb', $('.plugin_version').attr('version'));">自启动</p>
|
|
||||||
<p onclick="pluginConfig('mariadb', $('.plugin_version').attr('version'));">配置文件</p>
|
|
||||||
<p onclick="myDbPos();">存储位置</p>
|
|
||||||
<p onclick="myPort();">端口</p>
|
|
||||||
<p onclick="runInfo();">当前状态</p>
|
|
||||||
<p onclick="myPerfOpt();">性能优化</p>
|
|
||||||
<p onclick="myLogs();">日志</p>
|
|
||||||
<p onclick="pluginLogs('mariadb',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
|
|
||||||
<p onclick="dbList()">管理列表</p>
|
|
||||||
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
|
|
||||||
</div>
|
|
||||||
<div class="bt-w-con pd15">
|
|
||||||
<div class="soft-man-con"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<style type="text/css">
|
|
||||||
.db_list{
|
|
||||||
padding: 0px 0 10px 0;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 35px;
|
|
||||||
height: 45px;
|
|
||||||
}
|
|
||||||
.db_list a{
|
|
||||||
margin-right: 15px;
|
|
||||||
color: #555;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
.db_list span:nth-child(1){
|
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
padding-left: 15px;
|
|
||||||
background: #ececec;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#db_tools button {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
#db_tools button:last-child{
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<script type="text/javascript">
|
|
||||||
resetPluginWinWidth(800);
|
|
||||||
|
|
||||||
var loading = layer.msg("资源加载中...", { icon: 16, time: 0, shade: 0.3 });
|
|
||||||
$.getScript( "/plugins/file?name=mariadb&f=js/mariadb.js", function(){
|
|
||||||
layer.close(loading);
|
|
||||||
pluginService('mariadb',$('.plugin_version').attr('version'));
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"title":"MariaDB",
|
|
||||||
"tip":"soft",
|
|
||||||
"name":"mariadb",
|
|
||||||
"type":"运行环境",
|
|
||||||
"ps":"一种关系数据库管理系统!",
|
|
||||||
"uninstall_pre_inspection":true,
|
|
||||||
"checks": "server/mariadb",
|
|
||||||
"path": "server/mariadb",
|
|
||||||
"versions":["10.6","10.7","10.8"],
|
|
||||||
"shell":"install.sh",
|
|
||||||
"checks":"server/mariadb",
|
|
||||||
"path":"server/mariadb",
|
|
||||||
"author":"mariadb",
|
|
||||||
"home":"https://mariadb.org/",
|
|
||||||
"date":"2022-07-12",
|
|
||||||
"pid": "2"
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=MariaDB Server: The open source relational database
|
|
||||||
Documentation=https://mariadb.org/download/?t=mariadb
|
|
||||||
After=network.service
|
|
||||||
After=syslog.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=mysql
|
|
||||||
Group=mysql
|
|
||||||
Type=simple
|
|
||||||
ExecStart={$SERVER_PATH}/mariadb/bin/mysqld --defaults-file={$SERVER_PATH}/mariadb/etc/my.cnf
|
|
||||||
ExecReload=/bin/kill -USR2 $MAINPID
|
|
||||||
PermissionsStartOnly=true
|
|
||||||
LimitNOFILE=5000
|
|
||||||
Restart=on-failure
|
|
||||||
RestartSec=10
|
|
||||||
RestartPreventExitStatus=1
|
|
||||||
PrivateTmp=false
|
|
||||||
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@@ -1,384 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# chkconfig: 2345 55 25
|
|
||||||
# Description: mysql service
|
|
||||||
# distro. For CentOS/Redhat run: 'chkconfig --add mysql'
|
|
||||||
|
|
||||||
# Copyright Abandoned 1996 TCX DataKonsult AB & Monty Program KB & Detron HB
|
|
||||||
# This file is public domain and comes with NO WARRANTY of any kind
|
|
||||||
|
|
||||||
# MySQL daemon start/stop script.
|
|
||||||
|
|
||||||
# Usually this is put in /etc/init.d (at least on machines SYSV R4 based
|
|
||||||
# systems) and linked to /etc/rc3.d/S99mysql and /etc/rc0.d/K01mysql.
|
|
||||||
# When this is done the mysql server will be started when the machine is
|
|
||||||
# started and shut down when the systems goes down.
|
|
||||||
|
|
||||||
# Comments to support chkconfig on RedHat Linux
|
|
||||||
# chkconfig: 2345 64 36
|
|
||||||
# description: A very fast and reliable SQL database engine.
|
|
||||||
|
|
||||||
# Comments to support LSB init script conventions
|
|
||||||
### BEGIN INIT INFO
|
|
||||||
# Provides: mysql
|
|
||||||
# Required-Start: $local_fs $network $remote_fs
|
|
||||||
# Should-Start: ypbind nscd ldap ntpd xntpd
|
|
||||||
# Required-Stop: $local_fs $network $remote_fs
|
|
||||||
# Default-Start: 2 3 4 5
|
|
||||||
# Default-Stop: 0 1 6
|
|
||||||
# Short-Description: start and stop MySQL
|
|
||||||
# Description: MySQL is a very fast and reliable SQL database engine.
|
|
||||||
### END INIT INFO
|
|
||||||
|
|
||||||
# If you install MySQL on some other places than /www/server/mysql, then you
|
|
||||||
# have to do one of the following things for this script to work:
|
|
||||||
#
|
|
||||||
# - Run this script from within the MySQL installation directory
|
|
||||||
# - Create a /etc/my.cnf file with the following information:
|
|
||||||
# [mysqld]
|
|
||||||
# basedir=<path-to-mysql-installation-directory>
|
|
||||||
# - Add the above to any other configuration file (for example ~/.my.ini)
|
|
||||||
# and copy my_print_defaults to /usr/bin
|
|
||||||
# - Add the path to the mysql-installation-directory to the basedir variable
|
|
||||||
# below.
|
|
||||||
#
|
|
||||||
# If you want to affect other MySQL variables, you should make your changes
|
|
||||||
# in the /etc/my.cnf, ~/.my.cnf or other MySQL configuration files.
|
|
||||||
|
|
||||||
# If you change base dir, you must also change datadir. These may get
|
|
||||||
# overwritten by settings in the MySQL configuration files.
|
|
||||||
|
|
||||||
basedir=
|
|
||||||
datadir=
|
|
||||||
|
|
||||||
# Default value, in seconds, afterwhich the script should timeout waiting
|
|
||||||
# for server start.
|
|
||||||
# Value here is overriden by value in my.cnf.
|
|
||||||
# 0 means don't wait at all
|
|
||||||
# Negative numbers mean to wait indefinitely
|
|
||||||
service_startup_timeout=900
|
|
||||||
|
|
||||||
# Lock directory for RedHat / SuSE.
|
|
||||||
lockdir='/var/lock/subsys'
|
|
||||||
lock_file_path="$lockdir/mysql"
|
|
||||||
|
|
||||||
# The following variables are only set for letting mysql.server find things.
|
|
||||||
|
|
||||||
# Set some defaults
|
|
||||||
mysqld_pid_file_path=
|
|
||||||
if test -z "$basedir"
|
|
||||||
then
|
|
||||||
basedir={$SERVER_APP_PATH}
|
|
||||||
bindir={$SERVER_APP_PATH}/bin
|
|
||||||
if test -z "$datadir"
|
|
||||||
then
|
|
||||||
datadir={$SERVER_APP_PATH}/data
|
|
||||||
fi
|
|
||||||
sbindir={$SERVER_APP_PATH}/bin
|
|
||||||
libexecdir={$SERVER_APP_PATH}/bin
|
|
||||||
else
|
|
||||||
bindir="$basedir/bin"
|
|
||||||
if test -z "$datadir"
|
|
||||||
then
|
|
||||||
datadir="$basedir/data"
|
|
||||||
fi
|
|
||||||
sbindir="$basedir/sbin"
|
|
||||||
libexecdir="$basedir/libexec"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# datadir_set is used to determine if datadir was set (and so should be
|
|
||||||
# *not* set inside of the --basedir= handler.)
|
|
||||||
datadir_set=
|
|
||||||
|
|
||||||
#
|
|
||||||
# Use LSB init script functions for printing messages, if possible
|
|
||||||
#
|
|
||||||
lsb_functions="/lib/lsb/init-functions"
|
|
||||||
if test -f $lsb_functions ; then
|
|
||||||
. $lsb_functions
|
|
||||||
else
|
|
||||||
log_success_msg()
|
|
||||||
{
|
|
||||||
echo " SUCCESS! $@"
|
|
||||||
}
|
|
||||||
log_failure_msg()
|
|
||||||
{
|
|
||||||
echo " ERROR! $@"
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
|
|
||||||
PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin"
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
mode=$1 # start or stop
|
|
||||||
|
|
||||||
[ $# -ge 1 ] && shift
|
|
||||||
|
|
||||||
|
|
||||||
other_args=--sql-mode="NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION" # uncommon, but needed when called from an RPM upgrade action
|
|
||||||
# Expected: "--skip-networking --skip-grant-tables"
|
|
||||||
# They are not checked here, intentionally, as it is the resposibility
|
|
||||||
# of the "spec" file author to give correct arguments only.
|
|
||||||
|
|
||||||
case `echo "testing\c"`,`echo -n testing` in
|
|
||||||
*c*,-n*) echo_n= echo_c= ;;
|
|
||||||
*c*,*) echo_n=-n echo_c= ;;
|
|
||||||
*) echo_n= echo_c='\c' ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
parse_server_arguments() {
|
|
||||||
for arg do
|
|
||||||
case "$arg" in
|
|
||||||
--basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'`
|
|
||||||
bindir="$basedir/bin"
|
|
||||||
if test -z "$datadir_set"; then
|
|
||||||
datadir="$basedir/data"
|
|
||||||
fi
|
|
||||||
sbindir="$basedir/sbin"
|
|
||||||
libexecdir="$basedir/libexec"
|
|
||||||
;;
|
|
||||||
--datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'`
|
|
||||||
datadir_set=1
|
|
||||||
;;
|
|
||||||
--pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
|
|
||||||
--service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
wait_for_pid () {
|
|
||||||
verb="$1" # created | removed
|
|
||||||
pid="$2" # process ID of the program operating on the pid-file
|
|
||||||
pid_file_path="$3" # path to the PID file.
|
|
||||||
|
|
||||||
i=0
|
|
||||||
avoid_race_condition="by checking again"
|
|
||||||
|
|
||||||
while test $i -ne $service_startup_timeout ; do
|
|
||||||
|
|
||||||
case "$verb" in
|
|
||||||
'created')
|
|
||||||
# wait for a PID-file to pop into existence.
|
|
||||||
test -s "$pid_file_path" && i='' && break
|
|
||||||
;;
|
|
||||||
'removed')
|
|
||||||
# wait for this PID-file to disappear
|
|
||||||
test ! -s "$pid_file_path" && i='' && break
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# if server isn't running, then pid-file will never be updated
|
|
||||||
if test -n "$pid"; then
|
|
||||||
if kill -0 "$pid" 2>/dev/null; then
|
|
||||||
: # the server still runs
|
|
||||||
else
|
|
||||||
# The server may have exited between the last pid-file check and now.
|
|
||||||
if test -n "$avoid_race_condition"; then
|
|
||||||
avoid_race_condition=""
|
|
||||||
continue # Check again.
|
|
||||||
fi
|
|
||||||
|
|
||||||
# there's nothing that will affect the file.
|
|
||||||
log_failure_msg "The server quit without updating PID file ($pid_file_path)."
|
|
||||||
return 1 # not waiting any more.
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo $echo_n ".$echo_c"
|
|
||||||
i=`expr $i + 1`
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
if test -z "$i" ; then
|
|
||||||
log_success_msg
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
log_failure_msg
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get arguments from the my.cnf file,
|
|
||||||
# the only group, which is read from now on is [mysqld]
|
|
||||||
if test -x "$bindir/my_print_defaults"; then
|
|
||||||
print_defaults="$bindir/my_print_defaults"
|
|
||||||
else
|
|
||||||
# Try to find basedir in /etc/my.cnf
|
|
||||||
conf=/etc/my.cnf
|
|
||||||
print_defaults=
|
|
||||||
if test -r $conf
|
|
||||||
then
|
|
||||||
subpat='^[^=]*basedir[^=]*=\(.*\)$'
|
|
||||||
dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf`
|
|
||||||
for d in $dirs
|
|
||||||
do
|
|
||||||
d=`echo $d | sed -e 's/[ ]//g'`
|
|
||||||
if test -x "$d/bin/my_print_defaults"
|
|
||||||
then
|
|
||||||
print_defaults="$d/bin/my_print_defaults"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Hope it's in the PATH ... but I doubt it
|
|
||||||
test -z "$print_defaults" && print_defaults="my_print_defaults"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#
|
|
||||||
# Read defaults file from 'basedir'. If there is no defaults file there
|
|
||||||
# check if it's in the old (depricated) place (datadir) and read it from there
|
|
||||||
#
|
|
||||||
|
|
||||||
extra_args=""
|
|
||||||
if test -r "$basedir/my.cnf"
|
|
||||||
then
|
|
||||||
extra_args="-e $basedir/my.cnf"
|
|
||||||
else
|
|
||||||
if test -r "$datadir/my.cnf"
|
|
||||||
then
|
|
||||||
extra_args="-e $datadir/my.cnf"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
|
|
||||||
|
|
||||||
#
|
|
||||||
# Set pid file if not given
|
|
||||||
#
|
|
||||||
found_pid=`cd $datadir && ls |grep '.pid'`
|
|
||||||
if test -z "$mysqld_pid_file_path"
|
|
||||||
then
|
|
||||||
mysqld_pid_file_path=$datadir/$found_pid
|
|
||||||
else
|
|
||||||
case "$mysqld_pid_file_path" in
|
|
||||||
/* ) ;;
|
|
||||||
* ) mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
#ulimit -s unlimited
|
|
||||||
case "$mode" in
|
|
||||||
'start')
|
|
||||||
# Start daemon
|
|
||||||
|
|
||||||
# Safeguard (relative paths, core dumps..)
|
|
||||||
cd $basedir
|
|
||||||
|
|
||||||
echo $echo_n "Starting MySQL"
|
|
||||||
if test -x $bindir/mysqld_safe
|
|
||||||
then
|
|
||||||
# Give extra arguments to mysqld with the my.cnf file. This script
|
|
||||||
# may be overwritten at next upgrade.
|
|
||||||
$bindir/mysqld_safe --defaults-file=$basedir/etc/my.cnf --datadir="$datadir" $other_args >/dev/null &
|
|
||||||
wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
|
|
||||||
|
|
||||||
# Make lock for RedHat / SuSE
|
|
||||||
if test -w "$lockdir"
|
|
||||||
then
|
|
||||||
touch "$lock_file_path"
|
|
||||||
fi
|
|
||||||
|
|
||||||
exit $return_value
|
|
||||||
else
|
|
||||||
log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
'stop')
|
|
||||||
# Stop daemon. We use a signal here to avoid having to know the
|
|
||||||
# root password.
|
|
||||||
|
|
||||||
if test -s "$mysqld_pid_file_path"
|
|
||||||
then
|
|
||||||
mysqld_pid=`cat "$mysqld_pid_file_path"`
|
|
||||||
|
|
||||||
if (kill -0 $mysqld_pid 2>/dev/null)
|
|
||||||
then
|
|
||||||
echo $echo_n "Shutting down MySQL"
|
|
||||||
kill $mysqld_pid
|
|
||||||
# mysqld should remove the pid file when it exits, so wait for it.
|
|
||||||
wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$?
|
|
||||||
else
|
|
||||||
log_failure_msg "MySQL server process #$mysqld_pid is not running!"
|
|
||||||
rm "$mysqld_pid_file_path"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Delete lock for RedHat / SuSE
|
|
||||||
if test -f "$lock_file_path"
|
|
||||||
then
|
|
||||||
rm -f "$lock_file_path"
|
|
||||||
fi
|
|
||||||
exit $return_value
|
|
||||||
else
|
|
||||||
log_failure_msg "MySQL server PID file could not be found!"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
'restart')
|
|
||||||
# Stop the service and regardless of whether it was
|
|
||||||
# running or not, start it again.
|
|
||||||
if $0 stop $other_args; then
|
|
||||||
$0 start $other_args
|
|
||||||
else
|
|
||||||
log_failure_msg "Failed to stop running server, so refusing to try to start."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
|
|
||||||
'reload'|'force-reload')
|
|
||||||
if test -s "$mysqld_pid_file_path" ; then
|
|
||||||
read mysqld_pid < "$mysqld_pid_file_path"
|
|
||||||
kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"
|
|
||||||
touch "$mysqld_pid_file_path"
|
|
||||||
else
|
|
||||||
log_failure_msg "MySQL PID file could not be found!"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
'status')
|
|
||||||
# First, check to see if pid file exists
|
|
||||||
if test -s "$mysqld_pid_file_path" ; then
|
|
||||||
read mysqld_pid < "$mysqld_pid_file_path"
|
|
||||||
if kill -0 $mysqld_pid 2>/dev/null ; then
|
|
||||||
log_success_msg "MySQL running ($mysqld_pid)"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
log_failure_msg "MySQL is not running, but PID file exists"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
# Try to find appropriate mysqld process
|
|
||||||
mysqld_pid=`pidof $libexecdir/mysqld`
|
|
||||||
|
|
||||||
# test if multiple pids exist
|
|
||||||
pid_count=`echo $mysqld_pid | wc -w`
|
|
||||||
if test $pid_count -gt 1 ; then
|
|
||||||
log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)"
|
|
||||||
exit 5
|
|
||||||
elif test -z $mysqld_pid ; then
|
|
||||||
if test -f "$lock_file_path" ; then
|
|
||||||
log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
log_failure_msg "MySQL is not running"
|
|
||||||
exit 3
|
|
||||||
else
|
|
||||||
log_failure_msg "MySQL is running but PID file could not be found"
|
|
||||||
exit 4
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
# usage
|
|
||||||
basename=`basename "$0"`
|
|
||||||
echo "Usage: $basename {start|stop|restart|reload|force-reload|status} [ MySQL server options ]"
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
curPath=`pwd`
|
|
||||||
rootPath=$(dirname "$curPath")
|
|
||||||
rootPath=$(dirname "$rootPath")
|
|
||||||
serverPath=$(dirname "$rootPath")
|
|
||||||
|
|
||||||
|
|
||||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
|
||||||
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
type=$2
|
|
||||||
|
|
||||||
if [ "${2}" == "" ];then
|
|
||||||
echo '缺少安装脚本...' > $install_tmp
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d $curPath/versions/$2 ];then
|
|
||||||
echo '缺少安装脚本2...' > $install_tmp
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${action}" == "uninstall" ];then
|
|
||||||
|
|
||||||
if [ -f /usr/lib/systemd/system/mariadb.service ] || [ -f /lib/systemd/system/mariadb.service ];then
|
|
||||||
systemctl stop mariadb
|
|
||||||
systemctl disable mariadb
|
|
||||||
rm -rf /usr/lib/systemd/system/mariadb.service
|
|
||||||
rm -rf /lib/systemd/system/mariadb.service
|
|
||||||
systemctl daemon-reload
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
sh -x $curPath/versions/$2/install.sh $1
|
|
||||||
|
|
||||||
if [ "${action}" == "install" ] && [ -d $serverPath/mariadb ];then
|
|
||||||
#初始化
|
|
||||||
cd ${rootPath} && python3 ${rootPath}/plugins/mariadb/index.py start ${type}
|
|
||||||
cd ${rootPath} && python3 ${rootPath}/plugins/mariadb/index.py initd_install ${type}
|
|
||||||
fi
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,125 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
#-----------------------------
|
|
||||||
# 网站备份工具
|
|
||||||
#-----------------------------
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
if sys.platform != 'darwin':
|
|
||||||
os.chdir('/www/server/mdserver-web')
|
|
||||||
|
|
||||||
|
|
||||||
chdir = os.getcwd()
|
|
||||||
sys.path.append(chdir + '/class/core')
|
|
||||||
|
|
||||||
# reload(sys)
|
|
||||||
# sys.setdefaultencoding('utf-8')
|
|
||||||
|
|
||||||
|
|
||||||
import mw
|
|
||||||
import db
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
class backupTools:
|
|
||||||
|
|
||||||
def backupDatabase(self, name, count):
|
|
||||||
db_path = mw.getServerDir() + '/mariadb'
|
|
||||||
db_name = 'mysql'
|
|
||||||
name = mw.M('databases').dbPos(db_path, 'mysql').where(
|
|
||||||
'name=?', (name,)).getField('name')
|
|
||||||
startTime = time.time()
|
|
||||||
if not name:
|
|
||||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
|
||||||
log = "数据库[" + name + "]不存在!"
|
|
||||||
print("★[" + endDate + "] " + log)
|
|
||||||
print(
|
|
||||||
"----------------------------------------------------------------------------")
|
|
||||||
return
|
|
||||||
|
|
||||||
backup_path = mw.getRootDir() + '/backup/database'
|
|
||||||
if not os.path.exists(backup_path):
|
|
||||||
mw.execShell("mkdir -p " + backup_path)
|
|
||||||
|
|
||||||
filename = backup_path + "/db_" + name + "_" + \
|
|
||||||
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
|
|
||||||
|
|
||||||
import re
|
|
||||||
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
|
|
||||||
"id=?", (1,)).getField('mysql_root')
|
|
||||||
|
|
||||||
mycnf = mw.readFile(db_path + '/etc/my.cnf')
|
|
||||||
rep = "\[mysqldump\]\nuser=root"
|
|
||||||
sea = "[mysqldump]\n"
|
|
||||||
subStr = sea + "user=root\npassword=" + mysql_root + "\n"
|
|
||||||
mycnf = mycnf.replace(sea, subStr)
|
|
||||||
if len(mycnf) > 100:
|
|
||||||
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
|
|
||||||
|
|
||||||
# mw.execShell(db_path + "/bin/mysqldump --opt --default-character-set=utf8 " +
|
|
||||||
# name + " | gzip > " + filename)
|
|
||||||
|
|
||||||
# mw.execShell(db_path + "/bin/mysqldump --skip-lock-tables --default-character-set=utf8 " +
|
|
||||||
# name + " | gzip > " + filename)
|
|
||||||
|
|
||||||
mw.execShell(db_path + "/bin/mysqldump --single-transaction --quick --default-character-set=utf8 " +
|
|
||||||
name + " | gzip > " + filename)
|
|
||||||
|
|
||||||
if not os.path.exists(filename):
|
|
||||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
|
||||||
log = "数据库[" + name + "]备份失败!"
|
|
||||||
print("★[" + endDate + "] " + log)
|
|
||||||
print(
|
|
||||||
"----------------------------------------------------------------------------")
|
|
||||||
return
|
|
||||||
|
|
||||||
mycnf = mw.readFile(db_path + '/etc/my.cnf')
|
|
||||||
mycnf = mycnf.replace(subStr, sea)
|
|
||||||
if len(mycnf) > 100:
|
|
||||||
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
|
|
||||||
|
|
||||||
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
|
|
||||||
outTime = time.time() - startTime
|
|
||||||
pid = mw.M('databases').dbPos(db_path, db_name).where(
|
|
||||||
'name=?', (name,)).getField('id')
|
|
||||||
|
|
||||||
mw.M('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename(
|
|
||||||
filename), pid, filename, endDate, os.path.getsize(filename)))
|
|
||||||
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
|
|
||||||
mw.writeLog('计划任务', log)
|
|
||||||
print("★[" + endDate + "] " + log)
|
|
||||||
print("|---保留最新的[" + count + "]份备份")
|
|
||||||
print("|---文件名:" + filename)
|
|
||||||
|
|
||||||
# 清理多余备份
|
|
||||||
backups = mw.M('backup').where(
|
|
||||||
'type=? and pid=?', ('1', pid)).field('id,filename').select()
|
|
||||||
|
|
||||||
num = len(backups) - int(count)
|
|
||||||
if num > 0:
|
|
||||||
for backup in backups:
|
|
||||||
mw.execShell("rm -f " + backup['filename'])
|
|
||||||
mw.M('backup').where('id=?', (backup['id'],)).delete()
|
|
||||||
num -= 1
|
|
||||||
print("|---已清理过期备份文件:" + backup['filename'])
|
|
||||||
if num < 1:
|
|
||||||
break
|
|
||||||
|
|
||||||
def backupDatabaseAll(self, save):
|
|
||||||
db_path = mw.getServerDir() + '/mariadb'
|
|
||||||
db_name = 'mysql'
|
|
||||||
databases = mw.M('databases').dbPos(
|
|
||||||
db_path, db_name).field('name').select()
|
|
||||||
for database in databases:
|
|
||||||
self.backupDatabase(database['name'], save)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
backup = backupTools()
|
|
||||||
type = sys.argv[1]
|
|
||||||
if type == 'database':
|
|
||||||
if sys.argv[2] == 'ALL':
|
|
||||||
backup.backupDatabaseAll(sys.argv[3])
|
|
||||||
else:
|
|
||||||
backup.backupDatabase(sys.argv[2], sys.argv[3])
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
# coding:utf-8
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import subprocess
|
|
||||||
import re
|
|
||||||
import json
|
|
||||||
|
|
||||||
cur_dir = os.getcwd()
|
|
||||||
plugin_dir = os.path.dirname(cur_dir)
|
|
||||||
|
|
||||||
# print(plugin_dir)
|
|
||||||
root_dir = os.path.dirname(os.path.dirname(plugin_dir))
|
|
||||||
# print(root_dir)
|
|
||||||
|
|
||||||
sys.path.append(root_dir + "/class/core")
|
|
||||||
import mw
|
|
||||||
|
|
||||||
os.chdir(root_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginName():
|
|
||||||
return 'mariadb'
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginDir():
|
|
||||||
return root_dir + '/plugins/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getServerDir():
|
|
||||||
return os.path.dirname(root_dir) + '/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def pSqliteDb(dbname='databases'):
|
|
||||||
file = getServerDir() + '/mariadb.db'
|
|
||||||
name = 'mysql'
|
|
||||||
if not os.path.exists(file):
|
|
||||||
conn = mw.M(dbname).dbPos(getServerDir(), name)
|
|
||||||
csql = mw.readFile(getPluginDir() + '/conf/mariadb.sql')
|
|
||||||
csql_list = csql.split(';')
|
|
||||||
for index in range(len(csql_list)):
|
|
||||||
conn.execute(csql_list[index], ())
|
|
||||||
else:
|
|
||||||
conn = mw.M(dbname).dbPos(getServerDir(), name)
|
|
||||||
return conn
|
|
||||||
|
|
||||||
|
|
||||||
def getConf():
|
|
||||||
path = getServerDir() + '/etc/my.cnf'
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def pMysqlDb():
|
|
||||||
db = mw.getMyORM()
|
|
||||||
db.setDbConf(getConf())
|
|
||||||
db.__DB_SOCKET = mw.getServerDir() + '/mysql/mysql.socket'
|
|
||||||
|
|
||||||
print(mw.getServerDir() + '/mysql/mysql.socket')
|
|
||||||
db.setPwd(pSqliteDb('config').where('id=?', (1,)).getField('mysql_root'))
|
|
||||||
return db
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
p = pMysqlDb()
|
|
||||||
print(p.query("select User,Host from mysql.user where User!='root' AND Host!='localhost' AND Host!=''"))
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
# coding: utf-8
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
import mw
|
|
||||||
import db
|
|
||||||
|
|
||||||
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
|
|
||||||
info = mw.execShell(cmd)
|
|
||||||
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
|
|
||||||
sys.path.append(p)
|
|
||||||
|
|
||||||
|
|
||||||
def set_mysql_root(password):
|
|
||||||
# 设置MySQL密码
|
|
||||||
import db
|
|
||||||
import os
|
|
||||||
sql = db.Sql()
|
|
||||||
|
|
||||||
root_mysql = '''#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
pwd=$1
|
|
||||||
${server}/init.d/mysql stop
|
|
||||||
${server}/bin/mysqld_safe --skip-grant-tables&
|
|
||||||
echo '正在修改密码...';
|
|
||||||
echo 'The set password...';
|
|
||||||
sleep 6
|
|
||||||
m_version=$(cat ${server}/version.pl|grep -E "(5.1.|5.5.|5.6.|mariadb)")
|
|
||||||
if [ "$m_version" != "" ];then
|
|
||||||
${server}/bin/mysql -uroot -e "insert into mysql.user(Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,Event_priv,Trigger_priv,Create_tablespace_priv,User,Password,host)values('Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','root',password('${pwd}'),'127.0.0.1')"
|
|
||||||
${server}/bin/mysql -uroot -e "insert into mysql.user(Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv,Reload_priv,Shutdown_priv,Process_priv,File_priv,Grant_priv,References_priv,Index_priv,Alter_priv,Show_db_priv,Super_priv,Create_tmp_table_priv,Lock_tables_priv,Execute_priv,Repl_slave_priv,Repl_client_priv,Create_view_priv,Show_view_priv,Create_routine_priv,Alter_routine_priv,Create_user_priv,Event_priv,Trigger_priv,Create_tablespace_priv,User,Password,host)values('Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','root',password('${pwd}'),'localhost')"
|
|
||||||
${server}/bin/mysql -uroot -e "UPDATE mysql.user SET password=PASSWORD('${pwd}') WHERE user='root'";
|
|
||||||
else
|
|
||||||
${server}/bin/mysql -uroot -e "UPDATE mysql.user SET authentication_string='' WHERE user='root'";
|
|
||||||
${server}/bin/mysql -uroot -e "FLUSH PRIVILEGES";
|
|
||||||
${server}/bin/mysql -uroot -e "ALTER USER 'root'@'localhost' IDENTIFIED BY '${pwd}';";
|
|
||||||
fi
|
|
||||||
${server} -uroot -e "FLUSH PRIVILEGES";
|
|
||||||
pkill -9 mysqld_safe
|
|
||||||
pkill -9 mysqld
|
|
||||||
sleep 2
|
|
||||||
${server}/init.d/mysql start
|
|
||||||
|
|
||||||
echo '==========================================='
|
|
||||||
echo "root密码成功修改为: ${pwd}"
|
|
||||||
echo "The root password set ${pwd} successuful"'''
|
|
||||||
|
|
||||||
server = mw.getServerDir() + '/mariadb'
|
|
||||||
root_mysql = root_mysql.replace('${server}', server)
|
|
||||||
mw.writeFile('mysql_root.sh', root_mysql)
|
|
||||||
os.system("/bin/bash mysql_root.sh " + password)
|
|
||||||
os.system("rm -f mysql_root.sh")
|
|
||||||
|
|
||||||
pos = mw.getServerDir() + '/mariadb'
|
|
||||||
result = sql.table('config').dbPos(pos, 'mysql').where(
|
|
||||||
'id=?', (1,)).setField('mysql_root', password)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
type = sys.argv[1]
|
|
||||||
if type == 'root':
|
|
||||||
set_mysql_root(sys.argv[2])
|
|
||||||
else:
|
|
||||||
print('ERROR: Parameter error')
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
|
||||||
#https://dev.mysql.com/downloads/file/?id=480541
|
|
||||||
|
|
||||||
curPath=`pwd`
|
|
||||||
rootPath=$(dirname "$curPath")
|
|
||||||
rootPath=$(dirname "$rootPath")
|
|
||||||
serverPath=$(dirname "$rootPath")
|
|
||||||
sysName=`uname`
|
|
||||||
|
|
||||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
|
||||||
mariadbDir=${serverPath}/source/mariadb
|
|
||||||
|
|
||||||
MY_VER=10.6.9
|
|
||||||
|
|
||||||
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 "1" ];then
|
|
||||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
|
||||||
fi
|
|
||||||
# ----- cpu end ------
|
|
||||||
|
|
||||||
# https://mirrors.aliyun.com/mariadb/mariadb-10.8.3/source/mariadb-10.8.3.tar.gz
|
|
||||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
|
||||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
# https://downloads.mariadb.org/interstitial/mariadb-10.6.8/source/mariadb-10.6.8.tar.gz
|
|
||||||
if [ "$?" != "0" ];then
|
|
||||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
|
||||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
OPTIONS=''
|
|
||||||
if [ "$sysName" == "Darwin" ];then
|
|
||||||
OPTIONS='-DPLUGIN_TOKUDB=NO'
|
|
||||||
fi
|
|
||||||
|
|
||||||
INSTALL_CMD=cmake
|
|
||||||
CMAKE3=`which cmake3`
|
|
||||||
if [ "$?" == "0" ];then
|
|
||||||
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 \
|
|
||||||
$OPTIONS \
|
|
||||||
-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.6' > $serverPath/mariadb/version.pl
|
|
||||||
echo '安装完成' > $install_tmp
|
|
||||||
else
|
|
||||||
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
|
||||||
echo '安装失败' > $install_tmp
|
|
||||||
echo 'install fail'>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
Uninstall_app()
|
|
||||||
{
|
|
||||||
rm -rf $serverPath/mariadb
|
|
||||||
echo '卸载完成' > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
if [ "${1}" == 'install' ];then
|
|
||||||
Install_app
|
|
||||||
else
|
|
||||||
Uninstall_app
|
|
||||||
fi
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
|
||||||
#https://dev.mysql.com/downloads/file/?id=480541
|
|
||||||
|
|
||||||
curPath=`pwd`
|
|
||||||
rootPath=$(dirname "$curPath")
|
|
||||||
rootPath=$(dirname "$rootPath")
|
|
||||||
serverPath=$(dirname "$rootPath")
|
|
||||||
sysName=`uname`
|
|
||||||
|
|
||||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
|
||||||
mariadbDir=${serverPath}/source/mariadb
|
|
||||||
|
|
||||||
MY_VER=10.7.5
|
|
||||||
|
|
||||||
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 "1" ];then
|
|
||||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
|
||||||
fi
|
|
||||||
# ----- cpu end ------
|
|
||||||
|
|
||||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
|
||||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$?" != "0" ];then
|
|
||||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
|
||||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d $serverPath/mariadb ];then
|
|
||||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
|
||||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
|
||||||
-DMYSQL_USER=mysql \
|
|
||||||
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
|
|
||||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
|
||||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
|
||||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
|
||||||
-DENABLED_LOCAL_INFILE=1 \
|
|
||||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
|
||||||
-DEXTRA_CHARSETS=all \
|
|
||||||
-DDEFAULT_CHARSET=utf8mb4 \
|
|
||||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
|
||||||
-DCMAKE_C_COMPILER=/usr/bin/gcc \
|
|
||||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
|
||||||
make -j${cpuCore} && make install && make clean
|
|
||||||
|
|
||||||
if [ -d $serverPath/mariadb ];then
|
|
||||||
echo '10.7' > $serverPath/mariadb/version.pl
|
|
||||||
echo '安装完成' > $install_tmp
|
|
||||||
else
|
|
||||||
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
|
||||||
echo '安装失败' > $install_tmp
|
|
||||||
echo 'install fail'>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
Uninstall_app()
|
|
||||||
{
|
|
||||||
rm -rf $serverPath/mariadb
|
|
||||||
echo '卸载完成' > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
if [ "${1}" == 'install' ];then
|
|
||||||
Install_app
|
|
||||||
else
|
|
||||||
Uninstall_app
|
|
||||||
fi
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
|
|
||||||
export PATH
|
|
||||||
|
|
||||||
#https://dev.mysql.com/downloads/mysql/5.5.html#downloads
|
|
||||||
#https://dev.mysql.com/downloads/file/?id=480541
|
|
||||||
|
|
||||||
curPath=`pwd`
|
|
||||||
rootPath=$(dirname "$curPath")
|
|
||||||
rootPath=$(dirname "$rootPath")
|
|
||||||
serverPath=$(dirname "$rootPath")
|
|
||||||
sysName=`uname`
|
|
||||||
|
|
||||||
install_tmp=${rootPath}/tmp/mw_install.pl
|
|
||||||
mariadbDir=${serverPath}/source/mariadb
|
|
||||||
|
|
||||||
MY_VER=10.8.4
|
|
||||||
|
|
||||||
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 "1" ];then
|
|
||||||
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
|
|
||||||
fi
|
|
||||||
# ----- cpu end ------
|
|
||||||
|
|
||||||
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
|
|
||||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$?" != "0" ];then
|
|
||||||
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
|
|
||||||
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
if [ ! -d $serverPath/mariadb ];then
|
|
||||||
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
|
|
||||||
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
|
|
||||||
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
|
|
||||||
-DMYSQL_USER=mysql \
|
|
||||||
-DMYSQL_UNIX_ADDR=$serverPath/mariadb/mysql.sock \
|
|
||||||
-DWITH_MYISAM_STORAGE_ENGINE=1 \
|
|
||||||
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
|
|
||||||
-DWITH_MEMORY_STORAGE_ENGINE=1 \
|
|
||||||
-DENABLED_LOCAL_INFILE=1 \
|
|
||||||
-DWITH_PARTITION_STORAGE_ENGINE=1 \
|
|
||||||
-DEXTRA_CHARSETS=all \
|
|
||||||
-DDEFAULT_CHARSET=utf8mb4 \
|
|
||||||
-DDEFAULT_COLLATION=utf8mb4_general_ci \
|
|
||||||
-DCMAKE_C_COMPILER=/usr/bin/gcc \
|
|
||||||
-DCMAKE_CXX_COMPILER=/usr/bin/g++
|
|
||||||
make -j${cpuCore} && make install && make clean
|
|
||||||
|
|
||||||
if [ -d $serverPath/mariadb ];then
|
|
||||||
echo '10.8' > $serverPath/mariadb/version.pl
|
|
||||||
echo '安装完成' > $install_tmp
|
|
||||||
else
|
|
||||||
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
|
|
||||||
echo '安装失败' > $install_tmp
|
|
||||||
echo 'install fail'>&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
Uninstall_app()
|
|
||||||
{
|
|
||||||
rm -rf $serverPath/mariadb
|
|
||||||
echo '卸载完成' > $install_tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
action=$1
|
|
||||||
if [ "${1}" == 'install' ];then
|
|
||||||
Install_app
|
|
||||||
else
|
|
||||||
Uninstall_app
|
|
||||||
fi
|
|
||||||
@@ -1,242 +0,0 @@
|
|||||||
# coding:utf-8
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import io
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import re
|
|
||||||
|
|
||||||
sys.path.append(os.getcwd() + "/class/core")
|
|
||||||
import mw
|
|
||||||
|
|
||||||
app_debug = False
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
app_debug = True
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginName():
|
|
||||||
return 'memcached'
|
|
||||||
|
|
||||||
|
|
||||||
def getPluginDir():
|
|
||||||
return mw.getPluginDir() + '/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getServerDir():
|
|
||||||
return mw.getServerDir() + '/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getInitDFile():
|
|
||||||
if app_debug:
|
|
||||||
return '/tmp/' + getPluginName()
|
|
||||||
return '/etc/init.d/' + getPluginName()
|
|
||||||
|
|
||||||
|
|
||||||
def getConf():
|
|
||||||
path = getServerDir() + "/init.d/memcached"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getConfTpl():
|
|
||||||
path = getPluginDir() + "/init.d/memcached.tpl"
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def getMemPort():
|
|
||||||
path = getConf()
|
|
||||||
content = mw.readFile(path)
|
|
||||||
rep = 'PORT\s*=\s*(\d*)'
|
|
||||||
tmp = re.search(rep, content)
|
|
||||||
return tmp.groups()[0]
|
|
||||||
|
|
||||||
|
|
||||||
def getArgs():
|
|
||||||
args = sys.argv[2:]
|
|
||||||
tmp = {}
|
|
||||||
args_len = len(args)
|
|
||||||
|
|
||||||
if args_len == 1:
|
|
||||||
t = args[0].strip('{').strip('}')
|
|
||||||
t = t.split(':')
|
|
||||||
tmp[t[0]] = t[1]
|
|
||||||
elif args_len > 1:
|
|
||||||
for i in range(len(args)):
|
|
||||||
t = args[i].split(':')
|
|
||||||
tmp[t[0]] = t[1]
|
|
||||||
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
def status():
|
|
||||||
data = mw.execShell(
|
|
||||||
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
|
|
||||||
if data[0] == '':
|
|
||||||
return 'stop'
|
|
||||||
return 'start'
|
|
||||||
|
|
||||||
|
|
||||||
def initDreplace():
|
|
||||||
|
|
||||||
file_tpl = getConfTpl()
|
|
||||||
service_path = mw.getServerDir()
|
|
||||||
|
|
||||||
initD_path = getServerDir() + '/init.d'
|
|
||||||
if not os.path.exists(initD_path):
|
|
||||||
os.mkdir(initD_path)
|
|
||||||
file_bin = initD_path + '/memcached'
|
|
||||||
|
|
||||||
if not os.path.exists(file_bin):
|
|
||||||
content = mw.readFile(file_tpl)
|
|
||||||
content = content.replace('{$SERVER_PATH}', service_path)
|
|
||||||
mw.writeFile(file_bin, content)
|
|
||||||
mw.execShell('chmod +x ' + file_bin)
|
|
||||||
|
|
||||||
return file_bin
|
|
||||||
|
|
||||||
|
|
||||||
def memOp(method):
|
|
||||||
file = initDreplace()
|
|
||||||
data = mw.execShell(file + ' ' + method)
|
|
||||||
if data[1] == '':
|
|
||||||
return 'ok'
|
|
||||||
return data[1]
|
|
||||||
|
|
||||||
|
|
||||||
def start():
|
|
||||||
return memOp('start')
|
|
||||||
|
|
||||||
|
|
||||||
def stop():
|
|
||||||
return memOp('stop')
|
|
||||||
|
|
||||||
|
|
||||||
def restart():
|
|
||||||
return memOp('restart')
|
|
||||||
|
|
||||||
|
|
||||||
def reload():
|
|
||||||
return memOp('reload')
|
|
||||||
|
|
||||||
|
|
||||||
def runInfo():
|
|
||||||
# 获取memcached状态
|
|
||||||
import telnetlib
|
|
||||||
import re
|
|
||||||
port = getMemPort()
|
|
||||||
try:
|
|
||||||
tn = telnetlib.Telnet('127.0.0.1', int(port))
|
|
||||||
tn.write(b"stats\n")
|
|
||||||
tn.write(b"quit\n")
|
|
||||||
data = tn.read_all()
|
|
||||||
if type(data) == bytes:
|
|
||||||
data = data.decode('utf-8')
|
|
||||||
data = data.replace('STAT', '').replace('END', '').split("\n")
|
|
||||||
result = {}
|
|
||||||
res = ['cmd_get', 'get_hits', 'get_misses', 'limit_maxbytes', 'curr_items', 'bytes',
|
|
||||||
'evictions', 'limit_maxbytes', 'bytes_written', 'bytes_read', 'curr_connections']
|
|
||||||
for d in data:
|
|
||||||
if len(d) < 3:
|
|
||||||
continue
|
|
||||||
t = d.split()
|
|
||||||
if not t[0] in res:
|
|
||||||
continue
|
|
||||||
result[t[0]] = int(t[1])
|
|
||||||
result['hit'] = 1
|
|
||||||
if result['get_hits'] > 0 and result['cmd_get'] > 0:
|
|
||||||
result['hit'] = float(result['get_hits']) / \
|
|
||||||
float(result['cmd_get']) * 100
|
|
||||||
|
|
||||||
conf = mw.readFile(getConf())
|
|
||||||
result['bind'] = re.search('IP=(.+)', conf).groups()[0]
|
|
||||||
result['port'] = int(re.search('PORT=(\d+)', conf).groups()[0])
|
|
||||||
result['maxconn'] = int(re.search('MAXCONN=(\d+)', conf).groups()[0])
|
|
||||||
result['cachesize'] = int(
|
|
||||||
re.search('CACHESIZE=(\d+)', conf).groups()[0])
|
|
||||||
return mw.getJson(result)
|
|
||||||
except Exception as e:
|
|
||||||
return mw.getJson({})
|
|
||||||
|
|
||||||
|
|
||||||
def saveConf():
|
|
||||||
# 设置memcached缓存大小
|
|
||||||
import re
|
|
||||||
confFile = getConf()
|
|
||||||
# print confFile
|
|
||||||
try:
|
|
||||||
args = getArgs()
|
|
||||||
content = mw.readFile(confFile)
|
|
||||||
content = re.sub('IP=.+', 'IP=' + args['ip'], content)
|
|
||||||
content = re.sub('PORT=\d+', 'PORT=' + args['port'], content)
|
|
||||||
content = re.sub('MAXCONN=\d+', 'MAXCONN=' + args['maxconn'], content)
|
|
||||||
content = re.sub('CACHESIZE=\d+', 'CACHESIZE=' +
|
|
||||||
args['cachesize'], content)
|
|
||||||
mw.writeFile(confFile, content)
|
|
||||||
restart()
|
|
||||||
return 'save ok'
|
|
||||||
except Exception as e:
|
|
||||||
pass
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
|
|
||||||
def initdStatus():
|
|
||||||
if not app_debug:
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
initd_bin = getInitDFile()
|
|
||||||
if os.path.exists(initd_bin):
|
|
||||||
return 'ok'
|
|
||||||
return 'fail'
|
|
||||||
|
|
||||||
|
|
||||||
def initdInstall():
|
|
||||||
import shutil
|
|
||||||
if not app_debug:
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
|
|
||||||
mem_bin = initDreplace()
|
|
||||||
initd_bin = getInitDFile()
|
|
||||||
shutil.copyfile(mem_bin, initd_bin)
|
|
||||||
mw.execShell('chmod +x ' + initd_bin)
|
|
||||||
mw.execShell('chkconfig --add ' + getPluginName())
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
|
|
||||||
def initdUinstall():
|
|
||||||
if not app_debug:
|
|
||||||
if mw.isAppleSystem():
|
|
||||||
return "Apple Computer does not support"
|
|
||||||
|
|
||||||
mw.execShell('chkconfig --del ' + getPluginName())
|
|
||||||
initd_bin = getInitDFile()
|
|
||||||
os.remove(initd_bin)
|
|
||||||
return 'ok'
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
func = sys.argv[1]
|
|
||||||
if func == 'status':
|
|
||||||
print(status())
|
|
||||||
elif func == 'start':
|
|
||||||
print(start())
|
|
||||||
elif func == 'stop':
|
|
||||||
print(stop())
|
|
||||||
elif func == 'restart':
|
|
||||||
print(restart())
|
|
||||||
elif func == 'reload':
|
|
||||||
print(reload())
|
|
||||||
elif func == 'initd_status':
|
|
||||||
print(initdStatus())
|
|
||||||
elif func == 'initd_install':
|
|
||||||
print(initdInstall())
|
|
||||||
elif func == 'initd_uninstall':
|
|
||||||
print(initdUinstall())
|
|
||||||
elif func == 'run_info':
|
|
||||||
print(runInfo())
|
|
||||||
elif func == 'conf':
|
|
||||||
print(getConf())
|
|
||||||
elif func == 'conf_tpl':
|
|
||||||
print(getConfTpl())
|
|
||||||
elif func == 'save_conf':
|
|
||||||
print(saveConf())
|
|
||||||
else:
|
|
||||||
print('fail')
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 653 B After Width: | Height: | Size: 801 B |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user