Compare commits

...
973 Commits
Author SHA1 Message Date
Mr Chen a77e37ac65 Merge pull request #633 from midoks/dev
Update site.py
2024-12-13 01:16:03 +08:00
Mr Chen 296b1cfe86 Update site.py 2024-12-13 01:14:25 +08:00
Mr Chen c225570c00 Merge pull request #632 from midoks/dev
0.18.0
2024-12-12 23:29:56 +08:00
Mr Chen 4b1db3d02f 0.18.0
### 版本更新 0.18.0

- 重新架构面板。
- PHP84正式版。
- 加入alist插件。
- 数据管理-常用命令。
- 插件读取优化(加入缓存+定时检查状态)。
- 恢复面板书签。
- 常规更新。
2024-12-12 23:28:49 +08:00
Mr Chen c358954e6d Update version.py 2024-12-12 23:27:19 +08:00
Mr Chen cfea5d498f Update dashboard.py 2024-12-12 23:26:32 +08:00
Mr Chen e69136534b Update install.sh 2024-12-12 23:00:41 +08:00
Mr Chen 400ecfe690 Update alist.js 2024-12-12 22:23:45 +08:00
Mr Chen c64287fd51 Update index.py 2024-12-12 22:23:05 +08:00
Mr Chen 0edc306aa8 Update index.py 2024-12-12 22:22:47 +08:00
Mr Chen 839fec3a79 Update index.py 2024-12-12 22:15:39 +08:00
Mr Chen db2aab88f4 Update site.py 2024-12-12 17:43:26 +08:00
Mr Chen a5195956c2 Update sql_mysql.py 2024-12-12 12:41:55 +08:00
Mr Chen fc0b79f018 Update orm.py 2024-12-12 12:38:30 +08:00
Mr Chen 1b42bafc49 Update php.py 2024-12-12 04:19:00 +08:00
Mr Chen 83a2ea9b4e Update logs.py 2024-12-12 02:11:12 +08:00
Mr Chen 4bf5fd712d Update sql_mysql.py 2024-12-11 20:15:42 +08:00
Mr Chen 8a42898afe Update sql_mysql.py 2024-12-11 19:54:31 +08:00
Mr Chen 6577b37b76 Update plugin.py 2024-12-11 18:56:53 +08:00
Mr Chen ccb02f14a6 update 2024-12-11 18:56:37 +08:00
Mr Chen 0bd476340a Update install.sh 2024-12-11 14:26:01 +08:00
Mr Chen 84c9436546 Update plugin.py 2024-12-11 14:03:47 +08:00
Mr Chen e9d220b54d Update plugin.py 2024-12-11 14:03:34 +08:00
Mr Chen adecec811e Update Dockerfile 2024-12-11 13:35:10 +08:00
Mr Chen c3285f8b2e Update panel_tools.py 2024-12-11 12:11:04 +08:00
Mr Chen 864b5bb985 Update panel_tools.py 2024-12-11 12:10:42 +08:00
Mr Chen 39bf6b811a Update python-app-php.yml 2024-12-11 12:01:43 +08:00
Mr Chen c7d0744fa3 Update python-app-op.yml 2024-12-11 11:43:08 +08:00
Mr Chen 726cdd8dc7 Update python-app-op.yml 2024-12-11 00:04:55 +08:00
Mr Chen 93f895d4e4 Update python-app-op.yml 2024-12-11 00:04:02 +08:00
Mr Chen 00ed75502b Update python-app-php.yml 2024-12-10 23:55:14 +08:00
Mr Chen a4b1ca831e Update python-app-php.yml 2024-12-10 23:37:16 +08:00
Mr Chen 18e59c9538 Update panel_tools.py 2024-12-10 23:24:07 +08:00
Mr Chen 3fa51efd16 Update panel_tools.py 2024-12-10 23:23:57 +08:00
Mr Chen fcd747c4a5 Update panel_tools.py 2024-12-10 23:22:54 +08:00
Mr Chen 4d9dd26337 Update panel_tools.py 2024-12-10 23:22:07 +08:00
Mr Chen 7996722f04 Update setting.py 2024-12-10 22:33:27 +08:00
Mr Chen b0aa889a1f Update setting.py 2024-12-10 22:25:59 +08:00
Mr Chen 4b1d6acb77 Update panel_tools.py 2024-12-10 22:17:21 +08:00
Mr Chen d00da44fcb update 2024-12-10 22:13:20 +08:00
Mr Chen 1da7d08887 update 2024-12-10 21:27:30 +08:00
Mr Chen a04d24d410 update 2024-12-10 21:22:42 +08:00
Mr Chen 055422bac9 update 2024-12-10 19:56:26 +08:00
Mr Chen 4e09a802b0 update 2024-12-10 19:31:15 +08:00
Mr Chen a66bab02ab update 2024-12-10 19:20:19 +08:00
Mr Chen d217ebfc4f Update php.js 2024-12-10 19:05:09 +08:00
Mr Chen 31cafa59ab Update index.py 2024-12-10 18:50:06 +08:00
Mr Chen c66b9794ee Update php.js 2024-12-10 18:40:29 +08:00
Mr Chen ddd3d3a33a Update version.py 2024-12-10 18:36:04 +08:00
Mr Chen 7816dbf264 Update public.js 2024-12-10 18:35:57 +08:00
Mr Chen f78279a271 update 2024-12-10 18:34:21 +08:00
Mr Chen 411174c07c Update public.js 2024-12-10 18:27:27 +08:00
Mr Chen 28988eff93 Update public.js 2024-12-10 18:26:19 +08:00
Mr Chen 5ee9a6790e update 2024-12-10 18:25:52 +08:00
Mr Chen 6cce658ea3 Update public.js 2024-12-10 18:24:51 +08:00
Mr Chen 3c54e7943b Update php.js 2024-12-10 18:21:17 +08:00
Mr Chen c0923f7d4f Update index.py 2024-12-10 18:15:05 +08:00
Mr Chen 7973d369cc update 2024-12-10 18:05:43 +08:00
Mr Chen 2b70534fb2 update 2024-12-10 18:00:09 +08:00
Mr Chen 1d0a4c371c update 2024-12-10 17:42:51 +08:00
Mr Chen 18eee3f8e8 Update firewall.py 2024-12-10 16:49:12 +08:00
Mr Chen 2ae280e6c9 Update firewall.py 2024-12-10 16:48:42 +08:00
Mr Chen baf56d71e9 Update phplib.conf 2024-12-10 15:54:48 +08:00
Mr Chen fe6649a0a5 update 2024-12-10 15:51:15 +08:00
Mr Chen 452623a56e Update README.md 2024-12-10 15:33:44 +08:00
Mr Chen a361c31c11 Update push_notice_msg.py 2024-12-10 15:22:51 +08:00
Mr Chen fb15ca1d76 Update push_ad.py 2024-12-10 15:22:23 +08:00
Mr Chen 3d319c7c76 update 2024-12-10 15:17:22 +08:00
Mr Chen 069bef1f0d Update igbinary.sh 2024-12-10 14:56:36 +08:00
Mr Chen 3b0e624d92 Update README.md 2024-12-10 14:54:14 +08:00
Mr Chen ee13c8f519 Update solr.sh 2024-12-10 14:44:52 +08:00
Mr Chen 51eff5f671 Update yaml.sh 2024-12-10 14:43:32 +08:00
Mr Chen e544ba53b5 Update yaf.sh 2024-12-10 14:40:43 +08:00
Mr Chen e28a7124a2 Update yaf.sh 2024-12-10 14:39:03 +08:00
Mr Chen dd0c46286c Update swoole.sh 2024-12-10 14:37:46 +08:00
Mr Chen a1b39dcff5 Update site.py 2024-12-10 14:26:02 +08:00
Mr Chen a3022c7f80 Update site.py 2024-12-10 14:24:40 +08:00
Mr Chen f16dfd6819 update 2024-12-10 14:22:59 +08:00
Mr Chen 9f2bc6e0e1 Update phplib.conf 2024-12-10 05:30:44 +08:00
Mr Chen f2c4831786 update 2024-12-10 04:29:32 +08:00
Mr Chen 3f5b6a0b00 Update panel_bookmark.py 2024-12-10 04:18:21 +08:00
Mr Chen 1bf02abc1d Update __init__.py 2024-12-10 03:23:19 +08:00
Mr Chen 5dcf932a81 Update __init__.py 2024-12-10 03:15:26 +08:00
Mr Chen f2f02e4b1b update 2024-12-10 03:14:06 +08:00
Mr Chen 47ce5e05bc Update plugin.py 2024-12-10 03:10:48 +08:00
Mr Chen e878f79ffc up 2024-12-10 02:57:58 +08:00
Mr Chen 5e6774ee63 Update version.py 2024-12-10 02:52:44 +08:00
Mr Chen ec4c3f3574 Update public.js 2024-12-10 02:52:35 +08:00
Mr Chen e7e9379c09 update 2024-12-10 02:30:07 +08:00
Mr Chen 65c303272c update 2024-12-10 02:23:49 +08:00
Mr Chen 2be356a875 Update readline.sh 2024-12-10 02:05:33 +08:00
Mr Chen d60e1291c8 Update version.py 2024-12-10 00:35:02 +08:00
Mr Chen ae342c71a7 Update public.js 2024-12-10 00:27:47 +08:00
Mr Chen ec79bfc93b Update openssl.sh 2024-12-10 00:12:26 +08:00
Mr Chen f3006b55b3 Update phplib.conf 2024-12-10 00:02:06 +08:00
Mr Chen 08aa864fa0 Update install.sh 2024-12-09 23:29:57 +08:00
Mr Chen 93b39f4fb0 Update phplib.conf 2024-12-09 23:28:34 +08:00
Mr Chen b189241745 update 2024-12-09 23:25:45 +08:00
Mr Chen 3206e62583 update 2024-12-09 23:19:53 +08:00
Mr Chen 299b216c48 Update phplib.conf 2024-12-09 23:15:39 +08:00
Mr Chen fe53068055 Update zip.sh 2024-12-09 23:12:27 +08:00
Mr Chen 0a8b921327 Update phplib.conf 2024-12-09 23:10:59 +08:00
Mr Chen 1119371bdb Update phplib.conf 2024-12-09 22:58:25 +08:00
Mr Chen 980129a8ec Update phplib.conf 2024-12-09 22:58:19 +08:00
Mr Chen 5554ff3350 update 2024-12-09 22:49:39 +08:00
Mr Chen 3fd55fd5de Update sql_mysql.py 2024-12-09 20:11:02 +08:00
Mr Chen d4f9f5bcfd Update sql_mysql.py 2024-12-09 20:08:18 +08:00
Mr Chen 318cba0d43 Update sql_mysql.py 2024-12-09 20:07:41 +08:00
Mr Chen 173aae22b4 Update app.js 2024-12-09 19:59:01 +08:00
Mr Chen f86e30634d Update app.js 2024-12-09 19:55:27 +08:00
Mr Chen 6f9b9bbbc1 Update sql_mysql.py 2024-12-09 19:48:30 +08:00
Mr Chen fa7ad33474 Update sql_mysql.py 2024-12-09 19:46:13 +08:00
Mr Chen 834978adfd Update sql_mysql.py 2024-12-09 19:45:21 +08:00
Mr Chen e70fa6d257 Update app.js 2024-12-09 19:33:07 +08:00
Mr Chen 326179479c Update app.js 2024-12-09 19:30:57 +08:00
Mr Chen 909b8a3f88 Update sql_mysql.py 2024-12-09 19:25:55 +08:00
Mr Chen 973cbf4f9d update 2024-12-09 19:20:06 +08:00
Mr Chen ca52d5bf65 Update app.js 2024-12-09 18:53:47 +08:00
Mr Chen 5427a2b1ee Update nosql_redis.py 2024-12-09 18:49:34 +08:00
Mr Chen 7b925e5504 Update app.js 2024-12-09 18:46:08 +08:00
Mr Chen 6b7752e14a Update sql_mysql.py 2024-12-09 18:45:20 +08:00
Mr Chen f13a0c68dc Update site.py 2024-12-09 18:38:39 +08:00
Mr Chen 017d96872a Update site.py 2024-12-09 18:37:25 +08:00
Mr Chen f11b8637bb update 2024-12-09 18:34:30 +08:00
Mr Chen 5452ee3229 Update site.py 2024-12-09 18:24:12 +08:00
Mr Chen 41a76e1ac6 Update site.py 2024-12-09 18:22:39 +08:00
Mr Chen 2e3d5fda44 Update site.py 2024-12-09 18:21:58 +08:00
Mr Chen d26e2fb06f Update site.py 2024-12-09 18:08:15 +08:00
Mr Chen 7aa0bf59f2 Update site.py 2024-12-09 18:07:31 +08:00
Mr Chen 4cc72c7164 update 2024-12-09 18:01:25 +08:00
Mr Chen 10dffd71f7 update 2024-12-09 17:48:13 +08:00
Mr Chen 56c4710c55 Update site.py 2024-12-09 17:37:16 +08:00
Mr Chen 2bebf3503f Update site.py 2024-12-09 17:32:00 +08:00
Mr Chen 8e61c89bd3 Update site.py 2024-12-09 17:31:25 +08:00
Mr Chen 2e4fe6e434 Update site.py 2024-12-09 17:28:34 +08:00
Mr Chen be1e03828c Merge pull request #631 from midoks/revert-630-master
Revert "修复http3在多Worker 下需要reuseport以及不传HOST变量的问题"
2024-12-09 16:48:48 +08:00
Mr Chen 55d9700401 Revert "修复http3在多Worker 下需要reuseport以及不传HOST变量的问题" 2024-12-09 16:48:27 +08:00
Mr Chen e55f79b9b8 Update README.md 2024-12-09 15:57:46 +08:00
Mr Chen 5684fc217f Update README.md 2024-12-09 15:57:26 +08:00
Mr Chen f0071b5e82 Update panel_task.py 2024-12-09 15:52:21 +08:00
Mr Chen 7bb7ce2ef3 Update panel_task.py 2024-12-09 01:36:51 +08:00
Mr Chen 47569c475f Update file.py 2024-12-09 01:07:22 +08:00
Mr Chen eb8886b4eb update 2024-12-09 01:04:30 +08:00
Mr Chen 83711db1c8 update 2024-12-09 01:00:01 +08:00
Mr Chen 6858a827f9 update 2024-12-09 00:53:02 +08:00
Mr Chen 66c8900a30 update 2024-12-09 00:47:05 +08:00
Mr Chen 892b1144e1 Update files.py 2024-12-09 00:39:41 +08:00
Mr Chen 06d2b381b2 Update files.py 2024-12-09 00:38:19 +08:00
Mr Chen f8e3df36c8 Update file.py 2024-12-09 00:36:09 +08:00
Mr Chen b69c986dcd Update system.py 2024-12-09 00:18:03 +08:00
Mr Chen 3501323a12 Update system.py 2024-12-09 00:17:51 +08:00
Mr Chen 0671455b59 update 2024-12-09 00:10:10 +08:00
Mr Chen c4727b90da Update system.py 2024-12-09 00:08:37 +08:00
Mr Chen a14c4b566e update 2024-12-09 00:05:34 +08:00
Mr Chen 33353dd2a3 Update plugin.py 2024-12-08 23:55:44 +08:00
Mr Chen 3b436a15c1 Update plugin.py 2024-12-08 23:04:34 +08:00
Mr Chen 49f45314d1 Update plugin.py 2024-12-08 23:04:23 +08:00
Mr Chen 679aefba86 Update plugin.py 2024-12-08 23:00:42 +08:00
Mr Chen 255d297d61 Update plugin.py 2024-12-08 23:00:03 +08:00
Mr Chen c1a59d63fc 缓存检查插件状态,提高速度 2024-12-08 22:43:55 +08:00
Mr Chen d75c729e29 re 修复 2024-12-08 22:41:10 +08:00
Mr Chen f50be939f5 Update version.py 2024-12-06 04:17:29 +08:00
Mr Chen 3394a8892f update 2024-12-06 04:17:11 +08:00
Mr Chen 02e5f595fd Update sql_mysql.py 2024-12-06 03:50:14 +08:00
Mr Chen 1bee5e7429 Update option.py 2024-12-05 23:48:54 +08:00
Mr Chen a8b6ae4c21 Update option.py 2024-12-05 23:48:35 +08:00
Mr Chen 154c482e67 Update compatibility.md 2024-12-05 14:55:50 +08:00
Mr Chen 723d5e3959 Update __init__.py 2024-12-05 06:18:12 +08:00
Mr Chen 73f8226854 Update init_cmd.py 2024-12-05 06:11:49 +08:00
Mr Chen 3826bb53aa Update init_cmd.py 2024-12-05 06:11:23 +08:00
Mr Chen 7fbe40e73f Update init_cmd.py 2024-12-05 06:11:03 +08:00
Mr Chen e3606a1ca4 Update __init__.py 2024-12-05 06:07:05 +08:00
Mr Chen bfe0e0a31a Update panel_tools.py 2024-12-05 06:04:05 +08:00
Mr Chen 643338eab1 update 2024-12-05 06:02:42 +08:00
Mr Chen 0777b65919 up 2024-12-05 05:45:06 +08:00
Mr Chen c9ef1cd141 up 2024-12-05 05:38:11 +08:00
Mr Chen b9a1d142d1 Update crontab.py 2024-12-05 05:36:06 +08:00
Mr Chen 7959167554 Update version.py 2024-12-05 05:29:18 +08:00
Mr Chen fcf20958c9 Update crontab.html 2024-12-05 05:29:09 +08:00
Mr Chen 92b26bd14f update 2024-12-05 05:22:16 +08:00
Mr Chen d6b414f022 Update version.py 2024-12-05 05:13:45 +08:00
Mr Chen dd3092639e Update crontab.html 2024-12-05 05:13:38 +08:00
Mr Chen 0e633491bd Update version.py 2024-12-05 05:08:17 +08:00
Mr Chen 2250770f66 Update crontab.js 2024-12-05 05:08:06 +08:00
Mr Chen 1d8448d6bb update 2024-12-05 05:05:47 +08:00
Mr Chen 6eda36aec2 Update index.py 2024-12-05 04:56:02 +08:00
Mr Chen 09d656ef60 update 2024-12-05 04:54:06 +08:00
Mr Chen 19aadb581f Update index.py 2024-12-05 04:46:36 +08:00
Mr Chen c27248af98 Update index.py 2024-12-05 04:42:36 +08:00
Mr Chen 829a2516ba update 2024-12-05 04:27:37 +08:00
Mr Chen ac0dac2561 Update __init__.py 2024-12-05 04:23:06 +08:00
Mr Chen a308c630fc Update update.py 2024-12-05 03:58:04 +08:00
Mr Chen 661a346060 Update config.py 2024-12-05 03:11:29 +08:00
Mr Chen b251de30b1 Update version.py 2024-12-05 03:05:22 +08:00
Mr Chen 716c0a6d46 Update crontab.py 2024-12-05 03:04:37 +08:00
Mr Chen ac8c048b28 Update crontab.py 2024-12-05 02:57:33 +08:00
Mr Chen 00afaec282 Update index.html 2024-12-05 02:51:38 +08:00
Mr Chen 727c36ebc7 update 2024-12-05 02:11:47 +08:00
Mr Chen 2f5bd3b5ed Update index.py 2024-12-05 01:57:20 +08:00
Mr Chen 49ca076d6c Update index.py 2024-12-05 01:57:03 +08:00
Mr Chen f63e375b13 update 2024-12-05 01:54:12 +08:00
Mr Chen e480582fcf Update readline.sh 2024-12-05 01:11:43 +08:00
Mr Chen f45dd1bbf5 Update readline.sh 2024-12-05 01:10:51 +08:00
Mr Chen d37f651f23 Update readline.sh 2024-12-05 00:37:33 +08:00
Mr Chen 4d2793d4dc Update version.py 2024-12-04 18:07:10 +08:00
Mr Chen fb3404e92f Update upgrade.py 2024-12-04 18:06:54 +08:00
Mr Chen 2cdb62cbd3 update 2024-12-04 18:03:37 +08:00
Mr Chen a3d231f619 update 2024-12-04 17:58:16 +08:00
Mr Chen 34551409d9 Update version.py 2024-12-04 17:44:23 +08:00
Mr Chen be83c2c3bb Update version.py 2024-12-04 16:58:37 +08:00
Mr Chen b963302a96 Update push_ad.py 2024-12-04 15:24:41 +08:00
Mr Chen 5238d8f263 Update pathinfo.conf 2024-12-04 15:11:43 +08:00
Mr Chen 384419fa30 Update app.js 2024-12-04 04:24:46 +08:00
Mr Chen d18952a72e Update index.py 2024-12-04 03:57:56 +08:00
Mr Chen f1478369b5 Update index.py 2024-12-04 03:28:06 +08:00
Mr Chen face89efc5 Update file.py 2024-12-04 03:15:12 +08:00
Mr Chen 44f5f7f270 Update file.py 2024-12-04 03:11:35 +08:00
Mr Chen a30d68a3d9 Update file.py 2024-12-04 03:07:01 +08:00
Mr Chen 0e5f3bc23b Update file.py 2024-12-04 02:33:56 +08:00
Mr Chen 0f97e0db44 Update install.sh 2024-12-04 02:20:18 +08:00
Mr Chen 79ed3f3a4c Update index.py 2024-12-04 01:57:14 +08:00
Mr Chen 869a321c14 Update index.py 2024-12-04 01:57:01 +08:00
Mr Chen f338d8bd8e Update index.py 2024-12-04 01:54:30 +08:00
Mr Chen 2a60cd981d Update index.py 2024-12-04 01:37:00 +08:00
Mr Chen 3504ca24f2 Update mw_api.py 2024-12-04 01:26:36 +08:00
Mr Chen ebcd450f55 Update index.py 2024-12-04 01:26:33 +08:00
Mr Chen db8f74f848 update 2024-12-04 01:26:26 +08:00
Mr Chen b34cf3fc86 Update main.py 2024-12-04 00:38:34 +08:00
Mr Chen a1bb8b9816 update 2024-12-04 00:34:49 +08:00
Mr Chen 3db30b1298 Update __init__.py 2024-12-04 00:14:53 +08:00
Mr Chen 773bc41a12 Update version.py 2024-12-04 00:05:00 +08:00
Mr Chen c91928c55f update 2024-12-03 23:26:15 +08:00
Mr Chen 5588976f95 Update index.py 2024-12-03 21:52:15 +08:00
Mr Chen 87d76d7cf7 update 2024-12-03 20:48:01 +08:00
Mr Chen 18202b859b Update system.py 2024-12-03 20:19:41 +08:00
Mr Chen 8309b8e493 update 2024-12-03 20:16:19 +08:00
Mr Chen 50a96b198a update 2024-12-03 20:12:55 +08:00
Mr Chen 6ebc7a1514 update 2024-12-03 20:07:50 +08:00
Mr Chen 156f6d1791 Merge pull request #630 from jd82k/master
修复http3在多Worker 下需要reuseport以及不传HOST变量的问题
2024-12-03 18:56:32 +08:00
Mr Chen 6a013dd7f6 Update index.py 2024-12-03 18:48:56 +08:00
Mr Chen 05d8181202 update 2024-12-03 18:46:45 +08:00
Mr Chen 2f8217d5d5 Update index.py 2024-12-03 18:39:51 +08:00
Mr Chen d9234c9b77 Update index.py 2024-12-03 18:38:44 +08:00
Mr Chen 16b54569e0 update 2024-12-03 18:36:17 +08:00
Mr Chen 23ed3a7e47 update 2024-12-03 18:33:47 +08:00
Mr Chen d2f586dadd Update index.py 2024-12-03 18:25:04 +08:00
Mr Chen c72dcf02d2 Update xui.js 2024-12-03 18:23:22 +08:00
Mr Chen a099a83f9b Update xui.js 2024-12-03 18:18:56 +08:00
Mr Chen a986082f62 Update index.html 2024-12-03 18:18:41 +08:00
Mr Chen 5c9cde381c Update xui.js 2024-12-03 18:18:31 +08:00
Mr Chen c23ae77215 Update index.html 2024-12-03 18:05:28 +08:00
Mr Chen 33a83a6d8e Update index.html 2024-12-03 18:03:40 +08:00
Mr Chen 07d6ce0a34 Update index.html 2024-12-03 18:03:09 +08:00
Mr Chen 940006a10a update 2024-12-03 18:02:44 +08:00
Mr Chen c77b8d47fd Update xui.js 2024-12-03 18:02:15 +08:00
Mr Chen 58f24f0c75 Update xui.js 2024-12-03 18:01:33 +08:00
Mr Chen 41b11669d8 Update index.html 2024-12-03 17:59:11 +08:00
Mr Chen bb04f1666f update 2024-12-03 17:55:14 +08:00
Mr Chen 49c22a2d70 Update xui.js 2024-12-03 17:53:18 +08:00
Mr Chen 5616b90474 Update index.py 2024-12-03 17:51:26 +08:00
Mr Chen 230d3925df Update index.py 2024-12-03 17:49:23 +08:00
Mr Chen 5e92740b62 Update index.py 2024-12-03 17:47:22 +08:00
Mr Chen f353fc3e5a Update index.py 2024-12-03 17:42:55 +08:00
Mr Chen 8f5936135d Update index.py 2024-12-03 17:42:37 +08:00
Mr Chen 2954b92963 Update xui.js 2024-12-03 17:41:27 +08:00
Mr Chen 57141b3a90 Update index.py 2024-12-03 17:39:32 +08:00
Mr Chen 3b0db0359c update 2024-12-03 17:38:12 +08:00
Mr Chen ad66ecc628 update 2024-12-03 17:30:41 +08:00
Mr Chen 766dc32287 update 2024-12-03 17:29:50 +08:00
Mr Chen 761ddd72e9 Update index.py 2024-12-03 17:28:12 +08:00
Mr Chen 16e312bbe7 update 2024-12-03 17:25:53 +08:00
Mr Chen d36b36e1d3 Update index.py 2024-12-03 17:14:31 +08:00
Mr Chen 9eabb10e41 Update index.py 2024-12-03 17:12:37 +08:00
Mr Chen 7be3cdd5e8 update 2024-12-03 17:10:56 +08:00
Mr Chen 2f5842622c Update install.sh 2024-12-03 17:09:55 +08:00
Mr Chen 3f52744747 Update install.sh 2024-12-03 17:05:20 +08:00
Mr Chen 91a2558bf4 Update install.sh 2024-12-03 17:04:43 +08:00
Mr Chen aa397eb8e7 Update install.sh 2024-12-03 17:02:46 +08:00
Mr Chen 7663bdbc14 Create install_xui.sh 2024-12-03 17:01:12 +08:00
Mr Chen 51a9b551fd Update install.sh 2024-12-03 17:01:09 +08:00
Mr Chen 725572745b Update install.sh 2024-12-03 16:58:25 +08:00
Mr Chen 77e65252fb Update file.py 2024-12-03 16:50:32 +08:00
Mr Chen 1fc0a106b6 update 2024-12-03 16:49:04 +08:00
Mr Chen e8d72985e6 Update install.sh 2024-12-03 16:26:24 +08:00
Mr Chen 2ecc29269f update 2024-12-03 16:14:47 +08:00
Mr Chen 299eaa06b8 Update file.py 2024-12-03 15:35:41 +08:00
Mr Chen 154c7cbdbc Update file.py 2024-12-03 15:35:17 +08:00
Mr Chen 06bb5b5bb0 Update file.py 2024-12-03 15:34:27 +08:00
Mr Chen a718db5457 Update file.py 2024-12-03 15:34:14 +08:00
Mr Chen 2e17870d03 update 2024-12-03 15:32:31 +08:00
Mr Chen e70113c280 Update file.py 2024-12-03 15:29:05 +08:00
Mr Chen 4240f49de9 Update file.py 2024-12-03 15:28:33 +08:00
Mr Chen 9b0b8015df update 2024-12-03 15:19:58 +08:00
jd82k 998938e7ab fix http3 bugs 2024-12-02 20:06:59 -08:00
jd82k faffdaf535 Update pathinfo.conf 2024-12-02 20:04:17 -08:00
Mr Chen fce4cc332c Update install.sh 2024-12-03 01:10:02 +08:00
Mr Chen d211aa168c Update info.json 2024-12-03 00:27:34 +08:00
Mr Chen 2430cbb11a Update public.js 2024-12-02 23:46:02 +08:00
Mr Chen ddef7b1182 Update public.js 2024-12-02 23:45:31 +08:00
Mr Chen f5af7688a7 Update public.js 2024-12-02 23:43:36 +08:00
Mr Chen 1faef6799b update 2024-12-02 23:43:05 +08:00
Mr Chen 34e6bb75e0 Update index.py 2024-12-02 22:26:28 +08:00
Mr Chen 332aa43419 Update index.py 2024-12-02 22:24:49 +08:00
Mr Chen f96ff13843 Update version.py 2024-12-02 22:16:05 +08:00
Mr Chen f25066e23e Update public.js 2024-12-02 22:10:07 +08:00
Mr Chen 35ce2abae6 Update __init__.py 2024-12-02 22:09:34 +08:00
Mr Chen 897e236719 Update __init__.py 2024-12-02 22:08:53 +08:00
Mr Chen 916b3dff6c Update public.js 2024-12-02 22:03:25 +08:00
Mr Chen 846600ef99 Update index.py 2024-12-02 21:48:40 +08:00
Mr Chen 8cbae18986 Update README.md 2024-12-02 21:46:30 +08:00
Mr Chen c81616894c Update README.md 2024-12-02 21:13:50 +08:00
Mr Chen 408c9c291b Update init_cmd.py 2024-12-02 18:03:11 +08:00
Mr Chen 824032b338 Update init_cmd.py 2024-12-02 17:57:19 +08:00
Mr Chen 99c2c7ce4c Update init_cmd.py 2024-12-02 17:56:26 +08:00
Mr Chen 93d4749d9e Update init_cmd.py 2024-12-02 17:54:29 +08:00
Mr Chen 163776c5ff Update init_cmd.py 2024-12-02 17:54:09 +08:00
Mr Chen fd907e1dc9 Update mw.tpl 2024-12-02 17:39:19 +08:00
Mr Chen 6c306ad97f Update mw.tpl 2024-12-02 17:39:07 +08:00
Mr Chen 0357087b06 Update mw.tpl 2024-12-02 17:27:08 +08:00
Mr Chen 85a9ee4b29 Update mw.tpl 2024-12-02 17:22:16 +08:00
Mr Chen 5bab1ab4da Update mw.tpl 2024-12-02 17:18:29 +08:00
Mr Chen 0312c5ceb0 update 2024-12-02 17:12:29 +08:00
Mr Chen eca12b2cf3 update 2024-12-02 16:49:06 +08:00
Mr Chen 3476b4c30a Update init_cmd.py 2024-12-02 16:33:47 +08:00
Mr Chen 46d7f83cc4 Update mw.service.tpl 2024-12-02 16:28:42 +08:00
Mr Chen e1ef876db1 Update init_cmd.py 2024-12-02 16:25:55 +08:00
Mr Chen 8f1a89f978 Update init_cmd.py 2024-12-02 16:24:29 +08:00
Mr Chen a14301f769 Update tamper_proof_service.py 2024-12-02 14:53:23 +08:00
Mr Chen 54bd8f1d5c Update sql_mysql.py 2024-12-02 04:41:35 +08:00
Mr Chen 9d05edf09f Update orm.py 2024-12-02 04:33:02 +08:00
Mr Chen a0c228e352 Update sql_mysql.py 2024-12-02 04:13:19 +08:00
Mr Chen dfaf09735e Update sql_mysql.py 2024-12-02 04:08:03 +08:00
Mr Chen 6f2cc03044 Update ubuntu.sh 2024-12-02 03:54:47 +08:00
Mr Chen 2ff6d17d23 Update debian.sh 2024-12-02 03:54:32 +08:00
Mr Chen af83750220 update 2024-12-02 03:45:16 +08:00
Mr Chen 70dbb9eab5 Update sql_mysql.py 2024-12-02 03:18:06 +08:00
Mr Chen a58fd4476e Update app.js 2024-12-02 03:13:43 +08:00
Mr Chen 5f7f45c648 Update version.py 2024-12-02 03:09:33 +08:00
Mr Chen ca5b315725 update 2024-12-02 03:08:41 +08:00
Mr Chen 6a33354b2b Update index.py 2024-12-02 03:00:22 +08:00
Mr Chen 821683d484 Update init_cmd.py 2024-12-02 02:54:17 +08:00
Mr Chen a2e4fc8085 Update info.json 2024-12-02 02:41:49 +08:00
Mr Chen bb37fccee3 Update index.py 2024-12-02 02:40:52 +08:00
Mr Chen e9a01b5056 update 2024-12-02 02:33:32 +08:00
Mr Chen c1dec87784 Update install.sh 2024-12-02 02:31:48 +08:00
Mr Chen 74b3118bc3 Update install.sh 2024-12-02 02:31:43 +08:00
Mr Chen 853d5045f0 Update install.sh 2024-12-02 02:28:30 +08:00
Mr Chen 30db5569ad Update gdriveclient.py 2024-12-02 02:25:52 +08:00
Mr Chen 8c841e93a0 update 2024-12-02 02:00:13 +08:00
Mr Chen 46a752480c update 2024-12-02 01:54:28 +08:00
Mr Chen 1dddc3c5ba Update site.py 2024-12-02 01:47:26 +08:00
Mr Chen 61d90ef8e7 Update site.py 2024-12-02 01:44:19 +08:00
Mr Chen c3241a5c17 Update version.py 2024-12-02 01:32:07 +08:00
Mr Chen c6d1a44d43 Update control.js 2024-12-02 01:31:59 +08:00
Mr Chen 8ce5d6dfbe Update version.py 2024-12-02 01:30:41 +08:00
Mr Chen a8c8f922eb Update version.py 2024-12-02 01:28:54 +08:00
Mr Chen e7d458b2a9 Update control.js 2024-12-02 01:28:34 +08:00
Mr Chen 9cba031049 Update version.py 2024-12-02 01:26:45 +08:00
Mr Chen 73e5cc4fbd update 2024-12-02 01:25:06 +08:00
Mr Chen 3df5ae86d4 Update version.py 2024-12-02 01:21:06 +08:00
Mr Chen 542610f5a7 update 2024-12-02 01:20:37 +08:00
Mr Chen 1b1d3aec8c update 2024-12-02 01:16:05 +08:00
Mr Chen 829f4def27 update 2024-12-02 01:12:04 +08:00
Mr Chen cc9e628346 update 2024-12-02 01:04:40 +08:00
Mr Chen 921af80598 Update version.py 2024-12-02 01:00:42 +08:00
Mr Chen dae5d2d062 update 2024-12-02 01:00:28 +08:00
Mr Chen 6ee0496c4c Update requirements.txt 2024-12-02 00:36:48 +08:00
Mr Chen bbcac5f899 Update requirements.txt 2024-12-02 00:35:36 +08:00
Mr Chen 7fb006b2ff Update index.py 2024-12-02 00:27:31 +08:00
Mr Chen 6bfa72feb6 update 2024-12-01 23:54:04 +08:00
Mr Chen 8867799825 Update mt.toml 2024-12-01 23:46:54 +08:00
Mr Chen 12c90f5e6e update 2024-12-01 23:42:01 +08:00
Mr Chen 8ed608e9cd update 2024-12-01 23:16:27 +08:00
Mr Chen 1c0dbe76f9 update 2024-12-01 22:30:36 +08:00
Mr Chen 14ad247168 Update index.py 2024-12-01 22:24:41 +08:00
Mr Chen b114c768dc Update index.py 2024-12-01 22:21:36 +08:00
Mr Chen 58129d5209 update 2024-12-01 22:19:49 +08:00
Mr Chen 54f5b44e04 Update index.py 2024-12-01 22:16:30 +08:00
Mr Chen 85f64b72cb Update install.sh 2024-12-01 22:11:25 +08:00
Mr Chen 626c64afb2 Update index.py 2024-12-01 22:01:56 +08:00
Mr Chen e639fc5746 Update index.py 2024-12-01 22:01:45 +08:00
Mr Chen d988dce5d8 Update install.sh 2024-12-01 22:00:04 +08:00
Mr Chen 34f03d2ccb update 2024-12-01 21:57:23 +08:00
Mr Chen 4e66ed3a32 mtproxy 2024-12-01 21:51:31 +08:00
Mr Chen fde9da1af5 Update dashboard.py 2024-12-01 21:45:16 +08:00
Mr Chen bad42e8e48 Update dashboard.py 2024-12-01 21:40:02 +08:00
Mr Chen c562f9481d Update dashboard.py 2024-12-01 21:39:49 +08:00
Mr Chen caa9b598d0 update 2024-12-01 21:26:58 +08:00
Mr Chen ffa16648ae Update mw.tpl 2024-12-01 20:59:59 +08:00
Mr Chen a7a06ea7bf Update mw.tpl 2024-12-01 20:59:45 +08:00
Mr Chen 99de06abc0 Update mw.tpl 2024-12-01 20:59:32 +08:00
Mr Chen b538e646bd Update mw.tpl 2024-12-01 20:48:37 +08:00
Mr Chen 6088386e51 update 2024-12-01 20:47:39 +08:00
Mr Chen 404a38d990 update 2024-12-01 20:42:21 +08:00
Mr Chen 91e3900d12 Update panel_tools.py 2024-12-01 20:38:13 +08:00
Mr Chen 2b0dfcd460 Update panel_tools.py 2024-12-01 20:33:49 +08:00
Mr Chen f561a1da4f Update mw.tpl 2024-12-01 20:29:41 +08:00
Mr Chen 34b435ffca update 2024-12-01 20:24:57 +08:00
Mr Chen 5b92f109b9 Update version.py 2024-12-01 20:22:46 +08:00
Mr Chen fe68bf7226 update 2024-12-01 20:22:19 +08:00
Mr Chen 1e4989857e Update version.py 2024-12-01 17:42:52 +08:00
Mr Chen 56055000d9 Update public.js 2024-12-01 17:22:31 +08:00
Mr Chen 9365139430 Update public.js 2024-12-01 17:12:39 +08:00
Mr Chen b22f240719 Update public.js 2024-12-01 16:57:29 +08:00
Mr Chen 5b0e8ad2da update 2024-12-01 16:32:05 +08:00
Mr Chen cb794a946a Update sg11.sh 2024-12-01 15:48:17 +08:00
Mr Chen 446e39fb68 Update sg11.sh 2024-12-01 15:42:57 +08:00
Mr Chen 9276dd1bb8 Update sg11.sh 2024-12-01 15:23:03 +08:00
Mr Chen 1972df1f2d update 2024-12-01 15:20:29 +08:00
Mr Chen afb9f430b3 update 2024-12-01 15:04:12 +08:00
Mr Chen 52e9ff38fa Update phplib.conf 2024-12-01 14:54:25 +08:00
Mr Chen 37f4244484 update 2024-12-01 13:53:32 +08:00
Mr Chen 485b0605b4 Update python-app-op.yml 2024-12-01 13:52:36 +08:00
Mr Chen 30e2ea56c8 Update init_cmd.py 2024-12-01 13:34:58 +08:00
Mr Chen 371b6651f0 Update init_cmd.py 2024-12-01 04:21:09 +08:00
Mr Chen 37448dc827 update 2024-12-01 04:19:00 +08:00
Mr Chen 6e197f81ef Update app.js 2024-12-01 04:18:14 +08:00
Mr Chen bdd0634f61 update 2024-12-01 04:17:28 +08:00
Mr Chen a8019d1ec4 Update sql_mysql.py 2024-12-01 03:38:09 +08:00
Mr Chen d33ce43ad3 Update sql_mysql.py 2024-12-01 03:26:57 +08:00
Mr Chen cc165c4cde update 2024-12-01 03:23:13 +08:00
Mr Chen 1f6e6957ea Update init_cmd.py 2024-12-01 02:15:32 +08:00
Mr Chen 7b8bb6380d Update mw.py 2024-12-01 01:49:02 +08:00
Mr Chen b432b1c165 update 2024-12-01 01:40:56 +08:00
Mr Chen ce6f7153b3 Update firewall.py 2024-12-01 01:31:08 +08:00
Mr Chen 1cc4aee6f7 Update index.py 2024-12-01 01:23:14 +08:00
Mr Chen eafaf13a3d Update init_cmd.py 2024-12-01 01:14:12 +08:00
Mr Chen 7352f30d91 Update ubuntu.sh 2024-12-01 00:38:35 +08:00
Mr Chen 31db220719 Update python-app-op.yml 2024-11-30 23:35:48 +08:00
Mr Chen 000a4cccf1 Update python-app-op.yml 2024-11-30 23:35:34 +08:00
Mr Chen 1cc6953415 Update install.sh 2024-11-30 23:10:58 +08:00
Mr Chen 519951ad69 Update setting.py 2024-11-30 23:02:08 +08:00
Mr Chen b97b8c2c9b Update setting.py 2024-11-30 23:01:21 +08:00
Mr Chen 27b3bc1150 Update firewall.py 2024-11-30 23:00:46 +08:00
Mr Chen c66ad2b7fb Update firewall.py 2024-11-30 22:58:24 +08:00
Mr Chen f040b590d5 Update firewall.py 2024-11-30 22:53:40 +08:00
Mr Chen a36d2f2665 Update firewall.py 2024-11-30 22:43:17 +08:00
Mr Chen b0c3e5b7e5 update 2024-11-30 22:41:39 +08:00
Mr Chen 3d3cde4353 Update update_new.sh 2024-11-30 21:58:06 +08:00
Mr Chen da9c57cf84 update 2024-11-30 21:57:46 +08:00
Mr Chen 9915ed35d0 update 2024-11-30 21:44:09 +08:00
Mr Chen 97829cd944 Update install.sh 2024-11-30 21:16:59 +08:00
Mr Chen c355a120b4 Update install.sh 2024-11-30 21:16:21 +08:00
Mr Chen 1d9bc68e28 update 2024-11-30 18:07:22 +08:00
Mr Chen 778e1860df Update python-app-op.yml 2024-11-30 18:01:09 +08:00
Mr Chen 76b9298efd update 2024-11-30 17:11:00 +08:00
Mr Chen 371cc9c4c8 Update debian.sh 2024-11-30 16:57:58 +08:00
Mr Chen ab7c4792e2 Update sql_mysql.py 2024-11-30 16:51:26 +08:00
Mr Chen 7e2c192d40 update 2024-11-30 16:42:42 +08:00
Mr Chen 6874de5cda Update app.js 2024-11-30 04:26:28 +08:00
Mr Chen bd2ab7d529 update 2024-11-30 04:21:43 +08:00
Mr Chen 152fadfc87 Update app.js 2024-11-30 04:07:29 +08:00
Mr Chen d3b3b526db update 2024-11-30 03:52:58 +08:00
Mr Chen 00002a8540 update 2024-11-30 03:32:33 +08:00
Mr Chen a5bc06acf6 Update app.js 2024-11-29 22:08:54 +08:00
Mr Chen 2dcb8b257e 添加插件 2024-11-29 21:14:18 +08:00
Mr Chen fd1f64a6e2 Update .gitignore 2024-11-29 21:14:08 +08:00
Mr Chen fbf1a36e00 Update brotli.sh 2024-11-29 19:49:55 +08:00
Mr Chen 52d66b33cb update 2024-11-29 19:43:36 +08:00
Mr Chen eb0fe483b1 Update index.py 2024-11-29 19:24:31 +08:00
Mr Chen acc57ee993 Update mw.py 2024-11-29 19:19:21 +08:00
Mr Chen 0397090458 Update macos.sh 2024-11-29 19:08:11 +08:00
Mr Chen 5f6df46c90 Update mw.py 2024-11-29 18:52:38 +08:00
Mr Chen 3030849bd2 Update ftp_client.py 2024-11-29 18:46:15 +08:00
Mr Chen 7a1bc2ee39 Update ftp_client.py 2024-11-29 18:45:45 +08:00
Mr Chen efc715678b Update install.sh 2024-11-29 18:43:25 +08:00
Mr Chen 65ec08d40f Update install.sh 2024-11-29 18:42:55 +08:00
Mr Chen 7855df5aa2 up 2024-11-29 18:41:43 +08:00
Mr Chen abbe16eb87 up 2024-11-29 18:41:02 +08:00
Mr Chen 45645a52b5 up 2024-11-29 18:40:11 +08:00
Mr Chen 48d193141e Update install.sh 2024-11-29 18:31:04 +08:00
Mr Chen 264dd392f6 Update install.sh 2024-11-29 18:28:18 +08:00
Mr Chen 3e9b47cbf3 Update index.py 2024-11-29 18:23:25 +08:00
Mr Chen b350747eab update 2024-11-29 18:21:12 +08:00
Mr Chen d078b285a2 Update index.py 2024-11-29 18:14:02 +08:00
Mr Chen 7b5d9bb3c1 Update index.py 2024-11-29 18:09:33 +08:00
Mr Chen 346f07657d Update index.py 2024-11-29 17:55:37 +08:00
Mr Chen f4859ef7f6 Update index.py 2024-11-29 17:53:25 +08:00
Mr Chen 40bc9798a9 Update index.py 2024-11-29 17:44:05 +08:00
Mr Chen 98899cd76e Update index.py 2024-11-29 17:41:31 +08:00
Mr Chen 6da57d6ccc Update index.py 2024-11-29 17:38:03 +08:00
Mr Chen 0cef478d71 Update index.py 2024-11-29 17:36:34 +08:00
Mr Chen 30e0db5adb Update debian.sh 2024-11-29 17:25:08 +08:00
Mr Chen bb6a64c0dc Update ubuntu.sh 2024-11-29 17:23:02 +08:00
Mr Chen d940a12ed5 Update ubuntu.sh 2024-11-29 17:22:28 +08:00
Mr Chen fe9cd42210 Update debian.sh 2024-11-29 17:21:15 +08:00
Mr Chen ad503863ad update 2024-11-29 17:16:23 +08:00
Mr Chen a660014740 update 2024-11-29 17:15:07 +08:00
Mr Chen 637a4dacb9 update 2024-11-29 17:11:28 +08:00
Mr Chen 79c8081c30 Update index.py 2024-11-29 17:04:15 +08:00
Mr Chen 0903589e5b Update info.json 2024-11-29 17:04:09 +08:00
Mr Chen 777bfa1145 Update index.py 2024-11-29 16:06:02 +08:00
Mr Chen 4826dbd8a9 Update index.py 2024-11-29 16:05:27 +08:00
Mr Chen 70507e9f65 Update index.py 2024-11-29 16:05:06 +08:00
Mr Chen b8d6d9ed60 update 2024-11-29 15:54:29 +08:00
Mr Chen d62531c700 Update info.json 2024-11-29 15:31:37 +08:00
Mr Chen 96d5a817d5 Update install.sh 2024-11-29 15:31:26 +08:00
Mr Chen 6436a933c9 Update panel_task.py 2024-11-29 05:19:53 +08:00
Mr Chen db79be96ed Update mcrypt.sh 2024-11-29 05:16:39 +08:00
Mr Chen d2d79092ca up 2024-11-29 05:12:09 +08:00
Mr Chen 8f4fca5a6c update 2024-11-29 05:10:44 +08:00
Mr Chen dbe9fd4222 update 2024-11-29 04:49:47 +08:00
Mr Chen d0bc04e53b Update index.py 2024-11-29 04:05:33 +08:00
Mr Chen 49858199a5 Update install.sh 2024-11-29 03:55:03 +08:00
Mr Chen 7750fb7b38 Update readline.sh 2024-11-29 03:54:18 +08:00
Mr Chen d1d276d026 Update .gitignore 2024-11-29 03:35:01 +08:00
Mr Chen 70aca29ce1 Update .gitignore 2024-11-29 03:34:38 +08:00
Mr Chen dc17d67dc9 Update plugin.py 2024-11-29 03:32:10 +08:00
Mr Chen 407dc56f40 Update install.sh 2024-11-29 03:13:41 +08:00
Mr Chen bdfc044783 Update tasks.py 2024-11-29 03:13:34 +08:00
Mr Chen 325a113ac6 Update mw.py 2024-11-29 03:13:30 +08:00
Mr Chen 7e55e1e29a Update plugin.py 2024-11-29 03:13:04 +08:00
Mr Chen d604c966b2 update 2024-11-29 02:47:43 +08:00
Mr Chen 573e3192fc Update swoole.sh 2024-11-29 02:36:40 +08:00
Mr Chen 8ec3b66f20 Update install.sh 2024-11-29 02:24:37 +08:00
Mr Chen 5b9a414688 Update openssl.sh 2024-11-29 02:24:29 +08:00
Mr Chen 9553add27a Update readline.sh 2024-11-29 02:07:07 +08:00
Mr Chen fb3cd54ce0 Update install.sh 2024-11-29 01:54:48 +08:00
Mr Chen 1ce5cac3ba Update openssl.sh 2024-11-29 01:23:55 +08:00
Mr Chen fa1819feb8 Update readline.sh 2024-11-29 01:21:32 +08:00
Mr Chen bd873b48d0 Update readline.sh 2024-11-29 01:16:13 +08:00
Mr Chen 37e3850b43 update 2024-11-29 01:13:22 +08:00
Mr Chen 3182bac95e Update install.sh 2024-11-29 01:08:08 +08:00
Mr Chen 71dc92f59d Update phplib.conf 2024-11-29 01:08:01 +08:00
Mr Chen dc5a81ea89 Create curl.sh 2024-11-29 01:07:57 +08:00
Mr Chen e04214c14d Update install.sh 2024-11-29 00:23:17 +08:00
Mr Chen 1846af7271 update 2024-11-29 00:23:07 +08:00
Mr Chen 58cb061ef2 Update index.py 2024-11-28 23:28:58 +08:00
Mr Chen c71a59cce1 Update init.py 2024-11-28 20:48:57 +08:00
Mr Chen c3d6ec90e8 Update panel_tools.py 2024-11-28 20:43:33 +08:00
Mr Chen 9569b64d26 Update __init__.py 2024-11-28 20:43:17 +08:00
Mr Chen 6f7c26adc4 Update init.py 2024-11-28 20:42:53 +08:00
Mr Chen 82e4e5c1d3 Update mw.tpl 2024-11-28 20:39:52 +08:00
Mr Chen d6972bae75 Update init.py 2024-11-28 20:29:48 +08:00
Mr Chen 2beae29d25 Update init.py 2024-11-28 20:29:30 +08:00
Mr Chen e2d800a167 Update init.py 2024-11-28 20:29:11 +08:00
Mr Chen 630e518ae3 Update mw.tpl 2024-11-28 20:22:01 +08:00
Mr Chen 2c8108a0be Update mw.tpl 2024-11-28 20:21:40 +08:00
Mr Chen 11ba771db3 Update __init__.py 2024-11-28 20:17:23 +08:00
Mr Chen e20341d3da Update setting.py 2024-11-28 20:16:58 +08:00
Mr Chen 179b00e8a1 Update __init__.py 2024-11-28 20:16:02 +08:00
Mr Chen ab287d42ef Update __init__.py 2024-11-28 20:12:41 +08:00
Mr Chen 8b439801ab Update .gitignore 2024-11-28 20:05:09 +08:00
Mr Chen 8e39af00a3 update 2024-11-28 20:04:35 +08:00
Mr Chen 493553ec4b update 2024-11-28 19:48:36 +08:00
Mr Chen 0d1d4b66d6 Update panel_task.py 2024-11-28 19:47:24 +08:00
Mr Chen 7ba7272a7c Update panel_tools.py 2024-11-28 19:43:44 +08:00
Mr Chen 12d5ce5eea update 2024-11-28 19:31:45 +08:00
Mr Chen a059e09244 Update setting.py 2024-11-28 19:28:17 +08:00
Mr Chen 2ac28e9d80 Update plugin.py 2024-11-28 19:12:10 +08:00
Mr Chen de3f2ab4d2 Update mw.py 2024-11-28 19:08:22 +08:00
Mr Chen ee206f014d Update mw.py 2024-11-28 19:07:59 +08:00
Mr Chen 852fc6e5a7 Update mw.py 2024-11-28 19:04:25 +08:00
Mr Chen 17b40e5d1d Update setting.py 2024-11-28 18:58:55 +08:00
Mr Chen 769f36c560 Update app.py 2024-11-28 18:47:24 +08:00
Mr Chen 7d1c2bac14 Update setting.py 2024-11-28 18:44:17 +08:00
Mr Chen 58101f889d Update app.py 2024-11-28 18:43:49 +08:00
Mr Chen 009be7e920 Update config.py 2024-11-28 18:20:11 +08:00
Mr Chen 74817313f6 Update setting.py 2024-11-28 18:13:31 +08:00
Mr Chen 1dc55d5e1a Update setting.py 2024-11-28 18:05:23 +08:00
Mr Chen 2a943efcd7 Update setting.py 2024-11-28 18:03:31 +08:00
Mr Chen dfef78fc84 Update mw.py 2024-11-28 18:00:26 +08:00
Mr Chen 51d092ca19 Update setting.py 2024-11-28 18:00:04 +08:00
Mr Chen c210429086 update 2024-11-28 16:26:14 +08:00
Mr Chen 9cbec5a68f Update setting.py 2024-11-28 01:52:10 +08:00
Mr Chen b02a6a2d19 update 2024-11-28 01:49:17 +08:00
Mr Chen e5ef7d3e4d Update app.py 2024-11-28 01:40:52 +08:00
Mr Chen 1d1dbfc54c Update mw.tpl 2024-11-28 01:36:00 +08:00
Mr Chen 49867fadf0 Update setting.py 2024-11-28 01:31:27 +08:00
Mr Chen 0df069b9a4 update 2024-11-28 01:28:45 +08:00
Mr Chen ef59c3a654 Update app.py 2024-11-28 01:24:24 +08:00
Mr Chen af3ceeefe7 Update version.py 2024-11-28 01:21:14 +08:00
Mr Chen 655c2c2268 Update app.py 2024-11-28 01:19:44 +08:00
Mr Chen 83f48cb05e update 2024-11-28 01:18:57 +08:00
Mr Chen 25527d09f5 Update firewall.py 2024-11-28 01:07:00 +08:00
Mr Chen 32718d5450 Update mw.tpl 2024-11-28 00:55:49 +08:00
Mr Chen 7ce3160ade Update __init__.py 2024-11-28 00:52:16 +08:00
Mr Chen f4f4e32612 update 2024-11-28 00:45:50 +08:00
Mr Chen 1bb99bb90e Update app.py 2024-11-28 00:33:31 +08:00
Mr Chen 0ccf70be56 update 2024-11-28 00:33:08 +08:00
Mr Chen d6b68f45e5 Update __init__.py 2024-11-28 00:24:35 +08:00
Mr Chen 41978d33bd Update app.py 2024-11-28 00:20:33 +08:00
Mr Chen 85c62dd51a update 2024-11-27 23:59:56 +08:00
Mr Chen ccb9d678f6 Update __init__.py 2024-11-27 20:28:23 +08:00
Mr Chen d950501ec6 Create backup.py 2024-11-27 20:28:19 +08:00
Mr Chen 4edae5114e Update site.py 2024-11-27 20:28:15 +08:00
Mr Chen eb925d004e Create backup.py 2024-11-27 20:28:10 +08:00
Mr Chen 58fafd6233 Update all_test.sh 2024-11-27 18:09:17 +08:00
Mr Chen c4c3c1659c update 2024-11-27 15:59:25 +08:00
Mr Chen 5a800ac1b2 Update gd_old.sh 2024-11-27 15:52:17 +08:00
Mr Chen 0e6ea7cb7e Update setting.py 2024-11-27 06:05:54 +08:00
Mr Chen 4078f4c67b Update setting.py 2024-11-27 05:50:15 +08:00
Mr Chen a44873b142 update 2024-11-27 05:48:44 +08:00
Mr Chen 293c902a80 Update init.py 2024-11-27 05:23:05 +08:00
Mr Chen d25993e78b update 2024-11-27 04:48:39 +08:00
Mr Chen c3ef396728 Update panel_tools.py 2024-11-27 04:40:29 +08:00
Mr Chen 17d46958f8 Update panel_tools.py 2024-11-27 04:35:55 +08:00
Mr Chen aef3c5d694 Update init.py 2024-11-27 04:15:28 +08:00
Mr Chen 50eb0137a4 Update __init__.py 2024-11-27 04:13:19 +08:00
Mr Chen e8d1e6e1eb Update system.sql 2024-11-27 03:45:31 +08:00
Mr Chen e4c7a04701 Update init.py 2024-11-27 03:31:14 +08:00
Mr Chen e145e2c57f Update default.sql 2024-11-27 03:27:04 +08:00
Mr Chen 2d892575f3 Update default.sql 2024-11-27 03:17:24 +08:00
Mr Chen 0c4460282a Update default.sql 2024-11-27 03:01:15 +08:00
Mr Chen da0e599bad Update mw.py 2024-11-27 02:56:43 +08:00
Mr Chen 7d2ca4ea74 Update user.py 2024-11-27 02:53:02 +08:00
Mr Chen 7a1b30994b update 2024-11-27 02:47:23 +08:00
Mr Chen 3994d8f0ce update 2024-11-27 02:21:45 +08:00
Mr Chen aa5ffdc3c0 Update mw.tpl 2024-11-27 02:17:01 +08:00
Mr Chen db1dfb9aed Update crontab.py 2024-11-27 02:15:08 +08:00
Mr Chen 06db6b02d8 Update plugin.py 2024-11-27 02:13:28 +08:00
Mr Chen bf0269a7da Update plugin.py 2024-11-27 02:11:58 +08:00
Mr Chen 486361f3b7 Update config.py 2024-11-27 02:08:55 +08:00
Mr Chen ab088d9355 Update config.py 2024-11-27 02:07:30 +08:00
Mr Chen c9c52cf7f5 update 2024-11-27 02:07:08 +08:00
Mr Chen e4ad01dd42 update 2024-11-27 01:55:03 +08:00
Mr Chen 86ac000117 Update firewall.py 2024-11-27 01:51:15 +08:00
Mr Chen ae016172ea Update firewall.py 2024-11-27 01:50:47 +08:00
Mr Chen 2c5ab01237 Update firewall.py 2024-11-27 01:50:32 +08:00
Mr Chen 9b0a41c3d5 update 2024-11-27 01:49:20 +08:00
Mr Chen be55e79dcf Update sites.py 2024-11-27 01:47:53 +08:00
Mr Chen 9265bd57e4 update 2024-11-27 01:46:54 +08:00
Mr Chen 26bc566aed update 2024-11-27 01:41:17 +08:00
Mr Chen 1b007460de update 2024-11-27 01:35:37 +08:00
Mr Chen b007010912 Update mw.py 2024-11-27 01:34:38 +08:00
Mr Chen 053cd9bc01 Update mw.py 2024-11-27 01:33:15 +08:00
Mr Chen 37c8da89ae Update mw.py 2024-11-27 01:32:57 +08:00
Mr Chen 4f1001e487 Update file.py 2024-11-27 01:30:38 +08:00
Mr Chen f9f074ef01 update 2024-11-27 01:27:32 +08:00
Mr Chen 8df9799564 Update mw.py 2024-11-27 01:23:59 +08:00
Mr Chen 80e49a6ff8 Update setting.py 2024-11-27 01:19:40 +08:00
Mr Chen 2a3bad681b Update install_new.sh 2024-11-27 00:56:23 +08:00
Mr Chen f7c9d61e8d Update plugin.py 2024-11-27 00:22:33 +08:00
Mr Chen 296f54127d Update panel_task.py 2024-11-27 00:22:01 +08:00
Mr Chen b8161b86d2 update 2024-11-27 00:17:57 +08:00
Mr Chen 3305e51fda Update install.sh 2024-11-27 00:13:34 +08:00
Mr Chen 4adaa8565c Update setting.py 2024-11-27 00:01:00 +08:00
Mr Chen 5564b27ff2 Update mw.py 2024-11-26 23:50:47 +08:00
Mr Chen 0f1b98721b up 2024-11-26 23:50:17 +08:00
Mr Chen 3894eebfb5 update 2024-11-26 15:47:22 +08:00
Mr Chen e3070b618f Update plugin.py 2024-11-26 05:14:26 +08:00
Mr Chen 5f144924e4 update 2024-11-26 05:02:47 +08:00
Mr Chen 570f775c66 Update site.py 2024-11-26 04:58:11 +08:00
Mr Chen cbdf826951 Update site.py 2024-11-26 04:56:25 +08:00
Mr Chen 9933035cae update 2024-11-26 04:53:43 +08:00
Mr Chen 4e3e7b7301 update 2024-11-26 04:53:03 +08:00
Mr Chen 4ed5c48650 update 2024-11-26 04:45:38 +08:00
Mr Chen f46c28b39d update 2024-11-26 04:43:57 +08:00
Mr Chen b124aabb7b update 2024-11-26 04:38:55 +08:00
Mr Chen 6e48e0c339 Update mongodb.sh 2024-11-26 03:55:43 +08:00
Mr Chen 79160854b9 Update index.py 2024-11-26 03:53:33 +08:00
Mr Chen f5089eeb16 update 2024-11-26 03:53:21 +08:00
Mr Chen 453639bf92 Update index.py 2024-11-26 03:50:08 +08:00
Mr Chen 5ca5265b92 Update index.py 2024-11-26 03:49:36 +08:00
Mr Chen 88b86b2b2b Update install.sh 2024-11-26 03:46:00 +08:00
Mr Chen 7da0fa4379 Update index.py 2024-11-26 03:41:53 +08:00
Mr Chen add4d4bb5e Update panel_task.py 2024-11-26 02:01:07 +08:00
Mr Chen 39a1c1e6e0 update 2024-11-26 01:56:33 +08:00
Mr Chen 0b37a34528 up 2024-11-26 00:37:55 +08:00
Mr Chen ffcceb16cf update 2024-11-25 22:38:16 +08:00
Mr Chen 4b7296f99e Update panel_task.py 2024-11-25 22:16:19 +08:00
Mr Chen 5796e311a9 update 2024-11-25 22:13:45 +08:00
Mr Chen 8af22d14c8 update 2024-11-25 16:52:18 +08:00
Mr Chen bd5753eb27 Update panel_task.py 2024-11-25 16:26:18 +08:00
Mr Chen 6a6166c8ac update 2024-11-25 03:20:54 +08:00
Mr Chen 82a5af071a update 2024-11-25 03:17:52 +08:00
Mr Chen 4e6f867ba4 update 2024-11-25 03:16:46 +08:00
Mr Chen 8e0a4ec34b Update install.sh 2024-11-25 03:15:08 +08:00
Mr Chen d5678d3f34 Update firewall.py 2024-11-25 03:08:33 +08:00
Mr Chen cfd7030d00 Update firewall.py 2024-11-25 03:08:18 +08:00
Mr Chen 360d94d573 Update firewall.py 2024-11-25 03:07:09 +08:00
Mr Chen b3370f2937 Update firewall.py 2024-11-25 03:04:04 +08:00
Mr Chen ce3e37b6f8 Update site.py 2024-11-25 02:54:41 +08:00
Mr Chen 43384f8ca4 Update site.py 2024-11-25 02:53:55 +08:00
Mr Chen 9ab361604f Update site.py 2024-11-25 02:53:00 +08:00
Mr Chen 000b825ef0 Delete app.py 2024-11-25 02:40:26 +08:00
Mr Chen d00101f6eb update 2024-11-25 02:40:09 +08:00
Mr Chen 2d8528ca8d Update index.py 2024-11-25 02:32:11 +08:00
Mr Chen c6d900c4e0 Update index.py 2024-11-25 02:31:12 +08:00
Mr Chen 15314974f6 Update index.py 2024-11-25 02:27:21 +08:00
Mr Chen 60a1bfe679 Update index.py 2024-11-25 02:22:13 +08:00
Mr Chen a3af4ac405 Update index.py 2024-11-25 02:22:03 +08:00
Mr Chen df7a43919f Update index.py 2024-11-25 02:21:07 +08:00
Mr Chen ae4f3851e5 Update index.py 2024-11-25 02:20:47 +08:00
Mr Chen e0384dd6cb Update msodclient.py 2024-11-25 02:10:44 +08:00
Mr Chen d8a34e7a0b Update site.js 2024-11-25 02:04:47 +08:00
Mr Chen e013eb8137 update 2024-11-25 01:59:22 +08:00
Mr Chen 72917bdc5b Update site.py 2024-11-25 01:39:17 +08:00
Mr Chen cf74b0a941 Update mw.py 2024-11-25 01:37:38 +08:00
Mr Chen e027700d50 update 2024-11-25 01:33:59 +08:00
Mr Chen d7fe140ff2 update 2024-11-25 01:13:47 +08:00
Mr Chen 00c0c592fc Update index.py 2024-11-25 01:04:38 +08:00
Mr Chen 6603a49d7b Update index.py 2024-11-25 01:01:55 +08:00
Mr Chen 3340112c11 update 2024-11-25 01:01:20 +08:00
Mr Chen 741e1aedf6 Update mw.py 2024-11-25 00:56:59 +08:00
Mr Chen a156c14248 Update index.py 2024-11-25 00:52:48 +08:00
Mr Chen d56de6d827 Update site.py 2024-11-25 00:41:58 +08:00
Mr Chen 6433d6fc50 Update site.py 2024-11-25 00:40:41 +08:00
Mr Chen 58950d581c Update site.py 2024-11-25 00:40:18 +08:00
Mr Chen 6cd613a172 Update site.py 2024-11-25 00:38:50 +08:00
Mr Chen 1fa57de2c0 Update site.py 2024-11-25 00:35:54 +08:00
Mr Chen 5ebdbc74ad Update version.py 2024-11-25 00:30:10 +08:00
Mr Chen 9c130746fb update 2024-11-25 00:29:25 +08:00
Mr Chen 7d83f29db7 Update mw.tpl 2024-11-24 22:07:47 +08:00
Mr Chen 729ea2df8f Update cli.sh 2024-11-24 22:04:31 +08:00
Mr Chen c560d3fced Update mw.tpl 2024-11-24 22:04:07 +08:00
Mr Chen 590a246fc0 Update mw.tpl 2024-11-24 22:03:51 +08:00
Mr Chen 5ea712b943 Update cli.sh 2024-11-24 21:56:23 +08:00
Mr Chen 6329ce3fd6 Update cli.sh 2024-11-24 21:54:28 +08:00
Mr Chen cd069b24c6 Update cli.sh 2024-11-24 21:54:00 +08:00
Mr Chen 3da3453503 Update cli.sh 2024-11-24 21:53:38 +08:00
Mr Chen 1ab7c21910 update 2024-11-24 21:50:08 +08:00
Mr Chen d074224447 Update site.py 2024-11-24 21:43:03 +08:00
Mr Chen 3f0f219896 Update site.py 2024-11-24 21:31:44 +08:00
Mr Chen 06bdad4ab0 Update site.py 2024-11-24 21:31:04 +08:00
Mr Chen f2dac6e1e6 Update site.py 2024-11-24 21:28:30 +08:00
Mr Chen 116140f5df Update site.py 2024-11-24 21:20:57 +08:00
Mr Chen df46b40c0f Update site.py 2024-11-24 17:53:34 +08:00
Mr Chen 196ab188bb Update site.py 2024-11-24 17:53:07 +08:00
Mr Chen dc9d114ca4 Update site.py 2024-11-24 17:46:23 +08:00
Mr Chen d1f8cf9a8e update 2024-11-24 17:42:40 +08:00
Mr Chen 7836622cd6 Update site.py 2024-11-24 17:32:09 +08:00
Mr Chen c5500c57f1 Update site.py 2024-11-24 17:30:45 +08:00
Mr Chen 7956b6c8f4 update 2024-11-24 17:18:57 +08:00
Mr Chen 80dd014be5 update 2024-11-24 16:48:42 +08:00
Mr Chen 06f8a3c01a Update site.py 2024-11-24 16:38:08 +08:00
Mr Chen e76a0b1288 Update index.py 2024-11-24 06:25:28 +08:00
Mr Chen e9efc4cc35 Update index.py 2024-11-24 06:18:15 +08:00
Mr Chen 8d6e0f049c Update install.sh 2024-11-24 06:16:14 +08:00
Mr Chen b83e632328 Update tool_task.py 2024-11-24 06:12:24 +08:00
Mr Chen 315a3759c3 Update tool_cron.py 2024-11-24 06:10:07 +08:00
Mr Chen df0efaa7b1 update 2024-11-24 06:05:18 +08:00
Mr Chen c731077fba Update tool_task.py 2024-11-24 06:04:37 +08:00
Mr Chen c9f03c0f69 修改引入公共方法方式 2024-11-24 06:02:41 +08:00
Mr Chen 941285d168 update 2024-11-24 05:48:35 +08:00
Mr Chen 141c56fbc2 update 2024-11-24 05:46:05 +08:00
Mr Chen beb6dd874a update 2024-11-24 05:41:55 +08:00
Mr Chen b0392b7cf1 update 2024-11-24 05:40:30 +08:00
Mr Chen d57b0d0922 Update mw.py 2024-11-24 05:36:53 +08:00
Mr Chen add966bc62 Update crontab.py 2024-11-24 05:32:51 +08:00
Mr Chen 62a94c5c15 Update tool_task.py 2024-11-24 05:26:35 +08:00
Mr Chen 3b857833a7 update 2024-11-24 05:18:34 +08:00
Mr Chen 27e1e0c73c Update mw.py 2024-11-24 05:11:35 +08:00
Mr Chen 41000f0c5d update 2024-11-24 05:10:19 +08:00
Mr Chen c249da061d Update mw.py 2024-11-24 05:01:42 +08:00
Mr Chen aa2126e7e6 Update crontab.py 2024-11-24 04:57:24 +08:00
Mr Chen 2893f02735 update 2024-11-24 04:51:29 +08:00
Mr Chen 5a072d7cda Update crontab.py 2024-11-24 04:46:40 +08:00
Mr Chen 5218468b96 Update tool_task.py 2024-11-24 04:44:31 +08:00
Mr Chen e4d7ebbe25 Update tool_task.py 2024-11-24 04:44:24 +08:00
Mr Chen d32523c451 up 2024-11-24 04:43:22 +08:00
Mr Chen 7eb88d6a92 Update tool_task.py 2024-11-24 04:43:00 +08:00
Mr Chen 2d14184c82 Update index.py 2024-11-24 04:40:21 +08:00
Mr Chen 080e4ad696 Update tool_task.py 2024-11-24 04:38:28 +08:00
Mr Chen c639d2736e update 2024-11-24 04:24:46 +08:00
Mr Chen 339d9e829e Update cli.sh 2024-11-24 04:24:12 +08:00
Mr Chen 21af7b2c1c Update setting.py 2024-11-24 04:21:44 +08:00
Mr Chen 7ef0b5a9ae Update version.py 2024-11-24 04:19:22 +08:00
Mr Chen ba96b38a82 Update firewall.js 2024-11-24 04:18:02 +08:00
Mr Chen 92f9a2b9a2 update 2024-11-24 04:17:05 +08:00
Mr Chen 9f6cd75893 update 2024-11-24 04:13:22 +08:00
Mr Chen d8bf989f83 update 2024-11-24 04:06:53 +08:00
Mr Chen 2cf2a893e6 Update mw.tpl 2024-11-24 03:53:23 +08:00
Mr Chen 08ac6ea08c update 2024-11-24 03:49:53 +08:00
Mr Chen 6246cc84d5 Update notify_email.py 2024-11-24 03:20:34 +08:00
Mr Chen b056892676 update 2024-11-24 02:57:18 +08:00
Mr Chen c1607752b2 update 2024-11-24 00:44:39 +08:00
Mr Chen cf7323cf12 Update site.js 2024-11-24 00:19:45 +08:00
Mr Chen 9765cb99ea Update site.js 2024-11-24 00:19:18 +08:00
Mr Chen 33c67f90db Create cert.py 2024-11-23 23:48:13 +08:00
Mr Chen f510d23c92 Update site.py 2024-11-23 23:18:03 +08:00
Mr Chen 5b2e40404d update 2024-11-23 23:15:25 +08:00
Mr Chen ed375271d2 Update site.py 2024-11-23 17:42:03 +08:00
Mr Chen 4a16502269 up 2024-11-22 21:47:33 +08:00
Mr Chen 0862df3182 Update site.py 2024-11-22 01:39:37 +08:00
Mr Chen 4c1e2a206d up 2024-11-22 01:09:42 +08:00
Mr Chen 98fbaa099f update 2024-11-21 02:54:46 +08:00
Mr Chen 8ae54e30d0 update 2024-11-20 16:40:06 +08:00
Mr Chen 0eed51452a Update setting.py 2024-11-14 16:51:43 +08:00
Mr Chen f6ff18dd8d Update crontab.js 2024-11-14 15:14:53 +08:00
Mr Chen 4602b9fc07 Update crontab.js 2024-11-14 15:14:10 +08:00
Mr Chen bf6aa15505 Update crontab.js 2024-11-14 15:00:30 +08:00
Mr Chen ee64e55eca update 2024-11-13 19:28:56 +08:00
Mr Chen f685054a9a update 2024-11-13 14:45:53 +08:00
Mr Chen bfc1974043 Update setting.py 2024-11-13 14:27:27 +08:00
Mr Chen c8b9dd2ae9 Update setting.py 2024-11-13 14:25:29 +08:00
Mr Chen 289f736160 Update setting.py 2024-11-13 14:25:22 +08:00
Mr Chen 28def91c7d Update __init__.py 2024-11-12 22:56:40 +08:00
Mr Chen b9371e9b94 Update firewall.py 2024-11-12 22:40:15 +08:00
Mr Chen 29c65c0e7c update 2024-11-12 20:24:57 +08:00
Mr Chen b10e1ba8cc update 2024-11-12 20:24:48 +08:00
Mr Chen 31ac0c2542 Update firewall.py 2024-11-12 20:21:12 +08:00
Mr Chen 2d32d8dbb2 update 2024-11-12 20:05:34 +08:00
Mr Chen e6f1bbfabe Update __init__.py 2024-11-12 15:40:58 +08:00
Mr Chen 98f7c4810e Update __init__.py 2024-11-12 14:33:19 +08:00
Mr Chen c9288e8dbe Update __init__.py 2024-11-12 01:42:53 +08:00
Mr Chen 1cc8ac17f3 update 2024-11-12 01:42:02 +08:00
Mr Chen 687f16e1ef Update firewall.py 2024-11-12 01:37:59 +08:00
Mr Chen 1616d4d191 update 2024-11-12 01:36:30 +08:00
Mr Chen 0da42e9ec8 Update __init__.py 2024-11-12 01:21:14 +08:00
Mr Chen 49bfb5b3a8 update 2024-11-12 01:12:15 +08:00
Mr Chen 17a9f07f04 Update app.py 2024-11-12 01:06:31 +08:00
Mr Chen b03f7abcb8 Update requirements.txt 2024-11-12 01:03:49 +08:00
Mr Chen 990199ec89 update 2024-11-12 01:00:06 +08:00
Mr Chen 96fcdb8af3 Update README.md 2024-11-12 00:15:37 +08:00
Mr Chen 6e88b3b0c5 Create update.sh 2024-11-12 00:15:08 +08:00
Mr Chen c182635fd6 Update README.md 2024-11-12 00:10:16 +08:00
Mr Chen 7b37a86acb update 2024-11-12 00:09:20 +08:00
Mr Chen 0f5e196e3f update 2024-11-11 23:48:44 +08:00
Mr Chen 8f1396bb8b up 2024-11-11 22:18:32 +08:00
Mr Chen 89d6bbd317 Update default.sql 2024-11-11 00:56:03 +08:00
Mr Chen 111aaa768a update 2024-11-11 00:48:54 +08:00
Mr Chen f511b8e44f Update app.py 2024-11-10 22:48:41 +08:00
Mr Chen af29e865e8 update 2024-11-10 22:43:08 +08:00
Mr Chen 97b23b7148 Update files.js 2024-11-10 20:36:48 +08:00
Mr Chen a9f10842e7 Update files.js 2024-11-10 20:35:58 +08:00
Mr Chen 8520bfcd27 update 2024-11-10 20:05:21 +08:00
Mr Chen d8a2e91922 update 2024-11-10 19:33:56 +08:00
Mr Chen 08336eb2ee Update firewall.html 2024-11-10 19:13:53 +08:00
Mr Chen 9945425f99 update 2024-11-10 18:28:34 +08:00
Mr Chen 3a1a3f6579 update 2024-11-10 17:32:00 +08:00
Mr Chen 23b3f213b6 Update panel_tools.py 2024-11-10 14:15:53 +08:00
Mr Chen c2a8b95231 update 2024-11-10 13:19:03 +08:00
Mr Chen e6af36a34b Update panel_task.py 2024-11-10 02:26:15 +08:00
Mr Chen e5ed04ce31 update 2024-11-10 02:15:35 +08:00
Mr Chen 433ad507e7 update 2024-11-09 23:31:56 +08:00
Mr Chen d50d8abab8 update 2024-11-09 23:25:16 +08:00
Mr Chen 8233ba99df update 2024-11-09 19:02:08 +08:00
Mr Chen 020c8da426 update 2024-11-09 17:18:57 +08:00
Mr Chen f1a74e6275 update 2024-11-09 01:27:32 +08:00
Mr Chen 260c37f63b update 2024-11-08 21:29:01 +08:00
Mr Chen 03e37a2b88 Update __init__.py 2024-11-08 20:06:42 +08:00
Mr Chen e1e7fd51cd update 2024-11-08 19:56:37 +08:00
Mr Chen 5c24373a32 Update __init__.py 2024-11-08 19:35:48 +08:00
Mr Chen 8ed2f6848b update 2024-11-08 19:26:16 +08:00
Mr Chen 8f1ec01b58 update 2024-11-08 18:26:46 +08:00
Mr Chen d5a8efff0e update 2024-11-08 18:22:01 +08:00
Mr Chen 43420b7c38 update 2024-11-08 18:15:31 +08:00
Mr Chen fa614fcf88 Update site.py 2024-11-07 03:55:16 +08:00
Mr Chen 1b4785ec52 Update site.py 2024-11-07 03:54:48 +08:00
Mr Chen 35c42d94c6 Update site.py 2024-11-07 03:54:37 +08:00
Mr Chen 8609033d37 Update binding.py 2024-11-07 03:53:09 +08:00
Mr Chen 881facdfa8 update 2024-11-07 03:50:50 +08:00
Mr Chen e994cd80f1 Update panel_tools.py 2024-11-07 03:09:47 +08:00
Mr Chen accdb5834d up 2024-11-06 20:58:22 +08:00
Mr Chen bcfdd22161 update 2024-11-06 02:08:35 +08:00
Mr Chen 82ee20b1a9 update 2024-11-05 03:29:36 +08:00
Mr Chen d83e7b6905 Update firewall.py 2024-11-05 03:00:02 +08:00
Mr Chen f9b7526007 Update mw.py 2024-11-05 02:59:41 +08:00
Mr Chen 9ce92eb69e update 2024-11-05 02:56:12 +08:00
Mr Chen a4079c09ef Update tasks.py 2024-11-05 02:37:39 +08:00
Mr Chen a09a9d5889 Update tasks.py 2024-11-05 02:35:36 +08:00
Mr Chen 1a3972fa21 Update tasks.py 2024-11-05 02:35:16 +08:00
Mr Chen e477a69b98 Update tasks.py 2024-11-05 02:33:23 +08:00
Mr Chen 1ec2c33384 Update tasks.py 2024-11-05 02:30:46 +08:00
Mr Chen a0a4292cb8 Update panel_task.py 2024-11-05 02:28:22 +08:00
Mr Chen 2fe3ed5407 update 2024-11-05 02:28:06 +08:00
Mr Chen 0c9eae860f Update mw.py 2024-11-05 01:45:22 +08:00
Mr Chen f6c4f3b2ee Update mw.py 2024-11-05 01:44:04 +08:00
Mr Chen ec70d3e955 Update firewall.js 2024-11-05 01:42:09 +08:00
Mr Chen 534af4f017 Update index_php_yum.py 2024-11-05 01:39:21 +08:00
Mr Chen 804f7646d1 update 2024-11-05 01:39:07 +08:00
Mr Chen 4d44650609 Update install.sh 2024-11-05 01:35:39 +08:00
Mr Chen 91327c50f0 Update install.sh 2024-11-05 01:34:27 +08:00
Mr Chen 024dedabaf update 2024-11-05 01:26:45 +08:00
Mr Chen fed4a4ae48 Update tasks.py 2024-11-05 01:20:54 +08:00
Mr Chen f217c07d12 Update tasks.py 2024-11-05 01:19:09 +08:00
Mr Chen 8d2e70c31e Update panel_task.py 2024-11-05 01:16:17 +08:00
Mr Chen 36bd8d8a1f Update panel_task.py 2024-11-05 01:16:08 +08:00
Mr Chen 6bf4371a2b Update panel_task.py 2024-11-05 01:15:40 +08:00
Mr Chen 72c6dbabab update 2024-11-05 01:15:17 +08:00
Mr Chen ef7b680e37 update 2024-11-05 01:12:04 +08:00
Mr Chen 910defe18b update 2024-11-05 01:03:37 +08:00
Mr Chen 6f232aa46e Update panel_task.py 2024-11-05 00:59:38 +08:00
Mr Chen 8010ead35a update 2024-11-05 00:58:40 +08:00
Mr Chen 39c634ab14 Update panel_tools.py 2024-11-05 00:51:55 +08:00
Mr Chen 9cf9b53671 update 2024-11-05 00:46:25 +08:00
Mr Chen fbe2da1cd8 update 2024-11-05 00:38:22 +08:00
Mr Chen b1dd7ea609 update 2024-11-05 00:16:19 +08:00
Mr Chen d4cfd90ccd update 2024-11-04 19:08:39 +08:00
Mr Chen 1826adf50e Update install.sh 2024-11-04 01:21:17 +08:00
Mr Chen b58d457742 Update new_cli.sh 2024-11-04 00:33:15 +08:00
Mr Chen f37cd39a65 Update new_cli.sh 2024-11-04 00:32:57 +08:00
Mr Chen 98a53b8639 Update mw.py 2024-11-04 00:28:52 +08:00
Mr Chen 795bee7de3 update 2024-11-04 00:27:32 +08:00
Mr Chen 477b8b1f73 Update mw.py 2024-11-04 00:13:21 +08:00
Mr Chen d795dd7d47 Update logs.py 2024-11-04 00:02:30 +08:00
Mr Chen 4a7fea3b4c Update __init__.py 2024-11-03 23:59:22 +08:00
Mr Chen 83ae4562fa update 2024-11-03 23:56:25 +08:00
Mr Chen 06abfd92f2 update 2024-11-03 23:44:05 +08:00
Mr Chen 3ae8f0253e up 2024-11-03 22:21:41 +08:00
Mr Chen c77d409317 up 2024-11-03 21:16:13 +08:00
Mr Chen 39603f367f Update panel_tools.py 2024-11-03 20:24:45 +08:00
Mr Chen 044eb2b65f up 2024-11-03 20:21:35 +08:00
Mr Chen 0b6cdec4ce Update __init__.py 2024-11-03 19:50:58 +08:00
Mr Chen 8f0be8a475 Update init_cmd.py 2024-11-03 19:39:49 +08:00
Mr Chen 6114bcd9bc Update init_cmd.py 2024-11-03 19:36:17 +08:00
Mr Chen 0f89246b17 Update init_cmd.py 2024-11-03 19:36:09 +08:00
Mr Chen 63145c736f Update init_cmd.py 2024-11-03 19:33:16 +08:00
Mr Chen 52e98f6d41 update 2024-11-03 19:15:37 +08:00
Mr Chen 0c6fb48989 update 2024-11-03 18:57:50 +08:00
Mr Chen 7c696c24f3 Update panel_tools.py 2024-11-03 18:48:17 +08:00
Mr Chen 91612a8465 Update user.py 2024-11-03 18:46:41 +08:00
Mr Chen 063263d924 update 2024-11-03 18:45:36 +08:00
Mr Chen 514518e278 Update user.py 2024-11-03 18:36:16 +08:00
Mr Chen 3ce1289c44 update 2024-11-03 18:14:25 +08:00
Mr Chen ed90f9a087 Update system.sql 2024-11-03 14:57:20 +08:00
Mr Chen 9a9faa6a33 Update monitor.py 2024-11-03 03:38:07 +08:00
Mr Chen fa6900a937 Update monitor.py 2024-11-03 03:34:21 +08:00
Mr Chen b020f4c502 Update system.py 2024-11-03 03:31:47 +08:00
Mr Chen 122bef53ff Update system.sql 2024-11-03 03:25:21 +08:00
Mr Chen bed1d7ee85 Update system.sql 2024-11-03 03:25:08 +08:00
Mr Chen 7f68067f67 update 2024-11-03 03:17:02 +08:00
Mr Chen 06d43efd7f update 2024-11-03 03:06:40 +08:00
Mr Chen 745d95bbcb Update __init__.py 2024-11-03 02:20:52 +08:00
Mr Chen 7f5b45fbdc Update monitor.py 2024-11-03 02:01:20 +08:00
Mr Chen 179bc05e09 Update mw.py 2024-11-03 01:34:10 +08:00
Mr Chen 5e53c637c3 update 2024-11-03 01:28:19 +08:00
Mr Chen d7b7c572b0 update 2024-11-03 00:59:26 +08:00
Mr Chen 18e59ef377 up 2024-11-02 16:16:31 +08:00
Mr Chen fa64dfb89b update 2024-11-02 16:15:21 +08:00
Mr Chen 5788693e6c Update install.sh 2024-11-02 16:14:29 +08:00
Mr Chen 083f5e2271 update 2024-11-02 16:13:16 +08:00
Mr Chen 6b378a9712 update 2024-11-02 16:12:55 +08:00
Mr Chen 2a19a8f93d Update install.sh 2024-11-02 16:03:58 +08:00
Mr Chen c6418069fb Update install.sh 2024-11-02 16:01:48 +08:00
Mr Chen b66ab079ed Update install.sh 2024-11-02 15:58:50 +08:00
Mr Chen 07bca6cac8 update 2024-11-02 15:54:37 +08:00
Mr Chen 01b6ede03e update 2024-11-02 15:41:33 +08:00
Mr Chen 472f441c0e update 2024-11-02 02:47:47 +08:00
Mr Chen 31571a60e3 update 2024-11-02 02:19:58 +08:00
Mr Chen 8803d3ee03 Update new_cli.sh 2024-11-01 21:30:24 +08:00
Mr Chen d81764cc78 Update __init__.py 2024-11-01 21:30:18 +08:00
Mr Chen c56c1c7274 Update __init__.py 2024-11-01 21:28:39 +08:00
Mr Chen 580235b105 Update __init__.py 2024-11-01 21:24:14 +08:00
Mr Chen 210dbfe164 Update __init__.py 2024-11-01 21:18:49 +08:00
Mr Chen e6598ff57d update 2024-11-01 21:16:25 +08:00
Mr Chen 1dc21b3c0b Update __init__.py 2024-11-01 21:14:26 +08:00
Mr Chen 1bae404c5e Update adult_log.py 2024-11-01 19:06:54 +08:00
Mr Chen 39b3936eca Update adult_log.py 2024-11-01 19:04:14 +08:00
Mr Chen 205bb47101 Update user.py 2024-11-01 19:00:21 +08:00
Mr Chen a4cdc1e03b Update user.py 2024-11-01 18:59:08 +08:00
Mr Chen 0467d39c90 Update user.py 2024-11-01 18:57:12 +08:00
Mr Chen f8f152affb Update user.py 2024-11-01 18:56:49 +08:00
Mr Chen b2f595dfb2 Update user.py 2024-11-01 18:52:46 +08:00
Mr Chen 3f3221a3df Update user.py 2024-11-01 18:48:04 +08:00
Mr Chen 0eea41ba85 Update panel_tools.py 2024-11-01 18:45:07 +08:00
Mr Chen 90a406e5e9 Update panel_tools.py 2024-11-01 18:43:07 +08:00
Mr Chen 671859ad3c Update panel_tools.py 2024-11-01 18:37:00 +08:00
Mr Chen 306d69bd39 Update mw.tpl 2024-11-01 18:36:04 +08:00
Mr Chen f3552281c5 Update mw.tpl 2024-11-01 18:35:07 +08:00
Mr Chen 669bbfce93 Update mw.tpl 2024-11-01 18:34:35 +08:00
Mr Chen 9b1552269b update 2024-11-01 18:30:50 +08:00
Mr Chen 559e549590 Update panel_tools.py 2024-11-01 18:18:58 +08:00
Mr Chen fb8b5314e1 Update panel_tools.py 2024-11-01 18:18:12 +08:00
Mr Chen d767a4d4a2 update 2024-11-01 18:14:31 +08:00
Mr Chen 759cbd1065 Update mw.tpl 2024-11-01 17:34:48 +08:00
Mr Chen 386448d60c Update mw.tpl 2024-11-01 17:34:15 +08:00
Mr Chen 3d381b6dfa Update mw.tpl 2024-11-01 17:33:16 +08:00
Mr Chen 39c9a260cb Update mw.tpl 2024-11-01 17:32:30 +08:00
Mr Chen b0e9a13984 Update mw.tpl 2024-11-01 17:26:01 +08:00
Mr Chen 9ff26caa5f Update mw.tpl 2024-11-01 17:22:32 +08:00
Mr Chen d5e2f554f1 update 2024-11-01 17:21:19 +08:00
Mr Chen 14ee45918f Update panel_tools.py 2024-11-01 17:18:19 +08:00
Mr Chen 9fd7d20051 Update mw.tpl 2024-11-01 17:16:47 +08:00
Mr Chen 328543852c Update mw.tpl 2024-11-01 17:13:06 +08:00
Mr Chen aa23809390 Update mw.tpl 2024-11-01 17:01:52 +08:00
Mr Chen 6da09e708a Update mw.tpl 2024-11-01 16:58:51 +08:00
Mr Chen b44fec1859 Update __init__.py 2024-11-01 16:56:45 +08:00
Mr Chen 71ab5920c8 Update README.md 2024-11-01 16:55:47 +08:00
Mr Chen 4bd04eb71d Update update_new.sh 2024-11-01 16:55:22 +08:00
Mr Chen c08a2965ab Create update_new.sh 2024-11-01 16:54:42 +08:00
Mr Chen 87c50e529d Update mw.tpl 2024-11-01 16:51:45 +08:00
869 changed files with 19086 additions and 59236 deletions
+2 -2
View File
@@ -34,5 +34,5 @@ jobs:
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 &
cd web && gunicorn -c setting.py app:app
python3 panel_task.py &
+2 -2
View File
@@ -34,5 +34,5 @@ jobs:
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 &
cd web && gunicorn -c setting.py app:app
python3 panel_task.py &
+2 -2
View File
@@ -34,5 +34,5 @@ jobs:
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 &
cd web && gunicorn -c setting.py app:app
python3 panel_task.py &
+2 -2
View File
@@ -34,5 +34,5 @@ jobs:
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 &
cd web && gunicorn -c setting.py app:app
python3 panel_task.py &
+3 -3
View File
@@ -31,8 +31,8 @@ jobs:
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
cd /www/server/mdserver-web/plugins/openresty && sudo bash install.sh install 1.27.1
- name: Start DEBUG
run: |
gunicorn -c setting.py app:app
python3 task.py &
source /www/server/mdserver-web/bin/activate && cd web && gunicorn -c setting.py app:app
cd /www/server/mdserver-web && python3 panel_task.py &
+2 -2
View File
@@ -64,5 +64,5 @@ jobs:
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 &
source /www/server/mdserver-web/bin/activate && cd web && gunicorn -c setting.py app:app
cd /www/server/mdserver-web && python3 panel_task.py &
+10 -3
View File
@@ -119,7 +119,13 @@ debug.out
mdioks.session-journal
*.session
logs/*
temp
logs/panel.pid
logs/panel.log
logs/panel_task.log
logs/panel_exec.log
logs/panel_task.lock
ssl/local
ssl/nginx
@@ -161,6 +167,7 @@ data/api.json
data/bind_domain.pl
data/unauthorized_status.pl
data/auth_secret.pl
data/panelSpeed.pl
plugins/vip_*
plugins/own_*
@@ -170,7 +177,6 @@ plugins/l2tp
plugins/openlitespeed
plugins/tamper_proof
plugins/cryptocurrency_trade
plugins/mtproxy
plugins/zimg
plugins/bk_demo
plugins/mail
@@ -185,4 +191,5 @@ plugins/goedge-node
plugins/goedge-happy
plugins/dztasks
data/default_new.pl
/logs
/data
+16 -12
View File
@@ -39,6 +39,10 @@ Talk is cheap, show me the code. -- linus
- [兼容性测试报告](/compatibility.md)
- [常用命令说明](/cmd.md) [ mw default ] [ mw update_dev ]
### 特别赞助
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan1.cc)
### 主要插件介绍
* OpenResty - 轻量级,占有内存少,并发能力强。
@@ -88,10 +92,6 @@ PHP[72-84]支持phpMyAdmin[5.2.1]
- https://www.youtube.com/watch?v=2taa5K-Jmmw
# 特别赞助
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan1.cc)
# AD - VPS推荐 - 🙏
- [ZZZ评测](https://www.zzzvps.com/)
@@ -110,11 +110,14 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.17.3
### 版本更新 0.18.0
- 新增pgadmin插件。
- 新增acme_pandominassl_apply插件。
- 新增快捷指令:mw pgdb。
- 重新架构面板。
- PHP84正式版。
- 加入alist插件。
- 数据管理-常用命令。
- 插件读取优化(加入缓存+定时检查状态)。
- 恢复面板书签。
- 常规更新。
### JSDelivr安装地址
@@ -182,11 +185,12 @@ curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/dev/scripts/install_dev.sh | bash
curl --insecure -fsSL https://code.midoks.icu/midoks/mdserver-web/raw/branch/dev/scripts/update_dev.sh | bash
```
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_new.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_new.sh | bash
### 旧版安装
```
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/old/install.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/old/update.sh | bash
```
### 捐赠地址 USDT(TRC20)
-52
View File
@@ -1,52 +0,0 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 入口文件
# ---------------------------------------------------------------------------------
# pip install profiler_online
# 性能测试
# from profiler_online import run_profiler
# run_profiler()
import sys
import io
import os
sys.dont_write_bytecode = True
from route import app, socketio
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from gevent import monkey
monkey.patch_all()
try:
if __name__ == "__main__":
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'
# app.run(host=HOST, port=PORT)
http_server = WSGIServer(
(HOST, PORT), app, handler_class=WebSocketHandler)
http_server.serve_forever()
socketio.run(app, host=HOST, port=PORT)
except Exception as ex:
print(ex)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-146
View File
@@ -1,146 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 公共操作
# ---------------------------------------------------------------------------------
import os
import sys
import time
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()
initInitTask()
return True
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
# sysCfgDir = mw.systemdCfgDir()
# if os.path.exists(sysCfgDir) and mw.getOsName() == 'centos' and mw.getOsID() == '9':
# systemd_mw = sysCfgDir + '/mw.service'
# systemd_mw_task = sysCfgDir + '/mw-task.service'
# systemd_mw_tpl = mw.getRunDir() + '/scripts/init.d/mw.service.tpl'
# systemd_mw_task_tpl = mw.getRunDir() + '/scripts/init.d/mw-task.service.tpl'
# if os.path.exists(systemd_mw):
# os.remove(systemd_mw)
# if os.path.exists(systemd_mw_task):
# os.remove(systemd_mw_task)
# doContentReplace(systemd_mw_tpl, systemd_mw)
# doContentReplace(systemd_mw_task_tpl, systemd_mw_task)
# 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/rc.d/init.d"):
mw.execShell('mkdir -p /etc/rc.d/init.d')
if not mw.isAppleSystem() and not os.path.exists("/etc/init.d"):
mw.execShell('mkdir -p /etc/init.d')
# initd
if os.path.exists('/etc/rc.d/init.d'):
initd_bin = '/etc/rc.d/init.d/mw'
if not os.path.exists(initd_bin):
import shutil
shutil.copyfile(script_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
# 加入自启动
mw.execShell('which chkconfig && chkconfig --add mw')
if os.path.exists('/etc/init.d'):
initd_bin = '/etc/init.d/mw'
if not os.path.exists(initd_bin):
import shutil
shutil.copyfile(script_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
# 加入自启动
mw.execShell('which update-rc.d && update-rc.d -f mw defaults')
# 获取系统IPV4
mw.setHostAddr(mw.getLocalIp())
def initInitTask():
# 创建证书同步命令
import cert_api
api = cert_api.cert_api()
api.createCertCron()
def initUserInfo():
data = mw.M('users').where('id=?', (1,)).getField('password')
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))
File diff suppressed because it is too large Load Diff
-694
View File
@@ -1,694 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 计划任务操作
# ---------------------------------------------------------------------------------
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from 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)
rdata = {}
rdata['data'] = data
count = mw.M('crontab').where('', ()).count()
_page = {}
_page['count'] = count
_page['p'] = p
_page['row'] = psize
_page['tojs'] = "getCronData"
rdata['list'] = mw.getPage(_page)
rdata['p'] = p
# backup hook
bh_file = mw.getPanelDataDir() + "/hook_backup.json"
if os.path.exists(bh_file):
hb_data = mw.readFile(bh_file)
hb_data = json.loads(hb_data)
rdata['backup_hook'] = hb_data
return mw.getJson(rdata)
# 设置计划任务状态
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 cronCheck(self, params):
if params['stype'] == 'site' or params['stype'] == 'database' or params['stype'].find('database_') > -1 or params['stype'] == 'logs' or params['stype'] == 'path':
if params['save'] == '':
return False, '保留份数不能为空!'
if params['type'] == 'day':
if params['hour'] == '':
return False, '小时不能为空!'
if params['minute'] == '':
return False, '分钟不能为空!'
if params['type'] == 'day-n':
if params['where1'] == '':
return False, '天不能为空!'
if params['hour'] == '':
return False, '小时不能为空!'
if params['minute'] == '':
return False, '分钟不能为空!'
if params['type'] == 'hour':
if params['minute'] == '':
return False, '分钟不能为空!'
if params['type'] == 'hour-n':
if params['where1'] == '':
return False, '小时不能为空!'
if params['minute'] == '':
return False, '分钟不能为空!'
if params['type'] == 'minute-n':
if params['where1'] == '':
return False, '分钟不能为空!'
if params['type'] == 'week':
if params['hour'] == '':
return False, '小时不能为空!'
if params['minute'] == '':
return False, '分钟不能为空!'
if params['type'] == 'month':
if params['where1'] == '':
return False, '日不能为空!'
if params['hour'] == '':
return False, '小时不能为空!'
if params['minute'] == '':
return False, '分钟不能为空!'
return True, 'OK'
def modifyCrondApi(self):
sid = request.form.get('id', '')
iname = request.form.get('name', '')
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,
}
is_check_pass, msg = self.cronCheck(params)
if not is_check_pass:
return mw.returnJson(is_check_pass, msg)
cuonConfig, get, name = self.getCrondCycle(params)
cronInfo = mw.M('crontab').where(
'id=?', (sid,)).field(self.field).find()
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, sname, sbody,urladdress',
(iname, field_type, get['where1'], get['hour'], get['minute'], get['save'], get['backup_to'], sname, 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.getLastLine(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,
}
is_check_pass, msg = self.cronCheck(params)
if not is_check_pass:
return mw.returnJson(is_check_pass, msg)
addData = self.add(params)
if type(addData) == str:
return addData
if addData > 0:
return mw.returnJson(True, '添加成功')
return mw.returnJson(False, '添加失败')
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 == 'site' or stype == 'sites' or stype == 'database' or stype.find('database_') > -1 or stype == 'path':
hookPath = mw.getPanelDataDir() + "/hook_backup.json"
if os.path.exists(hookPath):
t = mw.readFile(hookPath)
bak_data = json.loads(t)
if stype == 'database' or stype.find('database_') > -1:
sqlite3_name = 'mysql'
path = mw.getServerDir() + '/mysql'
if stype != 'database':
soft_name = stype.replace('database_', '')
path = mw.getServerDir() + '/' + soft_name
if soft_name == 'postgresql':
sqlite3_name = 'pgsql'
if soft_name == 'mongodb':
sqlite3_name = 'mongodb'
db_list = {}
db_list['orderOpt'] = bak_data
if not os.path.exists(path + '/' + sqlite3_name + '.db'):
db_list['data'] = []
else:
db_list['data'] = mw.M('databases').dbPos(path, sqlite3_name).field('name,ps').select()
return mw.getJson(db_list)
if stype == 'path':
db_list = {}
db_list['data'] = [{"name": mw.getWwwDir(), "ps": "www"}]
db_list['orderOpt'] = bak_data
return mw.getJson(db_list)
data = {}
data['orderOpt'] = bak_data
default_db = 'sites'
# if stype == 'site' or stype == 'logs':
# stype == 'sites'
data['data'] = mw.M(default_db).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"
start_head = '''
SCRIPT_RUN_TIME="0s"
MW_ToSeconds()
{
SEC=$1
if [ $SEC -lt 60 ]; then
SCRIPT_RUN_TIME="${SEC}s"
elif [ $SEC -ge 60 ] && [ $SEC -lt 3600 ];then
SCRIPT_RUN_TIME="$(( SEC / 60 ))m$(( SEC % 60 ))s"
elif [ $SEC -ge 3600 ]; then
SCRIPT_RUN_TIME="$(( SEC / 3600 ))h$(( (SEC % 3600) / 60 ))m$(( (SEC % 3600) % 60 ))s"
fi
}
START_MW_SHELL_TIME=`date +%s`
'''
source_bin_activate = '''
export LANG=en_US.UTF-8
MW_PATH=%s/bin/activate
if [ -f $MW_PATH ];then
source $MW_PATH
fi''' % (mw.getRunDir(),)
head = head + start_head + source_bin_activate + "\n"
log = '.log'
#所有
if param['sname'] == 'ALL':
log = ''
script_dir = mw.getRunDir() + "/scripts"
source_stype = 'database'
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
script_dir = mw.getRunDir() + "/plugins/" + plugin_name + "/scripts"
source_stype = stype
stype = 'database'
wheres = {
'path': head + "python3 " + script_dir + "/backup.py path " + param['sname'] + " " + str(param['save']),
'site': head + "python3 " + script_dir + "/backup.py site " + param['sname'] + " " + str(param['save']),
'database': head + "python3 " + script_dir + "/backup.py 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'
}
if param['backup_to'] != 'localhost':
cfile = mw.getPluginDir() + "/" + \
param['backup_to'] + "/index.py"
wheres['path'] = head + "python3 " + cfile + \
" path " + param['sname'] + " " + str(param['save'])
wheres['site'] = head + "python3 " + cfile + \
" site " + param['sname'] + " " + str(param['save'])
wheres['database'] = head + "python3 " + cfile + " " + \
source_stype + " " + \
param['sname'] + " " + str(param['save'])
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"`
END_MW_SHELL_TIME=`date +"%s"`
((SHELL_COS_TIME=($END_MW_SHELL_TIME-$START_MW_SHELL_TIME)))
MW_ToSeconds $SHELL_COS_TIME
echo "★[$endDate] Successful | Script Run [$SCRIPT_RUN_TIME] "
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):
file = '/var/spool/cron/crontabs/root'
current_os = mw.getOs()
if current_os == 'darwin':
file = '/etc/crontab'
elif current_os.startswith("freebsd"):
file = '/var/cron/tabs/root'
if not os.path.exists(file):
file = '/var/spool/cron/root'
if 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(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():
# mw.execShell('/usr/sbin/cron restart')
if os.path.exists('/etc/crontab'):
pass
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()
-401
View File
@@ -1,401 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# sqlite3操作
# ---------------------------------------------------------------------------------
import sqlite3
import os
import sys
class Sql():
#------------------------------
# 数据库操作类 For sqlite3
#------------------------------
__DB_FILE = None # 数据库文件
__DB_CONN = None # 数据库连接对象
__DB_TABLE = "" # 被操作的表名称
__OPT_WHERE = "" # where条件
__OPT_LIMIT = "" # limit条件
__OPT_GROUP = "" # group条件
__OPT_ORDER = "" # order条件
__OPT_FIELD = "*" # field条件
__OPT_PARAM = () # where值
def __init__(self):
self.__DB_FILE = 'data/default.db'
def __getConn(self):
# 取数据库对象
try:
if self.__DB_CONN == None:
self.__DB_CONN = sqlite3.connect(self.__DB_FILE)
self.__DB_CONN.text_factory = str
except Exception as ex:
# print(mw.getTracebackInfo())
return "error: " + str(ex)
def changeTextFactoryToBytes(self):
self.__DB_CONN.text_factory = bytes
return True
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):
self.__DB_FILE = 'data/' + name + '.db'
return self
def dbPos(self, path, name, suffix_name = 'db'):
self.__DB_FILE = path + '/' + name + '.' + suffix_name
return self
def table(self, table):
# 设置表名
self.__DB_TABLE = table
return self
def where(self, where, param=()):
# WHERE条件
if where:
self.__OPT_WHERE = " WHERE " + where
self.__OPT_PARAM = param
return self
def andWhere(self, where, param):
# WHERE条件
if where:
self.__OPT_WHERE = self.__OPT_WHERE + " and " + where
# print(param)
# print(self.__OPT_PARAM)
self.__OPT_PARAM = self.__OPT_PARAM + param
return self
def order(self, order):
# ORDER条件
if len(order):
self.__OPT_ORDER = " ORDER BY " + order
else:
self.__OPT_ORDER = ""
return self
def group(self, group):
if len(group):
self.__OPT_GROUP = " GROUP BY " + group
else:
self.__OPT_GROUP = ""
return self
def limit(self, limit):
# LIMIT条件
if len(limit):
self.__OPT_LIMIT = " LIMIT " + limit
else:
self.__OPT_LIMIT = ""
return self
def field(self, field):
# FIELD条件
if len(field):
self.__OPT_FIELD = field
return self
def select(self):
# 查询数据集
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)
# print(self.__OPT_PARAM)
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
data = result.fetchall()
# 构造字曲系列
if self.__OPT_FIELD != "*":
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)
self.__close()
return data
except Exception as 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
if os.path.exists('data/debug.pl'):
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)
def getField(self, keyName):
# 取回指定字段
result = self.field(keyName).select()
# print(result)
if len(result) == 1:
return result[0][keyName]
return result
def setField(self, keyName, keyValue):
# 更新指定字段
return self.save(keyName, (keyValue,))
def find(self):
# 取一行数据
result = self.limit("1").select()
if len(result) == 1:
return result[0]
return result
def count(self):
# 取行数
key = "COUNT(*)"
data = self.field(key).select()
try:
return int(data[0][key])
except:
return 0
def add(self, keys, param):
# 插入数据
self.__getConn()
try:
values = ""
for key in keys.split(','):
values += "?,"
values = self.checkInput(values[0:len(values) - 1])
sql = "INSERT INTO " + self.__DB_TABLE + \
"(" + keys + ") " + "VALUES(" + values + ")"
result = self.__DB_CONN.execute(sql, param)
last_id = result.lastrowid
self.__close()
self.__DB_CONN.commit()
return last_id
except Exception as ex:
return "error: " + str(ex)
# 插入数据
def insert(self, pdata):
if not pdata:
return False
keys, param = self.__format_pdata(pdata)
return self.add(keys, param)
# 更新数据
def update(self, pdata):
if not pdata:
return False
keys, param = self.__format_pdata(pdata)
return self.save(keys, param)
# 构造数据
def __format_pdata(self, pdata):
keys = pdata.keys()
keys_str = ','.join(keys)
param = []
for k in keys:
param.append(pdata[k])
return keys_str, tuple(param)
def checkInput(self, data):
if not data:
return data
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 addAll(self, keys, param):
# 插入数据
self.__getConn()
try:
values = ""
for key in keys.split(','):
values += "?,"
values = values[0:len(values) - 1]
sql = "INSERT INTO " + self.__DB_TABLE + \
"(" + keys + ") " + "VALUES(" + values + ")"
result = self.__DB_CONN.execute(sql, param)
return True
except Exception as ex:
return "error: " + str(ex)
def commit(self):
self.__close()
self.__DB_CONN.commit()
def save(self, keys, param):
# 更新数据
self.__getConn()
try:
opt = ""
for key in keys.split(','):
opt += key + "=?,"
opt = opt[0:len(opt) - 1]
sql = "UPDATE " + self.__DB_TABLE + " SET " + opt + self.__OPT_WHERE
# import mw
# mw.writeFile('/tmp/test.pl', sql)
# 处理拼接WHERE与UPDATE参数
tmp = list(param)
for arg in self.__OPT_PARAM:
tmp.append(arg)
self.__OPT_PARAM = tuple(tmp)
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
self.__close()
self.__DB_CONN.commit()
return result.rowcount
except Exception as ex:
return "error: " + str(ex)
def delete(self, id=None):
# 删除数据
self.__getConn()
try:
if id:
self.__OPT_WHERE = " WHERE id=?"
self.__OPT_PARAM = (id,)
sql = "DELETE FROM " + self.__DB_TABLE + self.__OPT_WHERE
result = self.__DB_CONN.execute(sql, self.__OPT_PARAM)
self.__close()
self.__DB_CONN.commit()
return result.rowcount
except Exception as ex:
return "error: " + str(ex)
def originExecute(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语句返回受影响行
self.__getConn()
# print sql, param
try:
result = self.__DB_CONN.execute(sql, param)
self.__DB_CONN.commit()
return result.rowcount
except Exception as ex:
return "error: " + str(ex)
def query(self, sql, param=()):
# 执行SQL语句返回数据集
self.__getConn()
try:
result = self.__DB_CONN.execute(sql, param)
# 将元组转换成列表
# data = map(list, result)
return result
except Exception as ex:
return "error: " + str(ex)
def create(self, name):
# 创建数据表
self.__getConn()
import mw
script = mw.readFile('data/' + name + '.sql')
result = self.__DB_CONN.executescript(script)
self.__DB_CONN.commit()
return result.rowcount
def fofile(self, filename):
# 执行脚本
self.__getConn()
import mw
script = mw.readFile(filename)
result = self.__DB_CONN.executescript(script)
self.__DB_CONN.commit()
return result.rowcount
def __close(self):
# 清理条件属性
self.__OPT_WHERE = ""
self.__OPT_FIELD = "*"
self.__OPT_ORDER = ""
self.__OPT_LIMIT = ""
self.__OPT_PARAM = ()
def close(self):
# 释放资源
try:
self.__DB_CONN.close()
self.__DB_CONN = None
except:
pass
File diff suppressed because it is too large Load Diff
-513
View File
@@ -1,513 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 防火墙操作
# ---------------------------------------------------------------------------------
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from flask import request
class firewall_api:
__isFirewalld = False
__isIptables = False
__isUfw = False
__isMac = False
def __init__(self):
iptables_file = mw.systemdCfgDir() + '/iptables.service'
if os.path.exists('/usr/sbin/firewalld'):
self.__isFirewalld = True
elif os.path.exists('/usr/sbin/ufw'):
self.__isUfw = True
elif os.path.exists(iptables_file):
self.__isIptables = True
elif 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 = r"^\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.__isIptables:
cmd = 'iptables -I INPUT -s ' + address + ' -j DROP'
mw.execShell(cmd)
elif self.__isFirewalld:
cmd = 'firewall-cmd --permanent --add-rich-rule=\'rule family=ipv4 source address="' + \
address + '" drop\''
mw.execShell(cmd)
else:
pass
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, '防火墙启动时,才能添加规则!')
port = request.form.get('port', '').strip()
ps = request.form.get('ps', '').strip()
stype = request.form.get('type', '').strip()
protocol = request.form.get('protocol', '').strip()
data = self.addAcceptPortArgs(port, ps, stype, protocol)
return mw.getJson(data)
# 添加放行端口
def addAcceptPortArgs(self, port, ps, stype, protocol='tcp'):
import re
import time
if not self.getFwStatus():
self.setFw(0)
rep = r"^\d{1,5}(:\d{1,5})?$"
if not re.search(rep, port):
return mw.returnData(False, '端口范围不正确!')
if mw.M('firewall').where("port=?", (port,)).count() > 0:
return mw.returnData(False, '您要放行的端口已存在,无需重复放行!')
msg = mw.getInfo('放行端口[{1}][{2}]成功', (port, protocol,))
mw.writeLog("防火墙管理", msg)
addtime = time.strftime('%Y-%m-%d %X', time.localtime())
mw.M('firewall').add('port,protocol,ps,addtime',
(port, protocol, ps, addtime))
self.addAcceptPort(port, protocol)
self.firewallReload()
return mw.returnData(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')
elif self.__isFirewalld:
mw.execShell(
'firewall-cmd --permanent --remove-rich-rule=\'rule family=ipv4 source address="' + address + '" drop\'')
elif self.__isIptables:
cmd = 'iptables -D INPUT -s ' + address + ' -j DROP'
mw.execShell(cmd)
else:
pass
msg = mw.getInfo('解除IP[{1}]的屏蔽!', (address,))
mw.writeLog("防火墙管理", msg)
mw.M('firewall').where("id=?", (sid,)).delete()
self.firewallReload()
return mw.returnJson(True, '删除成功!')
def delAcceptPortArgs(self, port, protocol='tcp'):
if self.__isUfw:
if protocol == 'tcp':
mw.execShell('ufw delete allow ' + port + '/tcp')
if protocol == 'udp':
mw.execShell('ufw delete allow ' + port + '/udp')
if protocol == 'tcp/udp':
mw.execShell('ufw delete allow ' + port + '/tcp')
mw.execShell('ufw delete allow ' + port + '/udp')
elif self.__isFirewalld:
port = port.replace(':', '-')
if protocol == 'tcp':
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
if protocol == 'udp':
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
if protocol == 'tcp/udp':
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/tcp')
mw.execShell(
'firewall-cmd --permanent --zone=public --remove-port=' + port + '/udp')
elif self.__isIptables:
if protocol == 'tcp':
mw.execShell(
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
if protocol == 'udp':
mw.execShell(
'iptables -D INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT')
if protocol == 'tcp/udp':
mw.execShell(
'iptables -D INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT')
mw.execShell(
'iptables -D INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT')
else:
pass
mw.M('firewall').where("port=?", (port,)).delete()
msg = mw.getInfo('删除防火墙放行端口[{1}][{2}]成功!', (port, protocol,))
mw.writeLog("防火墙管理", msg)
self.firewallReload()
return True
# 删除放行端口
def delAcceptPortApi(self):
port = request.form.get('port', '').strip()
protocol = request.form.get('protocol', 'tcp').strip()
sid = request.form.get('id', '').strip()
mw_port = mw.readFile('data/port.pl')
if(port == mw_port):
return mw.returnJson(False, '失败,不能删除当前面板端口!')
try:
self.delAcceptPortArgs(port, protocol)
mw.M('firewall').where("id=?", (sid,)).delete()
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 getSshInfoApi(self):
data = {}
file = '/etc/ssh/sshd_config'
conf = mw.readFile(file)
rep = r"#*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'
sys_conf = mw.readFile(file)
rep = r"#*net\.ipv4\.icmp_echo_ignore_all\s*=\s*([0-9]+)"
tmp = re.search(rep, sys_conf).groups(0)[0]
if tmp == '1':
isPing = False
except:
isPing = True
# sshd 检测
status = True
cmd = "service sshd status | grep -P '(dead|stop)'|grep -v grep"
ssh_status = mw.execShell(cmd)
if ssh_status[0] != '':
status = False
cmd = "systemctl status sshd.service | grep 'dead'|grep -v grep"
ssh_status = mw.execShell(cmd)
if ssh_status[0] != '':
status = False
data['pass_prohibit_status'] = False
# 密码登陆配置检查
pass_rep = r"PasswordAuthentication\s+(\w*)\s*\n"
pass_status = re.search(pass_rep, conf)
if pass_status:
if pass_status and pass_status.groups(0)[0].strip() == 'no':
data['pass_prohibit_status'] = True
else:
data['pass_prohibit_status'] = True
data['port'] = port
data['status'] = status
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', '888']
if port in ports:
return mw.returnJson(False, '(' + port + ')' + '特殊端口不可设置!')
file = '/etc/ssh/sshd_config'
conf = mw.readFile(file)
rep = r"#*Port\s+([0-9]+)\s*\n"
conf = re.sub(rep, "Port " + port + "\n", conf)
mw.writeFile(file, conf)
self.addAcceptPortArgs(port, 'SSH端口修改', 'port')
if self.__isUfw:
mw.execShell("service ssh restart")
elif self.__isIptables:
mw.execShell("/etc/init.d/sshd restart")
elif self.__isFirewalld:
mw.execShell("systemctl restart sshd.service")
else:
return mw.returnJson(False, '修改失败!')
return mw.returnJson(True, '修改成功!')
def setSshStatusApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不能操作!')
status = request.form.get('status', '1').strip()
msg = 'SSH服务已启用'
act = 'start'
if status == "1":
msg = 'SSH服务已停用'
act = 'stop'
ssh_service = mw.systemdCfgDir() + '/sshd.service'
if os.path.exists(ssh_service):
mw.execShell("systemctl " + act + " sshd.service")
else:
mw.execShell('service sshd ' + act)
if os.path.exists('/etc/init.d/sshd'):
mw.execShell('/etc/init.d/sshd ' + act)
mw.writeLog("防火墙管理", msg)
return mw.returnJson(True, '操作成功!')
def setSshPassStatusApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不能操作!')
status = request.form.get('status', '1').strip()
msg = '禁止密码登陆成功'
if status == "1":
msg = '开启密码登陆成功'
file = '/etc/ssh/sshd_config'
if not os.path.exists(file):
return mw.returnJson(False, '无法设置!')
conf = mw.readFile(file)
pass_rep = r"PasswordAuthentication\s+(\w*)\s*\n"
pass_status = re.search(pass_rep, conf)
if not pass_status:
rep = r"(#)?PasswordAuthentication\s+(\w*)\s*\n"
conf = re.sub(rep, "PasswordAuthentication yes\n", conf)
if status == '1':
rep = r"PasswordAuthentication\s+(\w*)\s*\n"
conf = re.sub(rep, "PasswordAuthentication yes\n", conf)
else:
rep = r"PasswordAuthentication\s+(\w*)\s*\n"
conf = re.sub(rep, "PasswordAuthentication no\n", conf)
mw.writeFile(file, conf)
mw.execShell("systemctl restart sshd.service")
mw.writeLog("SSH管理", msg)
return mw.returnJson(True, msg)
def setPingApi(self):
if mw.isAppleSystem():
return mw.returnJson(True, '开发机不能操作!')
status = request.form.get('status')
filename = '/etc/sysctl.conf'
conf = mw.readFile(filename)
if conf.find('net.ipv4.icmp_echo') != -1:
rep = r"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')
return mw.getJson(self.setFw(status))
def setFwIptables(self, status):
# iptables特殊处理
if status == '1':
mw.execShell('service iptables save')
mw.execShell('service iptables stop')
else:
# 重新导入数据
_list = mw.M('firewall').field('id,port,ps,addtime').limit(
'0,1000').order('id desc').select()
mw.execShell('iptables -P INPUT DROP')
mw.execShell('iptables -P OUTPUT ACCEPT')
for x in _list:
port = x['port']
if mw.isIpAddr(port):
cmd = 'iptables -I INPUT -s ' + port + ' -j DROP'
mw.execShell(cmd)
else:
self.addAcceptPort(port)
mw.execShell('service iptables save')
mw.execShell('service iptables start')
def setFw(self, status):
if self.__isIptables:
self.setFwIptables(status)
return mw.returnData(True, '设置成功!')
if status == '1':
if self.__isUfw:
mw.execShell('/usr/sbin/ufw disable')
elif self.__isFirewalld:
mw.execShell('systemctl stop firewalld.service')
mw.execShell('systemctl disable firewalld.service')
else:
pass
else:
if self.__isUfw:
mw.execShell("echo 'y'| ufw enable")
elif self.__isFirewalld:
mw.execShell('systemctl start firewalld.service')
mw.execShell('systemctl enable firewalld.service')
else:
pass
return mw.returnData(True, '设置成功!')
##### ----- start ----- ###
def getList(self, page, limit):
start = (page - 1) * limit
_list = mw.M('firewall').field('id,port,protocol,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 addAcceptPort(self, port, protocol='tcp'):
if self.__isUfw:
if protocol == 'tcp':
mw.execShell('ufw allow ' + port + '/tcp')
if protocol == 'udp':
mw.execShell('ufw allow ' + port + '/udp')
if protocol == 'tcp/udp':
mw.execShell('ufw allow ' + port + '/tcp')
mw.execShell('ufw allow ' + port + '/udp')
elif self.__isFirewalld:
port = port.replace(':', '-')
if protocol == 'tcp':
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
mw.execShell(cmd)
if protocol == 'udp':
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/udp'
mw.execShell(cmd)
if protocol == 'tcp/udp':
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/tcp'
mw.execShell(cmd)
cmd = 'firewall-cmd --permanent --zone=public --add-port=' + port + '/udp'
mw.execShell(cmd)
elif self.__isIptables:
if protocol == 'tcp':
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
if protocol == 'udp':
cmd = 'iptables -I INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
if protocol == 'tcp/udp':
cmd = 'iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
cmd = 'iptables -I INPUT -p udp -m state --state NEW -m udp --dport ' + port + ' -j ACCEPT'
mw.execShell(cmd)
else:
pass
return True
def firewallReload(self):
if self.__isUfw:
mw.execShell('/usr/sbin/ufw reload')
return
elif self.__isIptables:
mw.execShell('service iptables save')
mw.execShell('service iptables restart')
elif self.__isFirewalld:
mw.execShell('firewall-cmd --reload')
else:
pass
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
elif self.__isIptables:
cmd = "systemctl status iptables | grep 'inactive'"
data = mw.execShell(cmd)
if data[0] != '':
return False
return True
elif self.__isFirewalld:
cmd = "ps -ef|grep firewalld |grep -v grep | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return False
return True
else:
return False
-355
View File
@@ -1,355 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 日志类操作
# ---------------------------------------------------------------------------------
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from datetime import datetime
from flask import request
class logs_api:
__months = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
'Jul': '07', 'Aug': '08', 'Sep': '09', 'Sept': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'}
def __init__(self):
pass
def delPanelLogsApi(self):
mw.M('logs').where('id>?', (0,)).delete()
mw.writeLog('面板设置', '面板操作日志已清空!')
return mw.returnJson(True, '面板操作日志已清空!')
def getLogListApi(self):
p = request.form.get('p', '1').strip()
limit = request.form.get('limit', '10').strip()
search = request.form.get('search', '').strip()
return self.getLogList(int(p), int(limit), search)
def getLogList(self, page, limit, search=''):
find_search = ''
if search != '':
find_search = "type like '%" + search + "%' or log like '%" + \
search + "%' or addtime like '%" + search + "%'"
start = (page - 1) * limit
_list = mw.M('logs').where(find_search, ()).field(
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
data = {}
data['data'] = _list
count = mw.M('logs').where(find_search, ()).count()
_page = {}
_page['count'] = count
_page['tojs'] = 'getLogs'
_page['p'] = page
data['page'] = mw.getPage(_page)
return mw.getJson(data)
def getLogsTitle(self, log_name):
log_name = log_name.replace('.1', '')
if log_name in ['mw-update.log']:
return '面板更新日志'
if log_name in ['mw-install.log']:
return '面板安装日志'
if log_name in ['auth.log', 'secure'] or log_name.find('auth.') == 0:
return '授权日志'
if log_name in ['dmesg'] or log_name.find('dmesg') == 0:
return '内核缓冲区日志'
if log_name in ['syslog'] or log_name.find('syslog') == 0:
return '系统日志'
if log_name in ['rsyncd.log']:
return '远程同步日志'
if log_name in ['btmp']:
return '失败的登录记录'
if log_name in ['utmp', 'wtmp']:
return '登录和重启记录'
if log_name in ['lastlog']:
return '用户最后登录'
if log_name in ['yum.log']:
return 'yum包管理器日志'
if log_name in ['anaconda.log']:
return 'Anaconda日志'
if log_name in ['dpkg.log']:
return 'dpkg日志'
if log_name in ['daemon.log']:
return '系统后台守护进程日志'
if log_name in ['boot.log']:
return '启动日志'
if log_name in ['kern.log']:
return '内核日志'
if log_name in ['maillog', 'mail.log']:
return '邮件日志'
if log_name.find('Xorg') == 0:
return 'Xorg日志'
if log_name in ['cron.log']:
return '定时任务日志'
if log_name in ['alternatives.log']:
return '更新替代信息'
if log_name in ['debug']:
return '调试信息'
if log_name.find('apt') == 0:
return 'apt-get相关日志'
if log_name.find('installer') == 0:
return '系统安装相关日志'
if log_name in ['messages']:
return '综合日志'
return '{}日志'.format(log_name.split('.')[0])
def getAuditLogsFilesApi(self):
log_dir = '/var/log'
log_files = []
for log_file in os.listdir(log_dir):
log_suffix = log_file.split('.')[-1:]
if log_suffix[0] in ['gz', 'xz', 'bz2', 'asl']:
continue
if log_file in ['.', '..']:
continue
filename = os.path.join(log_dir, log_file)
if not os.path.exists(filename):
continue
if os.path.isfile(filename):
file_size = os.path.getsize(filename)
if not file_size:
continue
tmp = {
'name': log_file,
'size': file_size,
'log_file': filename,
'title': self.getLogsTitle(log_file),
'uptime': os.path.getmtime(filename)
}
log_files.append(tmp)
else:
for next_name in os.listdir(filename):
if next_name[-3:] in ['.gz', '.xz']:
continue
next_file = os.path.join(filename, next_name)
if not os.path.isfile(next_file):
continue
file_size = os.path.getsize(next_file)
if not file_size:
continue
log_name = '{}/{}'.format(log_file, next_name)
tmp = {
'name': log_name,
'size': file_size,
'log_file': next_file,
'title': self.getLogsTitle(log_name),
'uptime': os.path.getmtime(next_file)
}
log_files.append(tmp)
log_files = sorted(log_files, key=lambda x: x['name'], reverse=True)
return mw.getJson(log_files)
def getAuditFileApi(self):
log_name = request.form.get('log_name', '').strip()
return self.getAuditLogsName(log_name)
def __to_date2(self, date_str):
tmp = date_str.split()
s_date = str(tmp[-1]) + '-' + self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
return s_date
def __to_date3(self, date_str):
tmp = date_str.split()
s_date = str(datetime.now().year) + '-' + self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
return s_date
def __to_date4(self, date_str):
tmp = date_str.split()
s_date = str(datetime.now().year) + '-' + \
self.__months.get(tmp[0], tmp[0]) + '-' + tmp[1] + ' ' + tmp[2]
return s_date
def getAuditLast(self, log_name):
# 获取日志
cmd = '''LANG=en_US.UTF-8 last -n 200 -x -f {} |grep -v 127.0.0.1|grep -v " begins"'''.format(
'/var/log/' + log_name)
result = mw.execShell(cmd)
lastlog_list = []
for _line in result[0].split("\n"):
if not _line:
continue
tmp = {}
sp_arr = _line.split()
tmp['用户'] = sp_arr[0]
if sp_arr[0] == 'runlevel':
tmp['来源'] = sp_arr[4]
tmp['端口'] = ' '.join(sp_arr[1:4])
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[5:])) + ' ' + ' '.join(sp_arr[-2:])
elif sp_arr[0] in ['reboot', 'shutdown']:
tmp['来源'] = sp_arr[3]
tmp['端口'] = ' '.join(sp_arr[1:3])
if sp_arr[-3] == '-':
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-3:])
else:
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-2:])
elif sp_arr[1] in ['tty1', 'tty', 'tty2', 'tty3', 'hvc0', 'hvc1', 'hvc2'] or len(sp_arr) == 9:
tmp['来源'] = ''
tmp['端口'] = sp_arr[1]
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[2:])) + ' ' + ' '.join(sp_arr[-3:])
else:
tmp['来源'] = sp_arr[2]
tmp['端口'] = sp_arr[1]
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[3:])) + ' ' + ' '.join(sp_arr[-3:])
# tmp['_line'] = _line
lastlog_list.append(tmp)
# lastlog_list = sorted(lastlog_list,key=lambda x:x['时间'],reverse=True)
return mw.returnData(True, 'ok!', lastlog_list)
def getAuditLastLog(self):
cmd = '''LANG=en_US.UTF-8 lastlog|grep -v Username'''
result = mw.execShell(cmd)
lastlog_list = []
for _line in result[0].split("\n"):
if not _line:
continue
tmp = {}
sp_arr = _line.split()
tmp['用户'] = sp_arr[0]
# tmp['_line'] = _line
if _line.find('Never logged in') != -1:
tmp['最后登录时间'] = '0'
tmp['最后登录来源'] = '-'
tmp['最后登录端口'] = '-'
lastlog_list.append(tmp)
continue
tmp['最后登录来源'] = sp_arr[2]
tmp['最后登录端口'] = sp_arr[1]
tmp['最后登录时间'] = self.__to_date2(' '.join(sp_arr[3:]))
lastlog_list.append(tmp)
lastlog_list = sorted(lastlog_list, key=lambda x: x[
'最后登录时间'], reverse=True)
for i in range(len(lastlog_list)):
if lastlog_list[i]['最后登录时间'] == '0':
lastlog_list[i]['最后登录时间'] = '从未登录过'
return mw.returnData(True, 'ok!', lastlog_list)
def parseAuditFile(self, log_name, result):
log_list = []
is_string = True
for _line in result.split("\n"):
if not _line.strip():
continue
if log_name.find('sa/sa') == -1:
if _line[:3] in self.__months:
_msg = _line[16:]
_tmp = _msg.split(": ")
_act = ''
if len(_tmp) > 1:
_act = _tmp[0]
_msg = _tmp[1]
else:
_msg = _tmp[0]
_line = {
"时间": self.__to_date4(_line[:16].strip()),
"角色": _act,
"事件": _msg
}
is_string = False
elif _line[:2] in ['19', '20', '21', '22', '23', '24']:
_msg = _line[19:]
_tmp = _msg.split(" ")
_act = _tmp[1]
_msg = ' '.join(_tmp[2:])
_line = {
"时间": _line[:19].strip(),
"角色": _act,
"事件": _msg
}
is_string = False
elif log_name.find('alternatives') == 0:
_tmp = _line.split(": ")
_last = _tmp[0].split(" ")
_act = _last[0]
_msg = ' '.join(_tmp[1:])
_line = {
"时间": ' '.join(_last[1:]).strip(),
"角色": _act,
"事件": _msg
}
is_string = False
else:
if not is_string:
if type(_line) != dict:
continue
log_list.append(_line)
return log_list
def getAuditLogsName(self, log_name):
# print(log_name)
if log_name in ['wtmp', 'btmp', 'utmp'] or log_name.find('wtmp') == 0 or log_name.find('btmp') == 0 or log_name.find('utmp') == 0:
return self.getAuditLast(log_name)
if log_name.find('lastlog') == 0:
return self.getAuditLastLog()
if log_name.find('sa/sa') == 0:
if log_name.find('sa/sar') == -1:
return mw.execShell("sar -f /var/log/{}".format(log_name))[0]
log_dir = '/var/log'
log_file = log_dir + '/' + log_name
if not os.path.exists(log_file):
return mw.returnData(False, '日志文件不存在!')
result = mw.getLastLine(log_file, 100)
try:
log_list = self.parseAuditFile(log_name, result)
_string = []
_dict = []
_list = []
for _line in log_list:
if isinstance(_line, str):
_string.append(_line.strip())
elif isinstance(_line, dict):
_dict.append(_line)
elif isinstance(_line, list):
_list.append(_line)
else:
continue
_str_len = len(_string)
_dict_len = len(_dict)
_list_len = len(_list)
if _str_len > _dict_len + _list_len:
return "\n".join(_string)
elif _dict_len > _str_len + _list_len:
return mw.returnData(True, 'ok!', _dict)
else:
return mw.returnData(True, 'ok!', _list)
except:
return mw.returnData(True, 'ok!', result)
-2287
View File
File diff suppressed because it is too large Load Diff
-245
View File
@@ -1,245 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 分页库操作
# ---------------------------------------------------------------------------------
import math
import string
class Page():
#--------------------------
# 分页类 - JS回调版
#--------------------------
__PREV = '上一页'
__NEXT = '下一页'
__START = '首页'
__END = '尾页'
__COUNT_START = '共'
__COUNT_END = '条数据'
__FO = '从'
__LINE = '条'
__LIST_NUM = 4
SHIFT = None # 偏移量
ROW = None # 每页行数
__C_PAGE = None # 当前页
__COUNT_PAGE = None # 总页数
__COUNT_ROW = None # 总行数
__URI = None # URI
__RTURN_JS = False # 是否返回JS回调
__START_NUM = None # 起始行
__END_NUM = None # 结束行
__ARGS_TPL = ''
def __init__(self):
if False:
self.__PREV = tmp['PREV']
self.__NEXT = tmp['NEXT']
self.__START = tmp['START']
self.__END = tmp['END']
self.__COUNT_START = tmp['COUNT_START']
self.__COUNT_END = tmp['COUNT_END']
self.__FO = tmp['FO']
self.__LINE = tmp['LINE']
def getPageNum(self, num):
return str(num) + self.__ARGS_TPL
def GetPage(self, pageInfo, limit='1,2,3,4,5,6,7,8'):
# 取分页信息
# @param pageInfo 传入分页参数字典
# @param limit 返回系列
self.__RTURN_JS = pageInfo['return_js']
self.__COUNT_ROW = pageInfo['count']
if 'args_tpl' in pageInfo:
self.__ARGS_TPL = pageInfo['args_tpl']
self.ROW = pageInfo['row']
self.__C_PAGE = self.__GetCpage(pageInfo['p'])
self.__START_NUM = self.__StartRow()
self.__END_NUM = self.__EndRow()
self.__COUNT_PAGE = self.__GetCountPage()
self.__URI = self.__SetUri(pageInfo['uri'])
self.SHIFT = self.__START_NUM - 1
keys = limit.split(',')
pages = {}
# 起始页
pages['1'] = self.__GetStart()
# 上一页
pages['2'] = self.__GetPrev()
# 分页
pages['3'] = self.__GetPages()
# 下一页
pages['4'] = self.__GetNext()
# 尾页
pages['5'] = self.__GetEnd()
# 当前显示页与总页数
pages['6'] = "<span class='Pnumber'>" + \
str(self.__C_PAGE) + "/" + \
str(self.__COUNT_PAGE) + "</span>"
# 本页显示开始与结束行
pages['7'] = "<span class='Pline'>" + str(self.__FO) + \
str(self.__START_NUM) + "-" + \
str(self.__END_NUM) + str(self.__LINE) + "</span>"
# 行数
pages['8'] = "<span class='Pcount'>" + str(self.__COUNT_START) + \
str(self.__COUNT_ROW) + str(self.__COUNT_END) + "</span>"
# 构造返回数据
retuls = '<div>'
for value in keys:
retuls += pages[value]
retuls += '</div>'
# 返回分页数据
return retuls
def __GetEnd(self):
# 构造尾页
endStr = ""
if self.__C_PAGE >= self.__COUNT_PAGE:
endStr = ''
else:
if self.__RTURN_JS == "":
endStr = "<a class='Pend' href='" + self.__URI + "p=" + \
str(self.__COUNT_PAGE) + "'>" + str(self.__END) + "</a>"
else:
endStr = "<a class='Pend' onclick='" + self.__RTURN_JS + \
"(" + self.getPageNum(self.__COUNT_PAGE) + ")'>" + \
str(self.__END) + "</a>"
return endStr
def __GetNext(self):
# 构造下一页
nextStr = ""
if self.__C_PAGE >= self.__COUNT_PAGE:
nextStr = ''
else:
if self.__RTURN_JS == "":
nextStr = "<a class='Pnext' href='" + self.__URI + "p=" + \
str(self.__C_PAGE + 1) + "'>" + str(self.__NEXT) + "</a>"
else:
nextStr = "<a class='Pnext' onclick='" + self.__RTURN_JS + \
"(" + self.getPageNum(self.__C_PAGE + 1) + ")'>" + \
str(self.__NEXT) + "</a>"
return nextStr
def __GetPages(self):
# 构造分页
pages = ''
num = 0
# 当前页之前
if (self.__COUNT_PAGE - self.__C_PAGE) < self.__LIST_NUM:
num = self.__LIST_NUM + \
(self.__LIST_NUM - (self.__COUNT_PAGE - self.__C_PAGE))
else:
num = self.__LIST_NUM
n = 0
for i in range(num):
n = num - i
page = self.__C_PAGE - n
if page > 0:
if self.__RTURN_JS == "":
pages += "<a class='Pnum' href='" + self.__URI + \
"p=" + str(page) + "'>" + str(page) + "</a>"
else:
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
"(" + self.getPageNum(page) + ")'>" + str(page) + "</a>"
# 当前页
if self.__C_PAGE > 0:
pages += "<span class='Pcurrent'>" + \
str(self.__C_PAGE) + "</span>"
# 当前页之后
if self.__C_PAGE <= self.__LIST_NUM:
num = self.__LIST_NUM + (self.__LIST_NUM - self.__C_PAGE) + 1
else:
num = self.__LIST_NUM
for i in range(num):
if i == 0:
continue
page = self.__C_PAGE + i
if page > self.__COUNT_PAGE:
break
if self.__RTURN_JS == "":
pages += "<a class='Pnum' href='" + self.__URI + \
"p=" + str(page) + "'>" + str(page) + "</a>"
else:
pages += "<a class='Pnum' onclick='" + self.__RTURN_JS + \
"(" + self.getPageNum(page) + ")'>" + str(page) + "</a>"
return pages
def __GetPrev(self):
# 构造上一页
startStr = ''
if self.__C_PAGE == 1:
startStr = ''
else:
if self.__RTURN_JS == "":
startStr = "<a class='Ppren' href='" + self.__URI + "p=" + \
str(self.__C_PAGE - 1) + "'>" + str(self.__PREV) + "</a>"
else:
startStr = "<a class='Ppren' onclick='" + self.__RTURN_JS + \
"(" + self.getPageNum(self.__C_PAGE - 1) + ")'>" + \
str(self.__PREV) + "</a>"
return startStr
def __GetStart(self):
# 构造起始分页
startStr = ''
if self.__C_PAGE == 1:
startStr = ''
else:
if self.__RTURN_JS == "":
startStr = "<a class='Pstart' href='" + \
self.__URI + "p=1'>" + str(self.__START) + "</a>"
else:
startStr = "<a class='Pstart' onclick='" + \
self.__RTURN_JS + "("+self.getPageNum(1)+")'>" + str(self.__START) + "</a>"
return startStr
def __GetCpage(self, p):
# 取当前页
if p:
return p
return 1
def __StartRow(self):
# 从多少行开始
return (self.__C_PAGE - 1) * self.ROW + 1
def __EndRow(self):
# 从多少行结束
if self.ROW > self.__COUNT_ROW:
return self.__COUNT_ROW
return self.__C_PAGE * self.ROW
def __GetCountPage(self):
# 取总页数
return int(math.ceil(self.__COUNT_ROW / float(self.ROW)))
def __SetUri(self, sinput):
# 构造URI
uri = '?'
for key in sinput:
if key == 'p':
continue
uri += key + '=' + sinput[key] + '&'
return str(uri)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-978
View File
@@ -1,978 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 系统信息操作
# ---------------------------------------------------------------------------------
import psutil
import time
import os
import re
import math
import sys
import json
from flask import Flask, session
from flask import request
import db
import mw
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:
setupPath = None
pids = None
cache = {}
def __init__(self):
self.setupPath = mw.getServerDir()
##### ----- start ----- ###
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):
try:
if not self.pids:
self.pids = psutil.pids()
for pid in self.pids:
if psutil.Process(pid).name() == pname:
return True
return False
except:
return False
# 检查端口是否占用
def isOpen(self, port):
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('127.0.0.1', int(port)))
s.shutdown(2)
return True
except:
return False
# 检测指定进程是否存活
def checkProcess(self, pid):
try:
if not self.pids:
self.pids = psutil.pids()
if int(pid) in self.pids:
return True
return False
except:
return False
def getEnvInfoApi(self, get=None):
serverInfo = {}
serverInfo['status'] = True
sdir = mw.getServerDir()
serverInfo['webserver'] = '未安装'
if os.path.exists(sdir + '/openresty/nginx/sbin/nginx'):
serverInfo['webserver'] = 'OpenResty'
serverInfo['php'] = []
phpversions = ['52', '53', '54', '55', '56', '70', '71',
'72', '73', '74', '80', '81', '82', '83', '84']
phpPath = sdir + '/php/'
for pv in phpversions:
if not os.path.exists(phpPath + pv + '/bin/php'):
continue
serverInfo['php'].append(pv)
serverInfo['mysql'] = False
if os.path.exists(sdir + '/mysql/bin/mysql'):
serverInfo['mysql'] = True
import psutil
try:
diskInfo = psutil.disk_usage('/www')
except:
diskInfo = psutil.disk_usage('/')
serverInfo['disk'] = diskInfo[2]
return mw.returnJson(True, 'ok', serverInfo)
def getPanelInfo(self, get=None):
# 取面板配置
address = mw.GetLocalIp()
try:
try:
port = web.ctx.host.split(':')[1]
except:
port = mw.readFile('data/port.pl')
except:
port = '7200'
domain = ''
if os.path.exists('data/domain.conf'):
domain = mw.readFile('data/domain.conf')
autoUpdate = ''
if os.path.exists('data/autoUpdate.pl'):
autoUpdate = 'checked'
limitip = ''
if os.path.exists('data/limitip.conf'):
limitip = mw.readFile('data/limitip.conf')
templates = []
for template in os.listdir('templates/'):
if os.path.isdir('templates/' + template):
templates.append(template)
template = mw.readFile('data/templates.pl')
check502 = ''
if os.path.exists('data/502Task.pl'):
check502 = 'checked'
return {'port': port, 'address': address, 'domain': domain, 'auto': autoUpdate, '502': check502, 'limitip': limitip, 'templates': templates, 'template': template}
def getSystemTotal(self, interval=1):
# 取系统统计信息
data = self.getMemInfo()
cpu = self.getCpuInfo(interval)
data['cpuNum'] = cpu[1]
data['cpuRealUsed'] = cpu[0]
data['time'] = self.getBootTime()
data['system'] = self.getSystemVersion()
data['isuser'] = mw.M('users').where(
'username=?', ('admin',)).count()
data['version'] = '0.0.1'
return data
def getLoadAverage(self):
c = os.getloadavg()
data = {}
data['one'] = round(float(c[0]), 2)
data['five'] = round(float(c[1]), 2)
data['fifteen'] = round(float(c[2]), 2)
data['max'] = psutil.cpu_count() * 2
data['limit'] = data['max']
data['safe'] = data['max'] * 0.75
return data
def getAllInfo(self, get):
data = {}
data['load_average'] = self.GetLoadAverage(get)
data['title'] = self.GetTitle()
data['network'] = self.GetNetWorkApi(get)
data['panel_status'] = not os.path.exists('/www/server/mdserver-web/data/close.pl')
import firewalls
ssh_info = firewalls.firewalls().GetSshInfo(None)
data['enable_ssh_status'] = ssh_info['status']
data['disable_ping_status'] = not ssh_info['ping']
data['time'] = self.GetBootTime()
# data['system'] = self.GetSystemVersion();
# data['mem'] = self.GetMemInfo();
data['version'] = web.ctx.session.version
return data
def getTitle(self):
titlePl = 'data/title.pl'
title = 'Linux面板'
if os.path.exists(titlePl):
title = mw.readFile(titlePl).strip()
return title
def getSystemDeviceTemperature(self):
if not hasattr(psutil, "sensors_temperatures"):
return False, "platform not supported"
temps = psutil.sensors_temperatures()
if not temps:
return False, "can't read any temperature"
for name, entries in temps.items():
for entry in entries:
return True, entry.label
# print("%-20s %s °C (high = %s °C, critical = %s °C)" % (
# entry.label or name, entry.current, entry.high,
# entry.critical))
return False, ""
def getSystemVersion(self):
#
# 取操作系统版本
current_os = mw.getOs()
# sys_temper = self.getSystemDeviceTemperature()
# print(sys_temper)
# mac
if current_os == 'darwin':
data = mw.execShell('sw_vers')[0]
data_list = data.strip().split("\n")
mac_version = ''
for x in data_list:
xlist = x.split("\t")
mac_version += xlist[len(xlist)-1] + ' '
arch_ver = mw.execShell("arch")
return mac_version + " (" + arch_ver[0].strip() + ")"
# freebsd
if current_os.startswith('freebsd'):
version = mw.execShell(
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
arch_ver = mw.execShell(
"sysctl -a | egrep -i 'hw.machine_arch' | awk -F ':' '{print $2}'")
return version[0].strip() + " (" + arch_ver[0].strip() + ")"
redhat_series = '/etc/redhat-release'
if os.path.exists(redhat_series):
version = mw.readFile('/etc/redhat-release')
version = version.replace('release ', '').strip()
arch_ver = mw.execShell("arch")
return version + " (" + arch_ver[0].strip() + ")"
os_series = '/etc/os-release'
if os.path.exists(os_series):
version = mw.execShell(
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
arch_ver = mw.execShell("arch")
return version[0].strip() + " (" + arch_ver[0].strip() + ")"
return '未识别系统信息'
def getBootTime(self):
# 取系统启动时间
uptime = mw.readFile('/proc/uptime')
if uptime == False:
start_time = psutil.boot_time()
run_time = time.time() - start_time
else:
run_time = uptime.split()[0]
tStr = float(run_time)
min = tStr / 60
hours = min / 60
days = math.floor(hours / 24)
hours = math.floor(hours - (days * 24))
min = math.floor(min - (days * 60 * 24) - (hours * 60))
return mw.getInfo('已不间断运行: {1}天{2}小时{3}分钟', (str(int(days)), str(int(hours)), str(int(min))))
def getCpuInfo(self, interval=1):
# 取CPU信息
cpuCount = psutil.cpu_count()
cpuLogicalNum = psutil.cpu_count(logical=False)
used = psutil.cpu_percent(interval=interval)
cpuLogicalNum = 0
if os.path.exists('/proc/cpuinfo'):
c_tmp = mw.readFile('/proc/cpuinfo')
d_tmp = re.findall("physical id.+", c_tmp)
cpuLogicalNum = len(set(d_tmp))
used_all = psutil.cpu_percent(percpu=True)
cpu_name = mw.getCpuType() + " * {}".format(cpuLogicalNum)
return used, cpuCount, used_all, cpu_name, cpuCount, cpuLogicalNum
def getMemInfo(self):
# 取内存信息
mem = psutil.virtual_memory()
if mw.getOs() == 'darwin':
memInfo = {
'memTotal': mem.total,
}
memInfo['memRealUsed'] = memInfo['memTotal'] * (mem.percent / 100)
else:
memInfo = {
'memTotal': mem.total,
'memFree': mem.free,
'memBuffers': mem.buffers,
'memCached': mem.cached
}
memInfo['memRealUsed'] = memInfo['memTotal'] - \
memInfo['memFree'] - memInfo['memBuffers'] - \
memInfo['memCached']
return memInfo
def getMemUsed(self):
# 取内存使用率
try:
import psutil
mem = psutil.virtual_memory()
if mw.getOs() == 'darwin':
return mem.percent
memInfo = {'memTotal': mem.total / 1024 / 1024, 'memFree': mem.free / 1024 / 1024,
'memBuffers': mem.buffers / 1024 / 1024, 'memCached': mem.cached / 1024 / 1024}
tmp = memInfo['memTotal'] - memInfo['memFree'] - \
memInfo['memBuffers'] - memInfo['memCached']
tmp1 = memInfo['memTotal'] / 100
return (tmp / tmp1)
except Exception as ex:
return 1
def getDiskInfo(self):
info = self.getDiskInfo2()
if len(info) != 0:
return info
# 取磁盘分区信息
diskIo = psutil.disk_partitions()
diskInfo = []
for disk in diskIo:
if disk[1] == '/mnt/cdrom':
continue
if disk[1] == '/boot':
continue
tmp = {}
tmp['path'] = disk[1]
size_tmp = 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)
return diskInfo
def getDiskInfo2(self):
# 取磁盘分区信息
temp = mw.execShell(
"df -h -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
tempInodes = mw.execShell(
"df -i -P|grep '/'|grep -v tmpfs | grep -v devfs")[0]
temp1 = temp.split('\n')
tempInodes1 = tempInodes.split('\n')
diskInfo = []
n = 0
cuts = ['/mnt/cdrom', '/boot', '/boot/efi', '/dev',
'/dev/shm', '/zroot', '/run/lock', '/run', '/run/shm', '/run/user']
for tmp in temp1:
n += 1
inodes = tempInodes1[n - 1].split()
disk = tmp.split()
if len(disk) < 5:
continue
if disk[1].find('M') != -1:
continue
if disk[1].find('K') != -1:
continue
if len(disk[5].split('/')) > 4:
continue
if disk[5] in cuts:
continue
arr = {}
arr['path'] = disk[5]
tmp1 = [disk[1], disk[2], disk[3], disk[4]]
arr['size'] = tmp1
arr['inodes'] = [inodes[1], inodes[2], inodes[3], inodes[4]]
diskInfo.append(arr)
return diskInfo
# 清理系统垃圾
def clearSystem(self, get):
count = total = 0
tmp_total, tmp_count = self.ClearMail()
count += tmp_count
total += tmp_total
tmp_total, tmp_count = self.ClearOther()
count += tmp_count
total += tmp_total
return count, total
# 清理邮件日志
def clearMail(self):
rpath = '/var/spool'
total = count = 0
import shutil
con = ['cron', 'anacron', 'mail']
for d in os.listdir(rpath):
if d in con:
continue
dpath = rpath + '/' + d
time.sleep(0.2)
num = size = 0
for n in os.listdir(dpath):
filename = dpath + '/' + n
fsize = os.path.getsize(filename)
size += fsize
if os.path.isdir(filename):
shutil.rmtree(filename)
else:
os.remove(filename)
# print('mail clear ok')
num += 1
total += size
count += num
return total, count
# 清理其它
def clearOther(self):
clearPath = [
{'path': '/www/server/mdserver-web', 'find': 'testDisk_'},
{'path': '/www/wwwlogs', 'find': 'log'},
{'path': '/tmp', 'find': 'panelBoot.pl'},
{'path': '/www/server/mdserver-web/install', 'find': '.rpm'}
]
total = count = 0
for c in clearPath:
for d in os.listdir(c['path']):
if d.find(c['find']) == -1:
continue
filename = c['path'] + '/' + d
fsize = os.path.getsize(filename)
total += fsize
if os.path.isdir(filename):
shutil.rmtree(filename)
else:
os.remove(filename)
count += 1
mw.restartWeb()
os.system('echo > /tmp/panelBoot.pl')
return total, count
def psutilNetIoCounters(self):
'''
统计网卡流量
'''
stat_pl = 'data/only_netio_counters.pl'
if os.path.exists(stat_pl):
local_lo = (0, 0, 0, 0)
ioName = psutil.net_io_counters(pernic=True).keys()
for x in ioName:
if x.find("lo") > -1:
local_lo = psutil.net_io_counters(
pernic=True).get(x)[:4]
all_io = psutil.net_io_counters()[:4]
result_io = tuple([all_io[i] - local_lo[i]
for i in range(0, len(all_io))])
# print(local_lo)
# print(all_io)
# print(result_io)
return result_io
return psutil.net_io_counters()[:4]
def getNetWork(self):
# 取网络流量信息
try:
networkInfo = {}
# 取网络流量信息
# networkIo = self.psutilNetIoCounters()
# if not "otime" in session:
# session['up'] = networkIo[0]
# session['down'] = networkIo[1]
# session['otime'] = time.time()
# ntime = time.time()
# print("source",ntime - session['otime'])
# networkInfo['upTotal'] = networkIo[0]
# networkInfo['downTotal'] = networkIo[1]
# networkInfo['up'] = round(float(
# networkIo[0] - session['up']) / (ntime - session['otime']), 2)
# networkInfo['down'] = round(
# float(networkIo[1] - session['down']) / (ntime - session['otime']), 2)
# networkInfo['downPackets'] = networkIo[3]
# networkInfo['upPackets'] = networkIo[2]
# # print networkIo[1], session['down'], ntime, session['otime']
# session['up'] = networkIo[0]
# session['down'] = networkIo[1]
# session['otime'] = time.time()
networkInfo['cpu'] = self.getCpuInfo()
networkInfo['load'] = self.getLoadAverage()
networkInfo['mem'] = self.getMemInfo()
networkInfo['iostat'] = self.getDiskIostat()
networkInfo['network'] = self.getNetWorkIostat()
return networkInfo
except Exception as e:
print(mw.getTracebackInfo())
return None
def getNetWorkIostat(self):
netInfo = {}
netInfo['ALL'] = {}
netInfo['ALL']['up'] = 0
netInfo['ALL']['down'] = 0
netInfo['ALL']['upTotal'] = 0
netInfo['ALL']['downTotal'] = 0
netInfo['ALL']['upPackets'] = 0
netInfo['ALL']['downPackets'] = 0
mtime = time.time()
iokey = 'netstat'
netio = None
if iokey in self.cache:
netio = self.cache[iokey]
if not netio:
netio = {}
netio['info'] = None
netio['all_io'] = None
netio['time'] = mtime
stime = mtime - netio['time']
if not stime: stime = 1
# print("new:",stime)
netio_group = psutil.net_io_counters(pernic=True).keys()
netio_cache = netio['info']
allio_cache = netio['all_io']
if not netio_cache:
netio_cache = {}
netio_group_t = {}
for name in netio_group:
netInfo[name] = {}
io_data = psutil.net_io_counters(pernic=True).get(name)
if not name in netio_cache:
netio_cache[name] = io_data
netio_group_t[name] = io_data
netInfo[name]['up'] = round(float((io_data[0] - netio_cache[name][0]) / stime), 2)
netInfo[name]['down'] = round(float((io_data[1] - netio_cache[name][1])/ stime), 2)
netInfo[name]['upTotal'] = io_data[0]
netInfo[name]['downTotal'] = io_data[1]
netInfo[name]['upPackets'] = io_data[2]
netInfo[name]['downPackets'] = io_data[3]
all_io = psutil.net_io_counters()[:4]
if not allio_cache:
allio_cache = all_io
netInfo['ALL']['up'] = round(float((all_io[0] - allio_cache[0]) /stime), 2)
netInfo['ALL']['down'] = round(float((all_io[1] - allio_cache[1]) /stime), 2)
netInfo['ALL']['upTotal'] = all_io[0]
netInfo['ALL']['downTotal'] = all_io[1]
netInfo['ALL']['upPackets'] = all_io[2]
netInfo['ALL']['downPackets'] = all_io[3]
self.cache[iokey] = {'info':netio_group_t,'all_io':all_io,'time':mtime}
return netInfo
def getDiskIostat(self):
iokey = 'iostat'
diskInfo = {}
diskInfo['ALL'] = {}
diskInfo['ALL']['read_count'] = 0
diskInfo['ALL']['write_count'] = 0
diskInfo['ALL']['read_bytes'] = 0
diskInfo['ALL']['write_bytes'] = 0
diskInfo['ALL']['read_time'] = 0
diskInfo['ALL']['write_time'] = 0
diskInfo['ALL']['read_merged_count'] = 0
diskInfo['ALL']['write_merged_count'] = 0
try:
diskio = None
if iokey in self.cache:
diskio = self.cache[iokey]
mtime = int(time.time())
if not diskio:
diskio = {}
diskio['info'] = None
diskio['time'] = mtime
diskio_cache = diskio['info']
stime = mtime - diskio['time']
if not stime: stime = 1
diskio_group = psutil.disk_io_counters(perdisk=True)
if not diskio_cache:
diskio_cache = diskio_group
for disk_name in diskio_group.keys():
diskInfo[disk_name] = {}
# print('disk_name',disk_name)
# print(diskio_group[disk_name].write_time , diskio_cache[disk_name].write_time)
# print(diskio_group[disk_name].write_count , diskio_cache[disk_name].write_count)
diskInfo[disk_name]['read_count'] = int((diskio_group[disk_name].read_count - diskio_cache[disk_name].read_count) / stime)
diskInfo[disk_name]['write_count'] = int((diskio_group[disk_name].write_count - diskio_cache[disk_name].write_count) / stime)
diskInfo[disk_name]['read_bytes'] = int((diskio_group[disk_name].read_bytes - diskio_cache[disk_name].read_bytes) / stime)
diskInfo[disk_name]['write_bytes'] = int((diskio_group[disk_name].write_bytes - diskio_cache[disk_name].write_bytes) / stime)
diskInfo[disk_name]['read_time'] = int((diskio_group[disk_name].read_time - diskio_cache[disk_name].read_time) / stime)
diskInfo[disk_name]['write_time'] = int((diskio_group[disk_name].write_time - diskio_cache[disk_name].write_time) / stime)
if 'read_merged_count' in diskio_group[disk_name] and 'read_merged_count' in diskio_cache[disk_name]:
diskInfo[disk_name]['read_merged_count'] = int((diskio_group[disk_name].read_merged_count - diskio_cache[disk_name].read_merged_count) / stime)
if 'write_merged_count' in diskio_group[disk_name] and 'write_merged_count' in diskio_cache[disk_name]:
diskInfo[disk_name]['write_merged_count'] = int((diskio_group[disk_name].write_merged_count - diskio_cache[disk_name].write_merged_count) / stime)
diskInfo['ALL']['read_count'] += diskInfo[disk_name]['read_count']
diskInfo['ALL']['write_count'] += diskInfo[disk_name]['write_count']
diskInfo['ALL']['read_bytes'] += diskInfo[disk_name]['read_bytes']
diskInfo['ALL']['write_bytes'] += diskInfo[disk_name]['write_bytes']
if diskInfo['ALL']['read_time'] < diskInfo[disk_name]['read_time']:
diskInfo['ALL']['read_time'] = diskInfo[disk_name]['read_time']
if diskInfo['ALL']['write_time'] < diskInfo[disk_name]['write_time']:
diskInfo['ALL']['write_time'] = diskInfo[disk_name]['write_time']
if 'read_merged_count' in diskInfo[disk_name] and 'read_merged_count' in diskInfo[disk_name]:
diskInfo['ALL']['read_merged_count'] += diskInfo[disk_name]['read_merged_count']
if 'write_merged_count' in diskInfo[disk_name] and 'write_merged_count' in diskInfo[disk_name]:
diskInfo['ALL']['write_merged_count'] += diskInfo[disk_name]['write_merged_count']
self.cache[iokey] = {'info':diskio_group,'time':mtime}
except Exception as e:
pass
return diskInfo
def getNetWorkIoData(self, start, end):
# 取指定时间段的网络Io
data = mw.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()
return self.toAddtime(data)
def getDiskIoData(self, start, end):
# 取指定时间段的磁盘Io
data = mw.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()
return self.toAddtime(data)
def getCpuIoData(self, start, end):
# 取指定时间段的CpuIo
data = mw.M('cpuio').dbfile('system').where("addtime>=? AND addtime<=?",
(start, end)).field('id,pro,mem,addtime').order('id asc').select()
return self.toAddtime(data, True)
def getLoadAverageData(self, start, end):
data = mw.M('load_average').dbfile('system').where("addtime>=? AND addtime<=?", (
start, end)).field('id,pro,one,five,fifteen,addtime').order('id asc').select()
return self.toAddtime(data)
# 格式化addtime列
def toAddtime(self, data, tomem=False):
import time
if tomem:
import psutil
mPre = (psutil.virtual_memory().total / 1024 / 1024) / 100
length = len(data)
he = 1
if length > 100:
he = 1
if length > 1000:
he = 3
if length > 10000:
he = 15
if he == 1:
for i in range(length):
data[i]['addtime'] = time.strftime(
'%m/%d %H:%M', time.localtime(float(data[i]['addtime'])))
if tomem and data[i]['mem'] > 100:
data[i]['mem'] = data[i]['mem'] / mPre
return data
else:
count = 0
tmp = []
for value in data:
if count < he:
count += 1
continue
value['addtime'] = time.strftime(
'%m/%d %H:%M', time.localtime(float(value['addtime'])))
if tomem and value['mem'] > 100:
value['mem'] = value['mem'] / mPre
tmp.append(value)
count = 0
return tmp
def setControl(self, stype, day):
filename = 'data/control.conf'
stat_pl = 'data/only_netio_counters.pl'
if stype == '0':
mw.execShell("rm -rf " + filename)
elif stype == '1':
_day = int(day)
if _day < 1:
return mw.returnJson(False, "设置失败!")
mw.writeFile(filename, day)
elif stype == '2':
mw.execShell("rm -rf " + stat_pl)
elif stype == '3':
mw.execShell("echo 'True' > " + stat_pl)
elif stype == 'del':
if not mw.isRestart():
return mw.returnJson(False, '请等待所有安装任务完成再执行')
os.remove("data/system.db")
sql = db.Sql().dbfile('system')
csql = mw.readFile('data/sql/system.sql')
csql_list = csql.split(';')
for index in range(len(csql_list)):
sql.execute(csql_list[index], ())
return mw.returnJson(True, "监控服务已关闭")
else:
data = {}
if os.path.exists(filename):
try:
data['day'] = int(mw.readFile(filename))
except:
data['day'] = 30
data['status'] = True
else:
data['day'] = 30
data['status'] = False
if os.path.exists(stat_pl):
data['stat_all_status'] = True
else:
data['stat_all_status'] = False
return mw.getJson(data)
return mw.returnJson(True, "设置成功!")
def versionDiff(self, old, new):
'''
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:
context = ssl._create_unverified_context()
req = urllib.request.urlopen(upAddr, context=context, timeout=3)
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=''):
return mw.returnJson(False, '与后续版本差异太大,不再提供更新')
# 更新服务
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 not 'name' in version_new_info:
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')
update_env = '''
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
P_VER=`python3 -V | awk '{print $2}'`
if [ ! -f /www/server/mdserver-web/bin/activate ];then
cd /www/server/mdserver-web && python3 -m venv .
cd /www/server/mdserver-web && source /www/server/mdserver-web/bin/activate
else
cd /www/server/mdserver-web && source /www/server/mdserver-web/bin/activate
fi
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
PIPSRC="https://pypi.python.org/simple"
if [ ! -z "$cn" ];then
PIPSRC="https://pypi.tuna.tsinghua.edu.cn/simple"
fi
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/requirements.txt -i $PIPSRC
P_VER_D=`echo "$P_VER"|awk -F '.' '{print $1}'`
P_VER_M=`echo "$P_VER"|awk -F '.' '{print $2}'`
NEW_P_VER=${P_VER_D}.${P_VER_M}
if [ -f /www/server/mdserver-web/version/r${NEW_P_VER}.txt ];then
cd /www/server/mdserver-web && pip3 install -r /www/server/mdserver-web/version/r${NEW_P_VER}.txt -i $PIPSRC
fi
'''
os.system(update_env)
self.restartMw()
return mw.returnJson(True, '安装更新成功!')
return mw.returnJson(False, '已经是最新,无需更新!')
except Exception as ex:
# print('updateServer', ex)
return mw.returnJson(False, "连接服务器失败!" + str(ex))
# 修复面板
def repPanel(self, get):
vp = ''
if mw.readFile('/www/server/mdserver-web/class/common.py').find('checkSafe') != -1:
vp = '_pro'
mw.ExecShell("wget -O update.sh " + mw.get_url() +
"/install/update" + vp + ".sh && bash update.sh")
if hasattr(web.ctx.session, 'getCloudPlugin'):
del(web.ctx.session['getCloudPlugin'])
return True
-103
View File
@@ -1,103 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 任务页操作
# ---------------------------------------------------------------------------------
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from 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)
-143
View File
@@ -1,143 +0,0 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 验证码操作
# ---------------------------------------------------------------------------------
import random
import math
from PIL import Image, ImageDraw, ImageFont, ImageFilter
class vieCode:
__fontSize = 20 # 字体大小
__width = 120 # 画布宽度
__heigth = 45 # 画布高度
__length = 4 # 验证码长度
__draw = None # 画布
__img = None # 图片资源
__code = None # 验证码字符
__str = None # 自定义验证码字符集
__inCurve = True # 是否画干扰线
__inNoise = True # 是否画干扰点
__type = 2 # 验证码类型 1、纯字母 2、数字字母混合
__fontPatn = 'class/fonts/2.ttf' # 字体
def GetCodeImage(self, size=80, length=4):
'''获取验证码图片
@param int size 验证码大小
@param int length 验证码长度
'''
# 准备基础数据
self.__length = length
self.__fontSize = size
self.__width = self.__fontSize * self.__length
self.__heigth = int(self.__fontSize * 1.5)
# 生成验证码图片
self.__createCode()
self.__createImage()
self.__createNoise()
self.__printString()
self.__cerateFilter()
return self.__img, self.__code
def __cerateFilter(self):
'''模糊处理'''
self.__img = self.__img.filter(ImageFilter.BLUR)
filter = ImageFilter.ModeFilter(8)
self.__img = self.__img.filter(filter)
def __createCode(self):
'''创建验证码字符'''
# 是否自定义字符集合
if not self.__str:
# 源文本
number = "3456789"
srcLetter = "qwertyuipasdfghjkzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
srcUpper = srcLetter.upper()
if self.__type == 1:
self.__str = number
else:
self.__str = srcLetter + srcUpper + number
# 构造验证码
self.__code = random.sample(self.__str, self.__length)
def __createImage(self):
'''创建画布'''
bgColor = (random.randint(200, 255), random.randint(
200, 255), random.randint(200, 255))
self.__img = Image.new('RGB', (self.__width, self.__heigth), bgColor)
self.__draw = ImageDraw.Draw(self.__img)
def __createNoise(self):
'''画干扰点'''
if not self.__inNoise:
return
font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5))
for i in range(5):
# 杂点颜色
noiseColor = (random.randint(150, 200), random.randint(
150, 200), random.randint(150, 200))
putStr = random.sample(self.__str, 2)
for j in range(2):
# 绘杂点
size = (random.randint(-10, self.__width),
random.randint(-10, self.__heigth))
self.__draw.text(size, putStr[j], font=font, fill=noiseColor)
pass
def __createCurve(self):
'''画干扰线'''
if not self.__inCurve:
return
x = y = 0
# 计算曲线系数
a = random.uniform(1, self.__heigth / 2)
b = random.uniform(-self.__width / 4, self.__heigth / 4)
f = random.uniform(-self.__heigth / 4, self.__heigth / 4)
t = random.uniform(self.__heigth, self.__width * 2)
xend = random.randint(self.__width / 2, self.__width * 2)
w = (2 * math.pi) / t
# 画曲线
color = (random.randint(30, 150), random.randint(
30, 150), random.randint(30, 150))
for x in range(xend):
if w != 0:
for k in range(int(self.__heigth / 10)):
y = a * math.sin(w * x + f) + b + self.__heigth / 2
i = int(self.__fontSize / 5)
while i > 0:
px = x + i
py = y + i + k
self.__draw.point((px, py), color)
i -= i
def __printString(self):
'''打印验证码字符串'''
font = ImageFont.truetype(self.__fontPatn, self.__fontSize)
x = 0
# 打印字符到画板
for i in range(self.__length):
# 设置字体随机颜色
color = (random.randint(30, 150), random.randint(
30, 150), random.randint(30, 150))
# 计算座标
x = random.uniform(self.__fontSize * i * 0.95,
self.__fontSize * i * 1.1)
y = self.__fontSize * random.uniform(0.3, 0.5)
# 打印字符
self.__draw.text((x, y), self.__code[i], font=font, fill=color)
-48
View File
@@ -1,48 +0,0 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# VIP用户管理
# ---------------------------------------------------------------------------------
import mw
from flask import request
import requests
class vip_api:
api_url = 'https://wo.midoks.icu/api/wp-json/vip'
def __init__(self):
pass
def loginApi(self):
username = request.form.get('username', '')
password = request.form.get('password', '')
password = mw.aesEncrypt(password)
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
print("name:", str(username))
print("pwd:", str(password))
args = {
'name': username,
'pass': password
}
data = requests.post(self.api_url + '/v1/login',
data=args, headers=headers)
print(data.text)
return mw.returnJson(False, "测试中!")
BIN
View File
Binary file not shown.
View File
View File
-5
View File
@@ -1,5 +0,0 @@
- fcgi-client.py
```
https://pypi.org/project/flup6/1.1.1/#files
```
-140
View File
@@ -1,140 +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_TIMEOUT=1
__DB_SOCKET = '/www/server/mysql/mysql.sock'
__DB_CHARSET = "utf8"
def __Conn(self):
# print(self.__DB_HOST, self.__DB_USER, self.__DB_PASS, self.__DB_SOCKET)
'''连接数据库'''
try:
if self.__DB_HOST != 'localhost':
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=self.__DB_TIMEOUT,
cursorclass=pymysql.cursors.DictCursor)
except Exception as e:
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=self.__DB_TIMEOUT,
cursorclass=pymysql.cursors.DictCursor)
elif 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=self.__DB_TIMEOUT,
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=self.__DB_TIMEOUT,
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=self.__DB_TIMEOUT,
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=self.__DB_TIMEOUT,
cursorclass=pymysql.cursors.DictCursor)
self.__DB_CUR = self.__DB_CONN.cursor()
return True
except Exception as e:
self.__DB_ERR = e
return False
def setDbConf(self, conf):
self.__DB_CNF = conf
def setSocket(self, sock):
self.__DB_SOCKET = sock
def setCharset(self, charset):
self.__DB_CHARSET = charset
def setHost(self, host):
self.__DB_HOST = host
def setPort(self, port):
self.__DB_PORT = port
def setUser(self, user):
self.__DB_USER = user
def setPwd(self, pwd):
self.__DB_PASS = pwd
def getPwd(self):
return self.__DB_PASS
def setTimeout(self, timeout = 1):
self.__DB_TIMEOUT = timeout
return True
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 ping(self):
try:
self.__DB_CONN.ping()
except Exception as e:
print(e)
return True
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()
-115
View File
@@ -1,115 +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 setDbName(self, name):
self.__DB_NAME = name
def setUser(self, user):
self.__DB_USER = user
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()
+40 -31
View File
@@ -3,31 +3,31 @@ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/hom
DIR=$(cd "$(dirname "$0")"; pwd)
MDIR=$(dirname "$DIR")
export LC_ALL="en_US.UTF-8"
# echo $DIR
PATH=$PATH:$DIR/bin
if [ -f bin/activate ];then
source bin/activate
if [ -f ${DIR}/bin/activate ];then
source ${DIR}/bin/activate
if [ "$?" != "0" ];then
echo "load local python env fail!"
fi
fi
export LC_ALL="en_US.UTF-8"
mw_start_task()
{
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
isStart=$(ps aux |grep 'panel_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 &
cd $DIR && python3 panel_task.py >> ${DIR}/logs/panel_task.log 2>&1 &
sleep 0.3
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
isStart=$(ps aux |grep 'panel_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
tail -n 20 $DIR/logs/panel_task.log
echo '------------------------------------------------------'
echo -e "\033[31mError: mw-tasks service startup failed.\033[0m"
return;
@@ -39,34 +39,44 @@ mw_start_task()
}
mw_start(){
gunicorn -c setting.py app:app
#安全启动
# 后台任务
mw_start_task
cd ${DIR}/web && gunicorn -c setting.py app:app
}
mw_start_debug(){
if [ ! -f $DIR/logs/task.log ];then
echo '' > $DIR/logs/task.log
if [ ! -f $DIR/logs/panel_task.log ];then
echo '' > $DIR/logs/panel_task.log
fi
python3 task.py >> $DIR/logs/task.log 2>&1 &
port=7200
python3 panel_task.py >> $DIR/logs/panel_task.log 2>&1 &
port=7200
if [ -f /www/server/mdserver-web/data/port.pl ];then
port=$(cat /www/server/mdserver-web/data/port.pl)
fi
# gunicorn -b :${port} -k gevent -w 1 app:app
gunicorn -b :${port} -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 app:app
if [ -f ${DIR}/data/port.pl ];then
port=$(cat ${DIR}/data/port.pl)
fi
cd ${DIR}/web && gunicorn -b :${port} -k eventlet -w 1 app:app
# cd ${DIR}/web && gunicorn -b :${port} -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -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_start_panel(){
port=7200
if [ -f ${DIR}/data/port.pl ];then
port=$(cat ${DIR}/data/port.pl)
fi
cd ${DIR}/web && gunicorn -b :${port} -k eventlet -w 1 app:app
# cd ${DIR}/web && gunicorn -b :${port} -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 app:app
}
mw_start_debug3(){
gunicorn -c setting.py app:app
python3 task.py
mw_start_bgtask(){
cd ${DIR}/web && gunicorn -c setting.py app:app
cd ${DIR} && python3 panel_task.py
}
@@ -78,9 +88,8 @@ mw_stop()
kill -9 $i > /dev/null 2>&1
done
pids=`ps -ef|grep task.py | grep -v grep |awk '{print $2}'`
arr=($pids)
for p in ${arr[@]}
PIDS=`ps -ef|grep panel_task.py | grep -v grep |awk '{print $2}'`
for p in $PIDS
do
kill -9 $p > /dev/null 2>&1
done
@@ -97,12 +106,12 @@ case "$1" in
mw_stop
mw_start_debug
;;
'debug2')
'panel')
mw_stop
mw_start_debug2
mw_start_panel
;;
'debug3')
mw_stop
mw_start_debug3
'task')
# mw_stop
mw_start_bgtask
;;
esac
+18 -18
View File
@@ -29,24 +29,24 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |PHP82 |PHP83 |
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 12 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |PHP82 |PHP83 |PHP84 |
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 12 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
+4
View File
@@ -0,0 +1,4 @@
# 自动生成
certificate.pem - 证书信息
privateKey.pem - 私钥
-1
View File
@@ -1 +0,0 @@
30
-42
View File
@@ -1,42 +0,0 @@
[
{
"title":"全部",
"type":0,
"ps":""
},
{
"title":"已安装",
"type":-1,
"ps":""
},
{
"title":"运行环境",
"type":1,
"ps":""
},
{
"title":"数据软件",
"type":2,
"ps":""
},
{
"title":"代码管理",
"type":3,
"ps":""
},
{
"title":"系统工具",
"type":4,
"ps":""
},
{
"title":"其他插件",
"type":5,
"ps":""
},
{
"title":"辅助插件",
"type":6,
"ps":""
}
]
-1
View File
@@ -1 +0,0 @@
True
-1
View File
@@ -1 +0,0 @@
存放VIP关键数据
+1 -1
View File
@@ -40,7 +40,7 @@ RUN apt update -y && \
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 && \
bash install.sh install 1.21.4 && \
cd /www/server/mdserver-web/plugins/mysql && \
bash install.sh install 5.6 && \
cd /www/server/mdserver-web/plugins/phpmyadmin && \
+1
View File
@@ -0,0 +1 @@
logs
-113
View File
@@ -1,113 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin:/opt/homebrew/bin
DIR=$(cd "$(dirname "$0")"; pwd)
MDIR=$(dirname "$DIR")
# echo $DIR
PATH=$PATH:$DIR/bin
if [ -f ${DIR}/bin/activate ];then
source ${DIR}/bin/activate
if [ "$?" != "0" ];then
echo "load local python env fail!"
fi
fi
export LC_ALL="en_US.UTF-8"
mw_start_task()
{
isStart=$(ps aux |grep 'panel_task.py'|grep -v grep|awk '{print $2}')
if [ "$isStart" == '' ];then
echo -e "starting mw-tasks... \c"
cd $DIR && python3 panel_task.py >> ${DIR}/logs/panel_task.log 2>&1 &
sleep 0.3
isStart=$(ps aux |grep 'panel_task.py'|grep -v grep|awk '{print $2}')
if [ "$isStart" == '' ];then
echo -e "\033[31mfailed\033[0m"
echo '------------------------------------------------------'
tail -n 20 $DIR/logs/panel_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(){
cd web && gunicorn -c setting.py app:app
#安全启动
mw_start_task
}
mw_start_debug(){
if [ ! -f $DIR/logs/panel_task.log ];then
echo '' > $DIR/logs/panel_task.log
fi
python3 panel_task.py >> $DIR/logs/panel_task.log 2>&1 &
port=7200
if [ -f /www/server/mdserver-web/data/port.pl ];then
port=$(cat /www/server/mdserver-web/data/port.pl)
fi
if [ -f ${DIR}/data/port.pl ];then
port=$(cat ${DIR}/data/port.pl)
fi
# gunicorn -b :${port} -k gevent -w 1 app:app
cd web && gunicorn -b :${port} -w 1 app:app
}
mw_start_debug2(){
python3 panel_task.py >> $DIR/logs/panel_task.log 2>&1 &
gunicorn -b :7200 -w 1 app:app
}
mw_start_debug3(){
gunicorn -c setting.py app:app
python3 panel_task.py
}
mw_stop()
{
PLIST=`ps -ef|grep app:app |grep -v grep|awk '{print $2}'`
for i in $PLIST
do
kill -9 $i > /dev/null 2>&1
done
pids=`ps -ef|grep panel_task.py | grep -v grep |awk '{print $2}'`
arr=($pids)
for p in ${arr[@]}
do
kill -9 $p > /dev/null 2>&1
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
;;
'debug3')
mw_stop
mw_start_debug3
;;
esac
+131 -398
View File
@@ -24,110 +24,28 @@ web_dir = os.getcwd() + "/web"
os.chdir(web_dir)
sys.path.append(web_dir)
from admin import app
from admin import model
import core.mw as mw
import core.db as db
import thisdb
from admin import setup
setup.init()
# print(mw.getPanelDir())
# print sys.path
# 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)
global pre, timeoutCount, logPath, isTask, oldEdate, isCheck
pre = 0
timeoutCount = 0
isCheck = 0
oldEdate = None
g_log_file = mw.getPanelTaskLog()
isTask = mw.getMWLogs() + '/panelTask.pl'
g_log_file = mw.getPanelTaskExecLog()
if not os.path.exists(g_log_file):
os.system("touch " + g_log_file)
def execShell(cmdstring, cwd=None, timeout=None, shell=True):
cmd = cmdstring + ' > ' + g_log_file + ' 2>&1'
return mw.execShell(cmd)
def writeLogs(data):
# 写输出日志
try:
global g_log_file
import shlex
import datetime
import subprocess
if timeout:
end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout)
cmd = cmdstring + ' > ' + g_log_file + ' 2>&1'
sub = subprocess.Popen(cmd, cwd=cwd, stdin=subprocess.PIPE, shell=shell, bufsize=4096)
while sub.poll() is None:
time.sleep(0.1)
data = sub.communicate()
# python3 fix 返回byte数据
if isinstance(data[0], bytes):
t1 = str(data[0], encoding='utf-8')
if isinstance(data[1], bytes):
t2 = str(data[1], encoding='utf-8')
return (t1, t2)
except Exception as e:
return (None, None)
def service_cmd(method):
cmd = '/etc/init.d/mw'
if os.path.exists(cmd):
execShell(cmd + ' ' + method)
return
cmd = mw.getRunDir() + '/scripts/init.d/mw'
if os.path.exists(cmd):
execShell(cmd + ' ' + method)
return
def openresty_cmd(method = 'reload'):
# 检查是否安装
odir = mw.getServerDir() + '/openresty'
if not os.path.exists(odir):
return False
# systemd
systemd = mw.systemdCfgDir()+'/openresty.service'
if os.path.exists(systemd):
execShell('systemctl ' + method + ' openresty')
return True
sys_initd = '/etc/init.d/openresty'
if os.path.exists(sys_initd):
os.system(sys_initd + ' ' + method)
return True
install_initd = mw.getServerDir()+'/openresty/init.d/openresty'
if os.path.exists(install_initd):
os.system(install_initd + ' ' + method)
return True
return False
def mw_async(f):
def wrapper(*args, **kwargs):
thr = threading.Thread(target=f, args=args, kwargs=kwargs)
thr.start()
return wrapper
@mw_async
def restartMw():
time.sleep(1)
cmd = mw.getRunDir() + '/scripts/init.d/mw reload &'
mw.execShell(cmd)
fp = open(g_log_file, 'w+')
fp.write(data)
fp.close()
except:
pass
def downloadFile(url, filename):
# 下载文件
@@ -146,257 +64,113 @@ def downloadFile(url, filename):
if not mw.isAppleSystem():
os.system('chown www.www ' + filename)
writeLogs('done')
writeLogs(filename + ' download success!')
except Exception as e:
writeLogs(str(e))
return True
def downloadHook(count, blockSize, totalSize):
# 下载文件进度回调
global pre
used = count * blockSize
pre1 = int((100.0 * used / totalSize))
if pre == (100 - pre1):
return
speed = {'total': totalSize, 'used': used, 'pre': pre1}
pre = int((100.0 * used / totalSize))
speed = {'total': totalSize, 'used': used, 'pre': pre}
writeLogs(json.dumps(speed))
def writeLogs(data):
# 写输出日志
try:
fp = open(g_log_file, 'w+')
fp.write(data)
fp.close()
except:
pass
def runPanelTask():
try:
bash_list = model.getTaskList(status=-1)
for task in bash_list:
model.setTaskStatus(task['id'], 0)
run_list = model.getTaskList(status=0)
for run_task in run_list:
start = int(time.time())
model.setTaskData(run_task['id'], start=start)
model.setTaskStatus(run_task['id'], -1)
if run_task['type'] == 'download':
argv = run_task['cmd'].split('|mw|')
downloadFile(argv[0], argv[1])
elif run_task['type'] == 'execshell':
execShell(run_task['cmd'])
end = int(time.time())
model.setTaskData(run_task['id'], end=end)
model.setTaskStatus(run_task['id'], 1)
except Exception as e:
print(str(e))
# 站点过期检查
# siteEdate()
siteEdateCheck()
lock_file = mw.getTriggerTaskLockFile()
try:
if os.path.exists(lock_file):
bash_list = thisdb.getTaskList(status=-1)
for task in bash_list:
thisdb.setTaskStatus(task['id'], 0)
run_list = thisdb.getTaskList(status=0)
for run_task in run_list:
start = int(time.time())
thisdb.setTaskData(run_task['id'], start=start)
thisdb.setTaskStatus(run_task['id'], -1)
if run_task['type'] == 'download':
argv = run_task['cmd'].split('|mw|')
downloadFile(argv[0], argv[1])
elif run_task['type'] == 'execshell':
execShell(run_task['cmd'])
end = int(time.time())
thisdb.setTaskData(run_task['id'], end=end)
thisdb.setTaskStatus(run_task['id'], 1)
if thisdb.getTaskUnexecutedCount() < 1:
os.remove(lock_file)
except Exception as e:
print('runPanelTask:',mw.getTracebackInfo())
# 网站到期处理
def siteEdateCheck():
try:
from utils.site import sites as MwSites
website_edate = thisdb.getOption('website_edate', default='0000-00-00')
now_time_ymd = time.strftime('%Y-%m-%d', time.localtime())
if website_edate == now_time_ymd:
return False
site_list = thisdb.getSitesEdateList(now_time_ymd)
for site in site_list:
MwSites.instance().stop(site['id'])
thisdb.setOption('website_edate', now_time_ymd)
except Exception as e:
print('siteEdateCheck:',mw.getTracebackInfo())
# 任务队列
def startPanelTask():
try:
while True:
runPanelTask()
time.sleep(1)
time.sleep(5)
except Exception as e:
print(str(e))
time.sleep(10)
print('startPanelTask:',mw.getTracebackInfo())
time.sleep(30)
startPanelTask()
# 网站到期处理
def siteEdate():
global oldEdate
try:
if not oldEdate:
oldEdate = mw.readFile('data/edate.pl')
if not oldEdate:
oldEdate = '0000-00-00'
mEdate = time.strftime('%Y-%m-%d', time.localtime())
if oldEdate == mEdate:
return False
edateSites = mw.M('sites').where('edate>? AND edate<? AND (status=? OR status=?)',
('0000-00-00', mEdate, 1, '正在运行')).field('id,name').select()
import site_api
for site in edateSites:
site_api.site_api().stop(site['id'], site['name'])
oldEdate = mEdate
mw.writeFile('data/edate.pl', mEdate)
except Exception as e:
print(str(e))
def systemTask():
# 系统监控任务
from utils.system import monitor
try:
import system_api
import psutil
sm = system_api.system_api()
filename = 'data/control.conf'
sql = db.Sql().dbfile('system')
csql = mw.readFile('data/sql/system.sql')
csql_list = csql.split(';')
for index in range(len(csql_list)):
sql.execute(csql_list[index], ())
cpuIo = cpu = {}
cpuCount = psutil.cpu_count()
used = count = 0
reloadNum = 0
network_up = network_down = diskio_1 = diskio_2 = networkInfo = cpuInfo = diskInfo = None
while True:
if not os.path.exists(filename):
time.sleep(10)
continue
day = 30
try:
day = int(mw.readFile(filename))
if day < 1:
time.sleep(10)
continue
except:
day = 30
tmp = {}
# 取当前CPU Io
tmp['used'] = psutil.cpu_percent(interval=1)
if tmp['used'] > 80:
panel_title = mw.getConfig('title')
ip = mw.getHostAddr()
now_time = mw.getDateFromNow()
msg = now_time + '|节点[' + panel_title + ':' + ip + \
']处于高负载[' + str(tmp['used']) + '],请排查原因!'
mw.notifyMessage(msg, '面板监控', 600)
if not cpuInfo:
tmp['mem'] = sm.getMemUsed()
cpuInfo = tmp
if cpuInfo['used'] < tmp['used']:
tmp['mem'] = sm.getMemUsed()
cpuInfo = tmp
# 取当前网络Io
networkIo = sm.psutilNetIoCounters()
if not network_up:
network_up = networkIo[0]
network_down = networkIo[1]
tmp = {}
tmp['upTotal'] = networkIo[0]
tmp['downTotal'] = networkIo[1]
tmp['up'] = round(float((networkIo[0] - network_up) / 1024), 2)
tmp['down'] = round(float((networkIo[1] - network_down) / 1024), 2)
tmp['downPackets'] = networkIo[3]
tmp['upPackets'] = networkIo[2]
network_up = networkIo[0]
network_down = networkIo[1]
if not networkInfo:
networkInfo = tmp
if (tmp['up'] + tmp['down']) > (networkInfo['up'] + networkInfo['down']):
networkInfo = tmp
# 取磁盘Io
# if os.path.exists('/proc/diskstats'):
diskio_2 = psutil.disk_io_counters()
if not diskio_1:
diskio_1 = diskio_2
tmp = {}
tmp['read_count'] = diskio_2.read_count - diskio_1.read_count
tmp['write_count'] = diskio_2.write_count - diskio_1.write_count
tmp['read_bytes'] = diskio_2.read_bytes - diskio_1.read_bytes
tmp['write_bytes'] = diskio_2.write_bytes - diskio_1.write_bytes
tmp['read_time'] = diskio_2.read_time - diskio_1.read_time
tmp['write_time'] = diskio_2.write_time - diskio_1.write_time
if not diskInfo:
diskInfo = tmp
else:
diskInfo['read_count'] += tmp['read_count']
diskInfo['write_count'] += tmp['write_count']
diskInfo['read_bytes'] += tmp['read_bytes']
diskInfo['write_bytes'] += tmp['write_bytes']
diskInfo['read_time'] += tmp['read_time']
diskInfo['write_time'] += tmp['write_time']
diskio_1 = diskio_2
# print diskInfo
if count >= 12:
try:
addtime = int(time.time())
deltime = addtime - (day * 86400)
data = (cpuInfo['used'], cpuInfo['mem'], addtime)
sql.table('cpuio').add('pro,mem,addtime', data)
sql.table('cpuio').where("addtime<?", (deltime,)).delete()
data = (networkInfo['up'] / 5, networkInfo['down'] / 5, networkInfo['upTotal'], networkInfo[
'downTotal'], networkInfo['downPackets'], networkInfo['upPackets'], addtime)
sql.table('network').add(
'up,down,total_up,total_down,down_packets,up_packets,addtime', data)
sql.table('network').where(
"addtime<?", (deltime,)).delete()
# if os.path.exists('/proc/diskstats'):
data = (diskInfo['read_count'], diskInfo['write_count'], diskInfo['read_bytes'], diskInfo[
'write_bytes'], diskInfo['read_time'], diskInfo['write_time'], addtime)
sql.table('diskio').add(
'read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime', data)
sql.table('diskio').where(
"addtime<?", (deltime,)).delete()
# LoadAverage
load_average = sm.getLoadAverage()
lpro = round(
(load_average['one'] / load_average['max']) * 100, 2)
if lpro > 100:
lpro = 100
sql.table('load_average').add('pro,one,five,fifteen,addtime', (lpro, load_average[
'one'], load_average['five'], load_average['fifteen'], addtime))
lpro = None
load_average = None
cpuInfo = None
networkInfo = None
diskInfo = None
count = 0
reloadNum += 1
if reloadNum > 1440:
reloadNum = 0
mw.writeFile('logs/sys_interrupt.pl',
"reload num:" + str(reloadNum))
restartMw()
except Exception as ex:
print(str(ex))
mw.writeFile('logs/sys_interrupt.pl', str(ex))
del(tmp)
monitor.instance().run()
time.sleep(5)
count += 1
except Exception as ex:
print(str(ex))
mw.writeFile('logs/sys_interrupt.pl', str(ex))
restartMw()
print('systemTask:',mw.getTracebackInfo())
time.sleep(30)
systemTask()
def panelPluginStatusCheck():
# 系统监控任务
from utils.plugin import plugin
try:
while True:
# start_t = time.time()
plugin.instance().autoCachePluginStatus()
# end_t = time.time()
time.sleep(60)
except Exception as ex:
print('panelPluginStatusCheck:',mw.getTracebackInfo())
time.sleep(120)
panelPluginStatusCheck()
# -------------------------------------- PHP监控 start --------------------------------------------- #
# 502错误检查线程
def check502Task():
try:
check_file = mw.getPanelDir() + '/data/502Task.pl'
while True:
if os.path.exists(mw.getPanelDir() + '/data/502Task.pl'):
if os.path.exists(check_file):
check502()
time.sleep(30)
time.sleep(10)
except:
time.sleep(30)
check502Task()
@@ -410,8 +184,8 @@ def check502():
'82', '83', '84'
]
for ver in verlist:
sdir = mw.getServerDir()
php_path = sdir + '/php/' + ver + '/sbin/php-fpm'
server_dir = mw.getServerDir()
php_path = server_dir + '/php/' + ver + '/sbin/php-fpm'
if not os.path.exists(php_path):
continue
if checkPHPVersion(ver):
@@ -419,13 +193,14 @@ def check502():
if startPHPVersion(ver):
print('检测到PHP-' + ver + '处理异常,已自动修复!')
mw.writeLog('PHP守护程序', '检测到PHP-' + ver + '处理异常,已自动修复!')
except Exception as e:
print(str(e))
mw.writeLog('PHP守护程序', '自动修复异常:'+str(e))
# 处理指定PHP版本
def startPHPVersion(version):
sdir = mw.getServerDir()
server_dir = mw.getServerDir()
try:
# system
phpService = mw.systemdCfgDir() + '/php' + version + '.service'
@@ -435,8 +210,8 @@ def startPHPVersion(version):
return True
# initd
fpm = sdir + '/php/init.d/php' + version
php_path = sdir + '/php/' + version + '/sbin/php-fpm'
fpm = server_dir + '/php/init.d/php' + version
php_path = server_dir + '/php/' + version + '/sbin/php-fpm'
if not os.path.exists(php_path):
if os.path.exists(fpm):
os.remove(fpm)
@@ -449,10 +224,9 @@ def startPHPVersion(version):
os.system(fpm + ' reload')
if checkPHPVersion(version):
return True
# 尝试重启服务
cgi = '/tmp/php-cgi-' + version + '.sock'
pid = sdir + '/php/' + version + '/var/run/php-fpm.pid'
pid = server_dir + '/php/' + version + '/var/run/php-fpm.pid'
data = mw.execShell("ps -ef | grep php/" + version +" | grep -v grep|grep -v python |awk '{print $2}'")
if data[0] != '':
os.system("ps -ef | grep php/" + version + " | grep -v grep|grep -v python |awk '{print $2}' | xargs kill ")
@@ -469,47 +243,19 @@ def startPHPVersion(version):
if os.path.exists(cgi):
return True
except Exception as e:
print(str(e))
print('startPHPVersion:',mw.getTracebackInfo())
mw.writeLog('PHP守护程序', '自动修复异常:'+str(e))
return True
def getFpmConfFile(version):
return mw.getServerDir() + '/php/' + version + '/etc/php-fpm.d/www.conf'
def getFpmAddress(version):
fpm_address = '/tmp/php-cgi-{}.sock'.format(version)
php_fpm_file = getFpmConfFile(version)
try:
content = readFile(php_fpm_file)
tmp = re.findall(r"listen\s*=\s*(.+)", content)
if not tmp:
return fpm_address
if tmp[0].find('sock') != -1:
return fpm_address
if tmp[0].find(':') != -1:
listen_tmp = tmp[0].split(':')
if bind:
fpm_address = (listen_tmp[0], int(listen_tmp[1]))
else:
fpm_address = ('127.0.0.1', int(listen_tmp[1]))
else:
fpm_address = ('127.0.0.1', int(tmp[0]))
return fpm_address
except:
return fpm_address
def checkPHPVersion(version):
# 检查指定PHP版本
try:
sock = getFpmAddress(version)
sock = mw.getFpmAddress(version)
data = mw.requestFcgiPHP(sock, '/phpfpm_status_' + version + '?json')
result = str(data, encoding='utf-8')
except Exception as e:
result = 'Bad Gateway'
# print(version,result)
# 检查openresty
if result.find('Bad Gateway') != -1:
return False
@@ -519,24 +265,9 @@ def checkPHPVersion(version):
# 检查Web服务是否启动
if result.find('Connection refused') != -1:
return False
# global isTask
# if os.path.exists(isTask):
# isStatus = mw.readFile(isTask)
# if isStatus == 'True':
# return True
# # systemd
# systemd = mw.systemdCfgDir() + '/openresty.service'
# if os.path.exists(systemd):
# execShell('systemctl reload openresty')
# return True
# # initd
# initd = '/etc/init.d/openresty'
# if os.path.exists(initd):
# os.system(initd + ' reload')
return True
# --------------------------------------PHP监控 end--------------------------------------------- #
# -------------------------------------- PHP监控 end --------------------------------------------- #
# --------------------------------------OpenResty Auto Restart Start --------------------------------------------- #
@@ -549,11 +280,10 @@ def openrestyAutoRestart():
if not os.path.exists(odir):
time.sleep(86400)
continue
openresty_cmd('reload')
mw.opWeb('reload')
time.sleep(86400)
except Exception as e:
print(str(e))
mw.writeLog('OpenResty检测', '自动修复异常:'+str(e))
time.sleep(86400)
# --------------------------------------OpenResty Auto Restart End --------------------------------------------- #
@@ -562,22 +292,23 @@ def openrestyAutoRestart():
def openrestyRestartAtOnce():
restart_nginx_tip = 'data/restart_nginx.pl'
restart_nginx_tip = mw.getPanelDir()+'/data/restart_nginx.pl'
while True:
if os.path.exists(restart_nginx_tip):
os.remove(restart_nginx_tip)
openresty_cmd('reload')
mw.opWeb('reload')
time.sleep(1)
# ----------------------------------- OpenResty Restart At Once End ------------------------------------------ #
# --------------------------------------Panel Restart Start --------------------------------------------- #
def restartPanelService():
restartTip = 'data/restart.pl'
restart_tip = mw.getPanelDir()+'/data/restart.pl'
while True:
if os.path.exists(restartTip):
os.remove(restartTip)
service_cmd('restart_panel')
if os.path.exists(restart_tip):
print("restart panel")
os.remove(restart_tip)
mw.panelCmd('restart_panel')
time.sleep(1)
# --------------------------------------Panel Restart End --------------------------------------------- #
@@ -590,37 +321,39 @@ def setDaemon(t):
return t
def run():
# # 系统监控
# sysTask = threading.Thread(target=systemTask)
# sysTask = setDaemon(sysTask)
# sysTask.start()
# 系统监控
sysTask = threading.Thread(target=systemTask)
sysTask = setDaemon(sysTask)
sysTask.start()
# # PHP 502错误检查线程
# php502 = threading.Thread(target=check502Task)
# php502 = setDaemon(php502)
# php502.start()
# PHP 502错误检查线程
php502 = threading.Thread(target=check502Task)
php502 = setDaemon(php502)
php502.start()
# # OpenResty Restart At Once Start
# oraos = threading.Thread(target=openrestyRestartAtOnce)
# oraos = setDaemon(oraos)
# oraos.start()
# OpenResty Restart At Once Start
oraos = threading.Thread(target=openrestyRestartAtOnce)
oraos = setDaemon(oraos)
oraos.start()
# OpenResty Auto Restart Start
oar = threading.Thread(target=openrestyAutoRestart)
oar = setDaemon(oar)
oar.start()
# # OpenResty Auto Restart Start
# oar = threading.Thread(target=openrestyAutoRestart)
# oar = setDaemon(oar)
# oar.start()
# Panel Plugin Status Check
pps = threading.Thread(target=panelPluginStatusCheck)
pps = setDaemon(pps)
pps.start()
# # Panel Restart Start
# rps = threading.Thread(target=restartPanelService)
# rps = setDaemon(rps)
# rps.start()
# Panel Restart Start
rps = threading.Thread(target=restartPanelService)
rps = setDaemon(rps)
rps.start()
# 面板后台任务
startPanelTask()
if __name__ == "__main__":
with app.app_context():
run()
run()
+174 -113
View File
@@ -23,13 +23,9 @@ web_dir = os.getcwd() + "/web"
os.chdir(web_dir)
sys.path.append(web_dir)
from utils.firewall import Firewall as MwFirewall
import core.mw as mw
import core.db as 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)
import thisdb
INIT_DIR = "/etc/rc.d/init.d"
if mw.isAppleSystem():
@@ -45,33 +41,54 @@ def mw_input_cmd(msg):
in_val = input(msg)
return in_val
def getRemainLen(cmd, max_length=100):
cmd_len = len(cmd)
cmd_u8_len = len(cmd.encode('utf-8'))
return max_length-int((cmd_u8_len - cmd_len)/2+cmd_len)
def mwcli(mw_input=0):
raw_tip = "======================================================"
panel_dir = mw.getPanelDir()
raw_tip = "========================================================================"
if not mw_input:
print("===============mdserver-web cli tools=================")
print("(1) 重启面板服务")
print("(2) 停止面板服务")
print("(3) 启动面板服务")
print("(4) 重载面板服务")
print("(5) 修改面板端口")
print("(10) 查看面板默认信息")
print("(11) 修改面板密码")
print("(12) 修改面板用户名")
print("(13) 显示面板错误日志")
print("(20) 关闭BasicAuth认证")
print("(21) 解除域名绑定")
print("(22) 解除面板SSL绑定")
print("(23) 开启IPV6支持")
print("(24) 关闭IPV6支持")
print("(25) 开启防火墙SSH端口")
print("(26) 关闭二次验证")
print("(27) 查看防火墙信息")
print("(100) 开启PHP52显示")
print("(101) 关闭PHP52显示")
print("(200) 切换Linux系统软件源")
print("(201) 简单速度测试")
print("(0) 取消")
print("========================mdserver-web cli tools==========================")
cmd_list = [
'(1) 重启面板服务',
'(2) 停止面板服务',
'(3) 启动面板服务',
'(4) 重载面板服务',
'(5) 修改面板端口',
'(10) 查看面板默认信息',
'(11) 修改面板密码',
'(12) 修改面板用户名',
'(13) 显示面板错误日志',
'(14) 关闭面板访问',
'(15) 开启面板访问',
'(20) 关闭BasicAuth认证',
'(21) 解除域名绑定',
'(22) 解除面板SSL绑定',
'(23) 开启IPV6支持',
'(24) 关闭IPV6支持',
'(25) 开启防火墙SSH端口',
'(26) 关闭二次验证',
'(27) 查看防火墙信息',
'(28) 自动识别防火墙端口到面板',
'(100) 开启PHP52显示',
'(101) 关闭PHP52显示',
'(200) 切换Linux系统软件源',
'(201) 简单速度测试',
'(0) 取消'
]
cmd_list_num = len(cmd_list)
for index in range(cmd_list_num):
cmd = cmd_list[index]
if index % 2 == 0:
if index == (cmd_list_num-1):
print(cmd)
else:
print(cmd + " " * getRemainLen(cmd, 40), end="")
if index % 2 == 1:
print(cmd)
print(raw_tip)
try:
mw_input = input("请输入命令编号:")
@@ -81,8 +98,8 @@ def mwcli(mw_input=0):
mw_input = 0
nums = [
1, 2, 3, 4, 5, 10, 11, 12, 13,
20, 21, 22, 23, 24, 25, 26, 27,
1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15,
20, 21, 22, 23, 24, 25, 26, 27, 28,
100, 101,
200, 201
]
@@ -103,72 +120,90 @@ def mwcli(mw_input=0):
in_port = mw_input_cmd("请输入新的面板端口:")
in_port_int = int(in_port.strip())
if in_port_int < 65536 and in_port_int > 0:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(
in_port, 'WEB面板[TOOLS修改]', 'port')
mw.writeFile('data/port.pl', in_port)
MwFirewall.instance().addAcceptPort(in_port, 'WEB面板[TOOLS修改]', 'port')
panel_port = panel_dir + '/data/port.pl'
mw.writeFile(panel_port, in_port)
os.system(INIT_CMD + " restart_panel")
os.system(INIT_CMD + " default")
else:
print("|-端口范围在0-65536之间")
mw.echoInfo("端口范围在0-65536之间")
return
elif mw_input == 10:
os.system(INIT_CMD + " default")
elif mw_input == 11:
input_pwd = mw_input_cmd("请输入新的面板密码:")
if len(input_pwd.strip()) < 5:
print("|-错误,密码长度不能小于5位")
mw.echoInfo("错误,密码长度不能小于5位")
return
set_panel_pwd(input_pwd.strip(), True)
elif mw_input == 12:
input_user = mw_input_cmd("请输入新的面板用户名(>=5位):")
set_panel_username(input_user.strip())
elif mw_input == 13:
os.system('tail -100 ' + mw.getPanelDir() + '/logs/error.log')
elif mw_input == 20:
basic_auth = 'data/basic_auth.json'
if os.path.exists(basic_auth):
os.remove(basic_auth)
os.system(INIT_CMD + " restart")
print("|-关闭basic_auth成功")
elif mw_input == 21:
bind_domain = 'data/bind_domain.pl'
if os.path.exists(bind_domain):
os.remove(bind_domain)
os.system(INIT_CMD + " unbind_domain")
print("|-解除域名绑定成功")
elif mw_input == 22:
ssl_choose = 'ssl/choose.pl'
if os.path.exists(ssl_choose):
os.remove(ssl_choose)
os.system(INIT_CMD + " unbind_ssl")
print("|-解除面板SSL绑定成功")
elif mw_input == 23:
listen_ipv6 = 'data/ipv6.pl'
if not os.path.exists(listen_ipv6):
mw.writeFile(listen_ipv6,'True')
os.system(INIT_CMD + " restart")
print("|-开启IPv6支持了")
os.system('tail -100 ' + panel_dir + '/logs/panel_error.log')
elif mw_input == 14:
admin_close = thisdb.getOption('admin_close')
if admin_close == 'no':
thisdb.setOption('admin_close', 'yes')
mw.echoInfo("关闭面板访问成功!")
else:
print("|-已开启IPv6支持!")
elif mw_input == 24:
listen_ipv6 = 'data/ipv6.pl'
mw.echoInfo("已关闭面板访问!")
elif mw_input == 15:
admin_close = thisdb.getOption('admin_close')
if admin_close == 'yes':
thisdb.setOption('admin_close', 'no')
mw.echoInfo("开启面板访问成功!")
else:
mw.echoInfo("已开启面板访问!")
elif mw_input == 20:
basic_auth = thisdb.getOptionByJson('basic_auth', default={'open':False})
if basic_auth['open']:
basic_auth['open'] = False
thisdb.setOption('basic_auth', json.dumps(basic_auth))
os.system(INIT_CMD + " restart")
mw.echoInfo("关闭basic_auth成功")
elif mw_input == 21:
panel_domain = thisdb.getOption('panel_domain', default='')
if panel_domain != '':
thisdb.setOption('panel_domain', '')
os.system(INIT_CMD + " unbind_domain")
mw.echoInfo("解除域名绑定成功")
else:
mw.echoInfo("面板未绑定域名!")
elif mw_input == 22:
panel_ssl = thisdb.getOptionByJson('panel_ssl', default={'open':False})
if panel_ssl['open']:
panel_ssl['open'] = False
thisdb.setOption('panel_ssl', json.dumps(panel_ssl))
os.system(INIT_CMD + " unbind_ssl")
mw.echoInfo("解除面板SSL绑定成功")
elif mw_input == 23:
listen_ipv6 = panel_dir + '/data/ipv6.pl'
if not os.path.exists(listen_ipv6):
print("|-已关闭IPv6支持!")
mw.writeFile(listen_ipv6, 'True')
os.system(INIT_CMD + " restart")
mw.echoInfo("开启IPv6支持了")
else:
mw.echoInfo("已开启IPv6支持!")
elif mw_input == 24:
listen_ipv6 = panel_dir + '/data/ipv6.pl'
if not os.path.exists(listen_ipv6):
mw.echoInfo("已关闭IPv6支持!")
else:
os.remove(listen_ipv6)
os.system(INIT_CMD + " restart")
print("|-关闭IPv6支持了")
mw.echoInfo("关闭IPv6支持了")
elif mw_input == 25:
open_ssh_port()
print("|-已开启!")
mw.echoInfo("已开启!")
elif mw_input == 26:
auth_secret = 'data/auth_secret.pl'
if os.path.exists(auth_secret):
os.remove(auth_secret)
print("|-关闭二次验证成功!")
two_step_verification = thisdb.getOptionByJson('two_step_verification', default={'open':False})
if two_step_verification['open']:
two_step_verification['open'] = False
thisdb.setOption('two_step_verification', json.dumps(two_step_verification))
mw.echoInfo("关闭二次验证成功!")
else:
print("|-二次验证已关闭!")
mw.echoInfo("二次验证已关闭!")
elif mw_input == 27:
cmd = 'which ufw'
run_cmd = False
@@ -184,22 +219,26 @@ def mwcli(mw_input=0):
os.system('firewall-cmd --list-all')
if not run_cmd:
mw.echoInfo("未检测到防火墙!")
elif mw_input == 28:
from utils.firewall import Firewall as MwFirewall
MwFirewall.instance().aIF()
mw.echoInfo("执行自动识别防火墙端口到面板成功!")
elif mw_input == 100:
php_conf = 'plugins/php/info.json'
php_conf = panel_dir + '/plugins/php/info.json'
if os.path.exists(php_conf):
cont = mw.readFile(php_conf)
cont = re.sub("\"53\"", "\"52\",\"53\"", cont)
cont = re.sub("\"5.3.29\"", "\"5.2.17\",\"5.3.29\"", cont)
mw.writeFile(php_conf, cont)
print("|-执行PHP52显示成功!")
mw.echoInfo("执行PHP52显示成功!")
elif mw_input == 101:
php_conf = 'plugins/php/info.json'
php_conf = panel_dir + '/plugins/php/info.json'
if os.path.exists(php_conf):
cont = mw.readFile(php_conf)
cont = re.sub("\"52\",", "", cont)
cont = re.sub("\"5.2.17\",", cont)
mw.writeFile(php_conf, cont)
print("|-执行PHP52隐藏成功!")
mw.echoInfo("执行PHP52隐藏成功!")
elif mw_input == 200:
os.system(INIT_CMD + " mirror")
elif mw_input == 201:
@@ -207,69 +246,65 @@ def mwcli(mw_input=0):
def open_ssh_port():
import firewall_api
find_ssh_port_cmd = "cat /etc/ssh/sshd_config | grep '^Port \\d*' | tail -1"
cmd_data = mw.execShell(find_ssh_port_cmd)
ssh_port = cmd_data[0].replace("Port ", '').strip()
if ssh_port == '':
ssh_port = '22'
print("|-SSH端口: "+ str(ssh_port))
firewall_api.firewall_api().addAcceptPortArgs(ssh_port, 'SSH远程管理服务', 'port')
mw.echoInfo("SSH端口: "+ str(ssh_port))
MwFirewall.instance().addAcceptPort(ssh_port, 'SSH远程管理服务', 'port')
return True
def set_panel_pwd(password, ncli=False):
# 设置面板密码
import db
sql = db.Sql()
result = sql.table('users').where('id=?', (1,)).setField(
'password', mw.md5(password))
username = sql.table('users').where('id=?', (1,)).getField('username')
info = thisdb.getUserByRoot()
thisdb.setUserByRoot(password=password)
if ncli:
print("|-用户名: " + username)
print("|-新密码: " + password)
mw.echoInfo("username: " + info['name'])
mw.echoInfo("password: " + password)
else:
print(username)
def show_panel_pwd():
# 设置面板密码
import db
sql = db.Sql()
password = sql.table('users').where('id=?', (1,)).getField('password')
# 面板密码展示
info = thisdb.getUserByRoot()
defailt_pwd_file = mw.getPanelDir()+'/data/default.pl'
pwd = ''
if os.path.exists(defailt_pwd_file):
pwd = mw.readFile(defailt_pwd_file).strip()
file_pwd = ''
if os.path.exists('data/default.pl'):
file_pwd = mw.readFile('data/default.pl').strip()
if mw.md5(file_pwd) == password:
print('password: ' + file_pwd)
if mw.md5(pwd) == info['password']:
mw.echoInfo('password: ' + pwd)
return
print("password has been changed!")
print("*-password has been changed!")
def show_panel_adminpath():
admin_path = thisdb.getOption('admin_path')
print('/'+admin_path)
def set_panel_username(username=None):
# 随机面板用户名
import db
sql = db.Sql()
if username:
if len(username) < 5:
print("|-错误,用户名长度不能少于5位")
mw.echoInfo("错误,用户名长度不能少于5位")
return
if username in ['admin', 'root']:
print("|-错误,不能使用过于简单的用户名")
mw.echoInfo("错误,不能使用过于简单的用户名")
return
sql.table('users').where('id=?', (1,)).setField('username', username)
print("|-新用户名: %s" % username)
thisdb.setUserByRoot(name=username)
mw.echoInfo("username: %s" % username)
return
username = sql.table('users').where('id=?', (1,)).getField('username')
if username == 'admin':
info = thisdb.getUserByRoot()
if info['name'] == 'admin':
username = mw.getRandomString(8).lower()
sql.table('users').where('id=?', (1,)).setField('username', username)
print('username: ' + username)
thisdb.setUserByRoot(name=username)
mw.echoInfo('username: ' + info['name'])
def getServerIp():
@@ -278,10 +313,25 @@ def getServerIp():
# "curl --insecure -{} -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text".format(version))
ip = mw.execShell(
"curl --insecure -{} -sS --connect-timeout 5 -m 60 https://ip.cachecha.com/?format=text".format(version))
print(ip[0])
# print(ip[0])
return ip[0]
if __name__ == "__main__":
def getPanelSslType():
scheme = 'http'
panel_ssl = thisdb.getOptionByJson('panel_ssl', default={'open':False})
if panel_ssl['open']:
scheme = 'https'
return scheme
def getPanelBindDomain():
return thisdb.getOption('panel_domain', default='')
def main():
if len(sys.argv) == 1:
print('ERROR: Parameter error!')
exit(-2)
method = sys.argv[1]
if method == 'panel':
set_panel_pwd(sys.argv[2])
@@ -292,8 +342,16 @@ if __name__ == "__main__":
set_panel_username()
elif method == 'password':
show_panel_pwd()
elif method == 'test':
thisdb.getOption('admin_path')
elif method == 'admin_path':
show_panel_adminpath()
elif method == 'getServerIp':
getServerIp()
print(getServerIp())
elif method == 'panel_ssl_type':
print(getPanelSslType())
elif method == 'panel_bind_domain':
print(getPanelBindDomain())
elif method == "cli":
clinum = 0
try:
@@ -304,3 +362,6 @@ if __name__ == "__main__":
mwcli(clinum)
else:
print('ERROR: Parameter error')
if __name__ == "__main__":
main()
+12 -9
View File
@@ -8,8 +8,12 @@ import re
import requests
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -127,7 +131,7 @@ def status():
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$SERVER_APP}', service_path + '/redis')
content = content.replace('{$REDIS_PASS}', mw.getRandomString(10))
@@ -163,7 +167,6 @@ def pSqliteDb(dbname='dnsapi'):
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
@@ -560,7 +563,7 @@ def runHookPy(domain,path):
# print(domain,path)
run_log = runLog()
hook_file = getConf()
cmd = 'cd '+mw.getRunDir()
cmd = 'cd '+mw.getPanelDir()
cmd += ' && python3 '+hook_file + ' ' + domain + ' ' + path
cmd += ' >> '+ run_log
print(cmd)
@@ -641,7 +644,7 @@ def getHookIdCmd():
if not data[0]:
return data[1]
cmd = "cd "+mw.getRunDir()+" "
cmd = "cd "+mw.getPanelDir()+" "
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_hook_id 1.0 {"id":"'+args['id']+'"}'
return mw.returnJson(True, 'ok',cmd)
@@ -658,7 +661,7 @@ def runHookId():
return 'run hook '+args['id']+' end'
def runHookCmd():
cmd = "cd "+mw.getRunDir()+" "
cmd = "cd "+mw.getPanelDir()+" "
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_hook'
return mw.returnJson(True, 'ok',cmd)
@@ -735,7 +738,7 @@ def runSyncCfData():
return ''
def runSyncCfCmd():
cmd = "cd "+mw.getRunDir()+" "
cmd = "cd "+mw.getPanelDir()+" "
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_sync_cf_data'
return mw.returnJson(True, 'ok',cmd)
@@ -788,7 +791,7 @@ def runSyncDnsPodData():
return ''
def runSyncDnsPodCmd():
cmd = "cd "+mw.getRunDir()+" "
cmd = "cd "+mw.getPanelDir()+" "
cmd += '&& python3 plugins/acme_pandominassl_apply/index.py run_sync_dnspod_data'
return mw.returnJson(True, 'ok',cmd)
+1 -2
View File
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
# curl https://get.acme.sh | sh
@@ -31,7 +30,7 @@ fi
# pip install cloudflare
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
mkdir -p $serverPath/acme_pandominassl_apply
echo "${VERSION}" > $serverPath/acme_pandominassl_apply/version.pl
+1 -1
View File
@@ -72,7 +72,7 @@ def createBgTaskByName(name):
import crontab_api
api = crontab_api.crontab_api()
mw_dir = mw.getRunDir()
mw_dir = mw.getPanelDir()
cmd = '''
mw_dir=%s
rname=%s
+36 -9
View File
@@ -5,9 +5,14 @@ import io
import os
import time
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -92,18 +97,40 @@ def readConfigTpl():
content = contentReplace(content)
return mw.returnJson(True, 'ok', content)
def __release_port(port, ps = '开启端口'):
try:
from utils.firewall import Firewall as MwFirewall
MwFirewall.instance().addAcceptPort(port, ps, 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
def __delete_port(port):
try:
from utils.firewall import Firewall as MwFirewall
MwFirewall.instance().delAcceptPortCmd(port, 'tcp')
return port
except Exception as e:
return "Delete failed {}".format(e)
def openPort():
content = mw.readFile(getConf())
data = json.loads(content)
http_port = data['scheme']['http_port']
__release_port(http_port, 'alist')
return True
def status():
data = mw.execShell(
"ps aux|grep alist |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
cmd = "ps aux|grep alist |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'"
data = mw.execShell(cmd)
if data[0] == '':
return 'stop'
return 'start'
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$SERVER_APP}', service_path + '/'+getPluginName())
return content
@@ -111,7 +138,7 @@ def contentReplace(content):
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
@@ -124,6 +151,7 @@ def initDreplace():
content = content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
# systemd
systemDir = mw.systemdCfgDir()
@@ -135,7 +163,7 @@ def initDreplace():
se_content = se_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(systemService, se_content)
mw.execShell('systemctl daemon-reload')
time.sleep(1)
return file_bin
@@ -247,7 +275,6 @@ def clearCopyTask():
return mw.returnJson(True, '清空成功并重启服务!')
def homePage():
import json
content = mw.readFile(getConf())
data = json.loads(content)
http_port = data['scheme']['http_port']
-1
View File
@@ -10,7 +10,6 @@ serverPath=$(dirname "$rootPath")
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/alist && bash install.sh install 3.37.4
# cd /www/server/mdserver-web/plugins/alist && bash install.sh install 3.37.4
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
sysArch=`arch`
+1
View File
@@ -83,6 +83,7 @@ function alistReadme(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>手动开启默认端口:5244</li>';
readme += '<li>默认admin:admin</li>';
readme += '<li>手动改密码: cd /www/server/alist && ./alist admin set NEW_PASSWORD</li>';
readme += '</ul>';
+7 -3
View File
@@ -14,8 +14,12 @@ import json
import paramiko
import ftplib
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
DEBUG = True
BLOCK_SIZE = 1024 * 1024 * 2
@@ -136,7 +140,7 @@ class FtpPSClient:
"database": "db",
"path": "path",
}
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+\."
file_regx = prefix_dict.get(data_type) + r"_(.+)_20\d+_\d+\."
sub_search = re.search(file_regx, file_name)
sub_path_name = ""
if sub_search:
+16 -22
View File
@@ -12,9 +12,13 @@ if sys.platform != "darwin":
os.chdir("/www/server/mdserver-web")
sys.path.append(os.getcwd() + "/class/core")
import mw
import db
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
import core.db as db
_ver = sys.version_info
is_py2 = (_ver[0] == 2)
@@ -184,7 +188,6 @@ def findPathName(path, filename):
return l
def backupAllFunc(stype):
os.chdir(mw.getRunDir())
name = sys.argv[2]
num = sys.argv[3]
@@ -196,20 +199,15 @@ def backupAllFunc(stype):
}
backups = []
sql = db.Sql()
# print("stype:", stype)
# 提前获取-清理多余备份
if stype == 'site':
pid = sql.table('sites').where('name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('0', pid)).field('id,filename').select()
pid = mw.M('sites').where('name=?', (name,)).getField('id')
backups = mw.M('backup').where('type=? and pid=?', ('0', pid)).field('id,filename').select()
if stype == 'database':
db_path = mw.getServerDir() + '/mysql'
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
pid = mw.M('databases').dbPos(db_path, 'mysql').where('name=?', (name,)).getField('id')
backups = mw.M('backup').where('type=? and pid=?', ('1', pid)).field('id,filename').select()
if stype == 'path':
backup_dir = mw.getBackupDir()
backup_path = backup_dir + '/path'
@@ -220,18 +218,15 @@ def backupAllFunc(stype):
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
db_path = mw.getServerDir() + '/' + plugin_name
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
pid = mw.M('databases').dbPos(db_path, 'mysql').where('name=?', (name,)).getField('id')
backups = mw.M('backup').where('type=? and pid=?', ('1', pid)).field('id,filename').select()
args = stype + " " + name + " " + num
cmd = 'python3 ' + mw.getRunDir() + '/scripts/backup.py ' + args
cmd = 'python3 ' + mw.getPanelDir() + '/scripts/backup.py ' + args
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
args = "database " + name + " " + num
cmd = 'python3 ' + mw.getRunDir() + '/plugins/' + plugin_name + \
'/scripts/backup.py ' + args
cmd = 'python3 ' + mw.getPanelDir() + '/plugins/' + plugin_name + '/scripts/backup.py ' + args
os.system(cmd)
@@ -251,8 +246,7 @@ def backupAllFunc(stype):
_name = 'path_{}'.format(os.path.basename(name))
find_path = mw.getBackupDir() + '/path/'+_name
find_new_file = "ls " + find_path + \
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
find_new_file = "ls " + find_path + "_* | grep '.gz' | cut -d \\ -f 1 | awk 'END {print}'"
filename = mw.execShell(find_new_file)[0].strip()
if filename == "":
+1 -2
View File
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
sys_os=`uname`
@@ -15,7 +14,7 @@ Install_App()
{
mkdir -p ${serverPath}/backup_ftp
echo "${1}" > ${serverPath}/backup_ftp/version.pl
echo '安装完成' > $install_tmp
echo '安装完成'
}
+6 -2
View File
@@ -5,8 +5,12 @@ import io
import os
import time
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
+3 -4
View File
@@ -10,7 +10,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
@@ -20,19 +19,19 @@ fi
Install_app()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/clean
cd ${rootPath} && python3 ${rootPath}/plugins/clean/index.py start
echo "${VERSION}" > $serverPath/clean/version.pl
echo '安装完成' > $install_tmp
echo '安装完成'
}
Uninstall_app()
{
cd ${rootPath} && python3 ${rootPath}/plugins/clean/index.py stop
rm -rf $serverPath/clean
echo "Uninstall_clean" > $install_tmp
echo "Uninstall_clean"
}
action=$1
+13 -13
View File
@@ -6,8 +6,13 @@ import os
import time
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
from utils.crontab import crontab as MwCrontab
app_debug = False
@@ -33,10 +38,9 @@ def getTaskConf():
def getConfigData():
try:
conf = getTaskConf()
if os.path.exists(conf):
return json.loads(mw.readFile(getTaskConf()))
except:
pass
return {
"task_id": -1,
"period": "day-n",
@@ -64,10 +68,8 @@ def createBgTaskByName(name):
if res and res["id"] == args["task_id"]:
print("计划任务已经存在!")
return True
import crontab_api
api = crontab_api.crontab_api()
mw_dir = mw.getRunDir()
mw_dir = mw.getPanelDir()
cmd = '''
mw_dir=%s
rname=%s
@@ -94,10 +96,10 @@ logs_file=$plugin_path/${rname}.log
'stype': "toShell",
'sname': '',
'sbody': cmd,
'urladdress': '',
'url_address': '',
}
task_id = api.add(params)
task_id = MwCrontab.instance().add(params)
if task_id > 0:
args["task_id"] = task_id
args["name"] = name
@@ -110,9 +112,7 @@ def removeBgTask():
res = mw.M("crontab").field("id, name").where(
"id=?", (cfg["task_id"],)).find()
if res and res["id"] == cfg["task_id"]:
import crontab_api
api = crontab_api.crontab_api()
data = api.delete(cfg["task_id"])
data = MwCrontab.instance().delete(cfg["task_id"])
if data[0]:
cfg["task_id"] = -1
mw.writeFile(getTaskConf(), json.dumps(cfg))
+8 -4
View File
@@ -6,8 +6,12 @@ import os
import time
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -103,7 +107,7 @@ def status():
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$SERVER_APP}', service_path + '/'+getPluginName())
return content
@@ -111,7 +115,7 @@ def contentReplace(content):
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
-1
View File
@@ -10,7 +10,6 @@ serverPath=$(dirname "$rootPath")
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/cloudreve && bash install.sh install 3.8.3
# cd /www/server/mdserver-web/plugins/cloudreve && bash install.sh install 3.8.3
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
sysArch=`arch`
+6 -2
View File
@@ -6,8 +6,12 @@ import os
import time
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
+1 -2
View File
@@ -7,12 +7,11 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
mkdir -p $serverPath/data_query
echo "${VERSION}" > $serverPath/data_query/version.pl
+8 -7
View File
@@ -11,11 +11,12 @@ import re
import json
import pymemcache
try:
sys.path.append(os.getcwd() + "/class/core")
import mw
except Exception as e:
import core.mw as mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
def singleton(cls):
@@ -68,7 +69,7 @@ class nosqlMemcached():
if not mem_content: return False
keys = ["bind", "PORT"]
rep = 'PORT\s*=\s*(.*)'
rep = r'PORT\s*=\s*(.*)'
port_re = re.search(rep, mem_content)
if port_re:
result['port'] = int(port_re.groups()[0].strip())
@@ -105,7 +106,7 @@ class nosqlMemcachedCtr():
item_no = []
for i in m_items:
item_match = b'items:(\d*?):number'
item_match = rb'items:(\d*?):number'
item_match_re = re.search(item_match, i)
if item_match_re:
v = item_match_re.groups()[0].strip()
+6 -5
View File
@@ -12,11 +12,12 @@ import yaml
from bson.objectid import ObjectId
from bson.json_util import dumps
try:
sys.path.append(os.getcwd() + "/class/core")
import mw
except Exception as e:
import core.mw as mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
def singleton(cls):
_instance = {}
+8 -11
View File
@@ -7,16 +7,12 @@ import time
import re
import redis
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
try:
sys.path.append(os.getcwd() + "/class/core")
import mw
except Exception as e:
import core.mw as mw
# def getPluginName():
# return 'data_query'
import core.mw as mw
def singleton(cls):
_instance = {}
@@ -47,7 +43,8 @@ class nosqlRedis():
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
redis_path = "{}/redis".format(mw.getServerDir())
if not os.path.exists(redis_path): return False
if not os.path.exists(redis_path):
return False
if not self.__DB_LOCAL:
self.__DB_PASS = self.__config['requirepass']
@@ -75,7 +72,7 @@ class nosqlRedis():
keys = ["bind", "port", "timeout", "maxclients", "databases", "requirepass", "maxmemory"]
for k in keys:
v = ""
rep = "\n%s\s+(.+)" % k
rep = r"\n%s\s+(.+)" % k
group = re.search(rep, redis_conf)
if not group:
if k == "maxmemory":
+481 -47
View File
@@ -8,11 +8,7 @@ import re
import pymongo
import json
try:
sys.path.append(os.getcwd() + "/class/core")
import mw
except Exception as e:
import core.mw as mw
import core.mw as mw
def singleton(cls):
_instance = {}
@@ -38,24 +34,18 @@ class nosqlMySQL():
__DB_LOCAL = None
def __init__(self):
self.__config = self.get_options(None)
pass
def setSid(self, sid):
self.__config = self.get_options(sid=sid)
def conn(self):
if self.__DB_HOST in ['127.0.0.1', 'localhost']:
my_path = "{}/mysql".format(mw.getServerDir())
if not os.path.exists(my_path): return False
if not self.__DB_LOCAL:
# print(self.__config)
self.__DB_PORT = int(self.__config['port'])
self.__DB_USER = self.__config['username']
self.__DB_PASS = self.__config['password']
self.__DB_SOCKET = self.__config['socket']
self.__DB_PORT = int(self.__config['port'])
self.__DB_USER = self.__config['username']
self.__DB_PASS = self.__config['password']
self.__DB_SOCKET = self.__config['socket']
try:
db = mw.getMyORM()
db.setPort(self.__DB_PORT)
db.setPwd(self.__DB_PASS)
@@ -68,42 +58,37 @@ class nosqlMySQL():
self.__DB_ERR = mw.get_error_info()
return False
def sqliteDb(self,dbname='databases'):
my_root_path = mw.getServerDir() +'/mysql'
def sqliteDb(self, db_pos_name, dbname='databases'):
mydb_path = mw.getServerDir() +'/'+db_pos_name
name = 'mysql'
conn = mw.M(dbname).dbPos(my_root_path, name)
conn = mw.M(dbname).dbPos(mydb_path, name)
return conn
# 获取配置项
def get_options(self, get=None):
def get_options(self, sid=None):
result = {}
my_cnf_path = "{}/mysql/etc/my.cnf".format(mw.getServerDir())
my_content = mw.readFile(my_cnf_path)
if not my_content: return False
mysql_pass = self.sqliteDb('config').where('id=?', (1,)).getField('mysql_root')
result['password'] = mysql_pass
result['username'] = 'root'
keys = ["bind_ip", "port"]
result['socket'] = ''
result['port'] = 3306
result['host'] = '127.0.0.1'
rep = 'port\s*=\s*(.*)'
result['username'] = 'root'
port_re = re.search(rep, my_content)
if port_re:
result['port'] = int(port_re.groups()[0].strip())
else:
result['port'] = 3306
if sid in ['mysql', 'mysql-apt', 'mysql-yum']:
my_cnf_path = "{}/{}/etc/my.cnf".format(mw.getServerDir(),sid)
socket_rep = 'socket\s*=\s*(.*)'
socket_re = re.search(socket_rep, my_content)
if socket_re:
result['socket'] = socket_re.groups()[0].strip()
else:
result['socket'] = ''
mydb_content = mw.readFile(my_cnf_path)
if not mydb_content: return False
mysql_pass = self.sqliteDb(sid, 'config').where('id=?', (1,)).getField('mysql_root')
result['password'] = mysql_pass
rep = r'port\s*=\s*(.*)'
port_re = re.search(rep, mydb_content)
if port_re:
result['port'] = int(port_re.groups()[0].strip())
socket_rep = r'socket\s*=\s*(.*)'
socket_re = re.search(socket_rep, mydb_content)
if socket_re:
result['socket'] = socket_re.groups()[0].strip()
return result
def set_host(self, host, port, name, username, password, prefix=''):
@@ -118,7 +103,22 @@ class nosqlMySQL():
self.__DB_LOCAL = 1
return self
def getServerList(self):
my_cnf_path = "{}/mysql/etc/my.cnf".format(mw.getServerDir())
data = []
local_mysql = "{}/mysql/etc/my.cnf".format(mw.getServerDir())
if os.path.exists(local_mysql):
data.append({'name':'本地服务器', 'val':'mysql'})
local_mysql_apt = "{}/mysql-apt/etc/my.cnf".format(mw.getServerDir())
if os.path.exists(local_mysql_apt):
data.append({'name':'本地服务器[apt]', 'val':'mysql-apt'})
local_mysql_yum = "{}/mysql-yum/etc/my.cnf".format(mw.getServerDir())
if os.path.exists(local_mysql_yum):
data.append({'name':'本地服务器[yum]', 'val':'mysql-yum'})
return mw.returnData(True, 'ok', data)
@singleton
class nosqlMySQLCtr():
@@ -126,8 +126,13 @@ class nosqlMySQLCtr():
def __init__(self):
pass
def getInstanceBySid(self, sid = 0):
def getServerList(self, args):
instance = nosqlMySQL()
return instance.getServerList()
def getInstanceBySid(self, sid):
instance = nosqlMySQL()
instance.setSid(sid)
return instance
def getDbList(self, args):
@@ -280,7 +285,372 @@ class nosqlMySQLCtr():
rdata['list'] = result
return mw.returnData(True,'ok', rdata)
def getNetRow(self, my_instance):
row = {}
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_select'")
row['select'] = data['Value']
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_insert'")
row['insert'] = data['Value']
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_update'")
row['update'] = data['Value']
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Com_delete'")
row['delete'] = data['Value']
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Bytes_received'")
row['recv_bytes'] = data['Value']
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Bytes_sent'")
row['send_bytes'] = data['Value']
return row
def getNetList(self, args):
from datetime import datetime
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
rdata = []
row = {}
row1 = self.getNetRow(my_instance)
# 等待1秒
time.sleep(1)
row2 = self.getNetRow(my_instance)
data = my_instance.find("SHOW GLOBAL VARIABLES LIKE 'max_connections'")
row['max_conn'] = data['Value']
data = my_instance.find("SHOW GLOBAL STATUS LIKE 'Threads_connected'")
row['conn'] = data['Value']
current_time = datetime.now()
row['current_time'] = current_time.strftime("%Y-%m-%d %H:%M:%S")
row['select'] = int(row2['select']) - int(row1['select'])
row['insert'] = int(row2['insert']) - int(row1['insert'])
row['update'] = int(row2['update']) - int(row1['update'])
row['delete'] = int(row2['delete']) - int(row1['delete'])
recv_per_second = int(row2['recv_bytes']) - int(row1['recv_bytes'])
send_per_second = int(row2['send_bytes']) - int(row1['send_bytes'])
# 将每秒接收和发送数据量从字节转换为兆比特
row['recv_mbps'] = "{:.2f}".format(recv_per_second * 8 / 1000000) + " MBit/s"
row['send_mbps'] = "{:.2f}".format(send_per_second * 8 / 1000000) + " MBit/s"
rdata.append(row)
return mw.returnData(True, 'ok', rdata)
def getTopnList(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
is_performance_schema = my_instance.find("SELECT @@performance_schema")
if is_performance_schema is None:
return mw.returnData(False,'异常中断,重试!')
if is_performance_schema["@@performance_schema"] == 0:
msg = "performance_schema参数未开启。\n"
msg += "在my.cnf配置文件里添加performance_schema=1,并重启mysqld进程生效。"
return mw.returnData(False, msg)
my_instance.execute("SET @sys.statement_truncate_len=4096")
data = my_instance.query("select query,db,last_seen,exec_count,max_latency,avg_latency from sys.statement_analysis order by exec_count desc, last_seen desc limit 20")
if data is None:
return mw.returnData(False, "查询失败!")
filter_db = args['filter_db']
if filter_db == 'yes':
new_data = []
for x in data:
if x['db'] is not None:
new_data.append(x)
return mw.returnData(True, 'ok', new_data)
return mw.returnData(True, 'ok', data)
# 查看重复或冗余的索引
def getRedundantIndexes(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
is_performance_schema = my_instance.find("SELECT @@performance_schema")
if is_performance_schema["@@performance_schema"] == 0:
msg = "performance_schema参数未开启。\n"
msg += "在my.cnf配置文件里添加performance_schema=1,并重启mysqld进程生效。"
return mw.returnData(False, msg)
data = my_instance.query("select table_schema,table_name,redundant_index_name,redundant_index_columns,sql_drop_index from sys.schema_redundant_indexes")
if data is None:
return mw.returnData(False, "查询失败!")
# print(data)
return mw.returnData(True, 'ok', data)
def redundantIndexesCmd(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
is_performance_schema = my_instance.find("SELECT @@performance_schema")
if is_performance_schema["@@performance_schema"] == 0:
msg = "performance_schema参数未开启。\n"
msg += "在my.cnf配置文件里添加performance_schema=1,并重启mysqld进程生效。"
return mw.returnData(False, msg)
data = my_instance.query("select table_schema,table_name,redundant_index_name,redundant_index_columns,sql_drop_index from sys.schema_redundant_indexes")
if data is None:
return mw.returnData(False, "查询失败!")
index = int(args['index'])
cmd = data[index]['sql_drop_index']
my_instance.execute(cmd)
return mw.returnData(True, '执行成功!')
def getTableInfo(self, args):
from decimal import Decimal
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
my_instance.execute("SET sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''))")
data = my_instance.query(
"""
SELECT t.TABLE_SCHEMA as TABLE_SCHEMA, t.TABLE_NAME as TABLE_NAME, t.ENGINE as ENGINE,
IFNULL(t.DATA_LENGTH/1024/1024/1024, 0) as DATA_LENGTH,
IFNULL(t.INDEX_LENGTH/1024/1024/1024, 0) as INDEX_LENGTH,
IFNULL((DATA_LENGTH+INDEX_LENGTH)/1024/1024/1024, 0) AS TOTAL_LENGTH,
c.column_name AS COLUMN_NAME, c.data_type AS DATA_TYPE, c.COLUMN_TYPE AS COLUMN_TYPE,
t.AUTO_INCREMENT AS AUTO_INCREMENT, locate('unsigned', c.COLUMN_TYPE) = 0 AS IS_SIGNED
FROM information_schema.TABLES t
JOIN information_schema.COLUMNS c ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.table_name=c.table_name
WHERE t.TABLE_SCHEMA NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
GROUP BY TABLE_NAME
ORDER BY TOTAL_LENGTH DESC, AUTO_INCREMENT DESC;
"""
)
if data is None:
return mw.returnData(True, 'ok', [])
for i in range(len(data)):
row = data[i]
data[i]['DATA_LENGTH'] = round(row['DATA_LENGTH'] or 0, 2)
data[i]['INDEX_LENGTH'] = round(row['INDEX_LENGTH'] or 0, 2)
data[i]['TOTAL_LENGTH'] = round(row['TOTAL_LENGTH'] or 0, 2)
AUTO_INCREMENT = row['AUTO_INCREMENT']
DATA_TYPE = row['DATA_TYPE']
IS_SIGNED = row['IS_SIGNED']
RESIDUAL_AUTO_INCREMENT = 0
if AUTO_INCREMENT is not None:
if DATA_TYPE == 'tinyint':
if IS_SIGNED == 0:
RESIDUAL_AUTO_INCREMENT = int(255 - AUTO_INCREMENT)
if IS_SIGNED == 1:
RESIDUAL_AUTO_INCREMENT = int(127 - AUTO_INCREMENT)
if DATA_TYPE == 'smallint':
if IS_SIGNED == 0:
RESIDUAL_AUTO_INCREMENT = int(65535 - AUTO_INCREMENT)
if IS_SIGNED == 1:
RESIDUAL_AUTO_INCREMENT = int(32767 - AUTO_INCREMENT)
if DATA_TYPE == 'int':
if IS_SIGNED == 0:
RESIDUAL_AUTO_INCREMENT = int(4294967295 - AUTO_INCREMENT)
if IS_SIGNED == 1:
RESIDUAL_AUTO_INCREMENT = int(2147483647 - AUTO_INCREMENT)
if DATA_TYPE == 'mediumint':
if IS_SIGNED == 0:
RESIDUAL_AUTO_INCREMENT = int(16777215 - AUTO_INCREMENT)
if IS_SIGNED == 1:
RESIDUAL_AUTO_INCREMENT = int(8388607 - AUTO_INCREMENT)
if DATA_TYPE == 'bigint':
if IS_SIGNED == 0:
RESIDUAL_AUTO_INCREMENT = Decimal("18446744073709551615") - Decimal(AUTO_INCREMENT)
if IS_SIGNED == 1:
RESIDUAL_AUTO_INCREMENT = Decimal("9223372036854775807") - Decimal(AUTO_INCREMENT)
else:
RESIDUAL_AUTO_INCREMENT = "主键非自增"
data[i]['RESIDUAL_AUTO_INCREMENT'] = RESIDUAL_AUTO_INCREMENT
return mw.returnData(True, 'ok', data)
# 查看应用端IP连接数总和
def getConnCount(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
data = my_instance.query(
"SELECT user,db,substring_index(HOST,':',1) AS Client_IP,count(1) AS count FROM information_schema.PROCESSLIST "
"GROUP BY user,db,substring_index(HOST,':',1) ORDER BY COUNT(1) DESC"
)
for i in range(len(data)):
if data[i]['db'] is None:
data[i]['db'] = '空'
if data[i]['Client_IP'] == '':
data[i]['Client_IP'] = '空'
# data2 = my_instance.query("SELECT USER, COUNT(*) as nums FROM information_schema.PROCESSLIST GROUP BY USER ORDER BY COUNT(*) DESC")
# print(data)
# print(data2)
return mw.returnData(True, 'ok', data)
# 快速找出没有主键的表
def getFpkInfo(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
data = my_instance.query(
"""
SELECT t.table_schema,
t.table_name
FROM information_schema.tables t
LEFT JOIN information_schema.key_column_usage k
ON t.table_schema = k.table_schema
AND t.table_name = k.table_name
AND k.constraint_name = 'PRIMARY'
WHERE t.table_schema NOT IN ('mysql', 'information_schema', 'sys', 'performance_schema')
AND k.constraint_name IS NULL
AND t.table_type = 'BASE TABLE';
"""
)
return mw.returnData(True, 'ok', data)
def getLockSql(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
data = my_instance.query(
"""
SELECT
a.trx_id AS trx_id,
a.trx_state AS trx_state,
a.trx_started AS trx_started,
b.id AS processlist_id,
b.info AS info,
b.user AS user,
b.host AS host,
b.db AS db,
b.command AS command,
b.state AS state,
CONCAT('KILL QUERY ', b.id) AS sql_kill_blocking_query
FROM
information_schema.INNODB_TRX a,
information_schema.PROCESSLIST b
WHERE
a.trx_mysql_thread_id = b.id
ORDER BY
a.trx_started
"""
)
return mw.returnData(True, 'ok', data)
def killLockPid(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
pid = args['pid']
my_instance.execute('kill %s' % pid)
return mw.returnData(True, '执行成功!')
def killAllLock(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
data = self.getLockSql(args)
if data['status']:
pid_data = data['data']
for x in pid_data:
cmd = 'kill %s' % x['processlist_id']
# print(cmd)
my_instance.execute(cmd)
return mw.returnData(True, '执行成功!')
def getDeadlockInfo(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
data = my_instance.find("SHOW ENGINE INNODB STATUS")
if data is not None:
innodb_status = data['Status']
deadlock_info = re.search(r"LATEST DETECTED DEADLOCK.*?WE ROLL BACK TRANSACTION\s+\(\d+\)", innodb_status, re.DOTALL)
if deadlock_info is None:
return mw.returnData(True, 'ok', '无锁表')
return mw.returnData(True, 'ok', deadlock_info.group(0))
return mw.returnData(True, 'ok', '无锁表')
def getSlaveStatus(self, args):
sid = args['sid']
my_instance = self.getInstanceBySid(sid).conn()
if my_instance is False:
return mw.returnData(False,'无法链接')
slave_info = my_instance.find('SHOW SLAVE STATUS')
if slave_info is None:
return mw.returnData(True, 'ok', '未开启从库!')
msg = ''
if slave_info['Auto_Position'] != 1:
msg += '你没有开启基于GTID全局事务ID复制,请确保CHANGE MASTER TO MASTER_AUTO_POSITION = 1.\n'
if slave_info['Slave_IO_Running'] == 'Yes' and slave_info['Slave_SQL_Running'] == 'Yes':
if slave_info['Seconds_Behind_Master'] == 0:
msg = "同步正常,无延迟"
return mw.returnData(True, 'ok', msg)
else:
return mw.returnData(True, 'ok', '同步正常,但有延迟,延迟时间为:%s' % slave_info['Seconds_Behind_Master'])
else:
msg = '主从复制报错,请检查\nSlave_IO_Running状态值是:%s, | Slave_SQL_Running状态值是:%s\nLast_Error错误信息是:%s\nLast_SQL_Error错误信息是:%s\n' \
% (slave_info['Slave_IO_Running'], slave_info['Slave_SQL_Running'], slave_info['Last_Error'], slave_info['Last_SQL_Error'])
error_dict = my_instance.find('select LAST_ERROR_NUMBER,LAST_ERROR_MESSAGE,LAST_ERROR_TIMESTAMP from performance_schema.replication_applier_status_by_worker ORDER BY LAST_ERROR_TIMESTAMP desc limit 1')
msg += '错误号是:%s \n' % error_dict['LAST_ERROR_NUMBER']
msg += '错误信息是:%s \n' % error_dict['LAST_ERROR_MESSAGE']
msg += '报错时间是:%s \n' % error_dict['LAST_ERROR_TIMESTAMP']
msg += 'MySQL Replication Health is NOT OK!'
return mw.returnData(True, 'ok', msg)
# ---------------------------------- run ----------------------------------
def get_server_list(args):
t = nosqlMySQLCtr()
return t.getServerList(args)
# 获取 mysql 列表
def get_db_list(args):
t = nosqlMySQLCtr()
@@ -307,6 +677,70 @@ def get_stats_list(args):
t = nosqlMySQLCtr()
return t.showStatsList(args)
# 查询执行次数最频繁的前N条SQL语句
def get_topn_list(args):
t = nosqlMySQLCtr()
return t.getTopnList(args)
# MySQL服务器的QPS/TPS/网络带宽指标
def get_net_list(args):
t = nosqlMySQLCtr()
return t.getNetList(args)
# 查看重复或冗余的索引
def get_redundant_indexes(args):
t = nosqlMySQLCtr()
return t.getRedundantIndexes(args)
# 删除重复或冗余的索引
def redundant_indexes_cmd(args):
t = nosqlMySQLCtr()
return t.redundantIndexesCmd(args)
# 统计库里每个表的大小
def get_table_info(args):
t = nosqlMySQLCtr()
return t.getTableInfo(args)
# 查看应用端IP连接数总和
def get_conn_count(args):
t = nosqlMySQLCtr()
return t.getConnCount(args)
# 快速找出没有主键的表
def get_fpk_info(args):
t = nosqlMySQLCtr()
return t.getFpkInfo(args)
# 查看当前锁阻塞的SQL
def get_lock_sql(args):
t = nosqlMySQLCtr()
return t.getLockSql(args)
# KILL阻塞SQL
def kill_lock_pid(args):
t = nosqlMySQLCtr()
return t.killLockPid(args)
# KILL阻塞SQL
def kill_all_lock(args):
t = nosqlMySQLCtr()
return t.killAllLock(args)
# 查看死锁信息
def get_deadlock_info(args):
t = nosqlMySQLCtr()
return t.getDeadlockInfo(args)
# 查看主从复制信息
def get_slave_status(args):
t = nosqlMySQLCtr()
return t.getSlaveStatus(args)
# 测试
def test(args):
+7 -3
View File
@@ -51,9 +51,11 @@
<input name="mysql_field_value" type="text" class="bt-input-text" placeholder="请输入查找内容">
</div>
<button type="button" class="mysql_find btn btn-success btn-sm mr5 ml5" style="float:right;">
<span>查找</span>
</button>
<div style="float:left;">
<button id="mysql_find" type="button" class="btn btn-success btn-sm mr5 ml5" >查找</button>
<button id="mysql_common" type="button" class="btn btn-success btn-sm mr5 ml5">常用功能</button>
</div>
</div>
</div>
@@ -78,6 +80,8 @@
</div>
</div>
<hr style="border:none;" />
<div class="col-md-12" style="padding-left: 3px;">
<div id="mysql_list_tab" style="padding-top:0px;">
<div class="tab-nav">
+650 -13
View File
@@ -247,11 +247,16 @@ function initTabMemcached(){
});
}
var mysql_timer = null;
function initTabMySQL(){
mysqlGetDbList();
mysqlProcessList();
var mysql_timer = setInterval(function(){
mysqlGetServerList(function(){
mysqlGetDbList();
mysqlProcessList();
});
clearInterval(mysql_timer);
mysql_timer = setInterval(function(){
var name = $('#mysql_list_tab .tab-nav span.on').data('name');
mysqlRunMysqlTab(name);
@@ -261,12 +266,613 @@ function initTabMySQL(){
}
},2000);
$('#mysql_list_tab .tab-nav span').click(function(){
$('#mysql_list_tab .tab-nav span').unbind('click').click(function(){
$('#mysql_list_tab .tab-nav span').removeClass('on');
$(this).addClass('on');
var name = $(this).data('name');
mysqlRunMysqlTab(name);
});
mysqlCommonFunc();
}
function mysqlCommonFuncMysqlNSQL(){
function renderSQL(){
var sid = mysqlGetSid();
var filter_db = $('#filter_db').is(':checked');
myPostCBN('get_topn_list',{'sid':sid,'filter_db':filter_db ? 'yes':'no'} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i].query+'</td>';
t += '<td>'+items[i].db+'</td>';
t += '<td>'+items[i].last_seen+'</td>';
t += '<td>'+items[i].exec_count+'</td>';
t += '<td>'+items[i].max_latency+'</td>';
t += '<td>'+items[i].avg_latency+'</td>';
t += '</tr>';
tbody += t;
}
$('#topn_list tbody').html(tbody);
} else {
layer.msg(data.msg,{icon:2});
}
});
}
var sql_timer = null;
layer.open({
type: 1,
title: "查询执行次数最频繁的前N条SQL语句",
area: ['1200px', '500px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
<div class="ss-text pull-left">\
<em>实时监控</em>\
<div class="ssh-item">\
<input class="btswitch btswitch-ios" id="real_time_monitoring" type="checkbox">\
<label id="real_time_label" class="btswitch-btn" for="real_time_monitoring"></label>\
</div>\
</div>\
<div class="ss-text pull-left" style="padding-left:10px;">\
<em>过滤数据库</em>\
<div class="ssh-item">\
<input class="btswitch btswitch-ios" id="filter_db" type="checkbox">\
<label class="btswitch-btn" for="filter_db"></label>\
</div>\
</div>\
</div>\
<hr />\
<table class="table table-hover" id="topn_list">\
<thead>\
<th>SQL</th>\
<th style="width:100px;">数据名</th>\
<th>最近时间</th>\
<th style="width:100px;">总次数</th>\
<th style="width:100px;">最大时间</th>\
<th style="width:100px;">平均时间</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
$('#real_time_label').click(function(){
sql_timer = setInterval(function(){
var t = $('#real_time_monitoring').is(':checked');
if (t){
renderSQL();
} else{
clearInterval(sql_timer);
}
}, 3000);
});
}
});
}
function mysqlCommonFuncMysqlNet(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_net_list',{'sid':sid} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i]['current_time']+'</td>';
t += '<td>'+items[i]['select']+'</td>';
t += '<td>'+items[i]['insert']+'</td>';
t += '<td>'+items[i]['update']+'</td>';
t += '<td>'+items[i]['delete']+'</td>';
t += '<td>'+items[i]['conn']+'</td>';
t += '<td>'+items[i]['max_conn']+'</td>';
t += '<td>'+items[i]['recv_mbps']+'</td>';
t += '<td>'+items[i]['send_mbps']+'</td>';
t += '</tr>';
tbody += t;
}
$('#net_list tbody').html(tbody);
} else {
layer.msg(data.msg,{icon:2});
}
});
}
var sql_timer = null;
layer.open({
type: 1,
title: "MySQL服务器的QPS/TPS/网络带宽指标",
area: ['750px', '220px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
<div class="ss-text pull-left">\
<em>实时监控</em>\
<div class="ssh-item">\
<input class="btswitch btswitch-ios" id="real_qps_monitoring" type="checkbox">\
<label id="real_qps_label" class="btswitch-btn" for="real_qps_monitoring"></label>\
</div>\
</div>\
</div>\
<hr />\
<table class="table table-hover" id="net_list">\
<thead>\
<th style="width:160px;">时间</th>\
<th style="width:50px;">Select</th>\
<th style="width:50px;">Insert</th>\
<th style="width:50px;">Update</th>\
<th style="width:50px;">Delete</th>\
<th style="width:50px;">Conn</th>\
<th style="width:50px;">Max_conn</th>\
<th style="width:90px;">Recv</th>\
<th style="width:90px;">Send</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
$('#real_qps_label').click(function(){
sql_timer = setInterval(function(){
var t = $('#real_qps_monitoring').is(':checked');
if (t){
renderSQL();
} else{
clearInterval(sql_timer);
}
}, 3000);
});
}
});
}
function mysqlCommonFuncRedundantIndexes(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_redundant_indexes',{'sid':sid} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i]['table_schema']+'</td>';
t += '<td>'+items[i]['table_name']+'</td>';
t += '<td>'+items[i]['redundant_index_name']+'</td>';
t += '<td>'+items[i]['redundant_index_columns']+'</td>';
t += '<td>'+items[i]['sql_drop_index']+'</td>';
t += '<td><a class="exec btlink" index="'+i+'">执行</a></td>';
t += '</tr>';
tbody += t;
}
$('#redundant_indexes tbody').html(tbody);
$('#redundant_indexes tbody .exec').click(function(){
var index = $(this).attr('index');
myPostCB('redundant_indexes_cmd', {'sid':sid, 'index':index}, function(rdata){
var data = rdata.data;
showMsg(data.msg,function(){
if (data.status){
renderSQL();
}
},{icon: data.status ? 1 : 2}, 2000);
});
});
} else {
layer.msg(data.msg,{icon:2});
}
});
}
layer.open({
type: 1,
title: "查看重复或冗余的索引",
area: ['1100px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<table class="table table-hover" id="redundant_indexes">\
<thead>\
<th style="width:100px;">数据库名</th>\
<th style="width:50px;">表名</th>\
<th style="width:50px;">冗余索引名</th>\
<th style="width:50px;">冗余索引列名</th>\
<th style="width:300px;">删除冗余索引SQL</th>\
<th style="width:30px;">操作</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
}
});
}
function mysqlCommonFuncTableInfo(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_table_info',{'sid':sid} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i]['TABLE_SCHEMA']+'</td>';
t += '<td>'+items[i]['TABLE_NAME']+'</td>';
t += '<td>'+items[i]['ENGINE']+'</td>';
t += '<td>'+items[i]['DATA_LENGTH']+'</td>';
t += '<td>'+items[i]['INDEX_LENGTH']+'</td>';
t += '<td>'+items[i]['TOTAL_LENGTH']+'</td>';
t += '<td>'+items[i]['COLUMN_NAME']+'</td>';
t += '<td>'+items[i]['COLUMN_TYPE']+'</td>';
t += '<td>'+items[i]['AUTO_INCREMENT']+'</td>';
t += '<td>'+items[i]['RESIDUAL_AUTO_INCREMENT']+'</td>';
t += '</tr>';
tbody += t;
}
$('#mysql_data_id tbody').html(tbody);
} else {
layer.msg(data.msg,{icon:2});
}
});
}
layer.open({
type: 1,
title: "统计库里每个表的大小",
area: ['1200px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<table class="table table-hover" id="mysql_data_id">\
<thead>\
<th style="width:100px;">库名</th>\
<th style="width:50px;">表名</th>\
<th style="width:80px;">储存引擎</th>\
<th style="width:150px;">数据大小(GB)</th>\
<th style="width:130px;">索引大小(GB)</th>\
<th style="width:100px;">总计(GB)</th>\
<th style="width:150px;">主键自增字段</th>\
<th style="width:200px;">主键字段属性</th>\
<th style="width:150px;">主键自增当前</th>\
<th style="width:150px;">主键自增剩余</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
}
});
}
function mysqlCommonFuncConnCount(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_conn_count',{'sid':sid} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i]['user']+'</td>';
t += '<td>'+items[i]['db']+'</td>';
t += '<td>'+items[i]['Client_IP']+'</td>';
t += '<td>'+items[i]['count']+'</td>';
t += '</tr>';
tbody += t;
}
$('#app_ip_list tbody').html(tbody);
} else {
layer.msg(data.msg,{icon:2});
}
});
}
var sql_timer = null;
layer.open({
type: 1,
title: "查看应用端IP连接数总和",
area: ['700px', '420px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
<div class="ss-text pull-left">\
<em>实时监控</em>\
<div class="ssh-item">\
<input class="btswitch btswitch-ios" id="app_ip_monitoring" type="checkbox">\
<label id="app_ip_label" class="btswitch-btn" for="app_ip_monitoring"></label>\
</div>\
</div>\
</div>\
<hr />\
<table class="table table-hover" id="app_ip_list">\
<thead>\
<th style="width:160px;">连接用户</th>\
<th style="width:50px;">数据库名</th>\
<th style="width:50px;">应用端IP</th>\
<th style="width:50px;">数量</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
$('#app_ip_label').click(function(){
sql_timer = setInterval(function(){
var t = $('#app_ip_monitoring').is(':checked');
if (t){
renderSQL();
} else{
clearInterval(sql_timer);
}
}, 3000);
});
}
});
}
function mysqlCommonFuncFpkInfo(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_fpk_info',{'sid':sid} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i]['table_schema']+'</td>';
t += '<td>'+items[i]['table_name']+'</td>';
t += '</tr>';
tbody += t;
}
$('#mysql_data_id tbody').html(tbody);
} else {
layer.msg(data.msg,{icon:2});
}
});
}
layer.open({
type: 1,
title: "快速找出没有主键的表",
area: ['800px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<table class="table table-hover" id="mysql_data_id">\
<thead>\
<th style="width:100px;">库名</th>\
<th style="width:50px;">表名</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
}
});
}
function mysqlCommonFuncLockSQL(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_lock_sql',{'sid':sid} ,function(rdata){
var data = rdata.data;
if (data['status']){
var items = data.data;
var tbody = '';
for (var i = 0; i < items.length; i++) {
var t = '<tr>';
t += '<td>'+items[i]['trx_id']+'</td>';
t += '<td>'+items[i]['trx_state']+'</td>';
t += '<td>'+items[i]['trx_started']+'</td>';
t += '<td>'+items[i]['processlist_id']+'</td>';
t += '<td>'+items[i]['info']+'</td>';
t += '<td>'+items[i]['user']+'</td>';
t += '<td>'+items[i]['host']+'</td>';
t += '<td>'+items[i]['db']+'</td>';
t += '<td>'+items[i]['command']+'</td>';
t += '<td>'+items[i]['state']+'</td>';
t += '<td>'+items[i]['sql_kill_blocking_query']+'</td>';
t += '<td><a class="exec btlink" index="'+i+'">执行</a></td>';
t += '</tr>';
tbody += t;
}
$('#mysql_data_id tbody').html(tbody);
$('#mysql_data_id tbody .exec').click(function(){
var index = $(this).attr('index');
var pid = items[index]['processlist_id'];
myPostCB('kill_lock_pid', {'sid':sid, 'pid':pid}, function(rdata){
var data = rdata.data;
showMsg(data.msg,function(){
if (data.status){
renderSQL();
}
},{icon: data.status ? 1 : 2}, 2000);
});
});
} else {
layer.msg(data.msg,{icon:2});
}
});
}
layer.open({
type: 1,
title: "查看当前锁阻塞的SQL",
area: ['1000px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20 divtable taskdivtable">\
<div class="mr20 pull-left" style="border-right: 1px solid #ccc; padding-right: 20px;">\
<button id="kill_all" type="button" class="btn btn-default btn-sm">关闭所有阻塞</button>\
</div>\
<hr />\
<table class="table table-hover" id="mysql_data_id">\
<thead>\
<th style="width:80px;">事务ID</th>\
<th style="width:80px;">事务状态</th>\
<th style="width:220px;">执行时间</th>\
<th style="width:100px;">线程ID</th>\
<th style="width:50px;">Info</th>\
<th style="width:50px;">user</th>\
<th style="width:50px;">host</th>\
<th style="width:50px;">db</th>\
<th style="width:50px;">command</th>\
<th style="width:50px;">state</th>\
<th style="width:140px;">kill</th>\
<th style="width:50px;">操作</th>\
</thead>\
<tbody></tbody>\
</table>\
</div>',
success:function(i,l){
renderSQL();
$('#kill_all').unbind('click').click(function(){
var sid = mysqlGetSid();
myPostCB('kill_all_lock', {'sid':sid}, function(rdata){
var data = rdata.data;
showMsg(data.msg,function(){
if (data.status){
renderSQL();
}
},{icon: data.status ? 1 : 2}, 2000);
});
});
}
});
}
function mysqlCommonFuncDeadlockInfo(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_deadlock_info',{'sid':sid} ,function(rdata){
var data = rdata.data;
$('#info_log').html(data.data);
var ob = document.getElementById('info_log');
ob.scrollTop = ob.scrollHeight;
});
}
layer.open({
type: 1,
title: "查看死锁信息",
area: ['800px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd15">\
<textarea readonly="" style="margin: 0px;height: 330px;width: 100%;background-color: #333;color:#fff; padding:0 5px" id="info_log"></textarea>\
</div>',
success:function(i,l){
renderSQL();
}
});
}
function mysqlCommonFuncSlaveStatus(){
function renderSQL(){
var sid = mysqlGetSid();
myPostCBN('get_slave_status',{'sid':sid} ,function(rdata){
var data = rdata.data;
$('#info_log').html(data.data);
var ob = document.getElementById('info_log');
ob.scrollTop = ob.scrollHeight;
});
}
layer.open({
type: 1,
title: "查看主从复制信息",
area: ['800px', '400px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd15">\
<textarea readonly="" style="margin: 0px;height: 330px;width: 100%;background-color: #333;color:#fff; padding:0 5px" id="info_log"></textarea>\
</div>',
success:function(i,l){
renderSQL();
}
});
}
function mysqlCommonFunc(){
$('#mysql_common').unbind('click').click(function(){
layer.open({
type: 1,
title: "MySQL常用功能",
area: ['600px', '200px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="bt-form pd20">\
<button style="margin-bottom: 8px;" id="mysql_top_nsql" type="button" class="btn btn-default btn-sm">查询执行次数最频繁的前N条SQL语句</button>\
<button style="margin-bottom: 8px;" id="mysql_net_stat" type="button" class="btn btn-default btn-sm">MySQL服务器的QPS/TPS/网络带宽指标</button>\
<button style="margin-bottom: 8px;" id="mysql_redundant_indexes" type="button" class="btn btn-default btn-sm">查看重复或冗余的索引</button>\
<button style="margin-bottom: 8px;" id="mysql_table_info" type="button" class="btn btn-default btn-sm">统计库里每个表的大小</button>\
<button style="margin-bottom: 8px;" id="mysql_conn_count" type="button" class="btn btn-default btn-sm">查看应用端IP连接数总和</button>\
<button style="margin-bottom: 8px;" id="mysql_fpk_info" type="button" class="btn btn-default btn-sm">快速找出没有主键的表</button>\
<button style="margin-bottom: 8px;" id="mysql_lock_sql" type="button" class="btn btn-default btn-sm">查看当前锁阻塞的SQL</button>\
<button style="margin-bottom: 8px;" id="mysql_deadlock_info" type="button" class="btn btn-default btn-sm">查看死锁信息</button>\
<button style="margin-bottom: 8px;" id="mysql_slave_status" type="button" class="btn btn-default btn-sm">查看主从复制信息</button>\
</div>',
success:function(i,l){
$('#mysql_top_nsql').click(function(){
mysqlCommonFuncMysqlNSQL();
});
$('#mysql_net_stat').click(function(){
mysqlCommonFuncMysqlNet();
});
$('#mysql_redundant_indexes').click(function(){
mysqlCommonFuncRedundantIndexes();
});
$('#mysql_table_info').click(function(){
mysqlCommonFuncTableInfo();
});
$('#mysql_conn_count').click(function(){
mysqlCommonFuncConnCount();
});
$('#mysql_fpk_info').click(function(){
mysqlCommonFuncFpkInfo();
});
$('#mysql_lock_sql').click(function(){
mysqlCommonFuncLockSQL();
});
$('#mysql_deadlock_info').click(function(){
mysqlCommonFuncDeadlockInfo();
});
$('#mysql_slave_status').click(function(){
mysqlCommonFuncSlaveStatus();
});
}
});
});
}
function mysqlRunMysqlTab(name){
@@ -279,7 +885,8 @@ function mysqlRunMysqlTab(name){
// ------------------------- mysql start -------------------------------
function mysqlGetSid(){
return 0;
return $('#mysql select[name=sid]').val();
// return 0;
}
function mysqlGetDbName(){
@@ -308,7 +915,7 @@ function mysqlInitField(f, data){
$('select[name="mysql_field_key"]').html(option_html);
$('#mysql .mysql_find').unbind('click').click(function(){
$('#mysql_find').unbind('click').click(function(){
var val = $('input[name="mysql_field_value"]').val();
if (val == ''){
layer.msg('搜索不能为空!',{icon:7});
@@ -319,11 +926,40 @@ function mysqlInitField(f, data){
}
function mysqlGetServerList(call_func){
myPostCBN('get_server_list', {}, function(rdata){
var rdata = rdata.data;
if (rdata.data.length != 0){
var items = rdata.data;
var content = '';
for (var i = 0; i < items.length; i++) {
var t = items[i];
if (i == 0){
content += '<option value="'+t['val']+'" selected>'+t['name']+'</option>';
} else {
content += '<option value="'+t['val']+'">'+t['name']+'</option>';
}
}
$('#mysql select[name=sid]').html(content);
$('#mysql select[name=sid]').change(function(){
mysqlGetDbList();
});
if (typeof(call_func) == 'function'){
call_func();
}
closeInstallLayer();
} else {
showInstallLayer();
}
});
}
function mysqlGetDbList(){
var sid = mysqlGetSid();
myPostCB('get_db_list',{'sid':sid} ,function(rdata){
myPostCBN('get_db_list',{'sid':sid} ,function(rdata){
if (rdata.data.status){
var items = rdata.data.data['list'];
var content = '';
for (var i = 0; i < items.length; i++) {
@@ -341,10 +977,6 @@ function mysqlGetDbList(){
});
mysqlGetTableList(1);
closeInstallLayer();
} else {
showInstallLayer();
}
});
}
@@ -353,7 +985,12 @@ function mysqlGetTableList(p){
// console.log('mysqlGetTableList',p);
var sid = mysqlGetSid();
var db = mysqlGetDbName();
myPostCB('get_table_list',{'sid':sid,'db':db} ,function(rdata){
if (!db){
return;
}
myPostCBN('get_table_list',{'sid':sid,'db':db} ,function(rdata){
if (rdata.data.status){
var items = rdata.data.data['list'];
+12 -8
View File
@@ -7,8 +7,12 @@ import time
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
try:
import docker
@@ -434,7 +438,7 @@ def dockerRemoveImage():
def getImageListFunc(dbname=''):
bkDir = mw.getRootDir() + '/backup/docker'
bkDir = mw.getFatherDir() + '/backup/docker'
blist = os.listdir(bkDir)
r = []
@@ -448,13 +452,13 @@ def getImageListFunc(dbname=''):
def dockerImagePickDir():
bkDir = mw.getRootDir() + '/backup/docker'
bkDir = mw.getFatherDir() + '/backup/docker'
return mw.returnJson(True, 'ok', bkDir)
def dockerImagePickList():
bkDir = mw.getRootDir() + '/backup/docker'
bkDir = mw.getFatherDir() + '/backup/docker'
if not os.path.exists(bkDir):
os.mkdir(bkDir)
@@ -486,7 +490,7 @@ def dockerImagePickSave():
if not data[0]:
return data[1]
bkDir = mw.getRootDir() + '/backup/docker/'
bkDir = mw.getFatherDir() + '/backup/docker/'
images = args['images']
try:
file_name = bkDir + \
@@ -606,8 +610,8 @@ def getDockerCreateInfo():
def __release_port(port):
from collections import namedtuple
try:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(port, 'docker', 'port')
from utils.firewall import Firewall as MwFirewall
MwFirewall.instance().addAcceptPort(port, 'docker', 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
+4 -5
View File
@@ -10,7 +10,6 @@ serverPath=$(dirname "$rootPath")
# cd /www/server/mdserver-web/plugins/docker && /bin/bash install.sh uninstall 1.0
# cd /www/server/mdserver-web/plugins/docker && /bin/bash install.sh install 1.0
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
@@ -42,11 +41,11 @@ Install_Docker()
{
# which docker
# if [ "$?" == "0" ];then
# echo '安装已经完成docker' > $install_tmp
# echo '安装已经完成docker'
# exit 0
# fi
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
if [ ! -d $serverPath/docker ];then
@@ -59,7 +58,7 @@ Install_Docker()
if [ -d $serverPath/docker ];then
echo "${VERSION}" > $serverPath/docker/version.pl
echo '安装完成' > $install_tmp
echo '安装Docker完成'
cd ${rootPath} && python3 ${rootPath}/plugins/docker/index.py start
cd ${rootPath} && python3 ${rootPath}/plugins/docker/index.py initd_install
@@ -94,7 +93,7 @@ Uninstall_Docker()
# docker-ce
rm -rf $serverPath/docker
echo "Uninstall_Docker" > $install_tmp
echo "卸载Docker"
}
action=$1
+7 -2
View File
@@ -6,8 +6,13 @@ import os
import time
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
+4 -5
View File
@@ -10,7 +10,6 @@ serverPath=$(dirname "$rootPath")
# cd /www/server/mdserver-web/plugins/dynamic-tracking && /bin/bash install.sh uninstall 1.0
# cd /www/server/mdserver-web/plugins/dynamic-tracking && /bin/bash install.sh install 1.0
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
@@ -31,7 +30,7 @@ fi
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
mkdir -p $serverPath/dynamic-tracking
@@ -57,7 +56,7 @@ Install_App()
shell_file=${curPath}/versions/${OSNAME}.sh
echo $shell_file
if [ ! -f $shell_file ];then
echo '不支持...' > $install_tmp
echo '不支持...'
exit 1
fi
@@ -67,7 +66,7 @@ Install_App()
cp -rf ${curPath}/shell $serverPath/dynamic-tracking
echo "${VERSION}" > $serverPath/dynamic-tracking/version.pl
echo '安装完成' > $install_tmp
echo '安装完成'
cd ${rootPath} && python3 ${rootPath}/plugins/dynamic-tracking/index.py start
# cd ${rootPath} && python3 ${rootPath}/plugins/dynamic-tracking/index.py initd_install
@@ -77,7 +76,7 @@ Install_App()
Uninstall_App()
{
rm -rf $serverPath/dynamic-tracking
echo "Uninstall_App" > $install_tmp
echo "Uninstall_App"
}
action=$1
@@ -7,5 +7,4 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
# apt-get install linux-perf
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
# 关于macosx使用dtrace
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
# export GOPROXY=https://goproxy.io
+8 -5
View File
@@ -7,8 +7,12 @@ import time
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -119,7 +123,7 @@ def status():
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
return content
@@ -143,7 +147,7 @@ def initJailD():
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
@@ -167,7 +171,6 @@ def initDreplace():
systemService = systemDir + '/' + getPluginName() + '.service'
if os.path.exists(systemDir) and not os.path.exists(systemService):
systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
service_path = mw.getServerDir()
content = mw.readFile(systemServiceTpl)
content = content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(systemService, content)
+8 -5
View File
@@ -8,7 +8,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
# cd /www/server/mdserver-web/plugins/fail2ban && bash install.sh install 1.1.0
@@ -16,10 +15,11 @@ VERSION=$2
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
apt install -y fail2ban
which yum && yum install -y fail2ban
which apt && apt install -y fail2ban
mkdir -p $serverPath/fail2ban
echo "${VERSION}" > $serverPath/fail2ban/version.pl
@@ -31,8 +31,11 @@ Install_App()
Uninstall_App()
{
apt remove -y fail2ban
apt purge -y fail2ban
which apt && apt remove -y fail2ban
which apt && apt purge -y fail2ban
which yum && yum remove -y fail2ban
which yum && yum purge -y fail2ban
if [ -f /usr/lib/systemd/system/fail2ban.service ];then
systemctl stop fail2ban
+7 -3
View File
@@ -9,8 +9,12 @@ import json
import io
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
# -----------------------------
import google.oauth2.credentials
@@ -211,7 +215,7 @@ class gdriveclient():
print("data_type 类型错误!!!")
exit(1)
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+\."
file_regx = prefix_dict.get(data_type) + r"_(.+)_20\d+_\d+\."
sub_search = re.search(file_regx.lower(), file_name)
sub_path_name = ""
if sub_search:
+1 -1
View File
@@ -302,7 +302,7 @@
</div>
</div>
</script>
<script type="text/javascript" src="/plugins/file?name=gdrive&f=js/gdrive.js"></script>
<!-- <script type="text/javascript" src="/plugins/file?name=gdrive&f=js/gdrive.js"></script> -->
<script type="text/javascript">
$.getScript( "/plugins/file?name=gdrive&f=js/gdrive.js", function(){
gdList('');
+16 -22
View File
@@ -13,9 +13,13 @@ if sys.platform != "darwin":
os.chdir("/www/server/mdserver-web")
sys.path.append(os.getcwd() + "/class/core")
import mw
import db
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
import core.db as db
_ver = sys.version_info
is_py2 = (_ver[0] == 2)
@@ -199,9 +203,8 @@ def backupAllFunc(stype):
mw.echoInfo("未授权API,无法使用!!!")
return ''
os.chdir(mw.getRunDir())
backup_dir = mw.getBackupDir()
run_dir = mw.getRunDir()
run_dir = mw.getPanelDir()
stype = sys.argv[1]
name = sys.argv[2]
@@ -214,20 +217,15 @@ def backupAllFunc(stype):
}
backups = []
sql = db.Sql()
# print("stype:", stype)
# 提前获取-清理多余备份
if stype == 'site':
pid = sql.table('sites').where('name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('0', pid)).field('id,filename').select()
pid = mw.M('sites').where('name=?', (name,)).getField('id')
backups = mw.M('backup').where('type=? and pid=?', ('0', pid)).field('id,filename').select()
if stype == 'database':
db_path = mw.getServerDir() + '/mysql'
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
pid = mw.M('databases').dbPos(db_path, 'mysql').where('name=?', (name,)).getField('id')
backups = mw.M('backup').where('type=? and pid=?', ('1', pid)).field('id,filename').select()
if stype == 'path':
backup_path = backup_dir + '/path'
_name = 'path_{}'.format(os.path.basename(name))
@@ -237,18 +235,15 @@ def backupAllFunc(stype):
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
db_path = mw.getServerDir() + '/' + plugin_name
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
pid = mw.M('databases').dbPos(db_path, 'mysql').where('name=?', (name,)).getField('id')
backups = mw.M('backup').where('type=? and pid=?', ('1', pid)).field('id,filename').select()
args = stype + " " + name + " " + num
cmd = 'python3 ' + run_dir + '/scripts/backup.py ' + args
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
args = "database " + name + " " + num
cmd = 'python3 ' + run_dir + '/plugins/' + \
plugin_name + '/scripts/backup.py ' + args
cmd = 'python3 ' + run_dir + '/plugins/' + plugin_name + '/scripts/backup.py ' + args
if stype == 'path':
name = os.path.basename(name)
@@ -267,8 +262,7 @@ def backupAllFunc(stype):
bk_name = stype
find_path = backup_dir + '/' + bk_name + '/' + bk_prefix + '_' + name
find_new_file = "ls " + find_path + \
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
find_new_file = "ls " + find_path + "_* | grep '.gz' | cut -d \\ -f 1 | awk 'END {print}'"
# print(find_new_file)
+4 -5
View File
@@ -10,7 +10,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
PATH=$PATH:${rootPath}/bin
export PATH
@@ -58,13 +57,13 @@ Install_App()
pip install -I google-api-python-client==2.39.0 google-auth-httplib2==0.1.0 google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
fi
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/gdrive
echo "${VERSION}" > $serverPath/gdrive/version.pl
echo '安装完成' > $install_tmp
echo '安装完成'
else
echo '服务器连接不上谷歌云!安装失败!' > $install_tmp
echo '服务器连接不上谷歌云!安装失败!'
exit 1
fi
}
@@ -72,7 +71,7 @@ Install_App()
Uninstall_App()
{
rm -rf $serverPath/gdrive
echo '卸载完成' > $install_tmp
echo '卸载完成'
}
+7 -10
View File
@@ -7,15 +7,12 @@ import sys
import re
import subprocess
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)
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -122,7 +119,7 @@ export HOME=%s && ''' % ( getRunUser(), getHomeDir())
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$RUN_USER}', getRunUser())
content = content.replace('{$HOME_DIR}', getHomeDir())
@@ -689,7 +686,7 @@ def projectScriptLoad():
commit_tpl = getPluginDir() + '/hook/commit.tpl'
commit = path + '/custom_hooks/commit'
codeDir = mw.getRootDir() + '/git'
codeDir = mw.getFatherDir() + '/git'
cc_content = mw.readFile(commit_tpl)
+1 -3
View File
@@ -7,8 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
@@ -115,7 +113,7 @@ Uninstall_App()
fi
rm -rf $serverPath/gitea
echo 'uninstall success' > $install_tmp
echo 'uninstall success'
}
+14 -19
View File
@@ -5,19 +5,17 @@ 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
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -105,8 +103,7 @@ def getHomeDir():
def getRunUser():
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
user = mw.execShell("who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return user
else:
return 'root'
@@ -121,7 +118,7 @@ export HOME=%s && ''' % ( getRunUser(), getHomeDir())
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$RUN_USER}', getRunUser())
content = content.replace('{$HOME_DIR}', getHomeDir())
@@ -568,8 +565,7 @@ def repoList():
# print(list_data)
list_data = checkRepoListIsHasScript(list_data)
data['list'] = mw.getPage({'count': count, 'p': page,
'row': page_size, 'tojs': 'gogsRepoListPage'})
data['list'] = mw.getPage({'count': count, 'p': page, 'row': page_size, 'tojs': 'gogsRepoListPage'})
data['page'] = page
data['page_size'] = page_size
data['page_count'] = int(math.ceil(count / page_size))
@@ -690,7 +686,7 @@ def projectScriptLoad():
commit_tpl = getPluginDir() + '/hook/commit.tpl'
commit = path + '/custom_hooks/commit'
codeDir = mw.getRootDir() + '/git'
codeDir = mw.getFatherDir() + '/git'
cc_content = mw.readFile(commit_tpl)
@@ -828,8 +824,7 @@ def projectScriptSelf_Create():
name = args['name'] + '.git'
file = args['file']
self_path = path = getRootPath() + '/' + user + '/' + \
name + '/custom_hooks/self'
self_path = path = getRootPath() + '/' + user + '/' + name + '/custom_hooks/self'
if not os.path.exists(self_path):
os.mkdir(self_path)
+3 -5
View File
@@ -7,8 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
@@ -36,7 +34,7 @@ Install_gogs()
mkdir -p $serverPath/source/gogs
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
version=$1
os=`getOs`
@@ -78,7 +76,7 @@ Install_gogs()
# echo "gogs ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
# fi
echo 'install success' > $install_tmp
echo 'install success'
}
Uninstall_gogs()
@@ -96,7 +94,7 @@ Uninstall_gogs()
fi
rm -rf $serverPath/gogs
echo 'uninstall success' > $install_tmp
echo 'uninstall success'
}
+9 -5
View File
@@ -6,8 +6,12 @@ import os
import time
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -121,7 +125,7 @@ def initRedisConf():
requirepass = ""
conf = mw.getServerDir() + '/redis/redis.conf'
content = mw.readFile(conf)
rep = r"^(requirepass" + r')\s*([.0-9A-Za-z_& ~]+)'
rep = r"^(requirepass" + r"\)\s*([.0-9A-Za-z_& ~]+)"
tmp = re.search(rep, content, re.M)
if tmp:
requirepass = tmp.groups()[1]
@@ -136,7 +140,7 @@ def initRedisConf():
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$CONFIG_ADMIN}', mw.getRandomString(6))
content = content.replace('{$CONFIG_PASS}', mw.getRandomString(10))
@@ -147,7 +151,7 @@ def contentReplace(content):
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
+1 -3
View File
@@ -12,13 +12,11 @@ sysArch=`arch`
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/gorse && bash install.sh install 0.4.15
# cd /www/server/mdserver-web/plugins/gorse && bash install.sh install 0.4.15
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
mkdir -p $serverPath/source/gorse
+8 -4
View File
@@ -8,8 +8,12 @@ import re
import string
import subprocess
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -95,7 +99,7 @@ def readConfigTpl():
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$HA_USER}', mw.getRandomString(8))
content = content.replace('{$HA_PWD}', mw.getRandomString(10))
@@ -114,7 +118,7 @@ def status():
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
-2
View File
@@ -8,8 +8,6 @@ curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
type=$2
+1 -4
View File
@@ -8,9 +8,6 @@ rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
@@ -63,7 +60,7 @@ Install_App()
fi
echo $MIN_VERSION > $serverPath/haproxy/version.pl
echo '安装Haproxy成功' > $install_tmp
echo '安装Haproxy成功'
#Haproxy日志配置
if [ -f /etc/rsyslog.conf ];then
+9 -5
View File
@@ -10,8 +10,12 @@ import json
from datetime import datetime
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -50,8 +54,8 @@ class App:
def __release_port(self, port):
from collections import namedtuple
try:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(port, 'IMail-Server', 'port')
from utils.firewall import Firewall as MwFirewall
MwFirewall.instance().addAcceptPort(port, 'IMail-Server', 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
@@ -100,7 +104,7 @@ class App:
def contentReplace(self, content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$RUN_USER}', self.getRunUser())
content = content.replace('{$HOME_DIR}', self.getHomeDir())
+2 -4
View File
@@ -7,18 +7,16 @@ 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
echo '缺少安装脚本...'
exit 0
fi
if [ ! -d $curPath/versions/$2 ];then
echo '缺少安装脚本2...' > $install_tmp
echo '缺少安装脚本2...'
exit 0
fi
+3 -4
View File
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=0.0.19
# bash install.sh install 0.0.19
@@ -67,7 +66,7 @@ download_file() {
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
echo '正在安装脚本文件...'
mkdir -p $serverPath/source
load_vars
@@ -93,7 +92,7 @@ Install_App()
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py start
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py initd_install
fi
echo 'install successful' > $install_tmp
echo 'install successful'
}
Uninstall_App()
@@ -101,7 +100,7 @@ Uninstall_App()
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py initd_uninstall
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py stop
rm -rf $serverPath/imail
echo "install fail" > $install_tmp
echo "install fail"
}
action=$1
+8 -5
View File
@@ -6,8 +6,12 @@ import os
import time
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -122,7 +126,7 @@ def status():
def contentReplace(content):
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$PLUGIN_PATH}', getPluginDir())
@@ -162,7 +166,7 @@ def copyScripts():
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
@@ -198,7 +202,6 @@ def initDreplace():
systemService = systemDir + '/' + getPluginName() + '.service'
if os.path.exists(systemDir) and not os.path.exists(systemService):
systemServiceTpl = getPluginDir() + '/init.d/' + getPluginName() + '.service.tpl'
service_path = mw.getServerDir()
content = mw.readFile(systemServiceTpl)
content = contentReplace(content)
mw.writeFile(systemService, content)
-2
View File
@@ -18,8 +18,6 @@ serverPath=$(dirname "$rootPath")
# systemctl restart keepalived
# ifconfig
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
Install_App()
+8 -4
View File
@@ -8,8 +8,12 @@ import re
import string
import subprocess
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
app_debug = False
if mw.isAppleSystem():
@@ -75,7 +79,7 @@ def status():
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
service_path = mw.getServerDir()
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
@@ -150,7 +154,7 @@ def initdUinstall():
def runLog():
path = getConf()
content = mw.readFile(path)
rep = 'log\s*=\s*(.*)'
rep = r'log\s*=\s*(.*)'
tmp = re.search(rep, content)
return tmp.groups()[0]
-1
View File
@@ -7,7 +7,6 @@ rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
sys_os=`uname`
VERSION=1.6.22
+9 -8
View File
@@ -9,11 +9,12 @@ import re
import json
# reload(sys)
# sys.setdefaultencoding('utf-8')
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
sys.path.append(os.getcwd() + "/class/core")
import mw
import core.mw as mw
if mw.isAppleSystem():
@@ -138,7 +139,7 @@ def getInitdTpl(version=''):
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$ROOT_PATH}', mw.getFatherDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$SERVER_APP_PATH}', service_path + '/mariadb')
server_id = int(time.time())
@@ -889,7 +890,7 @@ def importDbExternalProgressBar():
file = args['file']
name = args['name']
import_dir = mw.getRootDir() + '/backup/import/'
import_dir = mw.getFatherDir() + '/backup/import/'
file_path = import_dir + file
if not os.path.exists(file_path):
@@ -2477,7 +2478,7 @@ def trySlaveSyncBugfix(version=''):
return mw.returnJson(True, '修复成功!')
def getSlaveSyncCmd(version=''):
root = mw.getRunDir()
root = mw.getPanelDir()
cmd = 'cd ' + root + ' && python3 ' + root + \
'/plugins/mariadb/index.py do_full_sync {"db":"all","sign":""}'
return mw.returnJson(True, 'ok', cmd)
@@ -3026,7 +3027,7 @@ def fullSync(version=''):
status_file = asyncTmpfile()
if args['begin'] == '1':
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
cmd = 'cd ' + mw.getPanelDir() + ' && python3 ' + \
getPluginDir() + \
'/index.py do_full_sync {"db":"' + args['db'] + '","sign":"' + sign + '"} &'
# print(cmd)
+6 -2
View File
@@ -8,8 +8,12 @@ import subprocess
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
web_dir = os.getcwd() + "/web"
if os.path.exists(web_dir):
sys.path.append(web_dir)
os.chdir(web_dir)
import core.mw as mw
if mw.isAppleSystem():
+1 -1
View File
@@ -8,7 +8,7 @@
"uninstall_pre_inspection":true,
"checks": "server/mariadb",
"path": "server/mariadb",
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3","11.4","11.5"],
"versions":["10.6","10.7","10.8","10.9","10.11","11.0","11.1","11.2","11.3","11.4","11.5","11.6"],
"shell":"install.sh",
"checks":"server/mariadb",
"path":"server/mariadb",
-2
View File
@@ -14,8 +14,6 @@ serverPath=$(dirname "$rootPath")
# cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py init_slave_status
# cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py install_pre_inspection
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
type=$2

Some files were not shown because too many files have changed in this diff Show More