Compare commits

...
784 Commits
Author SHA1 Message Date
Mr Chen b6f7334f5e Merge pull request #449 from midoks/dev
0.16.1
2023-09-11 11:52:37 +08:00
midoks 27b77f8570 Update push_notice_msg.py 2023-09-10 23:18:13 +08:00
midoks 3d888961bc Update zip.sh 2023-09-10 22:02:43 +08:00
midoks 5edc4fb713 Update install.sh 2023-09-10 21:33:37 +08:00
midoks 214954b298 Update install.sh 2023-09-10 21:29:29 +08:00
midoks 13b0b2752e Update info.json 2023-09-10 21:23:27 +08:00
midoks a2918e651f Update common.py 2023-09-10 14:26:00 +08:00
midoks 55dd1d7d5a update 2023-09-10 14:06:41 +08:00
midoks df50eceeed update 2023-09-10 14:06:19 +08:00
midoks e1de6dd514 Update install_dev.sh 2023-09-10 14:04:13 +08:00
midoks 08328bbb86 Update install_dev.sh 2023-09-10 14:03:53 +08:00
midoks 6abc5b365b Update README.md 2023-09-10 12:37:34 +08:00
midoks 6cc1279729 update 2023-09-10 12:36:23 +08:00
midoks aeafaa2832 update 2023-09-10 12:25:51 +08:00
midoks e74a511763 Update euler.sh 2023-09-10 12:25:01 +08:00
midoks f86159eeac Update README.md 2023-09-10 12:20:02 +08:00
midoks 8097164475 支持华为欧拉系统 2023-09-10 12:19:14 +08:00
midoks 4ebb44e4c0 Update info.json 2023-09-09 22:32:52 +08:00
midoks 584f93461a update 2023-09-09 12:13:16 +08:00
midoks e21f0a53e5 Update update_dev.sh 2023-09-09 11:57:34 +08:00
midoks 1d31a0eae0 Update update.sh 2023-09-09 11:57:15 +08:00
midoks ded33ed6b4 update 2023-09-09 11:55:40 +08:00
midoks b703758d0e update 2023-09-09 11:37:18 +08:00
midoks 33493ac03c up 2023-09-09 11:35:08 +08:00
midoks 74e63c5bbd Update install.sh 2023-09-09 11:33:38 +08:00
midoks f2d34e5551 Update lib.sh 2023-09-09 11:32:02 +08:00
midoks 89c529f44c Update install_dev.sh 2023-09-09 11:28:53 +08:00
midoks 56b728601b MySQL/MYSQL-YUM/MySQL-APT添加重置master功能。
mysql主从同步数据过期时,可使用此命令
2023-09-07 21:17:56 +08:00
midoks bf1d2daeaa Update push_notice_msg.py 2023-09-07 20:37:46 +08:00
midoks cac45b3732 update 2023-09-07 13:36:54 +08:00
midoks ee498b7094 Update install.sh 2023-09-07 13:04:30 +08:00
midoks 385113fe4d Update push_notice_msg.py 2023-09-07 12:58:53 +08:00
midoks 5dbfc5bd51 Update README.md 2023-09-06 19:34:09 +08:00
midoks b76e0f606a Update install.sh 2023-09-06 19:24:25 +08:00
midoks 047702f26d Update debian.sh 2023-09-06 17:48:40 +08:00
midoks eb219caada Update config_api.py 2023-09-04 18:45:49 +08:00
midoks 78b2046f19 Update README.md 2023-09-04 18:45:10 +08:00
Mr Chen 5fe85730e6 Merge pull request #447 from midoks/dev
0.16.1-提前版,合并不release.
2023-09-04 18:44:41 +08:00
midoks adb72ef33b Update config_api.py 2023-09-04 18:40:39 +08:00
midoks d9c8a46031 Update install.sh 2023-09-04 18:35:12 +08:00
midoks 24f520bdc9 Update install.sh 2023-09-04 18:30:40 +08:00
midoks 7492756997 Update install.sh 2023-09-04 18:23:08 +08:00
midoks 616af16635 Update install.sh 2023-09-04 18:15:53 +08:00
midoks 916d39e205 Update install.sh 2023-09-04 18:15:21 +08:00
midoks 017958b6b0 Update install.sh 2023-09-04 18:07:52 +08:00
midoks d403c4c4ad Update opensuse.sh 2023-09-04 17:43:28 +08:00
midoks 9f1481db07 Update mw_api.py 2023-09-04 13:16:42 +08:00
midoks 47e0ec5fae update 2023-09-04 13:14:08 +08:00
midoks a2377d960e 给防盗链增加禁止空来源 2023-09-04 12:47:12 +08:00
midoks 60f1ce2575 update 2023-09-03 00:16:01 +08:00
midoks 0e368f7157 Update index.py 2023-09-03 00:01:20 +08:00
midoks 3cf5c5b190 Update gdriveclient.py 2023-09-02 23:45:33 +08:00
midoks 4ed07beca3 Update gdriveclient.py 2023-09-02 23:43:30 +08:00
midoks cee9619883 update 2023-09-02 23:30:02 +08:00
midoks 5db4a96fc9 Update install.sh 2023-09-02 23:17:38 +08:00
midoks 2e6b7bf5cd Update install.sh 2023-09-02 23:15:52 +08:00
midoks f404caa763 Update install.sh 2023-09-02 22:59:37 +08:00
midoks 062a518492 gdrive云备份开始测试 2023-09-02 22:47:01 +08:00
midoks 0310cab3ae Update msonedrive.js 2023-09-02 21:06:30 +08:00
midoks 4a0b8df57f Update index.html 2023-09-01 16:28:44 +08:00
Mr Chen 63e427b488 Merge pull request #445 from midoks/dev
0.16.0
2023-08-30 23:26:30 +08:00
midoks c688c692f9 0.16.0
yum install -y libargon2-devel
apt install -y libargon2-dev

OP防火墙 - 重载即可

* 增加PHP83。
* 面板日志单独为一页并加入日志审计功能。
* 修复webssh服务器读取问题。
* 站点批量删除修复。
* OP防火墙-修复`自动强制验证`关闭不生效。
* 新增OneDrive备份插件。
* FTP备份优化。
2023-08-30 23:24:49 +08:00
midoks c9f074b319 FTP备份优化 2023-08-30 20:48:54 +08:00
midoks 38b4042c5a Update msonedrive.js 2023-08-30 19:51:52 +08:00
midoks bf32390f0e Update README.md 2023-08-30 18:40:21 +08:00
midoks 91a9be4cc0 Update mw.py 2023-08-30 18:26:08 +08:00
midoks be5f438f84 Delete config.conf 2023-08-30 17:47:38 +08:00
midoks 2705fd7ba2 Update config_api.py 2023-08-30 17:45:21 +08:00
midoks 4de7e72f0a Update test.py 2023-08-30 17:37:49 +08:00
midoks da668c723c onedrive插件OK 2023-08-30 17:35:41 +08:00
midoks 20624217bf Update backup.py 2023-08-30 15:11:17 +08:00
midoks 2403af08c6 Update crontab.js 2023-08-30 13:35:52 +08:00
midoks 2350b73896 Update layout.html 2023-08-28 23:50:14 +08:00
midoks 464fa9cc0f Update cert_api.py 2023-08-28 23:06:16 +08:00
midoks 9a79f0b728 Update README.md 2023-08-28 22:57:47 +08:00
midoks 52cfff7038 OP防火墙-修复自动强制验证关闭不生效。 2023-08-28 22:50:03 +08:00
midoks 8d42f8137c Update .gitignore 2023-08-28 11:45:37 +08:00
midoks 41fb9759a3 Create readme.md 2023-08-28 11:38:44 +08:00
midoks 7d3833b2ef Update index.py 2023-08-27 19:56:17 +08:00
midoks 0badb053e0 站点批量删除修复。 2023-08-27 19:46:56 +08:00
midoks 80b9e7cbf7 Update index.py 2023-08-27 19:00:13 +08:00
midoks 94df21192f Update dynamic-tracking.js 2023-08-27 18:50:25 +08:00
midoks 346d687368 Update simple_trace.sh 2023-08-27 18:34:47 +08:00
midoks 46ec655365 Update simple_trace.sh 2023-08-27 18:28:52 +08:00
midoks e852020c38 Update simple_trace.sh 2023-08-27 17:51:18 +08:00
midoks d06e83676b Update simple_trace.sh 2023-08-27 17:50:32 +08:00
midoks 7a511f8217 Update dynamic-tracking.js 2023-08-27 17:09:49 +08:00
midoks 8c5021b9dc Update simple_trace.sh 2023-08-27 16:48:05 +08:00
midoks b7d50540ac Create ubuntu.sh 2023-08-27 16:45:06 +08:00
midoks 2a95fcc59a Update install.sh 2023-08-27 16:29:52 +08:00
midoks 2b04cb3947 Update dynamic-tracking.js 2023-08-27 16:17:15 +08:00
midoks 7f0ad25342 Update simple_macosx_trace.sh 2023-08-27 15:51:42 +08:00
midoks 09f7e6f5b5 update 2023-08-27 15:50:52 +08:00
midoks 17a7ffa0b4 update 2023-08-27 15:38:00 +08:00
midoks ba6dcabd04 Update simple_trace.sh 2023-08-27 14:29:17 +08:00
midoks 0ff5c170d3 update 2023-08-27 14:28:26 +08:00
midoks b78e020993 Update index.py 2023-08-26 23:14:06 +08:00
midoks 9586eeda07 up 2023-08-26 23:02:17 +08:00
midoks ea462aa51d update 2023-08-26 22:43:13 +08:00
midoks aaac8b5239 文件管理-svg预览优化 2023-08-26 22:38:27 +08:00
midoks 2b86c375b0 动态追踪- svg查看功能 2023-08-26 22:23:13 +08:00
midoks 600e2688f9 update 2023-08-26 21:11:34 +08:00
midoks 3537bc520f Update dynamic-tracking.js 2023-08-26 17:47:06 +08:00
midoks 9ffdffadd6 Update README.md 2023-08-26 17:42:59 +08:00
midoks 3942f2fbf5 Update index.py 2023-08-26 17:35:48 +08:00
midoks 8ff2f217b3 Update index.py 2023-08-26 17:23:34 +08:00
midoks 480bd154c6 Update index.py 2023-08-26 17:21:20 +08:00
midoks 5eb3ed4524 Update README.md 2023-08-26 16:49:19 +08:00
midoks 50e78ae6f6 Update logs.html 2023-08-26 16:22:08 +08:00
midoks 0ec9b31c2f update 2023-08-26 16:17:54 +08:00
midoks 191b54821e Update logs_api.py 2023-08-26 16:07:19 +08:00
midoks c2188a2c7e update 2023-08-26 16:04:35 +08:00
midoks d23b64a92c Update update_dev.sh 2023-08-26 16:03:29 +08:00
midoks 3ae97e1c75 Update config_api.py 2023-08-26 15:59:04 +08:00
midoks f0e7361436 Update logs_api.py 2023-08-26 15:57:54 +08:00
midoks 5f85d41352 日志审计转移完成 2023-08-26 15:55:09 +08:00
midoks 6fc8803446 update 2023-08-26 00:29:44 +08:00
midoks b3120f3435 日志功能从防火墙提出来 2023-08-26 00:24:04 +08:00
midoks f9f1b1a113 update 2023-08-25 21:21:58 +08:00
midoks 2645297cee update 2023-08-25 21:20:56 +08:00
midoks 7f171f5986 update 2023-08-25 20:56:53 +08:00
midoks c3b3e3b01c update 2023-08-25 16:55:44 +08:00
midoks 3824b394ad php argon2 2023-08-25 16:55:32 +08:00
midoks 270660fb53 update 2023-08-25 15:26:23 +08:00
midoks c4171a9506 Update install.sh 2023-08-25 15:09:54 +08:00
midoks 222943e312 Update index.py 2023-08-24 22:35:44 +08:00
midoks 92f8a4e949 Update mw.tpl 2023-08-24 22:12:02 +08:00
midoks eff1f55a21 Update cli.sh 2023-08-24 22:10:43 +08:00
midoks 0b54da9747 Update freebsd.sh 2023-08-24 21:39:29 +08:00
midoks 0bec57937f Update index.py 2023-08-24 21:31:35 +08:00
midoks 6c64f8ee5e Update install.sh 2023-08-24 21:25:15 +08:00
midoks b65ad9de80 Update install.sh 2023-08-24 21:18:49 +08:00
midoks 07be263d81 Update install.sh 2023-08-24 21:12:53 +08:00
midoks bf9cb52fec Update index.py 2023-08-24 21:07:42 +08:00
midoks f7135a6ded Update index.py 2023-08-24 21:02:36 +08:00
midoks 7b98dde1aa Update index.py 2023-08-24 21:02:26 +08:00
midoks b51f3fdd68 update 2023-08-24 21:00:47 +08:00
midoks e02c52df49 Update freebsd.sh 2023-08-24 20:58:26 +08:00
midoks 730bc7171b Update index.py 2023-08-24 20:55:57 +08:00
midoks c065eabb48 Update index.py 2023-08-24 20:47:49 +08:00
midoks 1ad1e3326d php扩展库读取优化 2023-08-24 20:45:25 +08:00
midoks d4346a51bc Update crontab_api.py 2023-08-24 20:22:53 +08:00
midoks 8260cc5f4a Update crontab_api.py 2023-08-24 20:12:50 +08:00
midoks 021b299b7d Update mw.tpl 2023-08-24 20:09:53 +08:00
midoks a767e7e578 Update index.py 2023-08-24 20:05:08 +08:00
midoks 57da2aef27 Update freebsd.sh 2023-08-24 19:48:06 +08:00
midoks 5b43438cb1 Update index.py 2023-08-24 19:46:02 +08:00
midoks 7ab88a1bea Update index.py 2023-08-24 19:05:11 +08:00
midoks 31291a13c7 Update index.py 2023-08-24 18:58:59 +08:00
midoks 43d0b75d98 Update index.py 2023-08-24 18:58:35 +08:00
midoks 5490197b8a Update index.py 2023-08-24 18:58:16 +08:00
midoks 8f03574bce update 2023-08-24 18:56:19 +08:00
midoks 94487e0b3d Update index.py 2023-08-24 18:54:09 +08:00
midoks 45cc0159af Update index.py 2023-08-24 18:48:07 +08:00
midoks 504a618eb1 Update index.py 2023-08-24 18:33:48 +08:00
midoks 5e25849464 Update index.py 2023-08-24 18:33:22 +08:00
midoks 9bb59a1559 Update index.py 2023-08-24 18:10:07 +08:00
midoks 6883316efc Update index.py 2023-08-24 18:09:16 +08:00
midoks de7ea503e5 update 2023-08-24 18:03:23 +08:00
midoks 4fcad95c79 Update index.py 2023-08-24 15:28:10 +08:00
midoks 75dc1bd70d Update freebsd.sh 2023-08-24 15:18:38 +08:00
midoks 44758e3e55 Update index.py 2023-08-24 15:02:20 +08:00
midoks 140624e62f Update index.py 2023-08-24 14:47:01 +08:00
midoks 65f90b473c Update index.py 2023-08-24 14:44:59 +08:00
midoks 0a089fcedf Update index.py 2023-08-24 14:41:58 +08:00
midoks 010624023f update 2023-08-24 14:39:32 +08:00
midoks 9399a14a92 update 2023-08-24 12:52:10 +08:00
midoks 2875b40e62 Update README.md 2023-08-23 20:15:28 +08:00
midoks 78c3686091 Update freebsd.sh 2023-08-23 13:12:29 +08:00
midoks d7447197ec Update freebsd.sh 2023-08-22 19:58:23 +08:00
midoks 9b64ec5c6d Update freebsd.sh 2023-08-22 18:48:18 +08:00
midoks dad51dad77 Update files_api.py 2023-08-22 18:48:07 +08:00
midoks d89751f733 update 2023-08-22 18:25:46 +08:00
midoks 1dc486711b Update install.sh 2023-08-22 17:42:34 +08:00
midoks 60a2f85f02 Update install.sh 2023-08-22 17:41:57 +08:00
midoks 830d387ddb up 2023-08-22 17:37:53 +08:00
midoks ae225780f9 Update system_api.py 2023-08-22 17:27:21 +08:00
midoks e0a0a82d68 update 2023-08-22 17:25:54 +08:00
midoks 0b23c5f330 update 2023-08-22 17:18:32 +08:00
midoks fb01c68f5a Update mw.py 2023-08-22 17:09:26 +08:00
midoks 5755121fa5 Update mw.py 2023-08-22 17:05:23 +08:00
midoks 3d1c613864 Update mw.py 2023-08-22 17:02:39 +08:00
midoks 9590c4bb7d Update mw.py 2023-08-22 17:01:45 +08:00
midoks 32c0bdf093 Update system_api.py 2023-08-22 16:52:15 +08:00
midoks 4f5424a746 Update freebsd.sh 2023-08-22 16:36:56 +08:00
midoks 81ba3bce9d Update freebsd.sh 2023-08-22 16:21:24 +08:00
midoks 22b3a1bc42 Update op_waf.js 2023-08-21 23:15:10 +08:00
midoks df9a34aa31 Update index.py 2023-08-21 22:33:33 +08:00
midoks 2400213533 up 2023-08-21 22:20:51 +08:00
midoks 465eb118a9 0.16.0
改版为【老子面板】
2023-08-21 20:28:06 +08:00
midoks 7e81aa109f Update all_test.sh 2023-08-21 19:49:47 +08:00
midoks b23b41c7a7 Update phplib.conf 2023-08-21 19:22:19 +08:00
midoks 724a77ae81 Update install.sh 2023-08-21 19:17:37 +08:00
midoks 3499ed74ee Update info.json 2023-08-21 19:13:36 +08:00
midoks 52997049e2 Update layout.html 2023-08-21 19:11:28 +08:00
midoks a96a36b087 Create install.sh 2023-08-21 19:02:52 +08:00
midoks 5926f688a6 Update macos.sh 2023-08-21 00:41:26 +08:00
midoks 1b754f5c43 Update push_notice_msg.py 2023-08-21 00:12:30 +08:00
midoks c4c20de520 Update install.sh 2023-08-20 22:37:42 +08:00
midoks 616895785f Update init_cmd.py 2023-08-20 20:37:30 +08:00
midoks 29d6c8740a Update receive_music163_search.py 2023-08-20 20:35:33 +08:00
midoks 64aa9a9d01 Update receive_music163_search.py 2023-08-20 19:46:30 +08:00
midoks ffbe8ba6d4 Update receive_music163_search.py 2023-08-20 19:41:04 +08:00
midoks ed39c5d243 Update receive_music163_search.py 2023-08-20 16:56:48 +08:00
midoks 4bb2115040 Update receive_music163_search.py 2023-08-20 15:32:16 +08:00
midoks 6b0cf8129d Update receive_music163_search.py 2023-08-20 15:11:19 +08:00
midoks ab7bbe942b Update receive_music163_search.py 2023-08-20 15:11:01 +08:00
midoks a8a3fa1754 update 2023-08-20 15:10:58 +08:00
midoks e343f33b47 Update receive_faq.py 2023-08-20 14:58:48 +08:00
midoks f55367ab5e Update index.py 2023-08-20 00:26:17 +08:00
midoks 050bd158c1 update 2023-08-20 00:25:46 +08:00
midoks d35a680fec update 2023-08-19 20:11:08 +08:00
midoks 4a4ddeaabe Update system_api.py 2023-08-19 00:17:23 +08:00
midoks 0e74b0cccf Update system_api.py 2023-08-19 00:15:39 +08:00
midoks 806e29577e Update system_api.py 2023-08-19 00:14:47 +08:00
midoks 75923f5363 Update system_api.py 2023-08-19 00:13:19 +08:00
midoks 834196883c Update index.py 2023-08-18 00:53:15 +08:00
midoks 341826c641 Update index.py 2023-08-18 00:52:28 +08:00
midoks 1bd1ce5b31 Update index.py 2023-08-18 00:42:20 +08:00
Mr Chen eef504e172 Merge pull request #442 from midoks/dev
OP防火墙测试功能修复
2023-08-18 00:20:06 +08:00
midoks a0434ef7d6 Update index.py 2023-08-18 00:13:17 +08:00
midoks 893bbb8ea7 Update install.sh 2023-08-17 22:49:01 +08:00
midoks 92e3e277cc Update info.json 2023-08-17 21:38:44 +08:00
midoks 58e48bf013 Update info.json 2023-08-17 21:36:41 +08:00
midoks 644760d5b0 update 2023-08-17 21:35:37 +08:00
midoks d6ccd81def 动态追踪 - 专业人员使用 2023-08-17 21:29:54 +08:00
Mr Chen d32e71b2d9 Merge pull request #441 from midoks/dev
centos9 mysql8安装需要patchelf
2023-08-17 18:43:28 +08:00
midoks ae9e56c56c Update rhel.sh 2023-08-17 18:41:42 +08:00
midoks d7c0285bbf Update rhel.sh 2023-08-17 18:38:43 +08:00
midoks 5cc0957ffd Update rhel.sh 2023-08-17 18:38:18 +08:00
Mr Chen 1e44d64ace Merge pull request #440 from midoks/dev
mysql安装优化
2023-08-17 17:55:46 +08:00
midoks 907851c413 update 2023-08-17 17:29:04 +08:00
midoks 0faafc654b Update install.sh 2023-08-17 16:58:36 +08:00
Mr Chen 4cdc399b77 Merge pull request #439 from midoks/dev
mongodb脚本升级和检查openresty状态优化
2023-08-17 16:25:46 +08:00
midoks a085e5b1ea Update mw.py 2023-08-17 16:20:07 +08:00
midoks bdbf4dddc6 Update mongodb.tpl 2023-08-17 15:39:45 +08:00
midoks 5cee2f2b6d mongodb centos 2023-08-17 15:36:13 +08:00
Mr Chen b9652a7940 Merge pull request #437 from midoks/dev
0.15.4
2023-08-17 14:53:59 +08:00
midoks dc7ddbcf6b up 2023-08-17 14:52:52 +08:00
midoks 87a8bfe59e Update freebsd.sh 2023-08-17 13:49:30 +08:00
midoks cfdd5e5f73 Update freebsd.sh 2023-08-17 13:48:38 +08:00
midoks e2acf621ca Update freebsd.sh 2023-08-17 13:46:21 +08:00
midoks 0711a922d2 Update freebsd.sh 2023-08-17 13:45:05 +08:00
midoks 055ea0ca0c Update README.md 2023-08-17 13:23:26 +08:00
midoks 772d9c50f6 update 2023-08-17 13:18:46 +08:00
midoks 0809b51725 updaate 2023-08-17 12:27:31 +08:00
midoks 4e901e6750 update 2023-08-17 11:51:01 +08:00
midoks 5c62397234 update 2023-08-17 11:39:40 +08:00
midoks 63021a3eab Create centos.sh 2023-08-17 11:35:02 +08:00
midoks e617b07790 update 2023-08-17 11:32:03 +08:00
midoks 960eeed4ce update 2023-08-17 11:18:25 +08:00
midoks ccf020bf6b Update index.py 2023-08-17 11:14:56 +08:00
midoks c4918d8cd7 update 2023-08-17 11:09:50 +08:00
midoks b3d3ceb058 update 2023-08-17 11:02:39 +08:00
midoks 17a301c745 update 2023-08-17 00:56:07 +08:00
midoks 1bfa2ae3ab update 2023-08-17 00:52:43 +08:00
midoks 9be5dcfd8a Update index.py 2023-08-17 00:47:29 +08:00
midoks d9e8f1d4ad Update ubuntu.sh 2023-08-17 00:43:22 +08:00
midoks d85f544773 Create ubuntu.sh 2023-08-17 00:35:43 +08:00
midoks 577ac1f8ee Update debian.sh 2023-08-17 00:24:02 +08:00
midoks ed117a1b40 Update debian.sh 2023-08-17 00:21:44 +08:00
midoks 9d54f0b6cd Create debian.sh 2023-08-17 00:19:23 +08:00
midoks 707eced7bf Create debian.sh 2023-08-17 00:16:28 +08:00
midoks dd96833c09 Update index.py 2023-08-17 00:10:38 +08:00
midoks 4c61143918 update 2023-08-17 00:04:19 +08:00
midoks 8cb8a1bc70 update 2023-08-16 23:20:22 +08:00
midoks c55c3c23d1 up 2023-08-16 22:37:31 +08:00
midoks 04e6b9367a Update index.py 2023-08-16 22:24:41 +08:00
midoks f4f25b8ab3 Update index.py 2023-08-16 22:20:12 +08:00
midoks a0b0b9b294 update 2023-08-16 22:18:31 +08:00
midoks 699ad0b8ca Update debian.sh 2023-08-16 22:11:39 +08:00
midoks a45eaf1c3b Update debian.sh 2023-08-16 22:09:35 +08:00
midoks 0f51a6d481 update 2023-08-16 22:06:43 +08:00
midoks 142d5f7ed8 update 2023-08-16 22:00:57 +08:00
midoks 72bd528a24 update 2023-08-16 21:40:41 +08:00
midoks af2dc0585b up 2023-08-16 18:27:12 +08:00
midoks 0a0021b09d Update install.sh 2023-08-16 13:46:00 +08:00
midoks c5811d4494 Update install.sh 2023-08-16 12:11:11 +08:00
midoks e329892cd2 Update openssl.sh 2023-08-16 11:32:40 +08:00
midoks 368324a813 Update install.sh 2023-08-16 11:28:52 +08:00
midoks 6a7cc4f054 Update install.sh 2023-08-16 11:27:54 +08:00
midoks 1d3cba599c Update install.sh 2023-08-16 11:15:14 +08:00
midoks 7d902a50eb Update install.sh 2023-08-16 11:09:48 +08:00
midoks 25feb7c0ad Update install.sh 2023-08-16 11:07:32 +08:00
midoks e15d1716e5 Update install.sh 2023-08-16 11:02:48 +08:00
midoks ee16e0142e Update install.sh 2023-08-16 10:59:15 +08:00
midoks 68e06aa8f5 u 2023-08-16 10:52:58 +08:00
midoks d88003ca52 Update install.sh 2023-08-16 03:55:40 +08:00
midoks 8757c646f6 Update index.py 2023-08-16 03:49:13 +08:00
midoks c3e9d8aa4c update 2023-08-16 03:45:39 +08:00
midoks 7e3983f612 update 2023-08-16 03:25:46 +08:00
midoks a4e43b492d OP防火墙-加入地区限制 2023-08-16 02:53:29 +08:00
midoks 1f57517ea7 Update push_notice_msg.py 2023-08-15 09:47:44 +08:00
midoks b2fe35771d up 2023-08-15 00:00:44 +08:00
midoks 00ce3e00d3 update 2023-08-14 20:16:16 +08:00
midoks c7c28731a4 update 2023-08-14 19:42:08 +08:00
midoks 3305eab770 update 2023-08-14 18:30:29 +08:00
midoks b595359f38 Update index.py 2023-08-14 18:29:00 +08:00
midoks 5dc06b90ca Update init.lua 2023-08-14 12:56:59 +08:00
midoks 651fa7672c Update layout.html 2023-08-14 11:53:53 +08:00
midoks 7a0db5abef Update layout.html 2023-08-14 11:52:51 +08:00
midoks d21a5dfacc Update push_notice_msg.py 2023-08-14 09:15:50 +08:00
midoks 0c49749b63 Update waf_maxminddb.lua 2023-08-14 00:11:02 +08:00
midoks 11bb65a739 Update index.py 2023-08-13 22:03:55 +08:00
midoks ce44353cbf debug 1 2023-08-13 21:13:13 +08:00
midoks 2e5c5ef5b9 update 2023-08-13 18:32:30 +08:00
Mr Chen d1b687476b Merge pull request #436 from midoks/dev
0.15.4
2023-08-13 16:08:33 +08:00
midoks a46eabce10 update 2023-08-13 16:06:40 +08:00
midoks 08e378a3e4 Update push_ad.py 2023-08-13 16:02:29 +08:00
midoks c80ce63a4b Update push_notice_msg.py 2023-08-13 16:02:07 +08:00
midoks 72bb94df42 Update README.md 2023-08-13 15:26:45 +08:00
midoks e9b7aca47a Update imagemagick.sh 2023-08-13 15:20:26 +08:00
midoks f25d4f5a4f Update imagemagick.sh 2023-08-13 15:18:25 +08:00
midoks 59fcef76fe Update imagemagick.sh 2023-08-13 15:15:10 +08:00
midoks 4ab6ccbcbb Update imagemagick.sh 2023-08-13 15:14:22 +08:00
midoks fd457df3c8 up 2023-08-13 15:04:54 +08:00
midoks 147bec02a5 Update phplib.conf 2023-08-13 14:58:38 +08:00
midoks 34c126fbb7 Update ioncube.sh 2023-08-13 14:57:41 +08:00
midoks 4d21c920a8 Update all_test.sh 2023-08-13 14:56:25 +08:00
midoks 2d810fe7ab Update opcache.sh 2023-08-13 14:52:34 +08:00
midoks fb5260b9a5 Update opcache.sh 2023-08-13 14:50:24 +08:00
midoks 32b5542534 Update all_test.sh 2023-08-13 14:46:15 +08:00
midoks c665486122 Update redis.sh 2023-08-13 14:44:11 +08:00
midoks d3b885b1f9 Update redis.sh 2023-08-13 14:43:45 +08:00
midoks e476e36420 Update solr.sh 2023-08-13 14:37:24 +08:00
midoks 587503dc67 Update solr.sh 2023-08-13 14:31:18 +08:00
midoks cecfe9470f Update imagemagick.sh 2023-08-13 14:23:54 +08:00
midoks abc37acacc Update all_test.sh 2023-08-13 14:18:56 +08:00
midoks e0197fef3a Update eaccelerator.sh 2023-08-13 14:13:32 +08:00
midoks 04c4e7ddc8 Update xdebug.sh 2023-08-13 14:10:08 +08:00
midoks 6fb3e29a91 Update intl.sh 2023-08-13 14:01:10 +08:00
midoks 66fe66b479 update 2023-08-13 13:59:07 +08:00
midoks 4329d2470c update 2023-08-13 13:57:46 +08:00
midoks 0cd4527234 Update phalcon.sh 2023-08-13 13:44:07 +08:00
midoks bdba9149f2 update 2023-08-13 13:43:04 +08:00
midoks e05f7a9c3f Update seaslog.sh 2023-08-13 13:41:46 +08:00
midoks bddd81c94d Update zlib.sh 2023-08-13 13:40:54 +08:00
midoks f470392382 Update swoole.sh 2023-08-13 13:39:55 +08:00
midoks 895a250f06 update 2023-08-13 13:39:14 +08:00
midoks dd579b7e5c update 2023-08-13 13:33:47 +08:00
midoks cd0653d092 Update memcache.sh 2023-08-13 13:32:37 +08:00
midoks f2bc938ade Update memcache.sh 2023-08-13 13:32:18 +08:00
midoks dc694cae35 Update gettext.sh 2023-08-13 13:30:44 +08:00
midoks 0b98e40fec Update iconv.sh 2023-08-13 13:29:34 +08:00
midoks 10c40800ff Update mcrypt.sh 2023-08-13 13:28:38 +08:00
midoks 424d9fa799 Update intl.sh 2023-08-13 13:28:06 +08:00
midoks 1350fc7a4a Update gd_old.sh 2023-08-13 13:26:22 +08:00
midoks d678ade262 Update pcntl.sh 2023-08-13 13:24:54 +08:00
midoks 0b0b0bc9c5 Update bcmath.sh 2023-08-13 13:22:46 +08:00
midoks f3eee40e1e Update openssl.sh 2023-08-13 12:15:43 +08:00
midoks 8e0327a084 Update openssl.sh 2023-08-13 12:14:23 +08:00
midoks 0a4b5529b9 Update install.sh 2023-08-13 11:59:08 +08:00
midoks a8c17e1f3c update 2023-08-13 11:55:33 +08:00
midoks 4d242dd322 update 2023-08-13 11:49:54 +08:00
midoks 272a08f4eb Update install.sh 2023-08-13 11:45:15 +08:00
midoks 453009da40 Update install.sh 2023-08-13 11:39:20 +08:00
midoks 9c8880e1bb Update install.sh 2023-08-13 10:49:24 +08:00
midoks 4f716830ef update 2023-08-13 10:46:54 +08:00
midoks b4d799f8bd up 2023-08-13 10:14:22 +08:00
midoks e9fc7d5344 up 2023-08-13 01:42:50 +08:00
midoks 585d3d1839 Update install.sh 2023-08-13 00:12:35 +08:00
midoks 3278dd23b5 Update install.sh 2023-08-13 00:08:50 +08:00
midoks 5b406eaeb1 Update my8.0.cnf 2023-08-12 21:48:48 +08:00
midoks 0a354f649d mysql添加可过滤的同步错误 2023-08-12 21:11:32 +08:00
midoks 176dd4a5b8 Update install.sh 2023-08-12 20:13:44 +08:00
midoks 4bb9cc2d67 Update config_api.py 2023-08-12 17:05:12 +08:00
midoks f1edb26540 up 2023-08-12 17:04:56 +08:00
midoks 0692537cbd update 2023-08-12 16:41:15 +08:00
midoks 0710ca590a Update ubuntu.sh 2023-08-12 15:46:44 +08:00
midoks c19b12e8df Update swoole.sh 2023-08-12 15:37:40 +08:00
midoks 99eeee19ef Update all_test.sh 2023-08-12 15:19:10 +08:00
midoks fff3707031 Update solr.sh 2023-08-12 15:11:49 +08:00
midoks 0d0cb4add1 Update phalcon.sh 2023-08-12 15:06:52 +08:00
midoks 5ed37443da Update phalcon.sh 2023-08-12 14:47:18 +08:00
midoks 25b836e6f5 Update memcached.sh 2023-08-12 14:43:40 +08:00
midoks 4ca5c8e1a8 Merge branch 'master' into dev 2023-08-12 14:38:18 +08:00
midoks b522287a87 Merge branch 'master' into dev 2023-08-12 14:37:36 +08:00
Mr Chen 05cec7e0bf Merge pull request #435 from msycn/master
修复Openssl 1.1.1 重大漏洞/更新MySQL到8.0.34/更新php到8.2.8/更新redis到7.0.12
2023-08-12 14:36:42 +08:00
msycn b731868e06 Update openssl.sh 1.1.1 to 3.0.10
最新的稳定版本是 3.1 系列,支持到 2025 年 3 月 14 日。还提供 3.0 系列,它是长期支持 (LTS) 版本,支持到 2026 年 9 月 7 日。之前的 LTS 版本(1.1.1 系列)是 也可用并支持到 2023 年 9 月 11 日。所有旧版本(包括 1.1.0、1.0.2、1.0.0 和 0.9.8)现已不再支持,不应使用。 我们鼓励这些旧版本的用户尽快升级到3.1或3.0。 提供了对 1.0.2 的扩展支持,以获取该版本的安全修复程序。

The latest stable version is the 3.1 series supported until 14th March 2025. Also available is the 3.0 series which is a Long Term Support (LTS) version and is supported until 7th September 2026. The previous LTS version (the 1.1.1 series) is also available and is supported until 11th September 2023. All older versions (including 1.1.0, 1.0.2, 1.0.0 and 0.9.8) are now out of support and should not be used. Users of these older versions are encouraged to upgrade to 3.1 or 3.0 as soon as possible. Extended support for 1.0.2 to gain access to security fixes for that version is available.
2023-08-12 00:57:04 +08:00
msycn 9c4ceca41f Update install.sh 8.2.7 to 8.2.8
Version 8.2.8
06 Jul 2023
CLI:
Fixed bug GH-11246 (cli/get_set_process_title fails on MacOS).
Core:
Fixed build for the riscv64 architecture/GCC 12.
Curl:
Fixed bug GH-11433 (Unable to set CURLOPT_ACCEPT_ENCODING to NULL).
Date:
Fixed bug GH-11455 (Segmentation fault with custom object date properties).
DOM:
Fixed bugs GH-11288 and GH-11289 and GH-11290 and GH-9142 (DOMExceptions and segfaults with replaceWith).
Fixed bug GH-10234 (Setting DOMAttr::textContent results in an empty attribute value).
Fix return value in stub file for DOMNodeList::item.
Fix spec compliance error with '*' namespace for DOMDocument::getElementsByTagNameNS.
Fix DOMElement::append() and DOMElement::prepend() hierarchy checks.
Fixed bug GH-11347 (Memory leak when calling a static method inside an xpath query).
Fixed bug #67440 (append_node of a DOMDocumentFragment does not reconcile namespaces).
Fixed bug #81642 (DOMChildNode::replaceWith() bug when replacing a node with itself).
Fixed bug #77686 (Removed elements are still returned by getElementById).
Fixed bug #70359 (print_r() on DOMAttr causes Segfault in php_libxml_node_free_list()).
Fixed bug #78577 (Crash in DOMNameSpace debug info handlers).
Fix lifetime issue with getAttributeNodeNS().
Fix "invalid state error" with cloned namespace declarations.
Fixed bug #55294 and #47530 and #47847 (various namespace reconciliation issues).
Fixed bug #80332 (Completely broken array access functionality with DOMNamedNodeMap).
Opcache:
Fix allocation loop in zend_shared_alloc_startup().
Access violation on smm_shared_globals with ALLOC_FALLBACK.
Fixed bug GH-11336 (php still tries to unlock the shared memory ZendSem with opcache.file_cache_only=1 but it was never locked).
OpenSSL:
Fixed bug GH-9356 Incomplete validation of IPv6 Address fields in subjectAltNames (James Lucas, Jakub Zelenka).
PCRE:
Fix preg_replace_callback_array() pattern validation.
PGSQL:
Fixed intermittent segfault with pg_trace.
Phar:
Fix cross-compilation check in phar generation for FreeBSD.
SPL:
Fixed bug GH-11338 (SplFileInfo empty getBasename with more than one slash).
Standard:
Fix access on NULL pointer in array_merge_recursive().
Fix exception handling in array_multisort().
SQLite3:
Fixed bug GH-11451 (Invalid associative array containing duplicate keys).
2023-08-12 00:52:40 +08:00
msycn 22d266e710 Update redis 7.0.4 to 7.0.12 2023-08-12 00:50:36 +08:00
msycn d35bf118ff Update install.sh to 8.0.34 2023-08-12 00:48:17 +08:00
msycn 1adb2f751c Update MySQL to 8.0.34
Update MySQL to 8.0.34
2023-08-12 00:46:07 +08:00
midoks 54e743037e Update index.py 2023-08-11 21:04:46 +08:00
midoks 6debb93fd1 Update init.lua 2023-08-11 21:01:17 +08:00
midoks 7229f9c569 Update index.py 2023-08-11 20:59:34 +08:00
midoks 844dcbda00 cf验证问题解决 2023-08-11 20:58:52 +08:00
midoks af2b45a6f4 Update index.py 2023-08-11 20:54:37 +08:00
midoks d848d41a71 Update index.py 2023-08-11 20:44:59 +08:00
midoks 826ebfb2e5 Update init.lua 2023-08-11 20:05:04 +08:00
midoks e1807c1585 Update index.py 2023-08-11 17:17:08 +08:00
midoks 6e9d5a19c0 关于强制性验证优化 2023-08-11 17:15:47 +08:00
midoks 6eadad5db4 OP防火墙部分优化 2023-08-11 12:56:07 +08:00
midoks 2b2fc08120 Update index.py 2023-08-11 01:20:45 +08:00
midoks 175061884d update 2023-08-11 01:11:45 +08:00
midoks cc3fa8ac95 Update init.lua 2023-08-11 00:51:54 +08:00
midoks c9d736e338 update 2023-08-10 22:35:08 +08:00
midoks e4437e42f3 Update site_api.py 2023-08-10 21:19:49 +08:00
midoks 644fc2c81f Update mw.py 2023-08-10 21:09:59 +08:00
midoks d2314bf26f Update push_notice_msg.py 2023-08-10 18:44:22 +08:00
Mr Chen c17314b634 Merge pull request #434 from midoks/dev
MySQL,MariaDB数据库主从同步及多源同步
2023-08-10 11:32:24 +08:00
midoks 92a4b28fbf mariadb,mysql多源同步支持 2023-08-10 11:28:17 +08:00
midoks 733e4e81be update 2023-08-10 09:54:19 +08:00
midoks 8b99ae2515 update 2023-08-09 13:01:41 +08:00
midoks 2a72422402 update ad 2023-08-09 12:57:38 +08:00
midoks 145a259ef9 update 2023-08-09 08:57:49 +08:00
midoks a34b7719c8 update 2023-08-09 08:52:36 +08:00
midoks 4d98455c35 up 2023-08-08 21:17:49 +08:00
midoks c0c9def1fb Update index.py 2023-08-08 21:07:53 +08:00
midoks 02d8416466 update 2023-08-08 21:06:56 +08:00
midoks d505740269 Update index.py 2023-08-08 21:01:21 +08:00
midoks b1f6314df7 Update index.py 2023-08-08 16:54:17 +08:00
midoks 533653fe47 Update index.py 2023-08-08 16:48:21 +08:00
midoks dff4551fb1 update 2023-08-08 16:45:46 +08:00
midoks 79723149a5 Update install.sh 2023-08-08 16:32:07 +08:00
midoks 76da8a2ad5 Update install.sh 2023-08-08 16:25:40 +08:00
midoks 645538e633 Update index.py 2023-08-08 16:11:17 +08:00
midoks 1a1b4e9f3a Update index.py 2023-08-08 16:09:07 +08:00
midoks 3afde01f93 Update index.py 2023-08-08 16:07:44 +08:00
midoks a14db23971 Update index.py 2023-08-08 16:04:25 +08:00
midoks 316f06911b Update index.py 2023-08-08 16:01:34 +08:00
midoks 698d049314 up 2023-08-08 15:50:20 +08:00
midoks d397d74f73 Update index.py 2023-08-08 15:44:25 +08:00
midoks 8a7447a4ee Update mysql-apt.js 2023-08-08 15:37:45 +08:00
midoks 98414db41d update 2023-08-08 15:25:23 +08:00
midoks 7024185b59 Update my8.0.cnf 2023-08-08 14:52:57 +08:00
midoks 495f16f2cf Update mysql.js 2023-08-08 14:52:19 +08:00
midoks 62444b7b6d Update mysql.js 2023-08-08 14:51:59 +08:00
midoks 50b11457f7 update 2023-08-08 14:26:00 +08:00
midoks 393cbc3974 Merge branch 'master' into dev 2023-08-08 13:27:41 +08:00
midoks ce3bfc2ebd Merge branch 'master' into dev 2023-08-08 13:25:56 +08:00
Mr Chen b68e8f3650 Merge pull request #433 from midoks/midoks-patch-1
AD删除
2023-08-08 13:25:25 +08:00
Mr Chen 59a2765b2f AD删除 2023-08-08 13:24:29 +08:00
midoks 08c83edeb9 update 2023-08-08 13:17:39 +08:00
midoks c114e9aca8 Update index.py 2023-08-07 22:50:52 +08:00
midoks c5123268d0 Update index.py 2023-08-07 22:48:34 +08:00
midoks 54bbc3ff57 Update index.py 2023-08-07 22:39:24 +08:00
midoks 4658b991a9 Update index.py 2023-08-07 22:15:14 +08:00
midoks 52145e710b Update index.py 2023-08-07 22:05:01 +08:00
midoks 4acc48ded2 Update index.py 2023-08-07 22:04:00 +08:00
midoks 0d858f87ea Update index.py 2023-08-07 22:03:00 +08:00
midoks f37f08a9f5 Update index.py 2023-08-07 21:53:28 +08:00
midoks 0b5fc1de55 Update index.py 2023-08-07 21:52:53 +08:00
midoks 8748777101 Update index.py 2023-08-07 21:47:03 +08:00
midoks 48ed0b8034 Update index.py 2023-08-07 21:44:32 +08:00
midoks 41c9f6b7b6 Update mariadb.js 2023-08-07 21:24:42 +08:00
midoks c47336b65f update 2023-08-07 21:22:29 +08:00
midoks 24d7204ccc Update index.py 2023-08-07 21:05:22 +08:00
midoks 8c00fb8859 Update index.py 2023-08-07 20:42:08 +08:00
midoks c573b28f16 Update index.py 2023-08-07 20:41:11 +08:00
midoks afad548cf9 Update index.py 2023-08-07 20:22:26 +08:00
midoks 2605849de2 Update index.py 2023-08-07 20:02:18 +08:00
midoks 77598fa8a7 Update index.py 2023-08-07 19:44:47 +08:00
midoks b175ab735d Update index.py 2023-08-07 19:34:57 +08:00
midoks 54ed17ab8f Update index.py 2023-08-07 19:32:47 +08:00
midoks cadf72ea69 Update index.py 2023-08-07 17:53:33 +08:00
midoks dadb737f88 update 2023-08-07 15:59:00 +08:00
midoks fef2acf683 Update index.py 2023-08-07 15:56:59 +08:00
midoks 4b6dbf8887 Update mariadb.js 2023-08-07 15:46:10 +08:00
midoks 06c99e1cc1 Update index.py 2023-08-07 15:26:54 +08:00
midoks afb3e920f8 mariadb多住一从功能 2023-08-07 15:10:38 +08:00
midoks 2c346c9850 Update my.cnf 2023-08-06 14:38:47 +08:00
midoks 5b6c5be288 Update mariadb.js 2023-08-06 00:43:24 +08:00
midoks 63bd806222 Update index.py 2023-08-06 00:25:22 +08:00
midoks afe3848b71 update 2023-08-05 21:34:04 +08:00
midoks cd361ec7ec Update install.sh 2023-08-05 21:33:14 +08:00
midoks eb399fe799 Update install.sh 2023-08-05 21:32:25 +08:00
midoks 53e588b6fc Update install.sh 2023-08-05 21:31:58 +08:00
Mr Chen 612c104cca Merge pull request #432 from midoks/dev
PHP - libzip库修复
2023-08-05 17:35:09 +08:00
midoks 550ca7681a Update libzip.sh 2023-08-05 17:31:16 +08:00
midoks 6a09706362 Update libzip.sh 2023-08-05 17:30:26 +08:00
midoks ca040e8986 Update install.sh 2023-08-05 17:23:52 +08:00
midoks 6fcc980d5d Update libzip.sh 2023-08-05 17:19:39 +08:00
midoks b69adc9c7d Update libzip.sh 2023-08-05 17:09:10 +08:00
midoks 67da343705 Update libzip.sh 2023-08-05 17:05:48 +08:00
midoks 4b47e27a54 Update libzip.sh 2023-08-05 17:01:05 +08:00
midoks fba3ddc9a5 Update libzip.sh 2023-08-05 16:44:39 +08:00
Mr Chen 4769ce5be8 Merge pull request #431 from midoks/dev
0.15.2
2023-08-05 15:12:37 +08:00
midoks 8e16cbf7f9 0.15.2 2023-08-05 15:06:22 +08:00
midoks 4225d4c040 Update common.py 2023-08-05 14:43:14 +08:00
midoks b578f2fddc Update common.py 2023-08-05 14:42:43 +08:00
midoks 961c3423fd Update common.py 2023-08-05 14:29:52 +08:00
midoks 8040c8c67a Update common.py 2023-08-05 14:21:25 +08:00
midoks 5aca7d7c26 Update common.py 2023-08-05 14:17:16 +08:00
midoks d9f99e6b7c Update common.py 2023-08-05 14:17:01 +08:00
midoks 3addb46708 Update common.py 2023-08-05 13:46:19 +08:00
midoks e6b493237d 优化初始化安装SSH端口识别 2023-08-05 13:36:13 +08:00
midoks 7f42054a14 Update ubuntu.sh 2023-08-05 12:29:39 +08:00
midoks 501af3da15 Update plugins_api.py 2023-08-05 12:01:46 +08:00
midoks 68727cbe91 Update site_api.py 2023-08-05 11:28:33 +08:00
midoks c5207961f3 Update index.py 2023-08-05 01:52:49 +08:00
midoks a04e05c7e8 Update index.py 2023-08-05 01:19:42 +08:00
midoks 5b8cca24aa Update index.py 2023-08-05 00:46:41 +08:00
midoks cafe58f3fc Update index.py 2023-08-05 00:45:04 +08:00
midoks d1e2781eb9 Update index.py 2023-08-05 00:44:48 +08:00
midoks 67c899fc84 Update index.py 2023-08-05 00:43:06 +08:00
midoks 7432548ff9 Update index.py 2023-08-05 00:24:35 +08:00
midoks 0c2c136097 Update index.py 2023-08-04 23:58:21 +08:00
midoks 2a7e21951b Update my8.0.cnf 2023-08-04 22:49:18 +08:00
midoks 066185e404 网站设置反向代理升级功能 2023-08-04 20:27:20 +08:00
midoks bd431f1647 docker阶段性完成 2023-08-03 18:37:14 +08:00
midoks 0a6e88d81d update 2023-08-03 17:00:12 +08:00
midoks 02c9988ef7 Update docker.js 2023-08-03 00:24:13 +08:00
midoks 5ee7df4a46 Update nginx.conf 2023-08-03 00:14:16 +08:00
midoks 5f382c0034 update 2023-08-03 00:06:01 +08:00
midoks 63d17c4d77 Update docker.js 2023-08-02 23:24:10 +08:00
midoks 38722c1dc2 Update index.py 2023-08-02 17:51:29 +08:00
midoks ea982b7261 Update README.md 2023-08-02 17:50:22 +08:00
midoks 73d9edced8 使用mariadb二进制导入备份文件 2023-08-02 17:36:27 +08:00
midoks af03c004a3 Update rsyncd.js 2023-08-02 15:35:30 +08:00
midoks ddd9e70ac2 Update rsyncd.js 2023-08-02 15:29:32 +08:00
midoks 8976a7a147 Update rsyncd.js 2023-08-02 15:26:55 +08:00
midoks 677ff8ec0c Update README.md 2023-08-02 15:10:42 +08:00
midoks 47d240e2b8 rsyncd添加优化 2023-08-02 15:10:23 +08:00
midoks 1f7bd76875 Update crontab_api.py 2023-08-02 14:27:04 +08:00
midoks f04c70f022 计划任务自动脚本运行时间 2023-08-02 14:04:00 +08:00
midoks 5044cc5db9 Update README.md 2023-08-02 00:06:51 +08:00
midoks 4329b90ac4 Update info.json 2023-08-01 23:58:10 +08:00
midoks f7873b6dcd Update init_cmd.py 2023-07-25 00:03:20 +08:00
midoks a80d666786 update 2023-07-24 23:52:38 +08:00
Mr Chen 0598704dce Merge pull request #428 from midoks/dev
修复centos9源安装问题
2023-07-22 12:54:17 +08:00
midoks 8f19a05755 Update rhel.sh 2023-07-22 12:53:07 +08:00
midoks f320d7cc69 Update rhel.sh 2023-07-22 12:26:56 +08:00
midoks 1e97929a24 Update push_notice_msg.py 2023-07-21 12:10:55 +08:00
Mr Chen c66bbac97e Merge pull request #427 from midoks/dev
python3.7 urllib3在亚马逊降级
2023-07-20 16:14:22 +08:00
midoks 1f7a0d2795 Create r3.7.txt 2023-07-20 16:04:18 +08:00
midoks f05ce79e63 Update rhel.sh 2023-07-20 15:55:11 +08:00
midoks 9f3d06191a PHP提示优化 2023-07-19 18:35:27 +08:00
Mr Chen 2c6614a5ff Merge pull request #426 from midoks/dev
赞助换域名
2023-07-18 15:23:49 +08:00
midoks 905bad29cf Update README.md 2023-07-18 15:22:19 +08:00
midoks 9ba572a8ce AD修改 2023-07-16 17:23:45 +08:00
Mr Chen 85fc333d2c Merge pull request #424 from midoks/dev
0.15.1
2023-07-15 23:04:39 +08:00
midoks 5bc27a4725 Update config_api.py 2023-07-15 22:53:38 +08:00
midoks e5acf206f5 Update cli.sh 2023-07-15 20:43:13 +08:00
midoks ae7afc2eb5 Update rhel.sh 2023-07-15 20:34:46 +08:00
midoks 5c8527a5de 监控页面-自定义时间优化。 2023-07-15 19:33:17 +08:00
midoks 274592229e Update rhel.sh 2023-07-15 15:51:03 +08:00
midoks 60ddb13f8e Update rhel.sh 2023-07-15 15:50:35 +08:00
midoks f62af00fb7 Update rhel.sh 2023-07-15 15:49:28 +08:00
midoks 9c6faefffd Update rhel.sh 2023-07-15 15:38:14 +08:00
midoks c9e27c2add 优化
* [插件]docker - 添加IP地址池。
* PHP下载中国优化。
2023-07-15 15:00:00 +08:00
midoks 97b1e8b9b3 Update rhel.sh 2023-07-15 12:34:47 +08:00
midoks 18cdcd1436 修复子目录绑定-伪静态问题。 2023-07-13 10:36:16 +08:00
midoks 7d783c64b6 OP防火墙优化
站点配置-状态关闭后,不再防御。
2023-07-13 00:40:46 +08:00
midoks 0b65d69750 Update __init__.py 2023-07-12 22:18:55 +08:00
midoks 693dbb8cf1 Update __init__.py 2023-07-12 22:17:58 +08:00
midoks 117a99e729 增加标识 2023-07-12 09:46:58 +08:00
midoks 45d4b8a5de update 2023-07-11 16:25:34 +08:00
midoks a5791051b1 Update debian.sh 2023-07-11 16:11:20 +08:00
midoks dc3f8f8e0b 自动同步gitee 2023-07-11 12:21:48 +08:00
midoks bf1d00c012 Update config_api.py 2023-07-10 22:41:13 +08:00
midoks 51cf851cea Update site.js 2023-07-10 22:38:37 +08:00
midoks 1e09408eb9 Update index.py 2023-07-10 22:13:46 +08:00
midoks 7659865caf Update lib.sh 2023-07-05 22:19:44 +08:00
Mr Chen ad1851d068 Merge pull request #423 from midoks/dev
requests兼容低版本
2023-07-05 18:05:33 +08:00
midoks e174652afc Update requirements.txt 2023-07-05 18:02:40 +08:00
midoks a95e7aacd7 Update r3.6.txt 2023-07-05 18:00:36 +08:00
Mr Chen 6aa638ef9a Merge pull request #422 from midoks/dev
Update requirements.txt
2023-07-05 13:03:14 +08:00
midoks 6f3d50bae5 Update requirements.txt 2023-07-05 13:01:08 +08:00
Mr Chen 301a5a95b8 Merge pull request #421 from midoks/dev
AD
2023-07-05 12:51:37 +08:00
midoks d35b9dccc7 AD信息 2023-07-05 12:49:47 +08:00
midoks 82680605ac mvirtua ad 2023-07-05 12:47:05 +08:00
midoks 5b148b3d1a Update requirements.txt 2023-07-05 10:20:04 +08:00
Mr Chen 714acd20e5 Merge pull request #420 from midoks/dev
0.15.0
2023-07-04 20:55:21 +08:00
midoks bf58cd8acc Update config_api.py 2023-07-04 20:52:57 +08:00
midoks 059053d27c mysql安装成功后,删除原文件 2023-07-03 22:22:11 +08:00
midoks 185e73c26a Update index.py 2023-07-03 22:12:55 +08:00
midoks 569511d321 update 2023-07-03 22:08:00 +08:00
midoks f88bf5059f Update README.md 2023-07-03 17:52:56 +08:00
midoks 05b63b8d2b Update index.py 2023-07-03 17:45:12 +08:00
midoks 3a197b273d Update docker.js 2023-07-03 17:37:14 +08:00
midoks f4fdbab41c Update index.py 2023-07-03 17:35:34 +08:00
midoks f6b2940657 docker插件容器创建OK 2023-07-03 17:34:58 +08:00
midoks 78b9ac5df0 up 2023-07-03 11:53:54 +08:00
midoks 3ea4272307 Update docker.js 2023-07-02 16:29:10 +08:00
midoks efc7cee9ad Update docker.js 2023-07-02 15:36:38 +08:00
midoks 5c4805453d Update docker.js 2023-07-02 15:27:25 +08:00
midoks f6da241c85 update 2023-07-02 14:38:56 +08:00
midoks d5b6eb2325 update 2023-07-01 22:06:54 +08:00
midoks 6ed2cddf71 Update docker.js 2023-07-01 21:35:46 +08:00
midoks 9c31d76442 docker update 2023-07-01 21:34:04 +08:00
midoks 7aecbaf7df Update docker.js 2023-07-01 15:22:41 +08:00
midoks ee81a86d24 update 2023-07-01 15:17:43 +08:00
midoks 0a60d66732 update 2023-07-01 14:46:22 +08:00
midoks c3e3cff472 Update docker.js 2023-07-01 12:37:15 +08:00
midoks 194d46eb6a Update docker.js 2023-07-01 12:37:02 +08:00
midoks d66bc94edc Update docker.js 2023-07-01 12:34:09 +08:00
midoks fb4ffcd343 Update index.py 2023-07-01 12:30:58 +08:00
midoks 10c235e317 Update r3.6.txt 2023-07-01 12:25:32 +08:00
midoks 9c156928d8 up 2023-07-01 12:24:04 +08:00
midoks 771905d7f6 Update requirements.txt 2023-07-01 12:23:01 +08:00
midoks cd21b3f3e7 Update r3.6.txt 2023-07-01 12:22:18 +08:00
midoks 982026db24 update 2023-07-01 12:21:07 +08:00
midoks f9b91d9989 Update docker.js 2023-07-01 12:17:30 +08:00
midoks f7b1159bd7 update 2023-07-01 12:15:51 +08:00
midoks 6aa49ddbcf Update rhel.sh 2023-07-01 11:48:06 +08:00
midoks 866eddac1d Update lib.sh 2023-07-01 10:19:42 +08:00
midoks af0cce4216 Update install.sh 2023-07-01 10:16:39 +08:00
midoks 3951322d86 Update install_dev.sh 2023-07-01 10:16:23 +08:00
midoks dfdd16b444 Update index.py 2023-07-01 10:11:15 +08:00
midoks aa8fec2b7e update 2023-07-01 09:52:53 +08:00
midoks 2a8958ab84 Update index.py 2023-07-01 00:32:36 +08:00
midoks f5125670ee Update index.py 2023-07-01 00:19:24 +08:00
midoks 2a8d4fb7a9 Update requirements.txt 2023-07-01 00:14:04 +08:00
midoks 59f7fe2290 Update requirements.txt 2023-07-01 00:07:30 +08:00
midoks 928db6e7e7 Update requirements.txt 2023-07-01 00:02:13 +08:00
midoks f3927bd6cf Update requirements.txt 2023-07-01 00:01:32 +08:00
midoks bb92727b56 Update requirements.txt 2023-07-01 00:00:14 +08:00
midoks 21b80b1fce Update index.py 2023-06-30 23:54:05 +08:00
midoks 637da92834 up 2023-06-30 23:43:51 +08:00
midoks f5859626a9 update 2023-06-30 21:57:42 +08:00
midoks 003449eb0a update 2023-06-30 12:30:28 +08:00
midoks d27f926191 update 2023-06-30 12:16:25 +08:00
midoks 7483247d4d up 2023-06-30 10:17:02 +08:00
midoks 1ad841d3af Update docker.js 2023-06-30 00:09:15 +08:00
midoks 27376d879c up 2023-06-30 00:09:09 +08:00
midoks 8b824447c1 Update php.service.tpl 2023-06-29 18:29:39 +08:00
midoks a1d26dcd45 Update intl.sh 2023-06-29 16:25:12 +08:00
midoks 5e68c7bf0a Update install.sh 2023-06-29 13:00:08 +08:00
midoks 481ae16713 Update index.py 2023-06-29 12:59:05 +08:00
midoks 2d2bd39f9e Update intl.sh 2023-06-29 12:02:48 +08:00
midoks 7246a878a5 Update intl.sh 2023-06-29 12:00:37 +08:00
midoks 542ee3cdb0 Update intl.sh 2023-06-29 11:59:59 +08:00
midoks 69503b223b update 2023-06-29 11:43:56 +08:00
midoks 78d8fa7ebf Update lib.sh 2023-06-29 10:54:26 +08:00
midoks 21e9d8f2d8 Update update_dev.sh 2023-06-29 10:49:10 +08:00
midoks 3c6adfbd44 Update install.sh 2023-06-29 10:41:10 +08:00
midoks c0e70abe6d Update install_dev.sh 2023-06-29 10:40:31 +08:00
midoks f174e71228 Update app.py 2023-06-29 10:25:14 +08:00
midoks 7a9a811ea6 Update app.py 2023-06-29 10:21:39 +08:00
midoks c7e3d9d9a3 Update app.py 2023-06-29 10:20:39 +08:00
midoks 161f7a1bc0 Update app.py 2023-06-29 10:18:52 +08:00
midoks 175cce0131 Update lib.sh 2023-06-29 10:11:52 +08:00
midoks 3735897ed2 Update lib.sh 2023-06-29 09:59:06 +08:00
midoks 30bfa5a630 Update lib.sh 2023-06-29 09:56:24 +08:00
midoks 594fdb4712 Update lib.sh 2023-06-29 09:55:14 +08:00
midoks 31a441ea02 update 2023-06-29 09:52:30 +08:00
midoks 06f7087fad Update requirements.txt 2023-06-29 09:30:06 +08:00
midoks e7b8f5afdc Update index.py 2023-06-29 09:25:55 +08:00
midoks 6b57addfa7 Update index.py 2023-06-28 19:11:44 +08:00
midoks aea435fbaf Update index.py 2023-06-28 18:53:45 +08:00
midoks 9cd6656946 u 2023-06-28 16:04:17 +08:00
midoks 4f7df4b3c3 Update index.py 2023-06-28 14:58:45 +08:00
midoks 70d12b7b8d docker 2023-06-28 14:53:59 +08:00
midoks fe576c820a Update requirements.txt 2023-06-28 04:09:09 +08:00
midoks b48a53e0d7 Create nezha.conf 2023-06-28 04:04:44 +08:00
midoks 4701839c33 up 2023-06-28 03:40:23 +08:00
midoks 916bc67c4d Update cert_api.py 2023-06-28 03:21:11 +08:00
midoks d7bba830cc Update requirements.txt 2023-06-28 02:33:11 +08:00
midoks 7a28f8f57a Update index.py 2023-06-28 02:30:28 +08:00
midoks 41ee25aa7b update 2023-06-28 02:21:59 +08:00
midoks c8aa91cfa3 up 2023-06-28 02:09:28 +08:00
midoks 98f27498b0 Update index.py 2023-06-28 01:57:06 +08:00
midoks 5444fe6455 Update index.py 2023-06-28 01:40:41 +08:00
midoks 9627c6e47b Update index.py 2023-06-28 01:32:14 +08:00
midoks 13597d6282 Update index.py 2023-06-28 01:21:15 +08:00
midoks d09494e3aa Update index.py 2023-06-28 01:14:15 +08:00
midoks d35439d286 Update index.py 2023-06-28 01:14:03 +08:00
midoks ced48bab47 nezha 测试OK 2023-06-28 01:02:58 +08:00
midoks fe2df6cc8d up 2023-06-28 00:08:38 +08:00
midoks 8bdfe15101 nezha 60% 2023-06-28 00:04:07 +08:00
midoks 42e9983b88 Update config.json 2023-06-27 15:56:43 +08:00
midoks 9b7c0b6f99 up 2023-06-27 15:11:38 +08:00
midoks e421292c9e up 2023-06-27 14:13:04 +08:00
midoks 7b4d31779a Update install.sh 2023-06-27 01:31:52 +08:00
midoks f3b09056f3 init nezha plugin 2023-06-26 23:06:06 +08:00
midoks a92ccea6c5 lrzsz 2023-06-26 11:57:07 +08:00
midoks 9da77a0a9b up 2023-06-24 22:37:02 +08:00
midoks c233ecaaa7 up 2023-06-22 16:06:04 +08:00
midoks 5828b8b8cb up 2023-06-22 16:00:09 +08:00
midoks a4a1a2c83c up 2023-06-20 16:39:36 +08:00
midoks 0e20bc182c up 2023-06-19 20:28:44 +08:00
midoks 99c0b0a81a Update site_api.py 2023-06-17 23:20:24 +08:00
midoks 3fa199fec4 acme部署问题 2023-06-17 23:18:15 +08:00
midoks 194c36c6d8 tg ad 2023-06-15 01:43:21 +08:00
midoks 2fb542f6b4 Update all_test.sh 2023-06-14 01:25:55 +08:00
midoks 60af43ed31 Update intl.sh 2023-06-14 01:24:15 +08:00
midoks 9f02cf9744 Update install.sh 2023-06-14 01:21:47 +08:00
midoks 846bd270df Update yaf.sh 2023-06-14 01:14:47 +08:00
midoks d910d4f462 up 2023-06-14 00:31:20 +08:00
midoks 13f5b1bf02 up 2023-06-13 18:34:57 +08:00
midoks 1fc3fd6247 Update lib.sh 2023-06-13 18:03:53 +08:00
midoks 36e3feb886 Update requirements.txt 2023-06-13 17:46:00 +08:00
midoks 0ca34afacd Update lib.sh 2023-06-13 17:43:39 +08:00
midoks ffb3288f3d Update requirements.txt 2023-06-13 17:40:55 +08:00
midoks e2f68a73ed Update requirements.txt 2023-06-13 17:34:23 +08:00
midoks 92fa8da2f6 Update lib.sh 2023-06-13 17:19:23 +08:00
midoks 7c96ddd63e Update lib.sh 2023-06-13 17:14:50 +08:00
midoks c4e7872179 Update lib.sh 2023-06-13 17:14:31 +08:00
midoks d399cb2bb4 Update install.sh 2023-06-13 16:38:04 +08:00
midoks 985cbc7eca Update install.sh 2023-06-13 16:36:48 +08:00
midoks 27ed21a17d update 2023-06-10 15:09:31 +08:00
midoks 972165ba1a Update lib.sh 2023-05-30 17:53:16 +08:00
midoks e76eb4d0e8 Update client_check_member.py 2023-05-29 18:40:12 +08:00
midoks fd05c40dbb up 2023-05-29 18:34:37 +08:00
midoks a1a7fa5c82 网站备注优化 2023-05-28 19:59:31 +08:00
midoks 531de1407f Update push_notice_msg.py 2023-05-28 19:00:42 +08:00
midoks ca455f13e8 ad 2023-05-28 14:50:53 +08:00
midoks ab5342b01f Update docker.js 2023-05-27 00:18:44 +08:00
midoks a5a57c5718 update 2023-05-27 00:18:39 +08:00
midoks 27999b21e6 Update config.json 2023-05-24 23:04:59 +08:00
midoks d2c6caeef2 Update client_temp.py 2023-05-23 20:46:32 +08:00
midoks de30d8a41f Create client_temp.py 2023-05-23 20:42:08 +08:00
midoks d3abc8e7b2 up 2023-05-18 17:10:50 +08:00
midoks b7aad65eb5 Update site_api.py 2023-05-17 13:36:35 +08:00
midoks 240b1dec27 修正网站搜索功能 2023-05-16 20:34:12 +08:00
midoks 4756e0f68b Update push_notice_msg.py 2023-05-15 19:30:38 +08:00
midoks 59f62b948a Update push_notice_msg.py 2023-05-15 19:30:00 +08:00
midoks 0ab0741031 up 2023-05-15 19:23:32 +08:00
midoks 2fd2f6e844 AD 2023-05-15 19:20:58 +08:00
midoks e534c6177a update 2023-05-15 19:14:43 +08:00
midoks 897c6322fc Update install.sh 2023-05-14 23:57:41 +08:00
midoks 201e93f946 Update requirements.txt 2023-05-14 19:09:02 +08:00
Mr Chen a78fd957ec Merge pull request #411 from midoks/dev
更新pip库2
2023-05-14 19:05:30 +08:00
midoks 3ce037b0a1 Update requirements.txt 2023-05-14 19:03:39 +08:00
midoks f3176340f8 Update requirements.txt 2023-05-14 19:02:58 +08:00
midoks 7bfe096e8d Update requirements.txt 2023-05-14 19:00:45 +08:00
Mr Chen 066428fca8 Merge pull request #410 from midoks/dev
更新pip版本
2023-05-14 18:46:51 +08:00
midoks a1313846c8 Update requirements.txt 2023-05-14 18:43:47 +08:00
midoks 0433123abd Update requirements.txt 2023-05-14 18:36:50 +08:00
midoks 72e99844dd Update requirements.txt 2023-05-14 18:31:19 +08:00
Mr Chen 3a7882e7fa Merge pull request #409 from midoks/dev
0.14.5
2023-05-14 13:12:27 +08:00
midoks bec2a9a12c 0.14.5
* 软件管理-搜索功能。
* 文件-右键功能优化。
2023-05-14 13:10:17 +08:00
midoks 8f02363782 Update files.html 2023-05-12 11:22:38 +08:00
midoks 939c847f3e Update plugins_api.py 2023-05-10 18:23:06 +08:00
midoks a623039db7 完成搜索功能 2023-05-10 18:20:48 +08:00
midoks b7f49a1839 Update soft.html 2023-05-10 17:59:17 +08:00
midoks f1f60870f6 up 2023-05-09 12:46:09 +08:00
midoks 3b04739fd4 up 2023-05-09 12:45:25 +08:00
midoks fdf1e0b0be up 2023-05-09 12:39:44 +08:00
midoks d3385f526f Update client_check_member.py 2023-05-09 11:37:39 +08:00
midoks 20f9095b93 up 2023-05-09 09:17:54 +08:00
midoks 757cf483a2 Update client_ad.py 2023-05-08 12:07:36 +08:00
midoks 1712cfd024 Update client_ad.py 2023-05-08 12:03:16 +08:00
midoks 2b524cbe75 Update client_ad.py 2023-05-08 11:57:01 +08:00
midoks 607d384000 Update client_ad.py 2023-05-08 11:29:09 +08:00
midoks 14cdc7b82e Update client_ad.py 2023-05-08 11:15:27 +08:00
midoks c3219bcba2 Update client_check_member.py 2023-05-07 23:15:06 +08:00
Mr Chen a12c4dd78e Merge pull request #407 from midoks/dev
0.14.4
2023-05-06 14:54:52 +08:00
midoks 39c6f19592 Update README.md 2023-05-06 14:54:34 +08:00
midoks f18c05a097 0.14.4 2023-05-06 14:53:16 +08:00
midoks 80f296ea19 redat 系列 php74之后都需要安装oniguruma
debian系统,不需要
2023-05-06 14:42:54 +08:00
midoks b3e9283a58 Update rhel.sh 2023-05-06 14:37:25 +08:00
midoks 2e140a3ae1 Update index.py 2023-05-06 14:18:46 +08:00
midoks 4d733c8886 Update index.py 2023-05-06 14:16:50 +08:00
midoks 62a7320baf Update rhel.sh 2023-05-06 13:59:02 +08:00
midoks 3dc7c2f5c1 Update rhel.sh 2023-05-06 13:52:55 +08:00
midoks fe62bbee06 Update rhel.sh 2023-05-06 13:24:47 +08:00
midoks f7c0cd82a0 Update rhel.sh 2023-05-06 13:22:49 +08:00
midoks 13a2014558 Update rhel.sh 2023-05-06 12:49:25 +08:00
midoks 5981f94376 Update rhel.sh 2023-05-06 12:30:51 +08:00
midoks 005e0f1513 Update rhel.sh 2023-05-06 12:27:54 +08:00
midoks 63a0f0fbdc Update rhel.sh 2023-05-05 23:32:07 +08:00
midoks edc0be11a1 Update rhel.sh 2023-05-05 23:22:22 +08:00
midoks 908b6e67c6 Update rhel.sh 2023-05-05 23:21:57 +08:00
midoks dfe46332db up 2023-05-05 22:49:39 +08:00
midoks fcdf2e18b2 Update config_api.py 2023-05-05 22:19:33 +08:00
midoks 3c8f9bcf96 Update config.js 2023-05-05 22:19:26 +08:00
midoks ebadd6d80d 端口修改后,跳转优化 2023-05-05 22:16:53 +08:00
Mr Chen 6062699074 Merge pull request #406 from midoks/dev
0.14.3
2023-05-05 20:52:04 +08:00
midoks df9d57ba70 Update README.md 2023-05-05 20:50:20 +08:00
midoks ffca953539 up 2023-05-05 20:49:45 +08:00
midoks bd4946124f Update install.sh 2023-05-05 18:21:10 +08:00
midoks 8e18c63cee up 2023-05-05 17:52:13 +08:00
midoks d201ca2574 Update install_dev.sh 2023-05-05 17:51:09 +08:00
midoks b644f91090 安装时curl库软连接修复 2023-05-05 16:59:47 +08:00
midoks 931f51cf59 Update client_ad.py 2023-05-05 14:12:14 +08:00
midoks 0909a11fd9 Update client_ad.py 2023-05-05 14:03:45 +08:00
midoks 2ba2833699 Update client_ad.py 2023-05-05 13:59:14 +08:00
midoks 20389263fb Update client_ad.py 2023-05-04 20:41:10 +08:00
midoks 86141ccf3a Update my5.7.cnf 2023-05-04 16:42:59 +08:00
midoks b2fdf84ca0 Update index.py 2023-05-04 16:39:46 +08:00
midoks 8fbc456e1a Update my5.7.cnf 2023-05-04 13:19:21 +08:00
midoks 4e43382496 Update client_ad.py 2023-05-03 18:29:37 +08:00
midoks 0326d4f112 Update client_ad.py 2023-05-03 18:05:33 +08:00
midoks a87c13c5e0 Update client_ad.py 2023-05-03 13:02:21 +08:00
midoks 5f3720c855 Update client_ad.py 2023-05-03 12:50:41 +08:00
midoks f548e020c4 up 2023-05-03 12:33:56 +08:00
midoks 7f21781c0b Update tgclient.py 2023-05-03 12:33:01 +08:00
midoks 680b0f09f2 Update client_ad.py 2023-05-03 12:22:31 +08:00
midoks 482943a63c Update client_ad.py 2023-05-03 10:53:49 +08:00
midoks 2871aee18e Create client_ad.py 2023-05-03 10:53:18 +08:00
midoks ff46d9b36e up 2023-05-02 21:39:18 +08:00
midoks fd5fcba543 up 2023-05-02 13:25:07 +08:00
294 changed files with 16746 additions and 3161 deletions
+16
View File
@@ -0,0 +1,16 @@
name: sync2gitee
on: [push]
jobs:
repo-sync:
runs-on: ubuntu-latest
steps:
- name: Mirror the Github organization repos to Gitee.
uses: Yikun/hub-mirror-action@master
with:
src: 'github/midoks'
dst: 'gitee/midoks'
dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
dst_token: ${{ secrets.GITEE_TOKEN }}
static_list: "mdserver-web"
force_update: true
+2 -3
View File
@@ -163,7 +163,6 @@ plugins/l2tp
plugins/openlitespeed
plugins/tamper_proof
plugins/cryptocurrency_trade
plugins/gdrive
plugins/mtproxy
plugins/zimg
plugins/bk_demo
@@ -177,5 +176,5 @@ debug.out
mdioks.session-journal
*.session
mdioks.session-journal
*.session
+12 -6
View File
@@ -10,7 +10,7 @@
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
复制了后台管理界面,按照自己想要的方式写了一版。
![EulerOS](https://img.shields.io/badge/LINUX-EulerOS-blue?style=for-the-badge&logo=EulerOS)
![Debian](https://img.shields.io/badge/LINUX-Debian-blue?style=for-the-badge&logo=Debian)
![Ubuntu](https://img.shields.io/badge/LINUX-Ubuntu-blue?style=for-the-badge&logo=Ubuntu)
![Fedora](https://img.shields.io/badge/LINUX-Fedora-blue?style=for-the-badge&logo=Fedora)
@@ -79,7 +79,8 @@ PHP[72-82]支持phpMyAdmin[5.2.0]
# 特别赞助
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.la/)
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.pw/)
- [鲲鹏vpn,免费试用,解锁流媒体和chatGPT](https://down.xbjc888.top/?agent_code=github)
# AD - VPS推荐 - 🙏
@@ -99,11 +100,14 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.14.2
### 版本更新 0.16.1
* 加入TgClient插件
* 网站防篡改程序(测试中)
* Docker(测试中)
* 给防盗链增加禁止空来源。
* OpenResty安装兼容。
* Debian10安装优化。
* 安装时默认监控开启。
* MySQL/MYSQL-YUM/MySQL-APT添加重置master功能。
* 支持华为欧拉系统。
### JSDelivr安装地址
@@ -162,6 +166,8 @@ curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
wget --no-check-certificate -O install.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install.sh && bash install.sh
wget --no-check-certificate -O uninstall.sh https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/uninstall.sh && bash uninstall.sh
curl --insecure -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/quick/debug.sh | bash
+1
View File
@@ -28,6 +28,7 @@ from route import app, socketio
from gevent.pywsgi import WSGIServer
from geventwebsocket.handler import WebSocketHandler
from gevent import monkey
monkey.patch_all()
+14 -9
View File
@@ -930,7 +930,8 @@ fi
index).encode()
)
X509Req.set_pubkey(pk)
X509Req.set_version(2)
# X509Req.set_version(2)
X509Req.set_version(0)
X509Req.sign(pk, self.__digest)
return OpenSSL.crypto.dump_certificate_request(OpenSSL.crypto.FILETYPE_ASN1, X509Req)
@@ -1495,8 +1496,9 @@ fullchain.pem 粘贴到证书输入框
'cert_timeout'] = int(time.time())
if self.__config['orders'][i]['cert_timeout'] > start_time:
writeLog(
"|-本次跳过域名: {},未过期!".format(self.__config['orders'][i]['domains'][0]))
msg = "|-本次跳过域名: {},未过期!".format(
self.__config['orders'][i]['domains'][0])
writeLog(msg)
continue
# 已删除的网站直接跳过续签
@@ -1513,8 +1515,9 @@ fullchain.pem 粘贴到证书输入框
break
if not mw.M('domain').where("name=?", (domain,)).count() and not mw.M('binding').where("domain=?", domain).count():
auth_to = None
writeLog(
"|-跳过被删除的域名: {}".format(self.__config['orders'][i]['domains']))
msg = "|-跳过被删除的域名: {}".format(
self.__config['orders'][i]['domains'])
writeLog(msg)
if not auth_to:
continue
@@ -1525,15 +1528,17 @@ fullchain.pem 粘贴到证书输入框
timeout = self.__config['orders'][i][
'next_retry_time'] - int(time.time())
if timeout > 0:
writeLog('|-本次跳过域名:{},因第上次续签失败,还需要等待{}小时后再重试'.format(
self.__config['orders'][i]['domains'], int(timeout / 60 / 60)))
msg = '|-本次跳过域名:{},因第上次续签失败,还需要等待{}小时后再重试'.format(
self.__config['orders'][i]['domains'], int(timeout / 60 / 60))
writeLog(msg)
continue
# 是否到了最大重试次数
if 'retry_count' in self.__config['orders'][i]:
if self.__config['orders'][i]['retry_count'] >= 5:
writeLog('|-本次跳过域名:{},因连续5次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
self.__config['orders'][i]['domains']))
msg = '|-本次跳过域名:{},因连续5次续签失败,不再续签此证书(可尝试手动续签此证书,成功后错误次数将被重置)'.format(
self.__config['orders'][i]['domains'])
writeLog(msg)
continue
# 加入到续签订单
+2 -1
View File
@@ -840,7 +840,8 @@ class cert_request:
index).encode()
)
X509Req.set_pubkey(pk)
X509Req.set_version(2)
# X509Req.set_version(2)
X509Req.set_version(0)
X509Req.sign(pk, self.__digest)
return OpenSSL.crypto.dump_certificate_request(OpenSSL.crypto.FILETYPE_ASN1, X509Req)
+25
View File
@@ -32,7 +32,9 @@ from flask import redirect
def init():
initSystemControl()
initDB()
initDBSshPort()
initUserInfo()
initInitD()
initInitTask()
@@ -62,6 +64,17 @@ def initDB():
print(str(ex))
def initDBSshPort():
# SSH端口必须放开
import firewall_api
cmd_data = mw.execShell(
"cat /etc/ssh/sshd_config | grep '^Port \d*' | tail -1")
ssh_port = cmd_data[0].replace("Port ", '').strip()
if ssh_port == '':
ssh_port = '22'
firewall_api.firewall_api().addAcceptPortArgs(ssh_port, 'SSH远程管理服务', 'port')
def doContentReplace(src, dst):
content = mw.readFile(src)
content = content.replace("{$SERVER_PATH}", mw.getRunDir())
@@ -133,10 +146,22 @@ def initInitTask():
api.createCertCron()
def initSystemControl():
path = 'data/default.db'
if os.path.exists(path):
return False
import system_api
sapi = system_api.system_api()
r = sapi.setControl(1, 30)
print(r)
def initUserInfo():
data = mw.M('users').where('id=?', (1,)).getField('password')
if data == '21232f297a57a5a743894a0e4a801fc3':
pwd = mw.getRandomString(8).lower()
file_pw = mw.getRunDir() + '/data/default.pl'
mw.writeFile(file_pw, pwd)
+1 -1
View File
@@ -27,7 +27,7 @@ from flask import request
class config_api:
__version = '0.14.2'
__version = '0.16.1'
__api_addr = 'data/api.json'
def __init__(self):
+30 -9
View File
@@ -508,6 +508,22 @@ class crontab_api:
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
@@ -515,7 +531,7 @@ if [ -f $MW_PATH ];then
source $MW_PATH
fi''' % (mw.getRunDir(),)
head = head + source_bin_activate + "\n"
head = head + start_head + source_bin_activate + "\n"
log = '.log'
script_dir = mw.getRunDir() + "/scripts"
@@ -557,7 +573,10 @@ fi''' % (mw.getRunDir(),)
shell += '''
echo "----------------------------------------------------------------------------"
endDate=`date +"%Y-%m-%d %H:%M:%S"`
echo "★[$endDate] Successful"
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'
@@ -583,20 +602,22 @@ echo "--------------------------------------------------------------------------
# 将Shell脚本写到文件
def writeShell(self, config):
u_file = '/var/spool/cron/crontabs/root'
if not os.path.exists(u_file):
file = '/var/spool/cron/crontabs/root'
current_os = mw.getOs()
if current_os == 'darwin':
file = '/etc/crontab'
elif current_os.startswith("freebsd"):
file = '/var/cron/tabs/root'
if not os.path.exists(file):
file = '/var/spool/cron/root'
if mw.isAppleSystem():
file = '/etc/crontab'
else:
file = u_file
if not os.path.exists(file):
mw.writeFile(file, '')
conf = mw.readFile(file)
conf += str(config) + "\n"
if mw.writeFile(file, conf):
if not os.path.exists(u_file):
if not os.path.exists(file):
mw.execShell("chmod 600 '" + file +
"' && chown root.root " + file)
else:
+1 -1
View File
@@ -65,7 +65,7 @@ class Sql():
self.__DB_TABLE = table
return self
def where(self, where, param):
def where(self, where, param=()):
# WHERE条件
if where:
self.__OPT_WHERE = " WHERE " + where
+7 -5
View File
@@ -64,8 +64,13 @@ class files_api:
filename = request.args.get('filename', '')
if not os.path.exists(filename):
return ''
is_attachment = True
if filename.endswith(".svg"):
is_attachment = False
response = make_response(send_from_directory(
os.path.dirname(filename), os.path.basename(filename), as_attachment=True))
os.path.dirname(filename), os.path.basename(filename), as_attachment=is_attachment))
return response
def zipApi(self):
@@ -708,10 +713,7 @@ class files_api:
return not path in nDirs
def getDirSize(self, path):
if mw.isAppleSystem():
tmp = mw.execShell('du -sh ' + path)
else:
tmp = mw.execShell('du -sbh ' + path)
tmp = mw.execShell('du -sh ' + path)
return tmp
def checkFileName(self, filename):
-33
View File
@@ -178,12 +178,6 @@ class firewall_api:
limit = request.form.get('limit', '10').strip()
return self.getList(int(p), int(limit))
def getLogListApi(self):
p = request.form.get('p', '1').strip()
limit = request.form.get('limit', '10').strip()
search = request.form.get('search', '').strip()
return self.getLogList(int(p), int(limit), search)
def getSshInfoApi(self):
data = {}
@@ -389,11 +383,6 @@ class firewall_api:
return mw.returnData(True, '设置成功!')
def delPanelLogsApi(self):
mw.M('logs').where('id>?', (0,)).delete()
mw.writeLog('面板设置', '面板操作日志已清空!')
return mw.returnJson(True, '面板操作日志已清空!')
##### ----- start ----- ###
def getList(self, page, limit):
@@ -414,28 +403,6 @@ class firewall_api:
data['page'] = mw.getPage(_page)
return mw.getJson(data)
def getLogList(self, page, limit, search=''):
find_search = ''
if search != '':
find_search = "type like '%" + search + "%' or log like '%" + \
search + "%' or addtime like '%" + search + "%'"
start = (page - 1) * limit
_list = mw.M('logs').where(find_search, ()).field(
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
data = {}
data['data'] = _list
count = mw.M('logs').where(find_search, ()).count()
_page = {}
_page['count'] = count
_page['tojs'] = 'getLogs'
_page['p'] = page
data['page'] = mw.getPage(_page)
return mw.getJson(data)
def addAcceptPort(self, port):
if self.__isUfw:
mw.execShell('ufw allow ' + port + '/tcp')
+352
View File
@@ -0,0 +1,352 @@
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 日志类操作
# ---------------------------------------------------------------------------------
import psutil
import time
import os
import sys
import mw
import re
import json
import pwd
from datetime import datetime
from flask import request
class logs_api:
__months = {'Jan': '01', 'Feb': '02', 'Mar': '03', 'Apr': '04', 'May': '05', 'Jun': '06',
'Jul': '07', 'Aug': '08', 'Sep': '09', 'Sept': '09', 'Oct': '10', 'Nov': '11', 'Dec': '12'}
def __init__(self):
pass
def delPanelLogsApi(self):
mw.M('logs').where('id>?', (0,)).delete()
mw.writeLog('面板设置', '面板操作日志已清空!')
return mw.returnJson(True, '面板操作日志已清空!')
def getLogListApi(self):
p = request.form.get('p', '1').strip()
limit = request.form.get('limit', '10').strip()
search = request.form.get('search', '').strip()
return self.getLogList(int(p), int(limit), search)
def getLogList(self, page, limit, search=''):
find_search = ''
if search != '':
find_search = "type like '%" + search + "%' or log like '%" + \
search + "%' or addtime like '%" + search + "%'"
start = (page - 1) * limit
_list = mw.M('logs').where(find_search, ()).field(
'id,type,log,addtime').limit(str(start) + ',' + str(limit)).order('id desc').select()
data = {}
data['data'] = _list
count = mw.M('logs').where(find_search, ()).count()
_page = {}
_page['count'] = count
_page['tojs'] = 'getLogs'
_page['p'] = page
data['page'] = mw.getPage(_page)
return mw.getJson(data)
def getLogsTitle(self, log_name):
log_name = log_name.replace('.1', '')
if log_name in ['mw-update.log']:
return '面板更新日志'
if log_name in ['mw-install.log']:
return '面板安装日志'
if log_name in ['auth.log', 'secure'] or log_name.find('auth.') == 0:
return '授权日志'
if log_name in ['dmesg'] or log_name.find('dmesg') == 0:
return '内核缓冲区日志'
if log_name in ['syslog'] or log_name.find('syslog') == 0:
return '系统警告/错误日志'
if log_name in ['btmp']:
return '失败的登录记录'
if log_name in ['utmp', 'wtmp']:
return '登录和重启记录'
if log_name in ['lastlog']:
return '用户最后登录'
if log_name in ['yum.log']:
return 'yum包管理器日志'
if log_name in ['anaconda.log']:
return 'Anaconda日志'
if log_name in ['dpkg.log']:
return 'dpkg日志'
if log_name in ['daemon.log']:
return '系统后台守护进程日志'
if log_name in ['boot.log']:
return '启动日志'
if log_name in ['kern.log']:
return '内核日志'
if log_name in ['maillog', 'mail.log']:
return '邮件日志'
if log_name.find('Xorg') == 0:
return 'Xorg日志'
if log_name in ['cron.log']:
return '定时任务日志'
if log_name in ['alternatives.log']:
return '更新替代信息'
if log_name in ['debug']:
return '调试信息'
if log_name.find('apt') == 0:
return 'apt-get相关日志'
if log_name.find('installer') == 0:
return '系统安装相关日志'
if log_name in ['messages']:
return '综合日志'
return '{}日志'.format(log_name.split('.')[0])
def getAuditLogsFilesApi(self):
log_dir = '/var/log'
log_files = []
for log_file in os.listdir(log_dir):
log_suffix = log_file.split('.')[-1:]
if log_suffix[0] in ['gz', 'xz', 'bz2', 'asl']:
continue
if log_file in ['.', '..', 'faillog', 'fontconfig.log', 'unattended-upgrades', 'tallylog']:
continue
filename = os.path.join(log_dir, log_file)
if os.path.isfile(filename):
file_size = os.path.getsize(filename)
if not file_size:
continue
tmp = {
'name': log_file,
'size': file_size,
'log_file': filename,
'title': self.getLogsTitle(log_file),
'uptime': os.path.getmtime(filename)
}
log_files.append(tmp)
else:
for next_name in os.listdir(filename):
if next_name[-3:] in ['.gz', '.xz']:
continue
next_file = os.path.join(filename, next_name)
if not os.path.isfile(next_file):
continue
file_size = os.path.getsize(next_file)
if not file_size:
continue
log_name = '{}/{}'.format(log_file, next_name)
tmp = {
'name': log_name,
'size': file_size,
'log_file': next_file,
'title': self.getLogsTitle(log_name),
'uptime': os.path.getmtime(next_file)
}
log_files.append(tmp)
log_files = sorted(log_files, key=lambda x: x['name'], reverse=True)
return mw.getJson(log_files)
def getAuditFileApi(self):
log_name = request.form.get('log_name', '').strip()
return self.getAuditLogsName(log_name)
def __to_date2(self, date_str):
tmp = date_str.split()
s_date = str(tmp[-1]) + '-' + self.__months.get(tmp[1],
tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
return s_date
def __to_date3(self, date_str):
tmp = date_str.split()
s_date = str(datetime.now().year) + '-' + \
self.__months.get(tmp[1], tmp[1]) + '-' + tmp[2] + ' ' + tmp[3]
return s_date
def __to_date4(self, date_str):
tmp = date_str.split()
s_date = str(datetime.now().year) + '-' + \
self.__months.get(tmp[0], tmp[0]) + '-' + tmp[1] + ' ' + tmp[2]
return s_date
def getAuditLast(self, log_name):
# 获取日志
cmd = '''LANG=en_US.UTF-8 last -n 200 -x -f {} |grep -v 127.0.0.1|grep -v " begins"'''.format(
'/var/log/' + log_name)
result = mw.execShell(cmd)
lastlog_list = []
for _line in result[0].split("\n"):
if not _line:
continue
tmp = {}
sp_arr = _line.split()
tmp['用户'] = sp_arr[0]
if sp_arr[0] == 'runlevel':
tmp['来源'] = sp_arr[4]
tmp['端口'] = ' '.join(sp_arr[1:4])
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[5:])) + ' ' + ' '.join(sp_arr[-2:])
elif sp_arr[0] in ['reboot', 'shutdown']:
tmp['来源'] = sp_arr[3]
tmp['端口'] = ' '.join(sp_arr[1:3])
if sp_arr[-3] == '-':
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-3:])
else:
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[4:])) + ' ' + ' '.join(sp_arr[-2:])
elif sp_arr[1] in ['tty1', 'tty', 'tty2', 'tty3', 'hvc0', 'hvc1', 'hvc2'] or len(sp_arr) == 9:
tmp['来源'] = ''
tmp['端口'] = sp_arr[1]
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[2:])) + ' ' + ' '.join(sp_arr[-3:])
else:
tmp['来源'] = sp_arr[2]
tmp['端口'] = sp_arr[1]
tmp['时间'] = self.__to_date3(
' '.join(sp_arr[3:])) + ' ' + ' '.join(sp_arr[-3:])
# tmp['_line'] = _line
lastlog_list.append(tmp)
# lastlog_list = sorted(lastlog_list,key=lambda x:x['时间'],reverse=True)
return mw.returnData(True, 'ok!', lastlog_list)
def getAuditLastLog(self):
cmd = '''LANG=en_US.UTF-8 lastlog|grep -v Username'''
result = mw.execShell(cmd)
lastlog_list = []
for _line in result[0].split("\n"):
if not _line:
continue
tmp = {}
sp_arr = _line.split()
tmp['用户'] = sp_arr[0]
# tmp['_line'] = _line
if _line.find('Never logged in') != -1:
tmp['最后登录时间'] = '0'
tmp['最后登录来源'] = '-'
tmp['最后登录端口'] = '-'
lastlog_list.append(tmp)
continue
tmp['最后登录来源'] = sp_arr[2]
tmp['最后登录端口'] = sp_arr[1]
tmp['最后登录时间'] = self.__to_date2(' '.join(sp_arr[3:]))
lastlog_list.append(tmp)
lastlog_list = sorted(lastlog_list, key=lambda x: x[
'最后登录时间'], reverse=True)
for i in range(len(lastlog_list)):
if lastlog_list[i]['最后登录时间'] == '0':
lastlog_list[i]['最后登录时间'] = '从未登录过'
return mw.returnData(True, 'ok!', lastlog_list)
def parseAuditFile(self, log_name, result):
log_list = []
is_string = True
for _line in result.split("\n"):
if not _line.strip():
continue
if log_name.find('sa/sa') == -1:
if _line[:3] in self.__months:
_msg = _line[16:]
_tmp = _msg.split(": ")
_act = ''
if len(_tmp) > 1:
_act = _tmp[0]
_msg = _tmp[1]
else:
_msg = _tmp[0]
_line = {
"时间": self.__to_date4(_line[:16].strip()),
"角色": _act,
"事件": _msg
}
is_string = False
elif _line[:2] in ['19', '20', '21', '22', '23', '24']:
_msg = _line[19:]
_tmp = _msg.split(" ")
_act = _tmp[1]
_msg = ' '.join(_tmp[2:])
_line = {
"时间": _line[:19].strip(),
"角色": _act,
"事件": _msg
}
is_string = False
elif log_name.find('alternatives') == 0:
_tmp = _line.split(": ")
_last = _tmp[0].split(" ")
_act = _last[0]
_msg = ' '.join(_tmp[1:])
_line = {
"时间": ' '.join(_last[1:]).strip(),
"角色": _act,
"事件": _msg
}
is_string = False
else:
if not is_string:
if type(_line) != dict:
continue
log_list.append(_line)
return log_list
def getAuditLogsName(self, log_name):
# print(log_name)
if log_name in ['wtmp', 'btmp', 'utmp'] or log_name.find('wtmp') == 0 or log_name.find('btmp') == 0 or log_name.find('utmp') == 0:
return self.getAuditLast(log_name)
if log_name.find('lastlog') == 0:
return self.getAuditLastLog()
if log_name.find('sa/sa') == 0:
if log_name.find('sa/sar') == -1:
return mw.execShell("sar -f /var/log/{}".format(log_name))[0]
log_dir = '/var/log'
log_file = log_dir + '/' + log_name
if not os.path.exists(log_file):
return mw.returnData(False, '日志文件不存在!')
result = mw.getLastLine(log_file, 100)
try:
log_list = self.parseAuditFile(log_name, result)
_string = []
_dict = []
_list = []
for _line in log_list:
if isinstance(_line, str):
_string.append(_line.strip())
elif isinstance(_line, dict):
_dict.append(_line)
elif isinstance(_line, list):
_list.append(_line)
else:
continue
_str_len = len(_string)
_dict_len = len(_dict)
_list_len = len(_list)
if _str_len > _dict_len + _list_len:
return "\n".join(_string)
elif _dict_len > _str_len + _list_len:
return mw.returnData(True, 'ok!', _dict)
else:
return mw.returnData(True, 'ok!', _list)
except:
return mw.returnData(True, 'ok!', result)
+22 -7
View File
@@ -349,7 +349,8 @@ def restartMw():
def checkWebConfig():
op_dir = getServerDir() + '/openresty/nginx'
cmd = "ulimit -n 10240 && " + op_dir + \
# "ulimit -n 10240 && " +
cmd = op_dir + \
"/sbin/nginx -t -c " + op_dir + "/conf/nginx.conf"
result = execShell(cmd)
searchStr = 'test is successful'
@@ -1215,6 +1216,12 @@ def formatDate(format="%Y-%m-%d %H:%M:%S", times=None):
return time.strftime(format, time_local)
def strfToTime(sdate):
# 转换时间
import time
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%b %d %H:%M:%S %Y %Z'))
def checkIp(ip):
# 检查是否为IPv4地址
import re
@@ -1349,6 +1356,12 @@ def getCpuType():
cpuinfo = execShell(cmd)
return cpuinfo[0].strip()
current_os = getOs()
if current_os.startswith('freebsd'):
cmd = "sysctl -a | egrep -i 'hw.model' | awk -F ':' '{print $2}'"
cpuinfo = execShell(cmd)
return cpuinfo[0].strip()
# 取CPU类型
cpuinfo = open('/proc/cpuinfo', 'r').read()
rep = "model\s+name\s+:\s+(.+)"
@@ -1405,7 +1418,7 @@ def makeConf():
file = getRunDir() + '/data/json/config.json'
if not os.path.exists(file):
c = {}
c['title'] = '金蝉面板'
c['title'] = '老子面板'
c['home'] = 'http://github/midoks/mdserver-web'
c['recycle_bin'] = True
c['template'] = 'default'
@@ -1544,7 +1557,9 @@ def checkInput(data):
def checkCert(certPath='ssl/certificate.pem'):
# 验证证书
openssl = '/usr/local/openssl/bin/openssl'
openssl = '/usr/bin/openssl'
if not os.path.exists(openssl):
openssl = '/usr/local/openssl/bin/openssl'
if not os.path.exists(openssl):
openssl = 'openssl'
certPem = readFile(certPath)
@@ -2091,15 +2106,15 @@ done
def echoStart(tag):
print("=" * 90)
print("=" * 89)
print("★开始{}[{}]".format(tag, formatDate()))
print("=" * 90)
print("=" * 89)
def echoEnd(tag):
print("=" * 90)
print("=" * 89)
print("☆{}完成[{}]".format(tag, formatDate()))
print("=" * 90)
print("=" * 89)
print("\n")
+22 -8
View File
@@ -71,8 +71,9 @@ class plugins_api:
if not mw.isNumber(sType):
sType = 0
# print sPage
data = self.getPluginList(sType, int(sPage))
# print(sPage, sType)
search = request.args.get('search', '').lower()
data = self.getPluginList(sType, search, int(sPage))
return mw.getJson(data)
def menuGetAbsPath(self, tag, path):
@@ -138,7 +139,7 @@ class plugins_api:
def initApi(self):
plugin_names = {
'openresty': '1.21.4.1',
'openresty': '1.21.4.2',
'php': '56',
'swap': '1.1',
'mysql': '5.7',
@@ -781,7 +782,18 @@ class plugins_api:
print(e)
return plugins_info
def getAllListPage(self, sType='0', page=1, pageSize=10):
def searchKey(self, info, kw):
try:
if info['title'].lower().find(kw) > -1:
return True
if info['ps'].lower().find(kw) > -1:
return True
if info['name'].lower().find(kw) > -1:
return True
except Exception as e:
return False
def getAllListPage(self, sType='0', kw='', page=1, pageSize=10):
plugins_info = []
for dirinfo in os.listdir(self.__plugin_dir):
if dirinfo[0:1] == '.':
@@ -792,11 +804,13 @@ class plugins_api:
if os.path.exists(json_file):
try:
data = json.loads(mw.readFile(json_file))
# 判断是否搜索
if kw != '' and not self.searchKey(data, kw):
continue
tmp_data = self.makeList(data, sType)
for index in range(len(tmp_data)):
plugins_info.append(tmp_data[index])
except Exception as e:
print(json_file)
print(mw.getTracebackInfo())
start = (page - 1) * pageSize
@@ -927,14 +941,14 @@ class plugins_api:
return plugins_info
def getPluginList(self, sType, sPage=1, sPageSize=10):
# print sType, sPage, sPageSize
def getPluginList(self, sType, kw='', sPage=1, sPageSize=10):
# print(sType, kw, sPage, sPageSize)
ret = {}
ret['type'] = json.loads(mw.readFile(self.__type))
# plugins_info = self.getAllListThread(sType)
# plugins_info = self.getAllListProcess(sType)
data = self.getAllListPage(sType, sPage, sPageSize)
data = self.getAllListPage(sType, kw, sPage, sPageSize)
ret['data'] = data[0]
args = {}
+162 -65
View File
@@ -101,19 +101,31 @@ class site_api:
limit = request.form.get('limit', '10')
p = request.form.get('p', '1')
type_id = request.form.get('type_id', '0').strip()
search = request.form.get('search', '').strip()
start = (int(p) - 1) * (int(limit))
siteM = mw.M('sites').field('id,name,path,status,ps,addtime,edate')
if type_id != '' and int(type_id) >= 0:
siteM.where('type_id=?', (type_id,))
sql_where = ''
if search != '':
sql_where = " name like '%" + search + "%' or ps like '%" + search + "%' "
if type_id != '' and int(type_id) >= 0 and search != '':
sql_where = sql_where + " and type_id=" + type_id + ""
elif type_id != '' and int(type_id) >= 0:
sql_where = " type_id=" + type_id
if sql_where != '':
siteM.where(sql_where)
_list = siteM.limit((str(start)) + ',' +
limit).order('id desc').select()
for i in range(len(_list)):
_list[i]['backup_count'] = mw.M('backup').where(
"pid=? AND type=?", (_list[i]['id'], 0)).count()
if _list != None:
for i in range(len(_list)):
_list[i]['backup_count'] = mw.M('backup').where(
"pid=? AND type=?", (_list[i]['id'], 0)).count()
_ret = {}
_ret['data'] = _list
@@ -775,6 +787,9 @@ class site_api:
mw.execShell('echo "lets" > "' + path + '/README"')
elif ssl_type == 'acme':
ssl_acme_dir = mw.getAcmeDir() + '/' + site_name
if not os.path.exists(ssl_acme_dir):
ssl_acme_dir = mw.getAcmeDir() + '/' + site_name + '_ecc'
acme_csrpath = ssl_acme_dir + '/fullchain.cer'
acme_keypath = ssl_acme_dir + '/' + site_name + '.key'
if mw.md5(mw.readFile(acme_csrpath)) == mw.md5(mw.readFile(csr_path)):
@@ -1134,8 +1149,9 @@ class site_api:
domains = request.form.get('domains', '')
status = request.form.get('status', '')
name = request.form.get('name', '')
none = request.form.get('none', '')
sid = request.form.get('id', '')
return self.setSecurity(sid, name, fix, domains, status)
return self.setSecurity(sid, name, fix, domains, status, none)
def getLogsApi(self):
siteName = request.form.get('siteName', '')
@@ -1420,6 +1436,8 @@ class site_api:
data['data'] = mw.readFile(filename)
data['rlist'] = []
for ds in os.listdir(self.rewritePath):
if ds[0:1] == '.':
continue
if ds == 'list.txt':
continue
data['rlist'].append(ds[0:len(ds) - 5])
@@ -1853,19 +1871,16 @@ class site_api:
if _id == '' or _siteName == '':
return mw.returnJson(False, "必填项不能为空!")
_old_config = mw.readFile(
"{}/{}/{}.conf".format(self.proxyPath, _siteName, _id))
if _old_config == False:
return mw.returnJson(False, "非法操作")
mw.writeFile("{}/{}/{}.conf".format(self.proxyPath,
_siteName, _id), _config)
proxy_file = "{}/{}/{}.conf".format(self.proxyPath, _siteName, _id)
mw.backFile(proxy_file)
mw.writeFile(proxy_file, _config)
rule_test = mw.checkWebConfig()
if rule_test != True:
mw.writeFile("{}/{}/{}.conf".format(self.proxyPath,
_siteName, _id), _old_config)
mw.restoreFile(proxy_file)
mw.removeBackFile(proxy_file)
return mw.returnJson(False, "OpenResty 配置测试不通过, 请重试: {}".format(rule_test))
mw.removeBackFile(proxy_file)
self.operateRedirectConf(_siteName, 'start')
mw.restartWeb()
return mw.returnJson(True, "ok")
@@ -1906,21 +1921,20 @@ class site_api:
_from = request.form.get('from', '')
_to = request.form.get('to', '')
_host = request.form.get('host', '')
_name = request.form.get('name', '')
_open_proxy = request.form.get('open_proxy', '')
_open_cache = request.form.get('open_cache', '')
_cache_time = request.form.get('cache_time', '')
_id = request.form.get('id', '')
if _siteName == "" or _from == "" or _to == "" or _host == "":
# print(_name, _siteName, _from, _to, _host)
if _name == "" or _siteName == "" or _from == "" or _to == "" or _host == "":
return mw.returnJson(False, "必填项不能为空")
data_path = self.getProxyDataPath(_siteName)
data_content = mw.readFile(
data_path) if os.path.exists(data_path) else ""
data = json.loads(data_content) if data_content != "" else []
rep = "http(s)?\:\/\/([a-zA-Z0-9][-a-zA-Z0-9]{0,62}\.)+([a-zA-Z0-9][a-zA-Z0-9]{0,62})+.?"
if not re.match(rep, _to):
return mw.returnJson(False, "错误的目标地址!")
# _to = _to.strip("/")
# get host from url
try:
if _host == "$host":
@@ -1929,7 +1943,11 @@ class site_api:
except:
return mw.returnJson(False, "错误的目标地址")
# location ~* ^{from}(.*)$ {
proxy_site_path = self.getProxyDataPath(_siteName)
data_content = mw.readFile(
proxy_site_path) if os.path.exists(proxy_site_path) else ""
data = json.loads(data_content) if data_content != "" else []
tpl = "#PROXY-START\n\
location ^~ {from} {\n\
proxy_pass {to};\n\
@@ -1937,12 +1955,29 @@ location ^~ {from} {\n\
proxy_set_header X-Real-IP $remote_addr;\n\
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n\
proxy_set_header REMOTE-HOST $remote_addr;\n\
proxy_set_header Upgrade $http_upgrade;\n\
proxy_set_header Connection $connection_upgrade;\n\
proxy_http_version 1.1;\n\
\n\
add_header X-Cache $upstream_cache_status;\n\
proxy_ignore_headers Set-Cookie Cache-Control expires;\n\
add_header Cache-Control no-cache;\n\
\n\
set $static_files_app 0;\n\
{proxy_cache}\n\
}\n\
# PROXY-END"
tpl_proxy_cache = "\n\
if ( $uri ~* \"\.(gif|png|jpg|css|js|woff|woff2)$\" )\n\
{\n\
expires {cache_time}m;\n\
}\n\
proxy_ignore_headers Set-Cookie Cache-Control expires;\n\
proxy_cache mw_cache;\n\
proxy_cache_key \"$host$uri$is_args$args\";\n\
proxy_cache_valid 200 304 301 302 {cache_time}m;\n\
"
tpl_proxy_nocache = "\n\
set $static_files_app 0; \n\
if ( $uri ~* \"\.(gif|png|jpg|css|js|woff|woff2)$\" )\n\
{\n\
set $static_files_app 1;\n\
@@ -1952,8 +1987,7 @@ location ^~ {from} {\n\
{\n\
add_header Cache-Control no-cache;\n\
}\n\
}\n\
#PROXY-END"
"
# replace
if _from[0] != '/':
@@ -1961,28 +1995,69 @@ location ^~ {from} {\n\
tpl = tpl.replace("{from}", _from, 999)
tpl = tpl.replace("{to}", _to)
tpl = tpl.replace("{host}", _host, 999)
tpl = tpl.replace("{cache_time}", _cache_time, 999)
_id = mw.md5("{}+{}+{}".format(_from, _to, _siteName))
for item in data:
if item["id"] == _id:
return mw.returnJson(False, "已存在该规则!")
if item["from"] == _from:
return mw.returnJson(False, "代理目录已存在!")
data.append({
"from": _from,
"to": _to,
"host": _host,
"id": _id
})
if _open_cache == 'on':
tpl_proxy_cache = tpl_proxy_cache.replace(
"{cache_time}", _cache_time, 999)
tpl = tpl.replace("{proxy_cache}", tpl_proxy_cache, 999)
else:
tpl = tpl.replace("{proxy_cache}", tpl_proxy_nocache, 999)
proxy_action = 'add'
if _id == "":
_id = mw.md5("{}".format(_name))
else:
proxy_action = 'edit'
conf_proxy = "{}/{}.conf".format(self.getProxyPath(_siteName), _id)
conf_bk = "{}/{}.conf.txt".format(self.getProxyPath(_siteName), _id)
mw.writeFile(conf_proxy, tpl)
rule_test = mw.checkWebConfig()
if rule_test != True:
os.remove(conf_proxy)
return mw.returnJson(False, "OpenResty配置测试不通过, 请重试: {}".format(rule_test))
if proxy_action == "add":
# 添加代理
_id = mw.md5("{}".format(_name))
for item in data:
if item["name"] == _name:
return mw.returnJson(False, "名称重复!")
if item["from"] == _from:
return mw.returnJson(False, "代理目录已存在!")
data.append({
"name": _name,
"from": _from,
"to": _to,
"host": _host,
"open_cache": _open_cache,
"open_proxy": _open_proxy,
"cache_time": _cache_time,
"id": _id,
})
else:
# 修改代理
dindex = -1
for x in range(len(data)):
if data[x]["id"] == _id:
dindex = x
break
if dindex < 0:
return mw.returnJson(False, "异常请求")
data[dindex]['from'] = _from
data[dindex]['to'] = _to
data[dindex]['host'] = _host
data[dindex]['open_cache'] = _open_cache
data[dindex]['open_proxy'] = _open_proxy
data[dindex]['cache_time'] = _cache_time
conf_file = "{}/{}.conf".format(self.getProxyPath(_siteName), _id)
if _open_proxy != 'on':
conf_file = "{}/{}.conf.txt".format(
self.getProxyPath(_siteName), _id)
mw.writeFile(data_path, json.dumps(data))
mw.writeFile(conf_file, tpl)
os.rename(conf_proxy, conf_bk)
mw.writeFile(proxy_site_path, json.dumps(data))
self.operateProxyConf(_siteName, 'start')
mw.restartWeb()
return mw.returnJson(True, "ok", {"hash": _id})
@@ -2013,10 +2088,10 @@ location ^~ {from} {\n\
self.getProxyPath(_siteName), _id)
mw.execShell(cmd)
except:
return mw.returnJson(False, "删除失败!")
return mw.returnJson(False, "删除反代失败!")
mw.restartWeb()
return mw.returnJson(True, "删除成功!")
return mw.returnJson(True, "删除反代成功!")
def getSiteTypesApi(self):
# 取网站分类
@@ -2083,7 +2158,7 @@ location ^~ {from} {\n\
##### ----- end ----- ###
# 域名编码转换
# 域名编码转换
def toPunycode(self, domain):
import re
if sys.version_info[0] == 2:
@@ -2091,7 +2166,7 @@ location ^~ {from} {\n\
tmp = domain.split('.')
newdomain = ''
for dkey in tmp:
# 匹配非ascii字符
# 匹配非ascii字符
match = re.search(u"[\x80-\xff]+", dkey)
if not match:
newdomain += dkey + '.'
@@ -2356,9 +2431,28 @@ location ^~ {from} {\n\
tmp = re.search(rep, conf).group()
data['fix'] = re.search(
"\(.+\)\$", tmp).group().replace('(', '').replace(')$', '').replace('|', ',')
data['domains'] = ','.join(re.search(
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp).groups()[0].split())
data['status'] = True
data['status'] = False
data['none'] = False
valid_referers = re.search(
"valid_referers\s+(.+);\n", tmp)
valid_referers_none = re.search(
"valid_referers\s+none\s+blocked\s+(.+);\n", tmp)
if valid_referers or valid_referers_none:
data['status'] = True
if valid_referers_none:
domain_t = valid_referers_none.groups()[0].split()
data['domains'] = ','.join(domain_t)
data['none'] = True
elif valid_referers:
domain_t = valid_referers.groups()[0].split()
data['domains'] = ','.join(domain_t)
data['none'] = False
# print(data)
else:
data['fix'] = 'jpg,jpeg,gif,png,js,css'
domains = mw.M('domain').where(
@@ -2368,19 +2462,27 @@ location ^~ {from} {\n\
tmp.append(domain['name'])
data['domains'] = ','.join(tmp)
data['status'] = False
data['none'] = False
return mw.getJson(data)
def setSecurity(self, sid, name, fix, domains, status):
def setSecurity(self, sid, name, fix, domains, status, none=''):
if len(fix) < 2:
return mw.returnJson(False, 'URL后缀不能为空!')
file = self.getHostConf(name)
if os.path.exists(file):
conf = mw.readFile(file)
if conf.find('SECURITY-START') != -1:
if status == 'false':
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
conf = re.sub(rep, '', conf)
mw.writeLog('网站管理', '站点[' + name + ']已关闭防盗链设置!')
else:
rep = "\s{0,4}#SECURITY-START(\n|.){1,500}#SECURITY-END\n?"
conf = re.sub(rep, '', conf)
valid_referers = domains.strip().replace(',', ' ')
if none == 'true':
valid_referers = 'none blocked ' + valid_referers
pre_path = self.setupPath + "/php/conf"
re_path = "include\s+" + pre_path + "/enable-php-"
rconf = '''#SECURITY-START 防盗链配置
@@ -2388,13 +2490,13 @@ location ^~ {from} {\n\
{
expires 30d;
access_log /dev/null;
valid_referers none blocked %s;
valid_referers %s;
if ($invalid_referer){
return 404;
}
}
#SECURITY-END
include %s/enable-php-''' % (fix.strip().replace(',', '|'), domains.strip().replace(',', ' '), pre_path)
include %s/enable-php-''' % (fix.strip().replace(',', '|'), valid_referers, pre_path)
conf = re.sub(re_path, rconf, conf)
mw.writeLog('网站管理', '站点[' + name + ']已开启防盗链!')
mw.writeFile(file, conf)
@@ -2646,7 +2748,7 @@ location ^~ {from} {\n\
mw.writeLog('TYPE_SITE', '设置成功,站点到期后将自动停止!', (siteName, edate))
return mw.returnJson(True, '设置成功,站点到期后将自动停止!')
# ssl相关方法 start
# ssl相关方法 start
def setSslConf(self, siteName):
file = self.getHostConf(siteName)
conf = mw.readFile(file)
@@ -2686,7 +2788,7 @@ location ^~ {from} {\n\
self.saveCert(keyPath, certPath)
msg = mw.getInfo('网站[{1}]开启SSL成功!', siteName)
msg = mw.getInfo('网站[{}]开启SSL成功!', siteName)
mw.writeLog('网站管理', msg)
mw.restartWeb()
@@ -2745,9 +2847,4 @@ location ^~ {from} {\n\
mw.execShell("chattr +i " + filename)
return mw.returnJson(True, '已打开防跨站设置!')
# 转换时间
def strfToTime(self, sdate):
import time
return time.strftime('%Y-%m-%d', time.strptime(sdate, '%b %d %H:%M:%S %Y %Z'))
# ssl相关方法 end
# ssl相关方法 end
+32 -5
View File
@@ -274,26 +274,43 @@ class system_api:
return title
def getSystemVersion(self):
#
# 取操作系统版本
if mw.getOs() == 'darwin':
current_os = mw.getOs()
# mac
if current_os == 'darwin':
data = mw.execShell('sw_vers')[0]
data_list = data.strip().split("\n")
mac_version = ''
for x in data_list:
mac_version += x.split("\t")[1] + ' '
return mac_version
arch_ver = mw.execShell("arch")
return mac_version + " (" + arch_ver[0].strip() + ")"
# freebsd
if current_os.startswith('freebsd'):
version = mw.execShell(
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
arch_ver = mw.execShell(
"sysctl -a | egrep -i 'hw.machine_arch' | awk -F ':' '{print $2}'")
return version[0].strip() + " (" + arch_ver[0].strip() + ")"
redhat_series = '/etc/redhat-release'
if os.path.exists(redhat_series):
version = mw.readFile('/etc/redhat-release')
version = version.replace('release ', '').strip()
return version
arch_ver = mw.execShell("arch")
return version + " (" + arch_ver[0].strip() + ")"
os_series = '/etc/os-release'
if os.path.exists(os_series):
version = mw.execShell(
"cat /etc/*-release | grep PRETTY_NAME | awk -F = '{print $2}' | awk -F '\"' '{print $2}'")
return version[0].strip()
arch_ver = mw.execShell("arch")
return version[0].strip() + " (" + arch_ver[0].strip() + ")"
return '未识别系统信息'
@@ -318,7 +335,7 @@ class system_api:
cpuCount = psutil.cpu_count()
cpuLogicalNum = psutil.cpu_count(logical=False)
used = psutil.cpu_percent(interval=interval)
cpuLogicalNum = 0
if os.path.exists('/proc/cpuinfo'):
c_tmp = mw.readFile('/proc/cpuinfo')
d_tmp = re.findall("physical id.+", c_tmp)
@@ -755,6 +772,8 @@ class system_api:
#!/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
@@ -769,6 +788,14 @@ if [ ! -z "$cn" ];then
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()
+6 -2
View File
@@ -7,6 +7,10 @@ MDIR=$(dirname "$DIR")
PATH=$PATH:$DIR/bin
if [ -f bin/activate ];then
source bin/activate
if [ "$?" != "0" ];then
echo "load local python env fail!"
fi
fi
export LC_ALL="en_US.UTF-8"
@@ -16,7 +20,7 @@ mw_start_task()
{
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
if [ "$isStart" == '' ];then
echo -e "Starting mw-tasks... \c"
echo -e "starting mw-tasks... \c"
cd $DIR && python3 task.py >> ${DIR}/logs/task.log 2>&1 &
sleep 0.3
isStart=$(ps aux |grep 'task.py'|grep -v grep|awk '{print $2}')
@@ -30,7 +34,7 @@ mw_start_task()
fi
echo -e "\033[32mdone\033[0m"
else
echo "Starting mw-tasks... mw-tasks (pid $(echo $isStart)) already running"
echo "starting mw-tasks... mw-tasks (pid $(echo $isStart)) already running"
fi
}
+20 -17
View File
@@ -16,6 +16,7 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
| CentOS 9 Stream |✅ |✅ |
| Debian 10.3 |✅ |✅ |
| Debian 11.3 |✅ |✅ |
| Debian 12.0 |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |
@@ -28,23 +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 |
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| CentOS 7.9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 8 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| CentOS 9 Stream |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 31 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Fedora 32 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| AlmaLinux 9 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| RockyLinux 8.6 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| Arch Linux |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| openSUSE 15.4 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
| 系统名称 |PHP53 |PHP54 |PHP55 |PHP56 |PHP70 |PHP71 |PHP72 |PHP73 |PHP74 |PHP80 |PHP81 |PHP82 |
| ----------------- |-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|-------|
| 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 |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |✅ |
@@ -56,6 +58,7 @@ cd /www/server/mdserver-web/plugins/php/versions && bash all_test.sh
| CentOS 9 Stream |✅ |✅ |✅ |✅ |
| Debian 10.3 |✅ |✅ |✅ |✅ |
| Debian 11.3 |✅ |✅ |✅ |✅ |
| Debian 12 |✅ |✅ |✅ |✅ |
| Ubuntu 18.04 |✅ |✅ |✅ |✅ |
| Ubuntu 20.04 |✅ |✅ |✅ |✅ |
| Ubuntu 22.04 |✅ |✅ |✅ |✅ |
+2 -3
View File
@@ -46,9 +46,8 @@ CREATE TABLE IF NOT EXISTS `firewall` (
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
(1, '80', '网站默认端口', '0000-00-00 00:00:00'),
(2, '22', 'SSH远程管理服务', '0000-00-00 00:00:00'),
(3, '443', 'HTTPS', '0000-00-00 00:00:00'),
(4, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00');
(2, '443', 'HTTPS', '0000-00-00 00:00:00'),
(3, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00');
+2 -9
View File
@@ -39,20 +39,13 @@ server
allow all;
}
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
error_log off;
error_log /dev/null;
access_log /dev/null;
}
location ~ .*\\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
}
access_log {$LOGPATH}/{$SERVER_NAME}.log main;
error_log {$LOGPATH}/{$SERVER_NAME}.error.log;
}
+3 -10
View File
@@ -35,18 +35,11 @@ server
allow all;
}
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf)$
location ~ .*\\.(gif|jpg|jpeg|png|bmp|swf|js|css)$
{
expires 30d;
error_log off;
error_log /dev/null;
access_log /dev/null;
}
location ~ .*\\.(js|css)?$
{
expires 12h;
error_log off;
access_log /dev/null;
expires 30d;
}
access_log {$LOGPATH}/{$SERVER_MAIN}_{$DIRBIND}.log;
+48 -6
View File
@@ -14,6 +14,7 @@ if sys.platform != "darwin":
sys.path.append(os.getcwd() + "/class/core")
import mw
import db
_ver = sys.version_info
is_py2 = (_ver[0] == 2)
@@ -185,6 +186,35 @@ def backupAllFunc(stype):
"path": "path",
}
backups = []
sql = db.Sql()
# print("stype:", stype)
# 提前获取-清理多余备份
if stype == 'site':
pid = sql.table('sites').where('name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('0', pid)).field('id,filename').select()
if stype == 'database':
db_path = mw.getServerDir() + '/mysql'
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
if stype == 'path':
backup_path = backup_dir + '/path'
_name = 'path_{}'.format(os.path.basename(name))
backups = findPathName(backup_path, _name)
# 其他类型关系性数据库(mysql类的)
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
db_path = mw.getServerDir() + '/' + plugin_name
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
args = stype + " " + name + " " + num
cmd = 'python3 ' + mw.getRunDir() + '/scripts/backup.py ' + args
if stype.find('database_') > -1:
@@ -213,19 +243,31 @@ def backupAllFunc(stype):
filename = mw.execShell(find_new_file)[0].strip()
if filename == "":
mw.echoInfo("not find upload file!")
return False
return ''
print("|-准备上传文件 {}".format(filename))
ftp = FtpPSClient()
ftp.uploadFile(filename, stype)
# print(backups)
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
mw.echoStart('开始删除远程备份')
num = int(num)
sep = len(backups) - num
if sep > -1:
for backup in backups:
fn = os.path.basename(backup['filename'])
object_name = ftp.buildDirName(stype, fn)
ftp.deleteFile(object_name)
mw.echoInfo("---已清理远程过期备份文件:" + object_name)
sep -= 1
if sep < 0:
break
mw.echoEnd('结束删除远程备份')
return ''
def backupSite():
# 备份站点
pass
def in_array(name, arr=[]):
for x in arr:
if name == x:
+40 -2
View File
@@ -1,10 +1,48 @@
<style type="text/css">
.docker-sub {
border-bottom: 1px solid #ccc;
height: 30px;
line-height: 30px;
margin-bottom: 15px;
}
.docker-sub .on {
border-bottom: 2px solid #20a53a;
color: #20a53a;
font-weight: bold;
font-family: "宋体";
}
.docker-sub span {
display: inline-block;
font-size: 14px;
height: 30px;
padding: 0 25px;
cursor: pointer;
}
.docker-environments {
resize: none;
width: 330px;
height: 80px;
line-height: 20px;
padding: 5px 8px;
border: 1px solid #ddd;
font-size: 12px;
}
</style>
<div class="bt-form">
<div class='plugin_version'></div>
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('docker');">服务</p>
<p onclick="pluginInitD('docker');">自启动</p>
<p onclick="dockerList();">容器列表</p>
<p onclick="dockerConList();">容器列表</p>
<p onclick="dockerImageList();">镜像列表</p>
<p onclick="dockerImageOutput();">镜像导出</p>
<p onclick="dockerIpList();">IP地址池</p>
<p onclick="repoList();">仓库</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
@@ -12,7 +50,7 @@
</div>
</div>
<script type="text/javascript">
resetPluginWinWidth(700);
resetPluginWinWidth(800);
resetPluginWinHeight(400);
$.getScript( "/plugins/file?name=docker&f=js/docker.js", function(){
pluginService('docker', $('.plugin_version').attr('version'));
+705 -14
View File
@@ -5,15 +5,28 @@ import io
import os
import time
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
import docker
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getDClient():
try:
client = docker.from_env()
except Exception as e:
client = docker.DockerClient(
base_url='unix:///Users/midoks/.docker/run/docker.sock')
return client
def getPluginName():
return 'docker'
@@ -26,12 +39,6 @@ def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getConf():
path = getServerDir() + "/redis.conf"
return path
@@ -48,7 +55,7 @@ def getInitDTpl():
def getArgs():
args = sys.argv[3:]
args = sys.argv[2:]
tmp = {}
args_len = len(args)
@@ -57,19 +64,27 @@ def getArgs():
if t.strip() == '':
tmp = []
else:
t = t.split(':')
t = t.split(':', 1)
tmp[t[0]] = t[1]
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
t = args[i].split(':', 1)
tmp[t[0]] = t[1]
return tmp
def checkArgs(self, data, ck=[]):
for i in range(len(ck)):
print(data[i])
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
data = mw.execShell(
"ps -ef|grep dockerd |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
"ps -ef|grep docker |grep -v grep | grep -v python | grep -v mdserver-web | awk '{print $2}'")
if data[0] == '':
return 'stop'
@@ -138,9 +153,641 @@ def initdUinstall():
mw.execShell('systemctl disable ' + getPluginName())
return 'ok'
# UTC时间转换为时间戳
def runLog():
return getServerDir() + '/data/redis.log'
def utc_to_local(utc_time_str, utc_format='%Y-%m-%dT%H:%M:%S'):
import pytz
import datetime
import time
local_tz = pytz.timezone('Asia/Chongqing')
local_format = "%Y-%m-%d %H:%M"
utc_dt = datetime.datetime.strptime(utc_time_str, utc_format)
local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz)
time_str = local_dt.strftime(local_format)
return int(time.mktime(time.strptime(time_str, local_format)))
def conList():
c = getDClient()
clist = c.containers.list(all=True)
conList = []
for con in clist:
tmp = con.attrs
tmp['Created'] = utc_to_local(tmp['Created'].split('.')[0])
conList.append(tmp)
return conList
def conListData():
try:
clist = conList()
except Exception as e:
return mw.returnJson(False, '未开启Docker')
return mw.returnJson(True, 'ok', clist)
def dockerRemoveCon():
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
try:
path_list = conFind.attrs['GraphDriver'][
'Data']['LowerDir'].split(':')
for i in path_list:
mw.execShell('chattr -R -i %s' % i)
except:
pass
conFind.remove(force=True)
return mw.returnJson(True, '成功删除!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '删除失败!' + str(ex))
def dockerLogCon():
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
if not conFind:
return mw.returnJson(False, 'The specified container does not exist!')
log = conFind.logs()
if not isinstance(log, str):
log = log.decode()
return mw.returnJson(True, log)
except docker.errors.APIError as ex:
return mw.returnJson(False, 'Get Logs failed')
def dockerRunCon():
# 启动容器
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
if not conFind:
return mw.returnJson(False, 'The specified container does not exist!')
conFind.start()
return mw.returnJson(True, '启动成功!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '启动失败!' + str(ex))
def dockerStopCon():
# 停止容器
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
c = getDClient()
try:
conFind = c.containers.get(Hostname)
if not conFind:
return mw.returnJson(False, 'The specified container does not exist!')
conFind.stop()
return mw.returnJson(True, '停止成功!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '停止失败!' + str(ex))
def dockerExec():
# 容器执行命令
args = getArgs()
data = checkArgs(args, ['Hostname'])
if not data[0]:
return data[1]
Hostname = args['Hostname']
debug_path = 'data/debug.pl'
if os.path.exists(debug_path):
return mw.returnJson(False, '开发模式不能进入!')
c = getDClient()
try:
conFind = c.containers.get(Hostname)
cmd = 'docker container exec -it %s /bin/sh' % Hostname
return mw.returnJson(True, cmd)
except docker.errors.APIError as ex:
return mw.returnJson(False, '连接失败!')
def imageList():
imageList = []
c = getDClient()
ilist = c.images.list()
for image in ilist:
tmp_attrs = image.attrs
if len(tmp_attrs['RepoTags']) == 1:
tmp_image = {}
tmp_image['Id'] = tmp_attrs['Id'].split(':')[1][:12]
tmp_image['RepoTags'] = tmp_attrs['RepoTags'][0]
tmp_image['Size'] = tmp_attrs['Size']
tmp_image['Labels'] = tmp_attrs['Config']['Labels']
tmp_image['Comment'] = tmp_attrs['Comment']
tmp_image['Created'] = utc_to_local(
tmp_attrs['Created'].split('.')[0])
imageList.append(tmp_image)
else:
for i in range(len(tmp_attrs['RepoTags'])):
tmp_image = {}
tmp_image['Id'] = tmp_attrs['Id'].split(':')[1][:12]
tmp_image['RepoTags'] = tmp_attrs['RepoTags'][i]
tmp_image['Size'] = tmp_attrs['Size']
tmp_image['Labels'] = tmp_attrs['Config']['Labels']
tmp_image['Comment'] = tmp_attrs['Comment']
tmp_image['Created'] = utc_to_local(
tmp_attrs['Created'].split('.')[0])
imageList.append(tmp_image)
imageList = sorted(imageList, key=lambda x: x['Created'], reverse=True)
return imageList
def dockerPull():
# pull Dockr 官方镜像
args = getArgs()
data = checkArgs(args, ['images'])
if not data[0]:
return data[1]
images = args['images']
if ':' in images:
pass
else:
images = images + ':latest'
c = getDClient()
try:
ret = c.images.pull(images)
if ret:
return mw.returnJson(True, '拉取成功!')
else:
return mw.returnJson(False, '拉取失败,请检查镜像名称或是否需要登录docker进行下载')
except:
ret = mw.execShell('docker image pull %s' % images)
if 'invalid' in ret[-1]:
return mw.returnJson(False, '拉取失败,请检查镜像名称或是否需要登录docker进行下载')
else:
return mw.returnJson(True, '拉取成功!')
def dockerPlulPath(path):
if not path and path == '':
return mw.returnJson(False, 'Invalid address')
ret = mw.execShell('docker image pull %s' % path)
if 'invalid' in ret[-1]:
return mw.returnJson(False, '拉取失败,请检查镜像名称或是否需要登录docker进行下载')
else:
return mw.returnJson(True, '拉取成功!')
def dockerPullReg():
# pull Dockr 官方镜像
args = getArgs()
data = checkArgs(args, ['path'])
if not data[0]:
return data[1]
path = args['path']
return dockerPlulPath(path)
# 判断镜像是否存在
def checkImage(path):
image_list = imageList()
for i in image_list:
if path == i["RepoTags"]:
return mw.returnData(False, '镜像已存在!')
def dockerPullPrivateNew():
# pull Dockr 官方镜像
args = getArgs()
data = checkArgs(args, ['path'])
if not data[0]:
return data[1]
path = args['path']
check = checkImage(path)
if check:
return mw.getJson(check)
my_repo = repoList()
if not my_repo:
return mw.returnJson(False, '未登录任何私人存储库,请登录然后拉取')
return dockerPlulPath(path)
def imageListData():
try:
ilist = imageList()
except Exception as e:
return mw.returnJson(False, '未开启Docker')
return mw.returnJson(True, 'ok', ilist)
def dockerRemoveImage():
args = getArgs()
data = checkArgs(args, ['imageId', 'repoTags'])
if not data[0]:
return data[1]
repoTags = args['repoTags']
imageId = args['imageId']
c = getDClient()
try:
c.images.remove(repoTags)
return mw.returnJson(True, '成功删除')
except:
try:
c.images.remove(imageId)
return mw.returnJson(True, '成功删除!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '删除失败, 当前镜像正在使用!')
def getImageListFunc(dbname=''):
bkDir = mw.getRootDir() + '/backup/docker'
blist = os.listdir(bkDir)
r = []
bname = 'db_' + dbname
blen = len(bname)
for x in blist:
fbstr = x[0:blen]
if fbstr == bname:
r.append(x)
return r
def dockerImagePickDir():
bkDir = mw.getRootDir() + '/backup/docker'
return mw.returnJson(True, 'ok', bkDir)
def dockerImagePickList():
bkDir = mw.getRootDir() + '/backup/docker'
if not os.path.exists(bkDir):
os.mkdir(bkDir)
r = os.listdir(bkDir)
rr = []
for x in range(0, len(r)):
p = bkDir + '/' + r[x]
data = {}
data['name'] = r[x]
rsize = os.path.getsize(p)
data['size'] = mw.toSize(rsize)
t = os.path.getctime(p)
t = time.localtime(t)
data['time'] = time.strftime('%Y-%m-%d %H:%M:%S', t)
rr.append(data)
data['file'] = p
return mw.returnJson(True, 'ok', rr)
def dockerImagePickSave():
# image 导出
args = getArgs()
data = checkArgs(args, ['images'])
if not data[0]:
return data[1]
bkDir = mw.getRootDir() + '/backup/docker/'
images = args['images']
try:
file_name = bkDir + \
str(time.strftime('%Y%m%d_%H%M%S', time.localtime())) + '.tar.gz'
mw.execShell('docker image save %s | gzip > %s' %
(images, file_name))
return mw.returnJson(True, '导出镜像 {} 成功!'.format(file_name))
except docker.errors.APIError as ex:
return mw.returnJson(False, '操作失败: ' + str(ex))
def dockerImagePickLoad():
# 镜像文件导入
args = getArgs()
data = checkArgs(args, ['file'])
if not data[0]:
return data[1]
try:
file_path = args['file']
if not os.path.exists(file_path):
return mw.returnJson(False, '文件不存在')
if file_path.endswith('.tar'):
mw.execShell('docker image load < %s' % file_path)
elif file_path.endswith('.tar.gz'):
mw.execShell('gunzip -c %s | docker image load' % file_path)
else:
return mw.returnJson(False, '不支持改文件类型!')
return mw.returnJson(True, '导入镜像文件成功!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '操作失败: ' + str(ex))
def dockerLoginCheck(user_name, user_pass, registry):
# 登陆验证
cmd = 'docker login -u=%s -p %s %s' % (user_name, user_pass, registry)
# print(cmd)
login_test = mw.execShell(cmd)
# print(login_test)
ret = 'required$|Error'
ret2 = re.findall(ret, login_test[-1])
if len(ret2) == 0:
return True
else:
return False
def getDockerIpListData():
# 取IP列表
path = getServerDir()
ipConf = path + '/iplist.json'
if not os.path.exists(ipConf):
return []
iplist = json.loads(mw.readFile(ipConf))
return iplist
def getDockerIpList():
data = getDockerIpListData()
return mw.returnJson(True, 'ok!', data)
def dockerAddIP():
# 添加IP
args = getArgs()
data = checkArgs(args, ['address', 'netmask', 'gateway'])
if not data[0]:
return data[1]
path = getServerDir()
ipConf = path + '/iplist.json'
if not os.path.exists(ipConf):
iplist = []
mw.writeFile(ipConf, json.dumps(iplist))
iplist = json.loads(mw.readFile(ipConf))
ipInfo = {
'address': args['address'],
'netmask': args['netmask'],
'gateway': args['gateway'],
}
iplist.append(ipInfo)
mw.writeFile(ipConf, json.dumps(iplist))
return mw.returnJson(True, '添加成功!')
def dockerDelIP():
# 删除IP
args = getArgs()
data = checkArgs(args, ['address'])
if not data[0]:
return data[1]
path = getServerDir()
ipConf = path + '/iplist.json'
if not os.path.exists(ipConf):
return mw.returnJson(False, '指定的IP不存在。!')
iplist = json.loads(mw.readFile(ipConf))
newList = []
for ipInfo in iplist:
if ipInfo['address'] == args['address']:
continue
newList.append(ipInfo)
mw.writeFile(ipConf, json.dumps(newList))
return mw.returnJson(True, '成功删除!')
def getDockerCreateInfo():
# 取创建依赖
import psutil
data = {}
data['images'] = imageList()
data['memSize'] = int(psutil.virtual_memory().total / 1024 / 1024)
data['iplist'] = getDockerIpListData()
return mw.returnJson(True, 'ok!', data)
def __release_port(port):
from collections import namedtuple
try:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(port, 'docker', 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
def dockerPortCheck():
args = getArgs()
data = checkArgs(args, ['port'])
if not data[0]:
return data[1]
port = args['port']
is_ok = IsPortExists(port)
if is_ok:
return mw.returnJson(True, 'ok')
return mw.returnJson(False, 'fail')
def IsPortExists(port):
# 判断端口是否被占用
ret = __check_dst_port(ip='localhost', port=port)
ret2 = __check_dst_port(ip='0.0.0.0', port=port)
if ret:
return ret
if not ret and ret2:
return ret2
if not ret and not ret2:
return False
def __check_dst_port(ip, port, timeout=3):
# 端口检测
import socket
ok = True
try:
s = socket.socket()
s.settimeout(timeout)
s.connect((ip, port))
s.close()
except:
ok = False
return ok
def dockerCreateCon():
args = getArgs()
data = checkArgs(args, ['environments', 'command',
'entrypoint', 'image', 'mem_limit', 'ports', 'volumes'])
if not data[0]:
return data[1]
environments = args['environments']
environments = environments.strip().split()
command = args['command']
entrypoint = args['entrypoint']
image = args['image']
mem_limit = args['mem_limit']
ports = args['ports']
ports = ports.replace('[', '(').replace(']', ')')
volumes = args['volumes']
# if __name__ == "__main__":
# print(args)
try:
c = getDClient()
conObject = c.containers.run(
image=image,
mem_limit=mem_limit + 'M',
ports=eval(ports),
auto_remove=False,
command=command,
detach=True,
stdin_open=True,
tty=True,
entrypoint=entrypoint,
privileged=True,
volumes=json.loads(volumes),
cpu_shares=10,
environment=environments
)
if conObject:
__release_port(ports)
return mw.returnJson(True, '创建成功!')
return mw.returnJson(False, '创建失败!')
except docker.errors.APIError as ex:
return mw.returnJson(False, '创建失败!' + str(ex))
def dockerLogin():
args = getArgs()
# print(args)
data = checkArgs(args, ['user', 'passwd', 'hub_name',
'namespace', 'registry', 'repository_name'])
if not data[0]:
return data[1]
user_name = args['user']
user_pass = args['passwd']
registry = args['registry']
hub_name = args['hub_name']
namespace = args['namespace']
repository_name = args['repository_name']
ret_status = dockerLoginCheck(user_name, user_pass, registry)
path = getServerDir()
if ret_status:
user_file = path + '/user.json'
user_info = mw.readFile(user_file)
if not user_info:
user_info = []
else:
user_info = json.loads(user_info)
ret = {}
ret['user_name'] = user_name
ret['user_pass'] = user_pass
ret['registry'] = registry
ret['hub_name'] = hub_name
ret['namespace'] = namespace
ret['repository_name'] = repository_name
if not registry:
ret['registry'] = "docker.io"
user_info.append(ret)
mw.writeFile(user_file, json.dumps(user_info))
return mw.returnJson(True, '成功登录!')
return mw.returnJson(False, '登录失败!')
# 删除用户信息
def delete_user_info(registry):
path = getServerDir()
user_file = path + '/user.json'
user_info = mw.readFile(user_file)
if user_info:
user_info = json.loads(user_info)
for i in range(len(user_info)):
if registry in user_info[i].values():
del(user_info[i])
mw.writeFile(user_file, json.dumps(user_info))
return True
def dockerLogout():
args = getArgs()
data = checkArgs(args, ['registry'])
if not data[0]:
return data[1]
registry = args['registry']
if registry == "docker.io":
registry = ""
login_test = mw.execShell('docker logout %s' % registry)
if registry == "":
registry = "docker.io"
ret = 'required$|Error'
ret2 = re.findall(ret, login_test[-1])
delete_user_info(registry)
if len(ret2) == 0:
return mw.returnJson(True, '退出成功')
else:
return mw.returnJson(True, '退出失败')
def repoList():
path = getServerDir()
repostory_info = []
user_file = path + '/user.json'
if os.path.exists(user_file):
user_info = mw.readFile(user_file)
user_info = json.loads(user_info)
for i in user_info:
tmp = {}
tmp["hub_name"] = i["hub_name"]
tmp["registry"] = i["registry"]
tmp["namespace"] = i["namespace"]
tmp['repository_name'] = i["repository_name"]
repostory_info.append(tmp)
return mw.returnJson(True, 'ok', repostory_info)
if __name__ == "__main__":
@@ -163,7 +810,51 @@ if __name__ == "__main__":
print(initdUinstall())
elif func == 'conf':
print(getConf())
elif func == 'run_log':
print(runLog())
elif func == 'con_list':
print(conListData())
elif func == 'docker_con_log':
print(dockerLogCon())
elif func == 'docker_remove_con':
print(dockerRemoveCon())
elif func == 'docker_run_con':
print(dockerRunCon())
elif func == 'docker_stop_con':
print(dockerStopCon())
elif func == 'docker_exec':
print(dockerExec())
elif func == 'docker_pull':
print(dockerPull())
elif func == 'docker_pull_reg':
print(dockerPullReg())
elif func == 'image_list':
print(imageListData())
elif func == 'image_pick_dir':
print(dockerImagePickDir())
elif func == 'image_pick_save':
print(dockerImagePickSave())
elif func == 'image_pick_load':
print(dockerImagePickLoad())
elif func == 'image_pick_list':
print(dockerImagePickList())
elif func == 'docker_get_iplist':
print(getDockerIpList())
elif func == 'docker_del_ip':
print(dockerDelIP())
elif func == 'docker_add_ip':
print(dockerAddIP())
elif func == 'get_docker_create_info':
print(getDockerCreateInfo())
elif func == 'docker_create_con':
print(dockerCreateCon())
elif func == 'docker_remove_image':
print(dockerRemoveImage())
elif func == 'docker_port_check':
print(dockerPortCheck())
elif func == 'docker_login':
print(dockerLogin())
elif func == 'docker_logout':
print(dockerLogout())
elif func == 'repo_list':
print(repoList())
else:
print('error')
+2 -1
View File
@@ -1,6 +1,6 @@
{
"sort": 7,
"ps": "Docker 是一个开源的应用容器引擎(开发测试中)",
"ps": "Docker是一个开源的应用容器引擎",
"name": "docker",
"title": "Docker",
"shell": "install.sh",
@@ -13,6 +13,7 @@
"author": "Zend",
"date": "2017-04-01",
"home": "https://docker.io",
"doc1":"https://docker-py.readthedocs.io/",
"type": 0,
"pid": "2"
}
+12 -5
View File
@@ -13,13 +13,17 @@ serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
Install_Docker()
{
which docker
if [ "$?" == "0" ];then
echo '安装已经完成docker' > $install_tmp
exit 0
fi
# which docker
# if [ "$?" == "0" ];then
# echo '安装已经完成docker' > $install_tmp
# exit 0
# fi
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source
@@ -28,6 +32,9 @@ Install_Docker()
curl -fsSL https://get.docker.com | bash
mkdir -p $serverPath/docker
fi
pip install docker
pip install pytz
if [ -d $serverPath/docker ];then
echo "${VERSION}" > $serverPath/docker/version.pl
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

+19
View File
@@ -0,0 +1,19 @@
<div class="bt-form">
<div class='plugin_version'></div>
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('dynamic-tracking');">服务</p>
<p onclick="pluginInitD('dynamic-tracking');">自启动</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
resetPluginWinHeight(300);
resetPluginWinWidth(500);
$.getScript( "/plugins/file?name=dynamic-tracking&f=static/js/dynamic-tracking.js", function(){
pluginService('dynamic-tracking', $('.plugin_version').attr('version'));
});
</script>
+228
View File
@@ -0,0 +1,228 @@
# coding:utf-8
import sys
import io
import os
import time
import re
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'dynamic-tracking'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getInitDFile():
if app_debug:
return '/tmp/' + getPluginName()
return '/etc/init.d/' + getPluginName()
def getInitDTpl():
path = getPluginDir() + "/init.d/" + getPluginName() + ".tpl"
return path
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
if t.strip() == '':
tmp = []
else:
t = t.split(':')
tmp[t[0]] = t[1]
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
dir_path = getServerDir() + '/trace'
if not os.path.exists(dir_path):
os.mkdir(dir_path)
return 'start'
def dtOp(method):
return 'ok'
def start():
return dtOp('start')
def stop():
return dtOp('stop')
def restart():
status = dtOp('restart')
return status
def reload():
return dtOp('reload')
def initdStatus():
return 'ok'
def initdInstall():
return 'ok'
def initdUinstall():
return 'ok'
def get_file(args):
dir_path = getServerDir() + '/trace'
path = dir_path + '/' + args['file'] + '/main.svg'
if os.path.exists(path):
d = mw.readFile(path)
return mw.returnData(True, 'ok', d)
else:
return mw.returnData(False, '无效目录')
def get_file_path(args):
dir_path = getServerDir() + '/trace'
path = dir_path + '/' + args['file'] + '/main.svg'
if os.path.exists(path):
return mw.returnData(True, 'ok', path)
else:
return mw.returnData(False, '无效目录')
def dtGetFilePath():
args = getArgs()
data = checkArgs(args, ['file'])
if not data[0]:
return data[1]
dir_path = getServerDir() + '/trace'
path = dir_path + '/' + args['file'] + '/main.svg'
if os.path.exists(path):
return mw.returnJson(True, 'ok', path)
else:
return mw.returnJson(False, '无效目录')
def dtRemoveFilePath():
args = getArgs()
data = checkArgs(args, ['file'])
if not data[0]:
return data[1]
dir_path = getServerDir() + '/trace'
path = dir_path + '/' + args['file']
if os.path.exists(path):
mw.execShell('rm -rf ' + path)
return mw.returnJson(True, '删除成功!')
def dtFileList():
dir_path = getServerDir() + '/trace'
if not os.path.exists(dir_path):
os.mkdir(dir_path)
file_info = []
for name in os.listdir(dir_path):
if name == ".DS_Store":
continue
# print(name)
info = {}
try:
info['name'] = name
info['abs_path'] = dir_path + '/' + name + '/main.svg'
except Exception as e:
return mw.returnJson(False, str(e))
file_info.append(info)
file_info = sorted(file_info, key=lambda x: x['name'], reverse=False)
return mw.returnJson(True, 'ok!', file_info)
def dtSimpleTrace():
if mw.isAppleSystem():
return mw.returnJson(False, 'macosx只能手动执行!')
args = getArgs()
data = checkArgs(args, ['pid'])
if not data[0]:
return data[1]
plugins_shell = getPluginDir() + '/shell/simple_trace.sh'
cmd = plugins_shell + ' "' + args['pid'] + '"'
data = mw.execShell("bash " + cmd + " &")
return mw.returnJson(True, '执行成功!')
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print(status())
elif func == 'start':
print(start())
elif func == 'stop':
print(stop())
elif func == 'restart':
print(restart())
elif func == 'reload':
print(reload())
elif func == 'initd_status':
print(initdStatus())
elif func == 'initd_install':
print(initdInstall())
elif func == 'initd_uninstall':
print(initdUinstall())
elif func == 'run_info':
print(runInfo())
elif func == 'conf':
print(getConf())
elif func == 'run_log':
print(runLog())
elif func == 'file_list':
print(dtFileList())
elif func == 'get_file_path':
print(dtGetFilePath())
elif func == 'remove_file_path':
print(dtRemoveFilePath())
elif func == 'simple_trace':
print(dtSimpleTrace())
else:
print('error')
+36
View File
@@ -0,0 +1,36 @@
{
"hook":[
{
"tag":"menu",
"menu": {
"title":"动态追踪",
"name":"dynamic-tracking",
"path":"static/html/index.html",
"css_path":"static/css/dynamic-tracking.css",
"js_path":"static/js/dynamic-tracking.js"
}
},
{
"tag":"global_static",
"global_static": {
"title":"动态追踪",
"name":"dynamic-tracking",
"css_path":"static/css/ico.css"
}
}
],
"sort": 7,
"ps": "专业使用,动态追踪调试程序<无侵入>![<span style='color:red;'>潜龙勿用|实验</span>]",
"name": "dynamic-tracking",
"title": "动态追踪",
"shell": "install.sh",
"versions":["0.1"],
"tip": "soft",
"checks": "server/dynamic-tracking",
"path": "server/dynamic-tracking",
"display": 1,
"author": "midoks",
"date": "2023-08-17",
"type": 0,
"pid": "4"
}
+88
View File
@@ -0,0 +1,88 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
# cd /www/server/mdserver-web/plugins/dynamic-tracking && /bin/bash install.sh uninstall 1.0
# cd /www/server/mdserver-web/plugins/dynamic-tracking && /bin/bash install.sh install 1.0
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
OSNAME=`bash ${rootPath}/scripts/getos.sh`
if [ "" == "$OSNAME" ];then
OSNAME=`cat ${rootPath}/data/osname.pl`
fi
if [ "macos" != "$OSNAME" ];then
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
fi
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source
mkdir -p $serverPath/dynamic-tracking
cn=$(curl -fsSL -m 10 http://ipinfo.io/json | grep "\"country\": \"CN\"")
HTTP_PREFIX="https://"
if [ ! -z "$cn" ];then
HTTP_PREFIX="https://ghproxy.com/"
fi
# FlameGraph start
if [ ! -d $serverPath/dynamic-tracking/FlameGraph ];then
if [ ! -f $serverPath/source/FlameGraph.zip ]; then
wget --no-check-certificate -O $serverPath/source/FlameGraph.zip ${HTTP_PREFIX}github.com/brendangregg/FlameGraph/archive/refs/heads/master.zip
fi
cd $serverPath/source && unzip $serverPath/source/FlameGraph.zip
mv $serverPath/source/FlameGraph-master $serverPath/dynamic-tracking/FlameGraph
fi
# FlameGraph end
shell_file=${curPath}/versions/${OSNAME}.sh
echo $shell_file
if [ ! -f $shell_file ];then
echo '不支持...' > $install_tmp
exit 1
fi
bash -x $shell_file
echo "cp -rf ${curPath}/shell $serverPath/dynamic-tracking"
cp -rf ${curPath}/shell $serverPath/dynamic-tracking
echo "${VERSION}" > $serverPath/dynamic-tracking/version.pl
echo '安装完成' > $install_tmp
cd ${rootPath} && python3 ${rootPath}/plugins/dynamic-tracking/index.py start
# cd ${rootPath} && python3 ${rootPath}/plugins/dynamic-tracking/index.py initd_install
}
Uninstall_App()
{
rm -rf $serverPath/dynamic-tracking
echo "Uninstall_App" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_App
else
Uninstall_App
fi
@@ -0,0 +1,39 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# debug
# cd /www/server/mdserver-web
# bash /www/server/mdserver-web/plugins/dynamic-tracking/shell/simple_macosx_trace.sh "22431"
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web
# bash /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/dynamic-tracking/shell/simple_macosx_trace.sh "22431"
# dtrace -x ustackframes=100 -n 'pid$target::mach_msg_trap:entry { @[ustack()] = count(); } tick-30s { exit(0); }' -p 18572 -o out.SystemUIServer_stacks
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/stackcollapse.pl out.SystemUIServer_stacks > kernel.cbt
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/flamegraph.pl kernel.cbt > kernel.svg
curPath=`pwd`
rootPath=$(dirname "$curPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
PID=$1
echo $rootPath # /Users/midoks/Desktop/mwdev/server
echo $curPath # /Users/midoks/Desktop/mwdev/server/mdserver-web
APP_DIR=${rootPath}/dynamic-tracking
DST_FILE_DIR=${APP_DIR}/trace/PID_${PID}
mkdir -p $DST_FILE_DIR
DST_FILE=${DST_FILE_DIR}/out.SystemUIServer_stacks
if [ ! -f $DST_FILE ];then
sudo dtrace -x ustackframes=100 -n 'pid$target::mach_msg_trap:entry { @[ustack()] = count(); } tick-30s { exit(0); }' -p "$PID" -o $DST_FILE
fi
${APP_DIR}/FlameGraph/stackcollapse.pl $DST_FILE > ${DST_FILE_DIR}/kernel.cbt
${APP_DIR}/FlameGraph/flamegraph.pl ${DST_FILE_DIR}/kernel.cbt > ${DST_FILE_DIR}/main.svg
@@ -0,0 +1,43 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# debug
# cd /www/server/mdserver-web
# bash /www/server/mdserver-web/plugins/dynamic-tracking/shell/simple_trace.sh "2401699"
curPath=`pwd`
rootPath=$(dirname "$curPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
PID=$1
echo $rootPath # /Users/midoks/Desktop/mwdev/server
echo $curPath # /Users/midoks/Desktop/mwdev/server/mdserver-web
APP_DIR=/www/server/dynamic-tracking
DST_FILE_DIR=${APP_DIR}/trace/PID_${PID}
mkdir -p $DST_FILE_DIR
# DST_FILE=${DST_FILE_DIR}/main.strace
# perf record -F 99 -p 335584 -g -- sleep 30
cd ${DST_FILE_DIR}
perf record -F 99 -p ${PID} -g -- sleep 30
perf script > out.perf
${APP_DIR}/FlameGraph/stackcollapse-perf.pl ${DST_FILE_DIR}/out.perf > ${DST_FILE_DIR}/out.folded
${APP_DIR}/FlameGraph/flamegraph.pl ${DST_FILE_DIR}/out.folded > ${DST_FILE_DIR}/main.svg
# perf record -F 99 -p 2401699 -g -- sleep 30
# perf script > out.perf
# /www/server/dynamic-tracking/FlameGraph/stackcollapse-perf.pl out.perf > out.folded
# /www/server/dynamic-tracking/FlameGraph/flamegraph.pl out.folded > php-zend-flame-graph.svg
# ${APP_DIR}/FlameGraph/stackcollapse.pl $DST_FILE > ${DST_FILE_DIR}/kernel.cbt
# ${APP_DIR}/FlameGraph/flamegraph.pl ${DST_FILE_DIR}/kernel.cbt > ${DST_FILE_DIR}/main.svg
@@ -0,0 +1,75 @@
.screen-all {
padding: 5px;
}
.s-right .panel-default{
margin-bottom: 10px;
}
.s-left .panel-default{
margin-bottom: 10px;
}
.data-collect {
width: 45px;
height: 30px;
border: 0;
cursor: pointer;
margin-right: 2px;
margin-top: 10px;
color: #fff;
background-color: #20a53a;
border-color: #20a53a;
}
#file_list .list {
list-style: none;
border-top: none;
border: 1px solid #ececec;
overflow-y: auto;
}
#file_list .list li.active {
background-color: #f2f2f2;
}
#file_list .tab-con{
padding: 0px;
margin-top: 10px;
}
#file_list .list li>span {
vertical-align: top;
display: inline-block;
}
#file_list .list li {
display: inline-block;
height: 38px;
line-height: 38px;
color: #444;
border-bottom: 1px solid #ececec;
font-size: 13px;
cursor: pointer;
position: relative;
width: 100%;
}
#file_list .file {
padding-left: 10px;
}
#file_list .list li .tootls{
width: 70px;
text-align: right;
padding-right: 10px;
/* display: none; */
position: absolute;
right: 5px;
}
/*.tab-con .tab-block.on {
display: inline-block;
}*/
@@ -0,0 +1,11 @@
/* menu start */
.menu .current .menu_dynamic-tracking:hover {
background-image: url("/plugins/file?name=dynamic-tracking&f=ico.png");
}
.menu .menu_plugin_dynamic-tracking {
background-image: url("/plugins/file?name=dynamic-tracking&f=ico.png");
}
/* menu end */
@@ -0,0 +1,81 @@
<style>
.weblog{
font-size: 12px;
display:inline-block;
line-height:30px;
}
.weblog em{
font-style:normal;
color:#666;
margin: 0 30px;
}
.weblog span{
margin-right:5px;
}
.weblog a{
color:#20a53a;
}
.firewall-port-box{
margin-bottom:15px;
}
</style>
<div class="main-content">
<div class="container-fluid">
<div class="pos-box bgw mtb15">
<div class="position f14 c9 pull-left">
<a class="plr10 c4" href="/">首页</a>/<span class="plr10 c4">动态追踪</span>
</div>
<div class="search pull-right">
<form target="hid" onsubmit='return false;'>
<input type="text" id="searchValue" class="ser-text pull-left" placeholder="进程ID" />
<button type="button" class="data-collect pull-left">采样</button>
</form>
</div>
</div>
<!-- //// -->
<div class="safe bgw pd15 mtb15" id="ff_box">
<div id="file_list" style="float:left;width:300px;">
<div class="tab-nav">
<span class="on">文件列表</span>
</div>
<div class="tab-con">
<div class="tab-block on">
<ul class="list" style="display: block; height: 94px;"></ul>
</div>
</div>
</div>
<div id="flame_graph" style="float:left;">
<div class="tab-nav">
<span class="on">火焰图</span>
</div>
<div class="tab-con">
<iframe class="tab-block on" width="100%" height="100%"
src=""
frameborder="0"
border="0"
marginwidth="0"
marginheight="0"
scrolling="yes"
noresize=""
allowfullscreen="allowfullscreen"
mozallowfullscreen="mozallowfullscreen"
msallowfullscreen="msallowfullscreen"
oallowfullscreen="oallowfullscreen"
webkitallowfullscreen="webkitallowfullscreen"
allowfullscreen="true"></iframe>
</div>
</div>
</div>
<!-- //// -->
</div>
</div>
+178
View File
@@ -0,0 +1,178 @@
function changeDivH(){
var l = $(window).height();
var w = $(window).width();
$('#ff_box').css('height',l-80-60);
$('#file_list').css('height',l-80-60);
$('#file_list .tab-con .list').css('height', l-80-60-70);
$('#flame_graph').css('height',l-80-60).css('width',w-300-200-40);
$('#flame_graph iframe').css('height',l-80-60-70);
}
$(document).ready(function(){
var tag = $.getUrlParam('tag');
if(tag == 'dynamic-tracking'){
dynamicTrackingLoad();
}
});
function dynamicTrackingLoad(){
changeDivH();
$(window).resize(function(){
changeDivH();
});
//加载采样数据列表
dtFileList();
}
$('.data-collect').click(function(){
layer.msg('开始采样',{icon:0,time:2000});
var pid = $('#searchValue').val();
dtPost('simple_trace', '', {pid:pid}, function(rdata){
// console.log(rdata);
var rdata = $.parseJSON(rdata.data);
layer.msg(rdata['msg'],{icon:rdata['status']?1:2,time:2000,shade: [0.3, '#000']});
});
});
function dtPost(method, version, args,callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
var req_data = {};
req_data['name'] = 'dynamic-tracking';
req_data['func'] = method;
req_data['version'] = version;
if (typeof(args) == 'string'){
req_data['args'] = JSON.stringify(toArrayObject(args));
} else {
req_data['args'] = JSON.stringify(args);
}
$.post('/plugins/run', req_data, function(data) {
layer.close(loadT);
if (!data.status){
//错误展示10S
layer.msg(data.msg,{icon:0,time:2000,shade: [10, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function dtPostCb(method, version, args,callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
var pdata = {};
pdata['name'] = 'dynamic-tracking';
pdata['func'] = method;
args['version'] = version;
if (typeof(args) == 'string'){
pdata['args'] = JSON.stringify(toArrayObject(args));
} else {
pdata['args'] = JSON.stringify(args);
}
$.post('/plugins/callback', pdata, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function dtFileList(){
dtPost('file_list', '', {}, function(data){
var rdata = $.parseJSON(data.data);
var alist = rdata.data;
if (alist.length == 0){
var em ='<li class="data-file-list" style="text-align: center;">无数据</li>';
$('#file_list .list').html(em);
return;
}
var tli = '';
for (var i = 0; i < alist.length; i++) {
if (i==0){
tli +='<li title="双击打开浏览" class="data-file-list active" data-index="'+i+'" data-file="'+alist[i]['name']+'">\
<span class="file">'+alist[i]['name']+'</span>\
<span class="tootls">\
<span class="glyphicon glyphicon-link" aria-hidden="true" title="外部连接"></span>\
<span class="glyphicon glyphicon-trash" aria-hidden="true" title="删除"></span>\
</span>\
</li>';
} else{
tli +='<li class="data-file-list" data-index="'+i+'" data-file="'+alist[i]['name']+'">\
<span class="file">'+alist[i]['name']+'</span>\
<span class="tootls">\
<span class="glyphicon glyphicon-link" aria-hidden="true" title="外部连接"></span>\
<span class="glyphicon glyphicon-trash" aria-hidden="true" title="删除"></span>\
</span>\
</li>';
}
}
$('#file_list .list').html(tli);
dtGetFile(alist[0]['name']);
$('#file_list li .file').click(function(){
$('#file_list li').removeClass('active');
$(this).parent().addClass('active');
var i = $(this).parent().data('index');
dtGetFile(alist[i]['name']);
});
$('#file_list li .glyphicon-link').click(function(){
var i = $(this).parent().parent().data('index');
var abs_p = alist[i]['abs_path'];
var durl = '/files/download?filename='+abs_p;
window.open(durl);
});
$('#file_list li .glyphicon-trash').click(function(){
var i = $(this).parent().parent().data('index');
var f = alist[i]['name'];
dtPost('remove_file_path', '',{file:f}, function(rdata){
var rdata = $.parseJSON(rdata.data);
layer.msg(rdata['msg'],{icon:rdata['status']?1:2,time:2000});
if (rdata.status){
dtFileList();
}
});
});
});
}
function dtGetFile(file){
dtPost('get_file_path', '', {file:file}, function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
if (!rdata.status){
layer.msg(rdata.msg,{icon:0,time:2000,shade: [2, '#000']});
return;
}
var durl = '/files/download?filename='+rdata.data;
$('#flame_graph .tab-con .tab-block').attr('src',durl);
});
}
@@ -0,0 +1,11 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
@@ -0,0 +1,26 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
# apt-get install linux-perf
# apt-get update -y
# strace -p $(ps -ef|grep "pool www" | awk '{print $2}' | grep -v grep | tr '\n' ',' )
# perf record -F 99 -p 2401699 -g -- sleep 30
# perf script > out.perf
# /www/server/dynamic-tracking/FlameGraph/stackcollapse-perf.pl out.perf > out.folded
# /www/server/dynamic-tracking/FlameGraph/flamegraph.pl out.folded > php-zend-flame-graph.svg
# WWW_PID=$(ps -ef|grep "pool www" | awk '{print $2}' | grep -v grep | tr '\n' ',')
# WWW_PID=${WWW_PID//,/}
# WWW_PID=${var%,}
# perf record -F 99 -p "1037,1038,1039,1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1127,1128,1129,1130,1131,1473,1768,2848,2962,21582,35891" \
# -g -- sleep 30
@@ -0,0 +1,21 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
# 关于macosx使用dtrace
# https://groups.google.com/g/openresty/c/MswlH_8DDHA
# http://dtrace.org/blogs/brendan/2012/11/14/dtracing-in-anger/
# dtrace -x ustackframes=100 -n 'pid$target::mach_msg_trap:entry { @[ustack()] = count(); } tick-30s { exit(0); }' -p 18572 -o out.SystemUIServer_stacks
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/stackcollapse.pl out.SystemUIServer_stacks > kernel.cbt
# /Users/midoks/Desktop/mwdev/server/dynamic-tracking/FlameGraph/flamegraph.pl kernel.cbt > kernel.svg
@@ -0,0 +1,11 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
SYS_ARCH=`arch`
+365
View File
@@ -0,0 +1,365 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import json
import io
sys.path.append(os.getcwd() + "/class/core")
import mw
# -----------------------------
import google.oauth2.credentials
import google_auth_oauthlib.flow
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from googleapiclient.http import MediaFileUpload
from googleapiclient.http import MediaIoBaseDownload
class gdriveclient():
__plugin_dir = ''
__server_dir = ''
__credentials = "/root/credentials.json"
__backup_dir_name = "backup"
__creds = None
__exclude = ""
__scpos = ['https://www.googleapis.com/auth/drive.file']
_title = 'Google Drive'
_name = 'Google Drive'
__debug = False
_DEFAULT_AUTH_PROMPT_MESSAGE = (
'Please visit this URL to authorize this application: {url}')
"""str: The message to display when prompting the user for
authorization."""
_DEFAULT_AUTH_CODE_MESSAGE = (
'Enter the authorization code: ')
"""str: The message to display when prompting the user for the
authorization code. Used only by the console strategy."""
_DEFAULT_WEB_SUCCESS_MESSAGE = (
'The authentication flow has completed, you may close this window.')
def __init__(self, plugin_dir, server_dir):
self.__plugin_dir = plugin_dir
self.__server_dir = server_dir
self.set_creds()
# self.get_exclode()
def setDebug(self, d=False):
self.__debug = d
def D(self, msg=''):
if self.__debug:
print(msg)
# 检查gdrive连接
def _check_connect(self):
try:
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name)").execute()
results.get('files', [])
except:
return False
return True
# 设置creds
def set_creds(self):
token_file = self.__server_dir + '/token.json'
if os.path.exists(token_file):
with open(token_file, 'rb') as token:
tmp_data = json.load(token)['credentials']
self.__creds = google.oauth2.credentials.Credentials(
tmp_data['token'],
tmp_data['refresh_token'],
tmp_data['id_token'],
tmp_data['token_uri'],
tmp_data['client_id'],
tmp_data['client_secret'],
tmp_data['scopes'])
# if not self._check_connect():
# return False
# else:
# return True
def get_sign_in_url(self):
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
self.__plugin_dir + '/credentials.json',
scopes=self.__scpos)
# flow.redirect_uri = 'https://drive.aapanel.com'
flow.redirect_uri = 'https://drive.aapanel.com'
auth_url, state = flow.authorization_url(
access_type='offline',
prompt='consent',
include_granted_scopes='false')
return auth_url, state
def set_auth_url(self, url):
token_file = self.__server_dir + '/token.json'
if os.path.exists(token_file):
return mw.returnJson(True, "验证成功")
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
self.__plugin_dir + '/credentials.json',
scopes=self.__scpos,
state=url.split('state=')[1].split('&code=')[0])
# flow.redirect_uri = 'https://localhost'
flow.redirect_uri = 'https://drive.aapanel.com'
flow.fetch_token(authorization_response=url)
credentials = flow.credentials
credentials_data = {}
credentials_data['credentials'] = {
'token': credentials.token,
'id_token': credentials.id_token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'scopes': credentials.scopes}
with open(token_file, 'w') as token:
json.dump(credentials_data, token)
if not self.set_creds():
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
return mw.returnJson(True, "验证成功")
# 获取token
def get_token(self, get):
token_file = self.__server_dir + '/token.json'
import requests
try:
respone = requests.get("https://www.google.com", timeout=2)
except:
return mw.returnJson(False, "连接谷歌失败")
if respone.status_code != 200:
return mw.returnJson(False, "连接谷歌失败")
if not self.set_creds():
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
if not os.path.exists(token_file):
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
return mw.returnJson(True, "验证成功")
# 获取auth_url
def get_auth_url(self, get):
self.get_sign_in_url()
if os.path.exists("/tmp/auth_url"):
return mw.readFile("/tmp/auth_url")
# 检查连接
def check_connect(self, get):
token_file = self.__server_dir + '/token.json'
if os.path.exists(token_file):
with open(token_file, 'rb') as token:
self.set_creds()
else:
self.D("Failed to get Google token, please verify before use")
return mw.returnJson(True, "Failed to get Google token, please verify before use")
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().list(
pageSize=10, fields="nextPageToken, files(id, name)").execute()
try:
results.get('files', [])
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
return mw.returnJson(True, "验证成功")
except:
return mw.returnJson(False, "验证失败,请根据页面1 2 3 步骤完成验证")
def _get_filename(self, filename):
l = filename.split("/")
return l[-1]
def _create_folder_cycle(self, filepath):
l = filepath.split("/")
fid_list = []
for i in l:
if not i:
continue
fid = self.__get_folder_id(i)
if fid:
fid_list.append(fid)
continue
if not fid_list:
fid_list.append("")
fid_list.append(self.create_folder(i, fid_list[-1]))
return fid_list[-1]
def build_object_name(self, data_type, file_name):
"""根据数据类型构建对象存储名称
:param data_type:
:param file_name:
:return:
"""
import re
prefix_dict = {
"site": "web",
"database": "db",
"path": "path",
}
if not prefix_dict.get(data_type):
print("data_type 类型错误!!!")
exit(1)
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+\."
sub_search = re.search(file_regx.lower(), file_name)
sub_path_name = ""
if sub_search:
sub_path_name = sub_search.groups()[0]
sub_path_name += '/'
# 构建OS存储路径
object_name = self.__backup_dir_name + \
'/{}/{}'.format(data_type, sub_path_name)
if object_name[:1] == "/":
object_name = object_name[1:]
return object_name
# 上传文件
def upload_file(self, filename, data_type=None):
"""
get.filename 上传后的文件名
get.filepath 上传文件路径
被面板新版计划任务调用时
get表示file_name
:param get:
:return:
"""
# filename = filename
filepath = self.build_object_name(data_type, filename)
_filename = self._get_filename(filename)
self.D(filepath)
self.D(filename)
parents = self._create_folder_cycle(filepath)
self.D(parents)
drive_service = build('drive', 'v3', credentials=self.__creds)
file_metadata = {'name': _filename, 'parents': [parents]}
media = MediaFileUpload(filename, resumable=True)
file = drive_service.files().create(
body=file_metadata, media_body=media, fields='id').execute()
self.D('Upload Success ,File ID: %s' % file.get('id'))
return True
def _get_file_id(self, filename):
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().list(pageSize=10, q="name='{}'".format(
filename), fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
if not items:
return []
else:
for item in items:
return item["id"]
def delete_file(self, filename=None, data_type=None):
file_id = self._get_file_id(filename)
self.delete_file_by_id(file_id)
return True
def delete_file_by_id(self, file_id):
self.D("delete id:{}".format(file_id))
try:
drive_service = build('drive', 'v3', credentials=self.__creds)
drive_service.files().delete(fileId=file_id).execute()
return True
except Exception as e:
return False
# 创建目录
def create_folder(self, folder_name, parents=""):
self.D(self.__creds)
self.D("folder_name: {}".format(folder_name))
self.D("parents: {}".format(parents))
service = build('drive', 'v3', credentials=self.__creds)
file_metadata = {
'name': folder_name,
'mimeType': 'application/vnd.google-apps.folder'
}
if parents:
file_metadata['parents'] = [parents]
folder = service.files().create(body=file_metadata, fields='id').execute()
self.D('Create Folder ID: %s' % folder.get('id'))
return folder.get('id')
def get_rootdir_id(self, folder_name='backup'):
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().list(pageSize=10, q="name='{}' and mimeType='application/vnd.google-apps.folder'".format(folder_name),
fields="nextPageToken, files(id, name,size,parents,webViewLink)").execute()
items = results.get('files', [])
if len(items) == 0:
self.create_folder(folder_name)
return self.get_rootdir_id(folder_name)
return items[0]['parents'][0]
# 获取目录id
def __get_folder_id(self, floder_name):
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().list(pageSize=10, q="name='{}' and mimeType='application/vnd.google-apps.folder'".format(floder_name),
fields="nextPageToken, files(id, name)").execute()
items = results.get('files', [])
if not items:
return []
else:
for item in items:
return item["id"]
def get_res_info(self, rid):
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().get(fileId='{}'.format(rid)).execute()
return results
def get_id_list(self, driveId=''):
service = build('drive', 'v3', credentials=self.__creds)
results = service.files().list(pageSize=10, driveId="{}".format(driveId),
fields="nextPageToken, files(id, name,size,parents)").execute()
items = results.get('files', [])
return items
def get_list(self, dir_id='', next_page_token=''):
if dir_id == '':
dir_id = self.get_rootdir_id(self.__backup_dir_name)
service = build('drive', 'v3', credentials=self.__creds)
cmd_query = "trashed=false and '{}' in parents".format(dir_id)
results = service.files().list(pageSize=10, q=cmd_query, orderBy='folder asc',
fields="nextPageToken, files(id, name,size,createdTime,parents,webViewLink)").execute()
items = results.get('files', [])
nextPageToken = results.get('nextPageToken', [])
# print(items)
# print(nextPageToken)
return items
def get_exclode(self, exclude=[]):
if not exclude:
tmp_exclude = os.getenv('MW_EXCLUDE')
if tmp_exclude:
exclude = tmp_exclude.split(',')
if not exclude:
return ""
for ex in exclude:
self.__exclude += " --exclude=\"" + ex + "\""
self.__exclude += " "
return self.__exclude
def download_file(self, filename):
file_id = self._get_file_id(filename)
service = build('drive', 'v3', credentials=self.__creds)
request = service.files().get_media(fileId=file_id)
with open('/tmp/{}'.format(filename), 'wb') as fh:
downloader = MediaIoBaseDownload(fh, request)
done = False
while done is False:
status, done = downloader.next_chunk()
print("Download %d%%." % int(status.progress() * 100))
+13
View File
@@ -0,0 +1,13 @@
{
"web": {
"client_id": "226011946234-d3e1vashgag64utjedu1ljt9u39ncrpq.apps.googleusercontent.com",
"project_id": "light-willow-341609",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "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",
"redirect_uris": [
"https://drive.aapanel.com"
]
}
}
+11
View File
@@ -0,0 +1,11 @@
{
"web": {
"client_id": "540181629246-1horo9i4htamdbhiqar9rcbq33bqe2ob.apps.googleusercontent.com",
"project_id": "plated-inn-369901",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "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",
"redirect_uris": ["https://drive.aapanel.com"]
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

+310
View File
@@ -0,0 +1,310 @@
<style>
.upyunCon {
height: 428px;
}
.up-place {
height: 62px;
border-bottom: 1px solid #ddd;
}
.up-place .btn {
border-radius: 0;
}
.up-place .place-input {
background-color: #f3f3f3;
border: 1px solid #ccc;
height: 30px;
line-height: 28px;
overflow: hidden;
margin: 1px 0 0 -1px;
width: 340px;
}
.place-input ul {
display: inline-block;
position: relative;
width: auto;
}
.place-input ul li {
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
float: left;
padding-left: 10px;
padding-right: 18px;
}
.place-input ul li a {
height: 28px;
cursor: pointer;
display: inline-block;
}
.upyunlist {
height: 516px;
overflow: auto;
}
.up-bottom {
background-color: #fafafa;
border-top: 1px solid #eee;
bottom: 0;
position: absolute;
width: 100%;
}
.up-use {
line-height: 50px
}
.list-list .cursor span {
line-height: 30px;
}
.btn-title {
margin-top: 1px
}
.tip {
font-size: 10px;
font-style: oblique;
color: green;
}
</style>
<div class="upyunCon">
<div class="up-place pd15">
<button id="backBtn" class="btn btn-default btn-sm glyphicon glyphicon-arrow-left pull-left" title="后退"></button>
<input id="myPath" type="hidden" value="">
<input id="curPath" type="hidden" value="">
<div class="place-input pull-left">
<div style="width:1400px;height:28px"><ul></ul></div>
</div>
<button class="refreshBtn btn btn-default btn-sm glyphicon glyphicon-refresh pull-left mr20" title="刷新" style="margin-left:-1px;"></button>
<button class="btn btn-default btn-sm pull-right btn-title" onclick="authApi()">授权</button>
<button class="btn btn-default btn-sm pull-right mr20 btn-title" onclick="createDir()">新建文件夹</button>
</div>
<div class="upyunlist pd15">
<div class="divtable" style="margin-bottom:15px">
<table class="table table-hover">
<thead><tr><th>名称</th><th>大小</th><th>更新时间</th><th class="text-right">操作</th></tr></thead>
<tbody class="list-list"></tbody>
</table>
</div>
</div>
</div>
<style type="text/css">
.check_api {
padding: 20px;
}
.up-place {
height: 62px;
border-bottom: 1px solid #ddd;
}
.up-place .btn {
border-radius: 0;
}
.up-place .place-input {
background-color: #f3f3f3;
border: 1px solid #ccc;
height: 30px;
line-height: 28px;
overflow: hidden;
margin: 1px 0 0 -1px;
width: 340px;
}
.place-input ul {
display: inline-block;
position: relative;
width: auto;
}
.place-input ul li {
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
float: left;
padding-left: 10px;
padding-right: 18px;
}
.place-input ul li a {
height: 28px;
cursor: pointer;
display: inline-block;
}
.upyunlist {
height: 546px;
overflow: auto;
}
.up-bottom {
background-color: #fafafa;
border-top: 1px solid #eee;
bottom: 0;
position: absolute;
width: 100%;
}
.up-use {
line-height: 50px
}
.list-list .cursor span {
line-height: 30px;
}
.btn-title {
margin-top: 1px
}
.step_item{
clear: both;
}
.step_item .serial_box{
display: inline-block;
clear: both;
}
.step_item .serial{
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
display: inline-block;
float: left;
}
.step_item .serial span{
display: inline-block;
width: 30px;
height: 30px;
text-align: center;
line-height: 28px;
font-size: 11px;
border-radius: 50%;
color: #20a53a;
border: 2px solid #20a53a;
}
.step_item .serial_title{
margin-bottom: 10px;
font-size: 15px;
line-height: 30px;
color: #666;
}
.step_two_url{
display: inline-block;
overflow: hidden;
width: 380px;
/*text-overflow: ellipsis;*/
white-space: nowrap;
height: 35px;
line-height: 35px;
margin-right: 15px;
border-radius: 2px;
padding: 0 10px;
float: left;
width:360px;
padding-right: 35px;
}
.btn_btlink{
display: inline-block;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
border: 1px solid #20a53a;
color: #fff;
background-color: #20a53a;
margin-right:10px;
}
.btn_btlink:hover{
color: #fff;
background-color: #10952a;
border-color: #398439;
}
.btn_btlink a:visited{
color: #fff;
background-color: #10952a;
border-color: #398439;
}
.view_video{
margin-bottom: 10px;
}
.view_video ul li{
line-height: 20px;
font-size: 13px;
}
.setp_one i{
position: absolute;
top: 8px;
left: 25px;
width: 30px;
height: 30px;
}
.google_drive{
width:465px;
height:100px;
margin-bottom:10px;
}
</style>
<script type="text/html" id="check_api">
<div class="check_api">
<div class="step_two">
<div class="step_item">
<div class="serial"><span>1</span></div>
<div class="serial_box">
<div class="serial_title">阅读简易操作教程:如何获取Google Drive授权?</div>
<div class="serial_conter">
<div class="view_video">
<ul>
<li>1. 点击下面第<div class="serial" style="float: none;width: 45px;"><span>2</span></div>步中的 打开授权链接。<li>
<li>2. 在新窗口页面上登录Google Drive账号。阅读授权权限,并同意。<li>
<li>3. 页面跳转后,将浏览器的地址栏地址复制到第<div class="serial" style="float: none;width: 45px;"><span>3</span></div>步的文本框中。<li>
<li>4. 点击 获取授权,随即完成授权。<li>
</ul>
</div>
<hr/>
</div>
</div>
</div>
<div class="step_item pb15">
<div class="serial"><span>2</span></div>
<div class="serial_box">
<div class="serial_title">操作1:👇打开授权链接,根据网页提示对插件进行授权。</div>
<div class="serial_conter step_two" style="width: 500px;">
<input class="bt-input-text mr5 step_two_url" type="text" disabled>
<span class="ico-copy mr10" data-copy="" style="vertical-align: middle;cursor: pointer;margin-left: -37px;margin-right: 20px;"></span>
<a href="" class="btn_btlink open_btlink" target="_blank" style="padding: 7px 10px;">打开授权链接</a>
</div>
</div>
</div>
<div class="step_item">
<div class="serial"><span>3</span></div>
<div class="serial_box">
<div class="serial_title">操作2:复制回浏览器跳转后的地址:</div>
<div class="serial_conter">
<textarea row="3" placeholder="验证URL地址" class="bt-input-text google_drive" style="resize: none;"/></br>
<button type="button" class="btn btn-success btn-sm set_auth_btn">获取授权</button>
</div>
</div>
</div>
</div>
</div>
</script>
<script type="text/javascript" src="/plugins/file?name=gdrive&f=js/gdrive.js"></script>
<script type="text/javascript">
$.getScript( "/plugins/file?name=gdrive&f=js/gdrive.js", function(){
gdList('');
});
</script>
+338
View File
@@ -0,0 +1,338 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import json
# print(sys.platform)
if sys.platform != "darwin":
os.chdir("/www/server/mdserver-web")
sys.path.append(os.getcwd() + "/class/core")
import mw
import db
_ver = sys.version_info
is_py2 = (_ver[0] == 2)
is_py3 = (_ver[0] == 3)
DEBUG = False
if is_py2:
reload(sys)
sys.setdefaultencoding('utf-8')
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'gdrive'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def in_array(name, arr=[]):
for x in arr:
if name == x:
return True
return False
sys.path.append(getPluginDir() + "/class")
from gdriveclient import gdriveclient
gd = gdriveclient(getPluginDir(), getServerDir())
gd.setDebug(False)
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
if t.strip() == '':
tmp = []
else:
t = t.split(':', 1)
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':', 1)
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
return 'start'
def isAuthApi():
cfg = getServerDir() + "/token.json"
if os.path.exists(cfg):
return True
return False
def getConf():
if not isAuthApi():
sign_in_url, state = gd.get_sign_in_url()
return mw.returnJson(False, "未授权!", {'auth_url': sign_in_url})
return mw.returnJson(True, "OK")
def setAuthUrl():
args = getArgs()
data = checkArgs(args, ['url'])
if not data[0]:
return data[1]
url = args['url']
try:
if url.startswith("http://"):
url = url.replace("http://", "https://")
token = gd.set_auth_url(url)
# gd.store_token(token)
# gd.store_user()
return mw.returnJson(True, "授权成功!")
except Exception as e:
return mw.returnJson(False, "授权失败2!:" + str(e))
return mw.returnJson(False, "授权失败!:" + str(e))
def clearAuth():
token = getServerDir() + "/token.json"
if os.path.exists(token):
os.remove(token)
return mw.returnJson(True, "清空授权成功!")
def getList():
if not isAuthApi():
return mw.returnJson(False, "未配置,请点击`授权`", [])
args = getArgs()
data = checkArgs(args, ['file_id'])
if not data[0]:
return data[1]
try:
flist = gd.get_list(args['file_id'])
return mw.returnJson(True, "ok", flist)
except Exception as e:
return mw.returnJson(False, str(e), [])
def createDir():
if not isAuthApi():
return mw.returnJson(False, "未配置,请点击`授权`", [])
args = getArgs()
data = checkArgs(args, ['parents', 'name'])
if not data[0]:
return data[1]
isok = gd.create_folder(args['name'], args['parents'])
if isok:
return mw.returnJson(True, "创建成功")
return mw.returnJson(False, "创建失败")
def deleteDir():
args = getArgs()
data = checkArgs(args, ['dir_name', 'path'])
if not data[0]:
return data[1]
isok = gd.delete_file_by_id(args['dir_name'])
if isok:
return mw.returnJson(True, "删除成功")
return mw.returnJson(False, "文件不为空,删除失败!")
def deleteFile():
args = getArgs()
data = checkArgs(args, ['path', 'filename'])
if not data[0]:
return data[1]
isok = gd.delete_file(args['filename'])
if isok:
return mw.returnJson(True, "删除成功")
return mw.returnJson(False, "删除失败")
def findPathName(path, filename):
f = os.scandir(path)
l = []
for ff in f:
t = {}
if ff.name.find(filename) > -1:
t['filename'] = path + '/' + ff.name
l.append(t)
return l
def backupAllFunc(stype):
if not isAuthApi():
mw.echoInfo("未授权API,无法使用!!!")
return ''
os.chdir(mw.getRunDir())
backup_dir = mw.getBackupDir()
run_dir = mw.getRunDir()
stype = sys.argv[1]
name = sys.argv[2]
num = sys.argv[3]
prefix_dict = {
"site": "web",
"database": "db",
"path": "path",
}
backups = []
sql = db.Sql()
# print("stype:", stype)
# 提前获取-清理多余备份
if stype == 'site':
pid = sql.table('sites').where('name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('0', pid)).field('id,filename').select()
if stype == 'database':
db_path = mw.getServerDir() + '/mysql'
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
if stype == 'path':
backup_path = backup_dir + '/path'
_name = 'path_{}'.format(os.path.basename(name))
backups = findPathName(backup_path, _name)
# 其他类型关系性数据库(mysql类的)
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
db_path = mw.getServerDir() + '/' + plugin_name
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
args = stype + " " + name + " " + num
cmd = 'python3 ' + run_dir + '/scripts/backup.py ' + args
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
args = "database " + name + " " + num
cmd = 'python3 ' + run_dir + '/plugins/' + \
plugin_name + '/scripts/backup.py ' + args
if stype == 'path':
name = os.path.basename(name)
# print("cmd:", cmd)
os.system(cmd)
# 开始执行上传信息.
if stype.find('database_') > -1:
bk_name = 'database'
plugin_name = stype.replace('database_', '')
bk_prefix = plugin_name + '/db'
stype = 'database'
else:
bk_prefix = prefix_dict[stype]
bk_name = stype
find_path = backup_dir + '/' + bk_name + '/' + bk_prefix + '_' + name
find_new_file = "ls " + find_path + \
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
# print(find_new_file)
filename = mw.execShell(find_new_file)[0].strip()
if filename == "":
mw.echoInfo("not find upload file!")
return False
mw.echoInfo("准备上传文件 {}".format(filename))
mw.echoStart('开始上传')
# gd.setDebug(False)
gd.upload_file(filename, stype)
mw.echoEnd('上传成功')
# print(backups)
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
mw.echoStart('开始删除远程备份')
num = int(num)
sep = len(backups) - num
if sep > -1:
for backup in backups:
fn = os.path.basename(backup['filename'])
gd.delete_file(fn, stype)
mw.echoInfo("---已清理远程过期备份文件:" + fn)
sep -= 1
if sep < 0:
break
mw.echoEnd('结束删除远程备份')
return ''
def installPreInspection():
return 'ok'
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print(status())
elif func == 'start':
print(start())
elif func == 'stop':
print(stop())
elif func == 'restart':
print(restart())
elif func == 'reload':
print(reload())
elif func == 'install_pre_inspection':
print(installPreInspection())
elif func == 'conf':
print(getConf())
elif func == 'set_auth_url':
print(setAuthUrl())
elif func == 'clear_auth':
print(clearAuth())
elif func == "get_list":
print(getList())
elif func == "create_dir":
print(createDir())
elif func == "delete_dir":
print(deleteDir())
elif func == 'delete_file':
print(deleteFile())
elif in_array(func, ['site', 'database', 'path']) or func.find('database_') > -1:
print(backupAllFunc(func))
else:
print('error')
+19
View File
@@ -0,0 +1,19 @@
{
"hook":["backup"],
"id":998,
"title":"谷歌云网盘",
"tip":"lib",
"name":"gdrive",
"type":"扩展",
"ps":"备份你的数据到谷歌云网盘",
"versions":"2.0",
"shell":"install.sh",
"checks": "server/gdrive",
"path":"server/gdrive",
"author":"google",
"home":"https://drive.google.com/",
"api_doc":"https://developers.google.com/drive/api/guides/about-sdk?hl=zh_CN",
"api_doc2":"https://developers.google.cn/drive/api/reference/rest/v3/comments/list?hl=zh-cn",
"date":"2022-06-26",
"pid":"4"
}
+87
View File
@@ -0,0 +1,87 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# cd /www/server/mdserver-web/plugins/gdrive && /bin/bash install.sh install 2.0
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
PATH=$PATH:${rootPath}/bin
export PATH
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
VERSION=$2
Install_App()
{
tmp_ping=`ping -c 1 google.com 2>&1`
echo $tmp_ping
if [ $? -eq 0 ];then
tmp=`python -V 2>&1|awk '{print $2}'`
pVersion=${tmp:0:3}
which pip
if [ "$?" -eq "0" ];then
tmp=$(pip list|grep google-api-python-client|awk '{print $2}')
if [ "$tmp" != '2.39.0' ];then
pip install --upgrade google-api-python-client
# pip uninstall google-api-python-client -y
pip install -I google-api-python-client==2.39.0 -i https://pypi.Python.org/simple
fi
tmp=$(pip list|grep google-auth-httplib2|awk '{print $2}')
if [ "$tmp" != '0.1.0' ];then
pip uninstall google-auth-httplib2 -y
pip install -I google-auth-httplib2==0.1.0 -i https://pypi.Python.org/simple
fi
tmp=$(pip list|grep google-auth-oauthlib|awk '{print $2}')
if [ "$tmp" != '0.5.0' ];then
# pip uninstall google-auth-oauthlib -y
pip install -I google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
fi
tmp=$(pip list|grep -E '^httplib2'|awk '{print $2}')
if [ "$tmp" != '0.18.1' ];then
# pip uninstall httplib2 -y
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
fi
else
pip install -I pyOpenSSL
pip install -I google-api-python-client==2.39.0 google-auth-httplib2==0.1.0 google-auth-oauthlib==0.5.0 -i https://pypi.Python.org/simple
pip install -I httplib2==0.18.1 -i https://pypi.Python.org/simple
fi
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/gdrive
echo "${VERSION}" > $serverPath/gdrive/version.pl
echo '安装完成' > $install_tmp
else
echo '服务器连接不上谷歌云!安装失败!' > $install_tmp
exit 1
fi
}
Uninstall_App()
{
rm -rf $serverPath/gdrive
echo '卸载完成' > $install_tmp
}
action=$1
type=$2
echo $action $type
if [ "${action}" == 'install' ];then
Install_App
else
Uninstall_App
fi
+260
View File
@@ -0,0 +1,260 @@
function gdPost(method,args,callback){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'gdrive', func:method, args:_args}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function createDir(){
layer.open({
type: 1,
area: "400px",
title: "创建目录",
closeBtn: 1,
shift: 5,
shadeClose: false,
btn: ['确定','取消'],
content:'<div class="bingfa bt-form c6" style="padding-bottom: 10px;">\
<p>\
<span class="span_tit">目录名称:</span>\
<input style="width: 200px;" type="text" name="newPath" value="">\
</p>\
</div>',
success:function(){
$("input[name='newPath']").focus().keyup(function(e){
if(e.keyCode == 13) $(".layui-layer-btn0").click();
});
},
yes:function(index,layero){
var name = $("input[name='newPath']").val();
if(name == ''){
layer.msg('目录名称不能为空!',{icon:2});
return;
}
var parents = $("#myPath").val();
var cur_file_id = $('#curPath').val();
if (cur_file_id!=''){
parents = cur_file_id;
}
var dirname = name;
var loadT = layer.msg('正在创建目录['+dirname+']...',{icon:16,time:0,shade: [0.3, '#000']});
gdPost('create_dir', {parents:parents,name:dirname}, function(data){
layer.close(loadT);
var rdata = $.parseJSON(data.data);
if(rdata.status) {
showMsg(rdata.msg, function(){
layer.close(index);
var file_id = $('#myPath').val();
if (cur_file_id!=''){
file_id = cur_file_id;
}
gdList(file_id);
} ,{icon:1}, 2000);
} else{
layer.msg(rdata.msg,{icon:2});
}
});
}
});
}
//设置API
function authApi(){
gdPost('conf', {}, function(rdata){
var rdata = $.parseJSON(rdata.data);
// console.log(rdata);
// console.log(rdata.data.auth_url);
var apicon = '';
if (rdata.status){
var html = '';
html += '<button id="clear_auth" onclick="clearAuth();" class="btn btn-default btn-sm">清空配置</button>';
var loadOpen = layer.open({
type: 1,
title: '已授权',
area: '240px',
content:'<div class="change-default pd20">'+html+'</div>',
success: function(){
$('#clear_auth').click(function(){
gdPost('clear_auth', {}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
layer.close(loadOpen);
gdList('');
},{icon:rdata.status?1:2},2000);
});
});
}
});
return true;
} else{
apicon = '<div class="new_form">'+$("#check_api").html()+'</div>';
}
var layer_auth = layer.open({
type: 1,
area: "620px",
title: "Google Drive 授权",
closeBtn: 1,
shift: 5,
shadeClose: false,
content:apicon,
success:function(layero,index){
// console.log(layero,index);
if (!rdata.status){
$('.check_api .step_two_url').val(rdata.data['auth_url']);
$('.check_api .open_btlink').attr('href',rdata.data['auth_url']);
$('.check_api .ico-copy').click(function(){
copyPass(rdata.data['auth_url']);
});
$('.check_api .set_auth_btn').click(function(){
var url = $('.check_api .google_drive').val();
if ( url == ''){
layer.msg("验证URL不能为空",{icon:2});
return;
}
// console.log(url);
gdPost('set_auth_url', {url:url}, function(rdata){
var rdata = $.parseJSON(rdata.data);
var show_time = 2000;
if (!rdata.status){
show_time = 10000;
}
showMsg(rdata.msg,function(){
if (rdata.status){
layer.close(layer_auth);
gdList('');
}
},{icon:rdata.status?1:2},show_time);
});
});
}
}
});
});
}
//计算当前目录偏移
function upPathLeft(){
var UlWidth = $(".place-input ul").width();
var SpanPathWidth = $(".place-input").width() - 20;
var Ml = UlWidth - SpanPathWidth;
if(UlWidth > SpanPathWidth ){
$(".place-input ul").css("left",-Ml)
}
else{
$(".place-input ul").css("left",0)
}
}
function getGDTime(a) {
return new Date(a).format("yyyy/MM/dd hh:mm:ss")
}
function gdList(file_id){
$('#curPath').val(file_id);
gdPost('get_list', {file_id:file_id}, function(rdata){
var rdata = $.parseJSON(rdata.data);
console.log(rdata);
if(rdata.status === false){
showMsg(rdata.msg,function(){
authApi();
},{icon:2},2000);
return;
}
var mlist = rdata.data;
var listBody = '';
var listFiles = '';
for(var i=0;i<mlist.length;i++){
if(mlist[i].size == null){
listFiles += '<tr><td class="cursor" onclick="gdList(\''+(mlist[i].id).replace('//','/')+'\')"><span class="ico ico-folder"></span>\<span>'+mlist[i].name+'</span></td>\
<td>-</td>\
<td>-</td>\
<td class="text-right"><a class="btlink" onclick="deleteFile(\''+mlist[i].id+'\', true)">删除</a></td></tr>'
}else{
listFiles += '<tr><td class="cursor"><span class="ico ico-file"></span><span>'+mlist[i].name+'</span></td>\
<td>'+toSize(mlist[i].size)+'</td>\
<td>'+getGDTime(mlist[i].createdTime)+'</td>\
<td class="text-right"><a target="_blank" href="'+mlist[i].webViewLink+'" class="btlink">下载</a> | <a class="btlink" onclick="deleteFile(\''+mlist[i].name+'\', false)">删除</a></td></tr>'
}
}
listBody += listFiles;
var pathLi = '<li><a title="根目录" onclick="gdList(\'\')">根目录</a></li>';
if (mlist.length>0){
$('#myPath').val(mlist[0]['parents'][0]);
}
$(".upyunCon .place-input ul").html(pathLi);
$(".upyunlist .list-list").html(listBody);
$('#backBtn').unbind().click(function() {
gdList('');
});
$('.upyunCon .refreshBtn').unbind().click(function(){
var file_id = $('#myPath').val();
gdList(file_id);
});
});
}
//删除文件
function deleteFile(name, is_dir){
if (is_dir === false){
safeMessage('删除文件','删除后将无法恢复,真的要删除['+name+']吗?',function(){
var path = $("#myPath").val();
var filename = name;
gdPost('delete_file', {filename:filename,path:path}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
var file_id = $('#myPath').val();
gdList(file_id);
},{icon:rdata.status?1:2},2000);
});
});
} else {
safeMessage('删除文件夹','删除后将无法恢复,真的要删除文件资源['+name+']吗?',function(){
var path = $("#myPath").val();
gdPost('delete_dir', {dir_name:name,path:path}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
var file_id = $('#myPath').val();
gdList(file_id);
},{icon:rdata.status?1:2},2000);
});
});
}
}
+113
View File
@@ -0,0 +1,113 @@
#!/usr/bin/python
# coding: utf-8
# python3 plugins/gdrive/t/test.py
# https://console.cloud.google.com/apis/credentials/consent?project=plated-inn-369901
# https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=226011946234-d3e1vashgag64utjedu1ljt9u39ncrpq.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fdrive.aapanel.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&state=I2da4aZUwqgmikrgrqAwwSjyoEHVs1&access_type=offline&prompt=consent&include_granted_scopes=false
# https://portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/08125e6b-6502-4ac9-9548-ad682f00848d/objectId/62b1d655-9828-47ed-be99-65eb18c3a929/isMSAApp~/false/defaultBlade/Overview/appSignInAudience/AzureADandPersonalMicrosoftAccount/servicePrincipalCreated~/true
# 0WA8Q~sZkZFZKv50ryP4ux~.fpVtbHw7BuTZmbQB
# client_id:d9878fac-8526-4ff6-8036-e1c92dd9dd80
# 08125e6b-6502-4ac9-9548-ad682f00848d
# /drive/v2internal/files?openDrive=false&reason=102&syncType=0&errorRecovery=false&q=trashed = false and '1-z6gUXseXmlxmntvkLzOe_tYFT5tdhM9' in parents&fields=kind,nextPageToken,items(kind,modifiedDate,hasVisitorPermissions,containsUnsubscribedChildren,modifiedByMeDate,lastViewedByMeDate,alternateLink,fileSize,owners(kind,permissionId,emailAddressFromAccount,id),lastModifyingUser(kind,permissionId,emailAddressFromAccount,id),customerId,ancestorHasAugmentedPermissions,hasThumbnail,thumbnailVersion,title,id,resourceKey,abuseIsAppealable,abuseNoticeReason,shared,accessRequestsCount,sharedWithMeDate,userPermission(role),explicitlyTrashed,mimeType,quotaBytesUsed,copyable,subscribed,folderColor,hasChildFolders,fileExtension,primarySyncParentId,sharingUser(kind,permissionId,emailAddressFromAccount,id),flaggedForAbuse,folderFeatures,spaces,sourceAppId,recency,recencyReason,version,actionItems,teamDriveId,hasAugmentedPermissions,createdDate,primaryDomainName,organizationDisplayName,passivelySubscribed,trashingUser(kind,permissionId,emailAddressFromAccount,id),trashedDate,parents(id),capabilities(canMoveItemIntoTeamDrive,canUntrash,canModifyContentRestriction,canMoveItemWithinTeamDrive,canMoveItemOutOfTeamDrive,canDeleteChildren,canTrashChildren,canRequestApproval,canReadCategoryMetadata,canEditCategoryMetadata,canAddMyDriveParent,canRemoveMyDriveParent,canShareChildFiles,canShareChildFolders,canRead,canMoveItemWithinDrive,canMoveChildrenWithinDrive,canAddFolderFromAnotherDrive,canChangeSecurityUpdateEnabled,canBlockOwner,canReportSpamOrAbuse,canCopy,canDownload,canEdit,canAddChildren,canDelete,canRemoveChildren,canShare,canTrash,canRename,canReadTeamDrive,canMoveTeamDriveItem),contentRestrictions(readOnly),approvalMetadata(approvalVersion,approvalSummaries,hasIncomingApproval),shortcutDetails(targetId,targetMimeType,targetLookupStatus,targetFile,canRequestAccessToTarget),spamMetadata(markedAsSpamDate,inSpamView),labels(starred,trashed,restricted,viewed)),incompleteSearch&appDataFilter=NO_APP_DATA&spaces=drive&maxResults=200&supportsTeamDrives=true&includeItemsFromAllDrives=true&corpora=default&orderBy=folder,title_natural asc&retryCount=0&key=AIzaSyD_InbmSFufIEps5UAt2NmB_3LvBH3Sz_8 HTTP/1.1
# http://localhost/?code=M.C106_BAY.2.3e12c859-6107-0c5b-9ef4-14b3fb8269ba&state=JzHdzHXmA7x6zl7Be6cJ6uOlf9Bg69
# python3 /www/mdserver-web/plugins/gdrive/index.py site bbs.midoks.me 3
# python3 /www/mdserver-web/plugins/gdrive/index.py database t1 3
# python3 /www/server/mdserver-web/plugins/msonedrive/index.py path
# /Users/midoks/Desktop/dev/python 3
import sys
import io
import os
import time
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
def getPluginName():
return 'gdrive'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
# print(getPluginDir())
sys.path.append(getPluginDir() + "/class")
from gdriveclient import gdriveclient
gd = gdriveclient(getPluginDir(), getServerDir())
gd.setDebug(True)
# sign_in_url, state = gd.get_sign_in_url()
# print(sign_in_url)
# url = 'https://localhost/?state=GH2YZ1VeytzVB1BqJJpQZIBk2GGAub&code=4/0Adeu5BXnD2dQvXx8Sg0WPn1XiMpihcRBNaG1yaFKIo86gUiG7q65KU1MaNCxrj_f2bjkwQ&scope=https://www.googleapis.com/auth/drive.file'
# t = gd.set_auth_url(url)
# print(t)
# def set_auth_url(url):
# try:
# if url.startswith("http://"):
# url = url.replace("http://", "https://")
# token = msodc.get_token_from_authorized_url(
# authorized_url=url)
# msodc.store_token(token)
# msodc.store_user()
# return mw.returnJson(True, "授权成功!")
# except Exception as e:
# print(e)
# return mw.returnJson(False, "授权失败2!:" + str(e))
# return mw.returnJson(False, "授权失败!:" + str(e))
# url = 'http://localhost/?code=M.C106_BAY.2.310112f3-a158-c400-9667-d158cbd1de6c&state=jEJz0ucR9bpZYD9PGxp2GgRDotrzO6'
# token = set_auth_url(url)
# print(token)
# token = msodc.get_token()
# print("token:", token)
# t = gd.get_list('')
# print(t)
# t = gd.get_id_list('1u7LjXGj1KoN-ltAdTRaib7IZJpsEnPdz')
# print(t)
# t = gd.create_folder('backup_demo')
# print(t)
# t = msodc.delete_object('backup')
# print(t)
# t = gd.upload_file('web_t1.cn_20230830_134549.tar.gz', 'site')
# print(t)
# print(gd.error_msg)
# /Users/midoks/Desktop/mwdev/server/mdserver-web/paramiko.log
# backup/site/paramiko.log
# |-正在上传到 backup/site/paramiko.log...
# True
t = gd.upload_file(
'db_zzzvps_20230830_210727.sql.gz', 'datebase')
print(t)
+1 -1
View File
@@ -2,7 +2,7 @@
"ps": "Gogs是一款极易搭建的自助Git服务",
"name": "gogs",
"title": "Gogs",
"versions": ["0.11.86","0.12.9"],
"versions": ["0.11.86","0.12.9","0.13.0"],
"tip": "soft",
"checks": "server/gogs",
"path":"server/gogs",
+4
View File
@@ -9,6 +9,10 @@ serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
GOGS_DOWNLOAD='https://dl.gogs.io'
+1
View File
@@ -65,6 +65,7 @@ binlog-ignore-db = performance_schema
#slave
log-slave-updates
slave_skip_errors=1062
#replicate-do-db
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
+2 -7
View File
@@ -2,7 +2,7 @@
<div class='plugin_version'></div>
<div class="bt-w-main">
<div class="bt-w-menu">
<script type="text/javascript">console.log($('.plugin_version').attr('version'));</script>
<!-- <script type="text/javascript">console.log($('.plugin_version').attr('version'));</script> -->
<p class="bgw" onclick="pluginService('mariadb', $('.plugin_version').attr('version'));">服务</p>
<p onclick="pluginInitD('mariadb', $('.plugin_version').attr('version'));">自启动</p>
<p onclick="pluginConfig('mariadb', $('.plugin_version').attr('version'));">配置文件</p>
@@ -15,14 +15,12 @@
<p onclick="dbList()">管理列表</p>
<p onclick="masterOrSlaveConf($('.plugin_version').attr('version'))">主从配置</p>
</div>
<div class="bt-w-con pd15">
<div class="bt-w-con pd15" style="height:555px;overflow: auto;">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<style type="text/css">
.db_list{
padding: 0px 0 10px 0;
@@ -52,10 +50,7 @@
</style>
<script type="text/javascript">
resetPluginWinWidth(800);
var loading = layer.msg("资源加载中...", { icon: 16, time: 0, shade: 0.3 });
$.getScript( "/plugins/file?name=mariadb&f=js/mariadb.js", function(){
layer.close(loading);
pluginService('mariadb',$('.plugin_version').attr('version'));
});
</script>
+260 -205
View File
@@ -48,19 +48,19 @@ def getInitDFile():
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = args[0].strip('{').strip('}').strip()
if (t == ''):
return tmp
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
@@ -107,6 +107,14 @@ def getDbPort():
return tmp.groups()[0].strip()
def getDbServerId():
file = getConf()
content = mw.readFile(file)
rep = 'server-id\s*=\s*(.*)'
tmp = re.search(rep, content)
return tmp.groups()[0].strip()
def getSocketFile():
file = getConf()
content = mw.readFile(file)
@@ -664,15 +672,15 @@ def isSqlError(mysqlMsg):
return mw.returnJson(False, "Can't connect to MySQL server on '127.0.0.1' (61)")
if "using password:" in mysqlMsg:
return mw.returnJson(False, '数据库密码错误,在管理列表-点击【修复】!')
if "1045" in mysqlMsg:
if "1045," in mysqlMsg:
return mw.returnJson(False, '连接错误!')
if "SQL syntax" in mysqlMsg:
return mw.returnJson(False, 'SQL语法错误!')
if "Connection refused" in mysqlMsg:
return mw.returnJson(False, '数据库连接失败,请检查数据库服务是否启动!')
if "1133" in mysqlMsg:
if "1133," in mysqlMsg:
return mw.returnJson(False, '数据库用户不存在!')
if "1007" in mysqlMsg:
if "1007," in mysqlMsg:
return mw.returnJson(False, '数据库已经存在!')
return None
@@ -739,7 +747,7 @@ def importDbBackup():
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
sock = getSocketFile()
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p' + pwd + \
' ' + name + ' < ' + file_path_sql
# print(mysql_cmd)
@@ -800,7 +808,7 @@ def importDbExternal():
sock = getSocketFile()
os.environ["MYSQL_PWD"] = pwd
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + \
mysql_cmd = getServerDir() + '/bin/mariadb -S ' + sock + ' -uroot -p' + \
pwd + ' ' + name + ' < ' + import_sql
# print(mysql_cmd)
@@ -940,7 +948,7 @@ def getDbList():
def syncGetDatabases():
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
psdb = pSqliteDb('databases')
data = pdb.query('show databases')
isError = isSqlError(data)
@@ -1706,12 +1714,14 @@ def getMasterStatus(version=''):
data['mode'] = recognizeDbMode()
data['status'] = master_status
db = pMysqlDb()
dlist = db.query('show slave status')
pdb = pMysqlDb('mysql')
dlist = pdb.query('show slave status')
if len(dlist) < 1:
dlist = pdb.query("show all slaves status")
# print(dlist[0])
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
data['slave_status'] = True
for v in dlist:
if v["Slave_IO_Running"] == 'Yes' or v["Slave_SQL_Running"] == 'Yes':
data['slave_status'] = True
return mw.returnJson(master_status, '设置成功', data)
except Exception as e:
@@ -1855,6 +1865,9 @@ def getMasterRepSlaveUserCmd(version):
clist = psdb.field(f).where("username=?", (username,)).limit(
'1').order('id desc').select()
if len(clist) == 0:
return mw.returnJson(False, '错误同步账户!')
ip = mw.getLocalIp()
port = getMyPort()
db = pMysqlDb()
@@ -1868,15 +1881,23 @@ def getMasterRepSlaveUserCmd(version):
# 查找同步点
# SELECT BINLOG_GTID_POS('master1-bin.000002', 561866201);
sid = getDbServerId()
connection_name = ""
if sid != '':
connection_name = "'r{}' ".format(sid)
# MASTER_USE_GTID={current_pos|slave_pos|no}
# current_pos 依赖-> select @@global.gtid_current_pos;
# slave_pos 依赖-> select @@global.gtid_slave_pos;
# no -> 啥都不依赖,保证多主同步成功。同步出现问题,根据日志查找问题。
if mode == "gtid":
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
sql = "CHANGE MASTER " + connection_name + "TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
clist[0]['username'] + "', MASTER_PASSWORD='" + \
clist[0]['password'] + "', " + "MASTER_LOG_FILE='" + mstatus[0]["File"] + \
"',MASTER_LOG_POS=" + \
str(mstatus[0]["Position"]) + \
",MASTER_USE_GTID=slave_pos,MASTER_CONNECT_RETRY=10;"
"',MASTER_USE_GTID=no,MASTER_CONNECT_RETRY=10;"
else:
sql = "CHANGE MASTER TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
sql = "CHANGE MASTER " + connection_name + "TO MASTER_HOST='" + ip + "', MASTER_PORT=" + port + ", MASTER_USER='" + \
clist[0]['username'] + "', MASTER_PASSWORD='" + \
clist[0]['password'] + \
"', MASTER_LOG_FILE='" + mstatus[0]["File"] + \
@@ -2151,48 +2172,20 @@ def updateSlaveSSH(version=''):
def getSlaveList(version=''):
db = pMysqlDb()
dlist = db.query('show slave status')
ret = []
for x in range(0, len(dlist)):
tmp = {}
tmp['Master_User'] = dlist[x]["Master_User"]
tmp['Master_Host'] = dlist[x]["Master_Host"]
tmp['Master_Port'] = dlist[x]["Master_Port"]
tmp['Master_Log_File'] = dlist[x]["Master_Log_File"]
tmp['Slave_IO_Running'] = dlist[x]["Slave_IO_Running"]
tmp['Slave_SQL_Running'] = dlist[x]["Slave_SQL_Running"]
tmp['Last_Error'] = dlist[x]["Last_Error"]
tmp['Last_IO_Error'] = dlist[x]["Last_IO_Error"]
tmp['Last_SQL_Error'] = dlist[x]["Last_SQL_Error"]
tmp['Slave_SQL_Running_State'] = dlist[x]["Slave_SQL_Running_State"]
if len(dlist) == 0:
dlist = db.query('show all slaves status')
tmp['Error'] = ''
if tmp['Last_Error'] != '':
tmp['Error'] = tmp['Last_Error']
if tmp['Last_IO_Error'] != '':
tmp['Error'] = tmp['Last_IO_Error']
if tmp['Last_SQL_Error'] != '':
tmp['Error'] = tmp['Last_SQL_Error']
if tmp['Error'] == '':
tmp['Error'] = tmp['Slave_SQL_Running_State']
ret.append(tmp)
data = {}
data['data'] = ret
data['data'] = dlist
return mw.getJson(data)
def getSlaveSyncCmd(version=''):
root = mw.getRunDir()
cmd = 'cd ' + root + ' && python3 ' + root + \
'/plugins/mysql/index.py do_full_sync {"db":"all"}'
'/plugins/mariadb/index.py do_full_sync {"db":"all","sign":""}'
return mw.returnJson(True, 'ok', cmd)
@@ -2208,102 +2201,151 @@ def initSlaveStatus(version=''):
return initSlaveStatusSyncUser(version)
def parseSlaveSyncCmd(cmd):
a = {}
vlist = cmd.split(',')
has_connection_name = vlist[0]
pattern_c = r"CHANGE MASTER \'(.*)\' TO MASTER_HOST"
match_val = re.match(pattern_c, has_connection_name, re.I)
if match_val:
m_groups = match_val.groups()
a['Connection_name'] = m_groups[0]
for i in vlist:
tmp = i.strip()
tmp_a = tmp.split(" ")
real_tmp = tmp_a[len(tmp_a) - 1]
kv = real_tmp.split("=")
a[kv[0]] = kv[1].replace("'", '').replace("'", '').replace(";", '')
return a
def initSlaveStatusSyncUser(version=''):
conn = pSqliteDb('slave_sync_user')
data = conn.field('ip,port,user,pass,mode,cmd').find()
if len(data) < 1:
slave_data = conn.field('id,ip,port,user,pass,mode,cmd').select()
if len(slave_data) < 1:
return mw.returnJson(False, '需要先添加同步用户配置!')
# print(data)
db = pMysqlDb()
dlist = db.query('show slave status')
if len(dlist) > 0:
return mw.returnJson(False, '已经初始化好了zz...')
pdb = pMysqlDb()
if len(slave_data) == 1:
dlist = pdb.query('show slave status')
if len(dlist) > 0:
return mw.returnJson(False, '已经初始化好了zz...')
u = data
msg = ''
mode_name = 'classic'
if u['mode'] == '1':
mode_name = 'gtid'
pdb.query("stop slave")
pdb.query("stop all slaves")
local_mode = recognizeDbMode()
if local_mode != mode_name:
return mw.returnJson(False, '同步模式不一致!')
for x in range(len(slave_data)):
slave_t = slave_data[x]
base_t = 'IP:' + slave_t['ip'] + ",PORT:" + \
slave_t['port'] + ",USER:" + slave_t['user']
# print(u['cmd'])
t = db.query(u['cmd'])
# print(t)
db.query("start slave")
return mw.returnJson(True, '初始化成功!')
mode_name = 'classic'
if slave_data[x]['mode'] == '1':
mode_name = 'gtid'
if local_mode != mode_name:
msg += base_t + '->同步模式不一致'
continue
cmd_sql = slave_t['cmd']
if cmd_sql == '':
msg += base_t + '->同步命令不能为空'
continue
try:
pinfo = parseSlaveSyncCmd(cmd_sql)
except Exception as e:
return mw.returnJson(False, base_t + '->CMD同步命令不合规范!')
pdb.query(cmd_sql)
pdb.query("start slave")
pdb.query("start all slaves ")
if msg == '':
msg = '初始化成功!'
return mw.returnJson(True, msg)
def initSlaveStatusSSH(version=''):
db = pMysqlDb()
dlist = db.query('show slave status')
if len(dlist) > 0:
return mw.returnJson(False, '已经初始化好了zz...')
if len(dlist) == 0:
dlist = db.query('show all slaves status')
conn = pSqliteDb('slave_id_rsa')
data = conn.field('ip,port,id_rsa,db_user').find()
ssh_list = conn.field('ip,port,id_rsa,db_user').select()
if len(data) < 1:
if len(ssh_list) < 1:
return mw.returnJson(False, '需要先配置【[主]SSH配置】!')
SSH_PRIVATE_KEY = "/tmp/t_ssh.txt"
ip = data['ip']
master_port = data['port']
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
import paramiko
paramiko.util.log_to_file('paramiko.log')
ssh = paramiko.SSHClient()
try:
for data in ssh_list:
ip = data['ip']
master_port = data['port']
SSH_PRIVATE_KEY = "/tmp/t_ssh_" + ip + ".txt"
mw.writeFile(SSH_PRIVATE_KEY, data['id_rsa'].replace('\\n', '\n'))
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=ip, port=int(master_port),
username='root', pkey=key)
db_user = data['db_user']
cmd = 'cd /www/server/mdserver-web && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
result = result.decode('utf-8')
cmd_data = json.loads(result)
time.sleep(1)
ssh.close()
if not cmd_data['status']:
return mw.returnJson(False, '[主]:' + cmd_data['msg'])
try:
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=ip, port=int(master_port),
username='root', pkey=key)
local_mode = recognizeDbMode()
if local_mode != cmd_data['data']['mode']:
return mw.returnJson(False, '主【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
db_user = data['db_user']
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
result = result.decode('utf-8')
if result.strip() == "":
return mw.returnJson(False, '[主][' + ip + ']:获取同步命令失败!')
cmd_data = json.loads(result)
time.sleep(1)
ssh.close()
if not cmd_data['status']:
return mw.returnJson(False, '[主][' + ip + ']:' + cmd_data['msg'])
u = cmd_data['data']['info']
ps = u['username'] + "|" + u['password']
conn.where('ip=?', (ip,)).setField('ps', ps)
db.query('stop slave')
local_mode = recognizeDbMode()
if local_mode != cmd_data['data']['mode']:
return mw.returnJson(False, '[主][' + ip + ']【{}】从【{}】,运行模式不一致!'.format(cmd_data['data']['mode'], local_mode))
# 保证同步IP一致
cmd = cmd_data['data']['cmd']
if cmd.find('SOURCE_HOST') > -1:
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
"SOURCE_HOST='" + ip + "'", cmd, 1)
u = cmd_data['data']['info']
ps = u['username'] + "|" + u['password']
conn.where('ip=?', (ip,)).setField('ps', ps)
db.query('stop slave')
db.query('stop all slaves')
if cmd.find('MASTER_HOST') > -1:
cmd = re.sub(r"MASTER_HOST='(.*?)'",
"MASTER_HOST='" + ip + "'", cmd, 1)
# 保证同步IP一致
cmd = cmd_data['data']['cmd']
if cmd.find('SOURCE_HOST') > -1:
cmd = re.sub(r"SOURCE_HOST='(.*?)'",
"SOURCE_HOST='" + ip + "'", cmd, 1)
# print(cmd)
db.query(cmd)
db.query("start slave")
if cmd.find('MASTER_HOST') > -1:
cmd = re.sub(r"MASTER_HOST='(.*?)'",
"MASTER_HOST='" + ip + "'", cmd, 1)
except Exception as e:
return mw.returnJson(False, 'SSH认证配置连接失败!' + str(e))
# print(cmd)
db.query(cmd)
db.query("start slave")
db.query("start all slaves")
if os.path.exists(SSH_PRIVATE_KEY):
os.system("rm -rf " + SSH_PRIVATE_KEY)
except Exception as e:
return mw.returnJson(False, '[主][' + ip + ']:SSH认证配置连接失败!' + str(e))
os.system("rm -rf " + SSH_PRIVATE_KEY)
return mw.returnJson(True, '初始化成功!')
@@ -2312,61 +2354,39 @@ def setSlaveStatus(version=''):
if not os.path.exists(mode_file):
return mw.returnJson(False, '需要先设置同步配置')
mode = mw.readFile(mode_file)
if mode == 'ssh':
return setSlaveStatusSSH(version)
if mode == 'sync-user':
return setSlaveStatusSyncUser(version)
pdb = pMysqlDb()
dlist = pdb.query('show slave status')
if len(dlist) == 0:
dlist = pdb.query('show all slaves status')
def setSlaveStatusSyncUser(version=''):
db = pMysqlDb()
dlist = db.query('show slave status')
if len(dlist) == 0:
return mw.returnJson(False, '需要手动添加同步账户或者执行初始化!')
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
db.query('stop slave')
else:
ip = dlist[0]['Master_Host']
conn = pSqliteDb('slave_sync_user')
data = conn.field('ip,port,user,pass,mode,cmd').find()
if len(data) == 0:
return mw.returnJson(False, '没有数据无法重启!')
user = data['user']
apass = data['pass']
for v in dlist:
connection_name = ''
cmd = "slave"
if 'Connection_name' in v:
connection_name = v['Connection_name']
cmd = "slave '{}'".format(connection_name)
db.query("start slave")
# db.query("start slave user='{}' password='{}';".format(user, apass))
return mw.returnJson(True, '设置成功!')
def setSlaveStatusSSH(version=''):
db = pMysqlDb()
dlist = db.query('show slave status')
if len(dlist) == 0:
return mw.returnJson(False, '需要手动添加主服务命令或者执行[初始化]!')
# print(dlist)
if len(dlist) > 0 and (dlist[0]["Slave_IO_Running"] == 'Yes' or dlist[0]["Slave_SQL_Running"] == 'Yes'):
db.query('stop slave')
else:
ip = dlist[0]['Master_Host']
conn = pSqliteDb('slave_id_rsa')
data = conn.field('ip,ps').where("ip=?", (ip,)).find()
if len(data) == 0:
return mw.returnJson(False, '没有数据无法重启!')
db.query("start slave")
if (v["Slave_IO_Running"] == 'Yes' or v["Slave_SQL_Running"] == 'Yes'):
pdb.query("stop {}".format(cmd))
else:
pdb.query("start {}".format(cmd))
return mw.returnJson(True, '设置成功!')
def deleteSlave(version=''):
args = getArgs()
db = pMysqlDb()
dlist = db.query('stop slave')
dlist = db.query('reset slave all')
if 'sign' in args:
sign = args['sign']
db.query("stop slave '{}'".format(sign))
db.query("reset slave '{}' all".format(sign))
else:
db.query('stop slave')
db.query('reset slave all')
return mw.returnJson(True, '删除成功!')
@@ -2402,14 +2422,54 @@ def dumpMysqlData(version=''):
############### --- 重要 同步---- ###########
def asyncTmpfile():
path = '/tmp/mariadb_async_status.txt'
return path
def writeDbSyncStatus(data):
path = '/tmp/db_async_status.txt'
# status_data['code'] = 1
# status_data['msg'] = '主服务器备份完成...'
# status_data['progress'] = 30
path = asyncTmpfile()
mw.writeFile(path, json.dumps(data))
def fullSync(version=''):
args = getArgs()
data = checkArgs(args, ['db', 'begin'])
if not data[0]:
return data[1]
sign = ''
if 'sign' in args:
sign = args['sign']
status_file = asyncTmpfile()
if args['begin'] == '1':
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
getPluginDir() + \
'/index.py do_full_sync {"db":"' + \
args['db'] + '","sign":"' + sign + '"} &'
# print(cmd)
mw.execShell(cmd)
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
if os.path.exists(status_file):
c = mw.readFile(status_file)
tmp = json.loads(c)
if tmp['code'] == 1:
sys_dump_sql = "/tmp/dump.sql"
if os.path.exists(sys_dump_sql):
dump_size = os.path.getsize(sys_dump_sql)
tmp['msg'] = tmp['msg'] + ":" + "同步文件:" + mw.toSize(dump_size)
c = json.dumps(tmp)
# if tmp['code'] == 6:
# os.remove(status_file)
return c
return json.dumps({'code': 0, 'msg': '点击开始,开始同步!', 'progress': 0})
def doFullSync(version=''):
mode_file = getSyncModeFile()
if not os.path.exists(mode_file):
@@ -2424,16 +2484,23 @@ def doFullSync(version=''):
def doFullSyncUser(version=''):
args = getArgs()
data = checkArgs(args, ['db'])
data = checkArgs(args, ['db', 'sign'])
if not data[0]:
return data[1]
sync_db = args['db']
sync_sign = args['sign']
# print(sync_sign, sync_db)
db = pMysqlDb()
conn = pSqliteDb('slave_sync_user')
data = conn.field('ip,port,user,pass,mode,cmd').find()
if sync_sign != '':
data = conn.field('ip,port,user,pass,mode,cmd').where(
'ip=?', (sync_sign,)).find()
else:
data = conn.field('ip,port,user,pass,mode,cmd').find()
user = data['user']
apass = data['pass']
port = data['port']
@@ -2442,12 +2509,12 @@ def doFullSyncUser(version=''):
bak_file = '/tmp/tmp.sql'
writeDbSyncStatus({'code': 0, 'msg': '开始同步...', 'progress': 0})
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 20})
writeDbSyncStatus({'code': 1, 'msg': '远程导出数据...', 'progress': 10})
if not os.path.exists(bak_file):
dump_sql_data = getServerDir() + "/bin/mysqldump --force --opt --default-character-set=utf8 --single-transaction -h" + ip + " -P" + \
port + " -u" + user + " -p" + apass + " " + sync_db + " > " + bak_file
print(dump_sql_data)
mw.execShell(dump_sql_data)
writeDbSyncStatus({'code': 2, 'msg': '本地导入数据...', 'progress': 40})
@@ -2458,24 +2525,38 @@ def doFullSyncUser(version=''):
' ' + sync_db + ' < ' + bak_file
mw.execShell(my_import_cmd)
db.query("start slave")
pinfo = parseSlaveSyncCmd(data['cmd'])
# print(pinfo)
if 'Connection_name' in pinfo:
db.query("start slave '{}'".format(pinfo['Connection_name']))
else:
db.query("start slave")
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
os.system("rm -rf " + bak_file)
if os.path.exists(bak_file):
os.system("rm -rf " + bak_file)
return True
def doFullSyncSSH(version=''):
args = getArgs()
data = checkArgs(args, ['db'])
data = checkArgs(args, ['db', 'sign'])
if not data[0]:
return data[1]
db = pMysqlDb()
sync_db = args['db']
sync_sign = args['sign']
id_rsa_conn = pSqliteDb('slave_id_rsa')
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
if sync_sign != '':
data = id_rsa_conn.field('ip,port,db_user,id_rsa').where(
'ip=?', (sync_sign,)).find()
else:
data = id_rsa_conn.field('ip,port,db_user,id_rsa').find()
SSH_PRIVATE_KEY = "/tmp/mysql_sync_id_rsa.txt"
id_rsa = data['id_rsa'].replace('\\n', '\n')
@@ -2498,7 +2579,6 @@ def doFullSyncSSH(version=''):
return 'fail'
try:
# ssh.load_system_host_keys()
mw.execShell("chmod 600 " + SSH_PRIVATE_KEY)
key = paramiko.RSAKey.from_private_key_file(SSH_PRIVATE_KEY)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
@@ -2516,7 +2596,7 @@ def doFullSyncSSH(version=''):
writeDbSyncStatus({'code': 0, 'msg': '登录Master成功...', 'progress': 5})
dbname = args['db']
cmd = "cd /www/server/mdserver-web && python3 plugins/mariadb/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
cmd = "cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py dump_mysql_data {\"db\":'" + dbname + "'}"
print(cmd)
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
@@ -2539,13 +2619,19 @@ def doFullSyncSSH(version=''):
if copy_status == None:
writeDbSyncStatus({'code': 2, 'msg': '数据同步本地完成...', 'progress': 40})
cmd = 'cd /www/server/mdserver-web && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
cmd = 'cd /www/server/mdserver-web && source bin/activate && python3 plugins/mariadb/index.py get_master_rep_slave_user_cmd {"username":"' + db_user + '","db":""}'
stdin, stdout, stderr = ssh.exec_command(cmd)
result = stdout.read()
result = result.decode('utf-8')
if result == '':
writeDbSyncStatus({'code': 1, 'msg': '同步命令获取失败!', 'progress': 100})
return 'fail'
cmd_data = json.loads(result)
db.query('stop slave')
db.query('stop all slaves')
writeDbSyncStatus({'code': 3, 'msg': '停止从库完成...', 'progress': 45})
cmd = cmd_data['data']['cmd']
@@ -2578,6 +2664,7 @@ def doFullSyncSSH(version=''):
return 'fail'
db.query("start slave")
db.query("start all slaves")
writeDbSyncStatus({'code': 6, 'msg': '从库重启完成...', 'progress': 100})
os.system("rm -rf " + SSH_PRIVATE_KEY)
@@ -2585,38 +2672,6 @@ def doFullSyncSSH(version=''):
return True
def fullSync(version=''):
args = getArgs()
data = checkArgs(args, ['db', 'begin'])
if not data[0]:
return data[1]
status_file = '/tmp/db_async_status.txt'
if args['begin'] == '1':
cmd = 'cd ' + mw.getRunDir() + ' && python3 ' + \
getPluginDir() + \
'/index.py do_full_sync {"db":"' + args['db'] + '"} &'
print(cmd)
mw.execShell(cmd)
return json.dumps({'code': 0, 'msg': '同步数据中!', 'progress': 0})
if os.path.exists(status_file):
c = mw.readFile(status_file)
tmp = json.loads(c)
if tmp['code'] == 1:
sys_dump_sql = "/tmp/dump.sql"
if os.path.exists(sys_dump_sql):
dump_size = os.path.getsize(sys_dump_sql)
tmp['msg'] = tmp['msg'] + ":" + "同步文件:" + mw.toSize(dump_size)
c = json.dumps(tmp)
# if tmp['code'] == 6:
# os.remove(status_file)
return c
return json.dumps({'code': 0, 'msg': '点击开始,开始同步!', 'progress': 0})
def installPreInspection(version):
swap_path = mw.getServerDir() + "/swap"
if not os.path.exists(swap_path):
+178 -86
View File
@@ -431,7 +431,6 @@ function syncToDatabase(type){
var postData = 'type='+type+'&ids='+JSON.stringify(data);
myPost('sync_to_databases', postData, function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
showMsg(rdata.msg,function(){
dbList();
},{ icon: rdata.status ? 1 : 2 });
@@ -439,18 +438,6 @@ function syncToDatabase(type){
}
function setRootPwd(type, pwd){
if (type==1){
var password = $("#MyPassword").val();
myPost('set_root_pwd', {password:password}, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
dbList();
$('.layui-layer-close1').click();
},{icon: rdata.status ? 1 : 2});
});
return;
}
var index = layer.open({
type: 1,
area: '500px',
@@ -467,8 +454,16 @@ function setRootPwd(type, pwd){
</div>\
</div>\
</form>",
yes:function(){
setRootPwd(1);
yes:function(index,layero){
var password = $("#MyPassword").val();
myPost('set_root_pwd', {password:password}, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
dbList();
layer.close(index);
},{icon: rdata.status ? 1 : 2});
});
return;
}
});
}
@@ -490,7 +485,6 @@ function showHidePass(obj){
function checkSelect(){
setTimeout(function () {
var num = $('input[type="checkbox"].check:checked').length;
// console.log(num);
if (num == 1) {
$('button[batch="true"]').hide();
$('button[batch="false"]').show();
@@ -861,7 +855,6 @@ function downloadBackup(file){
function importBackup(file,name){
myPost('import_db_backup',{file:file,name:name}, function(data){
// console.log(data);
layer.msg('执行成功!');
});
}
@@ -1619,7 +1612,6 @@ function getMasterRepSlaveList(){
_data['page'] = page;
_data['page_size'] = 10;
myPost('get_master_rep_slave_list', _data, function(data){
// console.log(data);
var rdata = [];
try {
rdata = $.parseJSON(data.data);
@@ -1672,12 +1664,12 @@ function getMasterRepSlaveListPage(){
}
function deleteSlave(){
myPost('delete_slave', {}, function(data){
function deleteSlave(sign = ''){
myPost('delete_slave', {sign:sign}, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata['msg'], function(){
masterOrSlaveConf();
},{},3000);
},{icon:rdata.status?1:2,time:3000},3000);
});
}
@@ -1685,28 +1677,72 @@ function deleteSlave(){
function getFullSyncStatus(db){
var timeId = null;
var btn = '<div class="table_toolbar" style="left:0px;"><span data-status="init" class="sync btn btn-default btn-sm" id="begin_full_sync" title="">开始</span></div>';
var loadOpen = layer.open({
type: 1,
title: '全量同步['+db+']',
area: '500px',
content:"<div class='bt-form pd20 c6'>\
<div class='divtable mtb10'>\
<span id='full_msg'></span>\
<div class='progress'>\
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
</div>\
</div>\
"+btn+"\
</div>",
cancel: function(){
clearInterval(timeId);
myPost('get_slave_list', {page:1,page_size:100}, function(data){
var rdata = $.parseJSON(data.data);
var rsource = rdata.data;
if (db == 'ALL' && rsource.length>1){
layer.msg("多主不支持该模式!",{icon:2});
return;
}
var dataSource = '';
if (rsource.length>1){
var sourceList = '';
for (var i = 0; i < rsource.length; i++) {
if ('Connection_name' in rsource[i]){
sourceList += '<option val="'+rsource[i]['Master_Host']+'">'+rsource[i]['Master_Host']+'</option>';
}
}
dataSource = "<p class='line' style='text-align:center;'>\
<span>同步数据源:</span>\
<select class='bt-input-text' name='data_source' style='width:200px;'>" + sourceList + "</select>\
</p>";
}
layer.open({
type: 1,
title: '全量同步['+db+']',
area: '500px',
content:"<div class='bt-form pd15'>\
<div class='divtable mtb10'>\
"+dataSource+"\
<span id='full_msg'></span>\
<div class='progress'>\
<div class='progress-bar' role='progressbar' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100' style='min-width: 2em;'>0%</div>\
</div>\
</div>\
<div class='table_toolbar' style='left:0px;'>\
<span data-status='init' class='sync btn btn-default btn-sm' id='begin_full_sync'>开始</span>\
</div>\
</div>",
cancel: function(){
clearInterval(timeId);
},
success:function(){
$('#begin_full_sync').click(function(){
var val = $(this).data('status');
var sign = '';
if (dataSource !=''){
sign = $('select[name="data_source"]').val();
}
if (val == 'init'){
fullSync(db, sign, 1);
timeId = setInterval(function(){
fullSync(db,sign,0);
}, 1000);
$(this).data('status','starting');
} else {
layer.msg("正在同步中..",{icon:0});
}
});
}
});
});
function fullSync(db,begin){
myPostN('full_sync', {db:db,begin:begin}, function(data){
function fullSync(db, sign, begin){
myPostN('full_sync', {db:db,sign:sign,begin:begin}, function(data){
var rdata = $.parseJSON(data.data);
$('#full_msg').text(rdata['msg']);
$('.progress-bar').css('width',rdata['progress']+'%');
@@ -1715,23 +1751,11 @@ function getFullSyncStatus(db){
if (rdata['code']==6 ||rdata['code']<0){
layer.msg(rdata['msg']);
clearInterval(timeId);
$("#begin_full_sync").attr('data-status','init');
$("#begin_full_sync").data('status','init');
}
});
}
$('#begin_full_sync').click(function(){
var val = $(this).attr('data-status');
if (val == 'init'){
fullSync(db,1);
timeId = setInterval(function(){
fullSync(db,0);
}, 1000);
$(this).attr('data-status','starting');
} else {
layer.msg("正在同步中..");
}
});
}
function addSlaveSSH(ip=''){
@@ -2077,7 +2101,7 @@ function getSlaveUserList(){
layerId = layer.open({
type: 1,
title: '同步账户列表',
area: '500px',
area: '600px',
content:"<div class='bt-form pd20 c6'>\
<div class='divtable mtb10'>\
<div><table class='table table-hover get-slave-ssh-list'>\
@@ -2101,7 +2125,7 @@ function getSlaveSSHList(page=1){
layerId = layer.open({
type: 1,
title: 'SSH列表',
area: '500px',
area: '600px',
content:"<div class='bt-form pd20 c6'>\
<div class='divtable mtb10'>\
<div><table class='table table-hover get-slave-ssh-list'>\
@@ -2142,11 +2166,15 @@ function handlerRun(){
function initSlaveStatus(){
myPost('init_slave_status', '', function(data){
var rdata = $.parseJSON(data.data);
if (!rdata.status ){
layer.msg(rdata.msg,{icon:2,time:10000});
return;
}
showMsg(rdata.msg,function(){
if (rdata.status){
masterOrSlaveConf();
}
},{icon:rdata.status?1:2},2000);
},{icon:1},2000);
});
}
@@ -2204,33 +2232,48 @@ function masterOrSlaveConf(version=''){
}
_data['page'] = page;
_data['page_size'] = 10;
_data['page_size'] = 100;
myPost('get_slave_list', _data, function(data){
var rdata = $.parseJSON(data.data);
var list = '';
var isHasSign = false;
for(i in rdata.data){
var v = rdata.data[i];
var status = "<a class='btlink db_error'>异常</>";
if ('Connection_name' in v){
isHasSign = true;
}
var status = "<a data-id="+i+" class='btlink db_error'>异常</>";
if (v['Slave_SQL_Running'] == 'Yes' && v['Slave_IO_Running'] == 'Yes'){
status = "正常";
}
list += '<tr>';
list += '<td>' + rdata.data[i]['Master_Host'] +'</td>';
list += '<td>' + rdata.data[i]['Master_Port'] +'</td>';
list += '<td>' + rdata.data[i]['Master_User'] +'</td>';
list += '<td>' + rdata.data[i]['Master_Log_File'] +'</td>';
list += '<td>' + rdata.data[i]['Slave_IO_Running'] +'</td>';
list += '<td>' + rdata.data[i]['Slave_SQL_Running'] +'</td>';
list += '<td>' + v['Master_Host'] +'</td>';
list += '<td>' + v['Master_Port'] +'</td>';
list += '<td>' + v['Master_User'] +'</td>';
list += '<td>' + v['Master_Log_File'] +'</td>';
list += '<td>' + v['Slave_IO_Running'] +'</td>';
list += '<td>' + v['Slave_SQL_Running'] +'</td>';
if (isHasSign){
list += '<td>' + v['Connection_name'] +'</td>';
}
list += '<td>' + status +'</td>';
list += '<td style="text-align:right">' +
'<a href="javascript:;" class="btlink" onclick="deleteSlave()" title="删除">删除</a>' +
'</td>';
list += '<td style="text-align:right">\
<a data-id="'+i+'" href="javascript:;" class="btlink btn_delete_slave" title="删除">删除</a>\
</td>';
list += '</tr>';
}
var signThead_th = '';
if (isHasSign){
var signThead_th = '<th>标识</th>';
}
var con = '<div class="divtable mtb10">\
<div class="tablescroll">\
<table id="DataBody" class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0" style="border: 0 none;">\
@@ -2241,6 +2284,7 @@ function masterOrSlaveConf(version=''){
<th>日志</th>\
<th>IO</th>\
<th>SQL</th>\
'+signThead_th+'\
<th>状态</th>\
<th style="text-align:right;">操作</th></tr></thead>\
<tbody>\
@@ -2255,22 +2299,75 @@ function masterOrSlaveConf(version=''){
// </div>
$(".table_slave_status_list").html(con);
$(".btn_delete_slave").click(function(){
var id = $(this).data('id');
var v = rdata.data[id];
if ('Connection_name' in v){
deleteSlave(v['Connection_name']);
} else{
deleteSlave();
}
});
$('.db_error').click(function(){
var id = $(this).data('id');
var info = rdata.data[id];
var err_line = "";
err_line +="<tr>\
<td>IO错误</td>\
<td>"+ (info['Last_IO_Error'] == '' ? '无':info['Last_IO_Error'])+"</td>\
</tr>";
err_line +="<tr>\
<td>SQL错误</td>\
<td>"+(info['Last_SQL_Error'] == '' ? '无':info['Last_SQL_Error'])+"</td>\
</tr>";
err_line +="<tr>\
<td>状态</td>\
<td>"+(info['Slave_SQL_Running_State'] == '' ? '无':info['Slave_SQL_Running_State']) +"</td>\
</tr>";
layer.open({
type: 1,
title: '同步异常信息',
area: '500px',
content:"<form class='bt-form pd20 pb70'>\
<div class='line'>"+v['Error']+"</div>\
<div class='bt-form-submit-btn'>\
<button type='button' class='btn btn-success btn-sm btn-title class-copy-db-err'>复制</button>\
area: ['600px','300px'],
btn:['复制错误',"取消"],
content:"<form class='bt-form pd15'>\
<div class='divtable mtb10'>\
<div class='tablescroll'>\
<table class='table table-hover' width='100%' cellspacing='0' cellpadding='0' border='0' style='border: 0 none;'>\
<thead><tr>\
<th style='width:80px;'>类型</th>\
<th>内容</th>\
</tr></thead>\
<tbody>"+ err_line +"</tbody>\
</table>\
</div>\
</div>\
</form>",
</form>",
success:function(){
copyText(v['Error']);
$('.class-copy-db-err').click(function(){
copyText(v['Error']);
});
// copyText(v['Error']);
// $('.class-copy-db-err').click(function(){
// copyText(v['Error']);
// });
},
yes:function(){
if (info['Last_IO_Error'] != ''){
copyText(info['Last_IO_Error']);
return;
}
if (info['Last_SQL_Error'] != ''){
copyText(info['Last_SQL_Error']);
return;
}
if (info['Slave_SQL_Running_State'] != ''){
copyText(info['Slave_SQL_Running_State']);
return;
}
}
});
});
@@ -2320,14 +2417,12 @@ function masterOrSlaveConf(version=''){
});
}
function getMasterStatus(){
myPost('get_master_status', '', function(rdata){
var rdata = $.parseJSON(rdata.data);
// console.log('mode:',rdata.data);
if ( typeof(rdata.status) != 'undefined' && !rdata.status && rdata.data == 'pwd'){
layer.msg(rdata.msg, {icon:2});
layer.msg(rdata.msg, {icon:2,time:2000});
return;
}
@@ -2409,7 +2504,6 @@ function masterOrSlaveConf(version=''){
return false;
},
change:function(index,mode,reload){
console.log(index,mode,reload);
myPost('set_dbrun_mode',{'mode':mode,'reload':reload},function(data){
layer.close(index);
var rdata = $.parseJSON(data.data);
@@ -2425,10 +2519,8 @@ function masterOrSlaveConf(version=''){
getMasterDbList();
}
// if (rdata.slave_status){
getAsyncMasterDbList();
getAsyncDataList()
// }
getAsyncMasterDbList();
getAsyncDataList()
});
}
getMasterStatus();
+2 -2
View File
@@ -87,7 +87,7 @@ class backupTools:
pid = mw.M('databases').dbPos(db_path, db_name).where(
'name=?', (name,)).getField('id')
mw.M('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename(
mw.M('backup').add('type,name,pid,filename,addtime,size', (3, os.path.basename(
filename), pid, filename, endDate, os.path.getsize(filename)))
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + "]秒"
mw.writeLog('计划任务', log)
@@ -97,7 +97,7 @@ class backupTools:
# 清理多余备份
backups = mw.M('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
'type=? and pid=?', ('3', pid)).field('id,filename').select()
num = len(backups) - int(count)
if num > 0:
+10 -1
View File
@@ -71,10 +71,19 @@ Install_app()
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
fi
INSTALL_CMD=cmake
# check cmake version
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
if [ "$CMAKE_VERSION" -eq "2" ];then
mkdir -p /var/log/mariadb
touch /var/log/mariadb/mariadb.log
INSTALL_CMD=cmake3
fi
if [ ! -d $serverPath/mariadb ];then
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
-DMYSQL_USER=mysql \
+10 -1
View File
@@ -73,8 +73,17 @@ Install_app()
fi
INSTALL_CMD=cmake
# check cmake version
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
if [ "$CMAKE_VERSION" -eq "2" ];then
mkdir -p /var/log/mariadb
touch /var/log/mariadb/mariadb.log
INSTALL_CMD=cmake3
fi
if [ ! -d $serverPath/mariadb ];then
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
-DMYSQL_USER=mysql \
+9 -1
View File
@@ -72,9 +72,17 @@ Install_app()
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
fi
INSTALL_CMD=cmake
# check cmake version
CMAKE_VERSION=`cmake -version | grep version | awk '{print $3}' | awk -F '.' '{print $1}'`
if [ "$CMAKE_VERSION" -eq "2" ];then
mkdir -p /var/log/mariadb
touch /var/log/mariadb/mariadb.log
INSTALL_CMD=cmake3
fi
if [ ! -d $serverPath/mariadb ];then
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
cd ${mariadbDir}/mariadb-${MY_VER} && ${INSTALL_CMD} \
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
-DMYSQL_USER=mysql \
+50 -11
View File
@@ -14,6 +14,10 @@ if mw.isAppleSystem():
app_debug = True
import warnings
warnings.filterwarnings('ignore', category=DeprecationWarning)
def getPluginName():
return 'memcached'
@@ -27,8 +31,13 @@ def getServerDir():
def getInitDFile():
if app_debug:
current_os = mw.getOs()
if current_os == 'darwin':
return '/tmp/' + getPluginName()
if current_os.startswith('freebsd'):
return '/etc/rc.d/' + getPluginName()
return '/etc/init.d/' + getPluginName()
@@ -84,7 +93,7 @@ def checkArgs(data, ck=[]):
def status():
data = mw.execShell(
"ps -ef|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
"ps aux|grep " + getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
@@ -109,8 +118,8 @@ def initDreplace():
# systemd
systemDir = mw.systemdCfgDir()
systemService = systemDir + '/memcached.service'
systemServiceTpl = getPluginDir() + '/init.d/memcached.service.tpl'
if os.path.exists(systemDir) and not os.path.exists(systemService):
systemServiceTpl = getPluginDir() + '/init.d/memcached.service.tpl'
service_path = mw.getServerDir()
se_content = mw.readFile(systemServiceTpl)
se_content = se_content.replace('{$SERVER_PATH}', service_path)
@@ -133,13 +142,20 @@ def initDreplace():
def memOp(method):
file = initDreplace()
if not mw.isAppleSystem():
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
current_os = mw.getOs()
if current_os == "darwin":
data = mw.execShell(file + ' ' + method)
if data[1] == '':
return 'ok'
return data[1]
data = mw.execShell(file + ' ' + method)
if current_os.startswith("freebsd"):
data = mw.execShell('service ' + getPluginName() + ' ' + method)
if data[1] == '':
return 'ok'
return data[1]
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
if data[1] == '':
return 'ok'
return data[1]
@@ -222,9 +238,15 @@ def saveConf():
def initdStatus():
if mw.isAppleSystem():
current_os = mw.getOs()
if current_os == 'darwin':
return "Apple Computer does not support"
if current_os.startswith('freebsd'):
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
return 'ok'
shell_cmd = 'systemctl status ' + \
getPluginName() + ' | grep loaded | grep "enabled;"'
data = mw.execShell(shell_cmd)
@@ -234,17 +256,34 @@ def initdStatus():
def initdInstall():
if mw.isAppleSystem():
current_os = mw.getOs()
if current_os == 'darwin':
return "Apple Computer does not support"
# freebsd initd install
if current_os.startswith('freebsd'):
import shutil
source_bin = initDreplace()
initd_bin = getInitDFile()
shutil.copyfile(source_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
mw.execShell('sysrc ' + getPluginName() + '_enable="YES"')
return 'ok'
mw.execShell('systemctl enable ' + getPluginName())
return 'ok'
def initdUinstall():
if not app_debug:
if mw.isAppleSystem():
return "Apple Computer does not support"
current_os = mw.getOs()
if current_os == 'darwin':
return "Apple Computer does not support"
if current_os.startswith('freebsd'):
initd_bin = getInitDFile()
os.remove(initd_bin)
mw.execShell('sysrc ' + getPluginName() + '_enable="NO"')
return 'ok'
mw.execShell('systemctl disable ' + getPluginName())
return 'ok'
+1 -1
View File
@@ -5,7 +5,7 @@
"title": "Memcached",
"shell": "install.sh",
"versions":["1.6"],
"updates":["1.6.15"],
"updates":["1.6.21"],
"tip": "soft",
"checks": "server/memcached",
"path":"server/memcached",
+1 -1
View File
@@ -6,7 +6,7 @@ port = 27017
fork = true
auth = false
# 5.0.2 - Master/slave replication is no longer supported
# Master/slave replication is no longer supported
#master = true
pidfilepath = {$SERVER_PATH}/mongodb/mongodb.pid
+37 -51
View File
@@ -35,13 +35,8 @@ def getInitDFile():
def getConf():
if mw.isAppleSystem():
path = getServerDir() + "/mongodb.conf"
return path
if os.path.exists("/etc/mongodb.conf"):
return "/etc/mongodb.conf"
return "/etc/mongod.conf"
path = getServerDir() + "/mongodb.conf"
return path
def getConfTpl():
@@ -90,6 +85,14 @@ def initDreplace():
os.mkdir(initD_path)
file_bin = initD_path + '/' + getPluginName()
logs_dir = getServerDir() + '/logs'
if not os.path.exists(logs_dir):
os.mkdir(logs_dir)
data_dir = getServerDir() + '/data'
if not os.path.exists(data_dir):
os.mkdir(data_dir)
# initd replace
content = mw.readFile(file_tpl)
content = content.replace('{$SERVER_PATH}', service_path)
@@ -101,6 +104,17 @@ def initDreplace():
conf_content = conf_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(getServerDir() + '/mongodb.conf', conf_content)
# systemd
systemDir = mw.systemdCfgDir()
systemService = systemDir + '/mongodb.service'
systemServiceTpl = getPluginDir() + '/init.d/mongodb.service.tpl'
if os.path.exists(systemDir) and not os.path.exists(systemService):
service_path = mw.getServerDir()
se_content = mw.readFile(systemServiceTpl)
se_content = se_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(systemService, se_content)
mw.execShell('systemctl daemon-reload')
return file_bin
@@ -112,14 +126,10 @@ def mgOp(method):
return 'ok'
return data[1]
cmd = 'systemctl ' + method + ' mongod'
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
cmd = 'systemctl ' + start + ' mongodb'
data = mw.execShell(cmd)
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
if data[1] == '':
return 'ok'
return data[1]
return 'fail'
def start():
@@ -162,13 +172,7 @@ def runInfo():
result["version"] = serverStatus['version']
result["uptime"] = serverStatus['uptime']
result['db_path'] = '/var/lib/mongo'
if os.path.exists("/var/lib/mongodb"):
result['db_path'] = '/var/lib/mongodb'
if mw.isAppleSystem():
result['db_path'] = getServerDir() + "/data"
result['db_path'] = getServerDir() + "/data"
result["connections"] = serverStatus['connections']['current']
if 'catalogStats' in serverStatus:
@@ -182,11 +186,7 @@ def initdStatus():
if mw.isAppleSystem():
return "Apple Computer does not support"
shell_cmd = 'systemctl status mongod | grep loaded | grep "enabled;"'
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
shell_cmd = 'systemctl status mongodb | grep loaded | grep "enabled;"'
shell_cmd = 'systemctl status mongodb | grep loaded | grep "enabled;"'
data = mw.execShell(shell_cmd)
if data[0] == '':
return 'fail'
@@ -197,10 +197,7 @@ def initdInstall():
if mw.isAppleSystem():
return "Apple Computer does not support"
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
mw.execShell('systemctl enable mongodb')
else:
mw.execShell('systemctl enable mongod')
mw.execShell('systemctl enable mongodb')
return 'ok'
@@ -208,24 +205,21 @@ def initdUinstall():
if mw.isAppleSystem():
return "Apple Computer does not support"
if os.path.exists("/usr/lib/systemd/system/mongodb.service"):
mw.execShell('systemctl disable mongodb')
else:
mw.execShell('systemctl disable mongod')
mw.execShell('systemctl disable mongodb')
return 'ok'
def runLog():
if mw.isAppleSystem():
return getServerDir() + '/logs/mongodb.log'
if os.path.exists("/var/log/mongodb/mongodb.log"):
return "/var/log/mongodb/mongodb.log"
return "/var/log/mongodb/mongod.log"
f = getServerDir() + '/logs/mongodb.log'
if os.path.exists(f):
return f
return getServerDir() + '/logs.pl'
def installPreInspection(version):
if mw.isAppleSystem():
return 'ok'
sys = mw.execShell(
"cat /etc/*-release | grep PRETTY_NAME |awk -F = '{print $2}' | awk -F '\"' '{print $2}'| awk '{print $1}'")
@@ -238,17 +232,9 @@ def installPreInspection(version):
sysName = sys[0].strip().lower()
sysId = sys_id[0].strip()
if not sysName in ('centos', 'fedora', 'ubuntu', 'debian'):
return '暂时仅不支持{}'.format(sysName)
if sysName == 'debian':
if version > 10:
return 'mongodb[' + version + ']不支持安装在debian[' + sysId + ']'
if sysName == 'ubuntu':
if version < 16:
return 'mongodb[' + version + ']不支持安装在ubuntu[' + sysId + ']'
supportOs = ['centos', 'ubuntu', 'debian', 'opensuse']
if not sysName in supportOs:
return '暂时仅支持{}'.format(','.join(supportOs))
return 'ok'
if __name__ == "__main__":
+2 -2
View File
@@ -4,8 +4,8 @@
"name": "mongodb",
"title": "Mongodb",
"shell": "install.sh",
"versions":["4.4","5.0"],
"updates":["4.4","5.0"],
"install_pre_inspection":true,
"versions":["4.4","5.0","6.0","7.0"],
"tip": "soft",
"checks": "server/mongodb",
"path": "server/mongodb",
@@ -0,0 +1,36 @@
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network-online.target
Wants=network-online.target
[Service]
User=root
Group=root
#EnvironmentFile=-/etc/default/mongod
Environment="MONGODB_CONFIG_OVERRIDE_NOFORK=1"
PIDFile={$SERVER_PATH}/mongodb/mongodb.pid
ExecStart={$SERVER_PATH}/mongodb/bin/mongod -f {$SERVER_PATH}/mongodb/mongodb.conf
ExecReload=/bin/kill -HUP $MAINPID
#RuntimeDirectory=mongodb
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings
[Install]
WantedBy=multi-user.target
+4 -3
View File
@@ -30,8 +30,9 @@ app_start(){
echo "Starting mongodb server..."
echo $EXEC -f $CONF
$EXEC -f $CONF >> {$SERVER_PATH}/mongodb/logs.pl 2>&1 &
$EXEC -f $CONF >> {$SERVER_PATH}/mongodb/logs.pl 1>&1 2>&1 &
}
app_stop(){
if [ ! -f $PIDFILE ]
then
@@ -42,10 +43,10 @@ app_stop(){
kill -9 $PID
while [ -x /proc/${PID} ]
do
echo "Waiting for Redis to shutdown ..."
echo "Waiting for mongodb to shutdown ..."
sleep 1
done
echo "Redis stopped"
echo "mongodb stopped"
rm -rf $PIDFILE
fi
}
+287
View File
@@ -0,0 +1,287 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
sysName=`uname`
echo "use system: ${sysName}"
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
Install_app_mac()
{
mkdir -p $serverPath/mongodb
if [ "$VERSION" == "5.0" ];then
G_VERSION="5.0.11"
elif [[ "$VERSION" == "4.4" ]]; then
G_VERSION="4.4.11"
fi
if [ ! -f $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz ];then
wget -O $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${G_VERSION}.tgz
fi
cd $serverPath/source && tar -zxvf mongodb-macos-x86_64-${G_VERSION}.tgz
cd mongodb-macos-x86_64-${G_VERSION} && mv ./* $serverPath/mongodb
}
Install_Linux_Ubuntu()
{
##################### Ubuntu start #####################
if [ "$SYS_VERSION_ID" == "22" ]; then
echo "Not yet supported"
exit 1
fi
echo $SYS_VERSION_ID
SOURCE_NAME=bionic
if [ "$SYS_VERSION_ID" == "18.04" ];then
SOURCE_NAME=bionic
elif [ "$SYS_VERSION_ID" == "16.04" ];then
SOURCE_NAME=xenial
elif [ "$SYS_VERSION_ID" == "20.04" ];then
SOURCE_NAME=focal
fi
# wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
# apt install -y gnupg
# touch /etc/apt/sources.list.d/mongodb-org-4.4.list
# echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
apt install -y gnupg
touch /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
lsb_release -dc
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${SOURCE_NAME}/mongodb-org/${VERSION} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
apt update -y
apt install -y mongodb-org
##################### Ubuntu end #####################
}
Uninstall_Linux_Ubuntu()
{
if [ -f /lib/systemd/system/mongod.service ] || [ -f /usr/lib/systemd/system/mongod.service ] ;then
systemctl stop mongod
fi
apt purge -y mongodb-org*
apt autoremove -y
rm -r /var/log/mongodb
rm -r /var/lib/mongodb
}
Install_Linux_Debian()
{
##################### debian start #####################
if [ "$SYS_VERSION_ID" -eq "11" ] && [ "$VERSION" -eq "4.4" ]; then
echo "Not yet supported"
exit 1
fi
if [ -f /usr/lib/systemd/system/mongod.service ];then
echo 'alreay install exist!'
exit 0
fi
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
apt install -y gnupg
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/${VERSION} main" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
apt update -y
apt install -y mongodb-org
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
##################### debian end #####################
}
Uninstall_Linux_Debian()
{
systemctl stop mongod
apt purge -y mongodb-org*
apt autoremove -y
rm -r /var/log/mongodb
rm -r /var/lib/mongodb
}
Install_Linux_Opensuse()
{
##################### opensuse start #####################
if [ "$SYS_VERSION_ID" -gt "15" ]; then
echo "Not yet supported"
exit 1
fi
if [ -f /usr/lib/systemd/system/mongod.service ];then
echo 'alreay exist!'
exit 0
fi
rpm --import https://www.mongodb.org/static/pgp/server-${VERSION}.asc
zypper addrepo --gpgcheck "https://repo.mongodb.org/zypper/suse/15/mongodb-org/${VERSION}/x86_64/" mongodb
zypper -n install mongodb-org
# zypper install mongodb-org-4.4.15 mongodb-org-server-4.4.15 mongodb-org-shell-4.4.15 mongodb-org-mongos-4.4.15 mongodb-org-tools-4.4.15
##################### opensuse end #####################
}
Uninstall_Linux_Opensuse()
{
systemctl stop mongod
zypper remove -y $(rpm -qa | grep mongodb-org)
rm -r /var/log/mongodb
rm -r /var/lib/mongo
}
# https://repo.mongodb.org/yum/redhat/7/mongodb-org/5.0/x86_64/RPMS/mongodb-org-server-5.0.4-1.el7.x86_64.rpm
Install_Linux_CentOS()
{
if [ -f /usr/lib/systemd/system/mongod.service ];then
echo 'alreay exist!'
exit 0
fi
#清空mongo的repo源
rm -rf /etc/yum.repos.d/mongodb-org-*
##################### centos start #####################
echo "
[mongodb-org-${VERSION}]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/${VERSION}/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-${VERSION}.asc
" > /etc/yum.repos.d/mongodb-org-${VERSION}.repo
yum install -y mongodb-org
##################### centos end #####################
}
Uninstall_Linux_CentOS()
{
systemctl stop mongod
yum erase -y $(rpm -qa | grep mongodb-org)
rm -r /var/log/mongodb
rm -r /var/lib/mongo
rm -rf /etc/yum.repos.d/mongodb-org-${VERSION}.repo
}
Install_app_linux()
{
if [ "$OSNAME" == "ubuntu" ];then
Install_Linux_Ubuntu
elif [ "$OSNAME" == "debian" ];then
Install_Linux_Debian
elif [ "$OSNAME" == "centos" ];then
Install_Linux_CentOS
elif [ "$OSNAME" == "opensuse" ];then
Install_Linux_Opensuse
else
echo "Not yet supported"
exit 1
fi
}
Install_app()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source
if [ "macos" == "$OSNAME" ];then
Install_app_mac
else
Install_app_linux
fi
if [ "$?" == "0" ];then
mkdir -p $serverPath/mongodb
echo "${VERSION}" > $serverPath/mongodb/version.pl
echo '安装完成' > $install_tmp
#初始化
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py start
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py initd_install
fi
}
Uninstall_app_linux()
{
##################
if [ "$OSNAME" == "ubuntu" ];then
Uninstall_Linux_Ubuntu
elif [ "$OSNAME" == "debian" ];then
Uninstall_Linux_Debian
elif [ "$OSNAME" == "centos" ];then
Uninstall_Linux_CentOS
elif [ "$OSNAME" == "opensuse" ];then
Uninstall_Linux_Opensuse
else
echo "ok"
fi
##################
}
Uninstall_app()
{
if [ "macos" == "$OSNAME" ];then
echo 'mac'
else
Uninstall_app_linux
fi
rm -rf $serverPath/mongodb
echo "Uninstall_mongodb" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_app
else
Uninstall_app
fi
+107
View File
@@ -0,0 +1,107 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
sysName=`uname`
echo "use system: ${sysName}"
# bash ${rootPath}/scripts/getos.sh
# OSNAME=`cat ${rootPath}/data/osname.pl`
# SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
Install_app()
{
# ----- cpu start ------
if [ -z "${cpuCore}" ]; then
cpuCore="1"
fi
if [ -f /proc/cpuinfo ];then
cpuCore=`cat /proc/cpuinfo | grep "processor" | wc -l`
fi
MEM_INFO=$(free -m|grep Mem|awk '{printf("%.f",($2)/1024)}')
if [ "${cpuCore}" != "1" ] && [ "${MEM_INFO}" != "0" ];then
if [ "${cpuCore}" -gt "${MEM_INFO}" ];then
cpuCore="${MEM_INFO}"
fi
else
cpuCore="1"
fi
if [ "$cpuCore" -gt "2" ];then
cpuCore=`echo "$cpuCore" | awk '{printf("%.f",($1)*0.8)}'`
else
cpuCore="1"
fi
# ----- cpu end ------
echo '正在安装脚本文件...' > $install_tmp
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh
echo "cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh"
export PKG_CONFIG_PATH=$serverPath/lib/openssl/lib/pkgconfig
if [ ! -f $MG_DIR/mongodb-src-r${VERSION}.tar.gz ]; then
wget --no-check-certificate -O $MG_DIR/mongodb-src-r${VERSION}.tar.gz https://fastdl.mongodb.org/src/mongodb-src-r${VERSION}.tar.gz
echo "wget --no-check-certificate -O $MG_DIR/mongodb-src-r${VERSION}.tar.gz https://fastdl.mongodb.org/src/mongodb-src-r${VERSION}.tar.gz"
fi
if [ ! -d $MG_DIR/mongodb-src-r${VERSION} ];then
cd $MG_DIR && tar -zxvf $MG_DIR/mongodb-src-r${VERSION}.tar.gz
fi
cd $MG_DIR/mongodb-src-r${VERSION} && python3 -m pip install requirements_parser
cd $MG_DIR/mongodb-src-r${VERSION} && python3 -m pip install -r etc/pip/compile-requirements.txt
# cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py all -j 2
# echo "cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py all -j 2"
# cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py all MONGO_VERSION=${VERSION} -j 4
cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py install-mongod MONGO_VERSION=${VERSION} -j ${cpuCore}
cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py DESTDIR=$serverPath/mongodb install-mongod MONGO_VERSION=${VERSION} \
--ssl=off
echo "cd $MG_DIR/mongodb-src-r${VERSION} && python3 buildscripts/scons.py DESTDIR=$serverPath/mongodb install MONGO_VERSION=${VERSION} \
--ssl=off CPPPATH=$serverPath/lib/openssl/include \
LIBPATH=$serverPath/lib/openssl/lib"
if [ "$?" == "0" ];then
mkdir -p $serverPath/mongodb
echo "${VERSION}" > $serverPath/mongodb/version.pl
echo '安装完成' > $install_tmp
#初始化
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py start
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py initd_install
fi
}
Uninstall_app()
{
rm -rf $serverPath/mongodb
echo "Uninstall_mongodb" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_app
else
Uninstall_app
fi
+51 -240
View File
@@ -2,8 +2,15 @@
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
# cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
# cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
# https://www.mongodb.com/try/download/community
'''
cd /Users/midoks/Desktop/mwdev/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 5.0.4
cd /www/server/mdserver-web/plugins/mongodb && /bin/bash install.sh install 7.0
cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mongodb/index.py start
'''
curPath=`pwd`
rootPath=$(dirname "$curPath")
@@ -16,230 +23,48 @@ VERSION=$2
sysName=`uname`
echo "use system: ${sysName}"
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
OSNAME=`bash ${rootPath}/scripts/getos.sh`
Install_app_mac()
{
mkdir -p $serverPath/mongodb
if [ "$VERSION" == "5.0" ];then
G_VERSION="5.0.11"
elif [[ "$VERSION" == "4.4" ]]; then
G_VERSION="4.4.11"
fi
if [ ! -f $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz ];then
wget -O $serverPath/source/mongodb-macos-x86_64-${G_VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${G_VERSION}.tgz
fi
cd $serverPath/source && tar -zxvf mongodb-macos-x86_64-${G_VERSION}.tgz
cd mongodb-macos-x86_64-${G_VERSION} && mv ./* $serverPath/mongodb
}
Install_Linux_Ubuntu()
{
##################### Ubuntu start #####################
if [ "$SYS_VERSION_ID" == "22" ]; then
echo "Not yet supported"
exit 1
if [ "" == "$OSNAME" ];then
OSNAME=`cat ${rootPath}/data/osname.pl`
fi
echo $SYS_VERSION_ID
SOURCE_NAME=bionic
if [ "$SYS_VERSION_ID" == "18.04" ];then
SOURCE_NAME=bionic
elif [ "$SYS_VERSION_ID" == "16.04" ];then
SOURCE_NAME=xenial
elif [ "$SYS_VERSION_ID" == "20.04" ];then
SOURCE_NAME=focal
if [ "macos" != "$OSNAME" ];then
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
fi
# wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
# apt install -y gnupg
# touch /etc/apt/sources.list.d/mongodb-org-4.4.list
# echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
apt install -y gnupg
touch /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
lsb_release -dc
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu ${SOURCE_NAME}/mongodb-org/${VERSION} multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
apt update -y
apt install -y mongodb-org
##################### Ubuntu end #####################
}
Uninstall_Linux_Ubuntu()
{
if [ -f /lib/systemd/system/mongod.service ] || [ -f /usr/lib/systemd/system/mongod.service ] ;then
systemctl stop mongod
fi
apt purge -y mongodb-org*
apt autoremove -y
rm -r /var/log/mongodb
rm -r /var/lib/mongodb
}
Install_Linux_Debian()
{
##################### debian start #####################
if [ "$SYS_VERSION_ID" -eq "11" ] && [ "$VERSION" -eq "4.4" ]; then
echo "Not yet supported"
exit 1
fi
if [ -f /usr/lib/systemd/system/mongod.service ];then
echo 'alreay install exist!'
exit 0
fi
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
apt install -y gnupg
wget -qO - https://www.mongodb.org/static/pgp/server-${VERSION}.asc | sudo apt-key add -
echo "deb http://repo.mongodb.org/apt/debian buster/mongodb-org/${VERSION} main" | sudo tee /etc/apt/sources.list.d/mongodb-org-${VERSION}.list
apt update -y
apt install -y mongodb-org
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
##################### debian end #####################
}
Uninstall_Linux_Debian()
{
systemctl stop mongod
apt purge -y mongodb-org*
apt autoremove -y
rm -r /var/log/mongodb
rm -r /var/lib/mongodb
}
Install_Linux_Opensuse()
{
##################### opensuse start #####################
if [ "$SYS_VERSION_ID" -gt "15" ]; then
echo "Not yet supported"
exit 1
fi
if [ -f /usr/lib/systemd/system/mongod.service ];then
echo 'alreay exist!'
exit 0
fi
rpm --import https://www.mongodb.org/static/pgp/server-${VERSION}.asc
zypper addrepo --gpgcheck "https://repo.mongodb.org/zypper/suse/15/mongodb-org/${VERSION}/x86_64/" mongodb
zypper -n install mongodb-org
# zypper install mongodb-org-4.4.15 mongodb-org-server-4.4.15 mongodb-org-shell-4.4.15 mongodb-org-mongos-4.4.15 mongodb-org-tools-4.4.15
##################### opensuse end #####################
}
Uninstall_Linux_Opensuse()
{
systemctl stop mongod
zypper remove -y $(rpm -qa | grep mongodb-org)
rm -r /var/log/mongodb
rm -r /var/lib/mongo
}
# https://repo.mongodb.org/yum/redhat/7/mongodb-org/5.0/x86_64/RPMS/mongodb-org-server-5.0.4-1.el7.x86_64.rpm
Install_Linux_CentOS()
{
if [ -f /usr/lib/systemd/system/mongod.service ];then
echo 'alreay exist!'
exit 0
fi
#清空mongo的repo源
rm -rf /etc/yum.repos.d/mongodb-org-*
##################### centos start #####################
echo "
[mongodb-org-${VERSION}]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/\$releasever/mongodb-org/${VERSION}/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-${VERSION}.asc
" > /etc/yum.repos.d/mongodb-org-${VERSION}.repo
yum install -y mongodb-org
##################### centos end #####################
}
Uninstall_Linux_CentOS()
{
systemctl stop mongod
yum erase -y $(rpm -qa | grep mongodb-org)
rm -r /var/log/mongodb
rm -r /var/lib/mongo
rm -rf /etc/yum.repos.d/mongodb-org-${VERSION}.repo
}
Install_app_linux()
{
if [ "$OSNAME" == "ubuntu" ];then
Install_Linux_Ubuntu
elif [ "$OSNAME" == "debian" ];then
Install_Linux_Debian
elif [ "$OSNAME" == "centos" ];then
Install_Linux_CentOS
elif [ "$OSNAME" == "opensuse" ];then
Install_Linux_Opensuse
else
echo "Not yet supported"
exit 1
fi
}
Install_app()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source
if [ "macos" == "$OSNAME" ];then
Install_app_mac
# if id mongodb &> /dev/null ;then
# echo "mongodb uid is `id -u mongodb`"
# echo "mongodb shell is `grep "^mongodb:" /etc/passwd |cut -d':' -f7 `"
# else
# groupadd mongodb
# useradd -g mongodb mongodb
# fi
# if [ "centos" == "$OSNAME" ];then
# OSNAME=rhel
# fi
# if [ "fedora" == "$OSNAME" ];then
# OSNAME=rhel
# fi
# if [ "rocky" == "$OSNAME" ];then
# OSNAME=rhel
# fi
shell_file=${curPath}/versions/${VERSION}/${OSNAME}.sh
if [ -f $shell_file ];then
bash -x $shell_file
else
Install_app_linux
echo '不支持...' > $install_tmp
exit 1
fi
if [ "$?" == "0" ];then
@@ -253,34 +78,20 @@ Install_app()
fi
}
Uninstall_app_linux()
{
##################
if [ "$OSNAME" == "ubuntu" ];then
Uninstall_Linux_Ubuntu
elif [ "$OSNAME" == "debian" ];then
Uninstall_Linux_Debian
elif [ "$OSNAME" == "centos" ];then
Uninstall_Linux_CentOS
elif [ "$OSNAME" == "opensuse" ];then
Uninstall_Linux_Opensuse
else
echo "ok"
fi
##################
}
Uninstall_app()
{
if [ "macos" == "$OSNAME" ];then
echo 'mac'
else
Uninstall_app_linux
cd ${rootPath} && python3 ${rootPath}/plugins/mongodb/index.py stop
rm -rf $serverPath/mongodb
if [ -f /usr/lib/systemd/system/mongodb.service ] || [ -f /lib/systemd/system/mongodb.service ];then
systemctl stop mongodb
systemctl disable mongodb
rm -rf /usr/lib/systemd/system/mongodb.service
rm -rf /lib/systemd/system/mongodb.service
systemctl daemon-reload
fi
rm -rf $serverPath/mongodb
echo "Uninstall_mongodb" > $install_tmp
}
+66
View File
@@ -0,0 +1,66 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=4.4.23
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" == "1" ];then
SYS_NAME=${SYS_NAME}0
fi
if [ "$SYS_ARCH" == "aarch64" ];then
if [ "$SYS_NAME" -gt "82" ];then
SYS_NAME="82"
fi
if [ "$SYS_NAME" -lt "62" ];then
SYS_NAME="62"
fi
else
if [ "$SYS_NAME" -gt "80" ];then
SYS_NAME="80"
fi
if [ "$SYS_NAME" -lt "70" ];then
SYS_NAME="70"
fi
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-rhel82-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-rhel82-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel80-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=4.4.23
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
if [ "$SYS_NAME" -gt "10" ];then
SYS_NAME="10"
fi
if [ "$SYS_NAME" -lt "10" ];then
SYS_NAME="10"
fi
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
fi
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=4.4.23
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
fi
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
fi
+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=4.4.23
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
SYS_NAME="15"
if [ "$SYS_VERSION_ID" -gt "15" ];then
SYS_NAME="15"
fi
if [ "$SYS_NAME" -lt "12" ];then
SYS_NAME="12"
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=4.4.23
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" == "1" ];then
SYS_NAME=${SYS_NAME}0
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=4.4.23
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
if [ "$SYS_NAME" -gt "2004" ];then
SYS_NAME="2004"
fi
if [ "$SYS_NAME" -lt "1604" ];then
SYS_NAME="1604"
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=5.0.20
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" == "1" ];then
SYS_NAME=${SYS_NAME}0
fi
if [ "$SYS_ARCH" == "aarch64" ];then
SYS_NAME="82"
else
if [ "$SYS_NAME" -gt "80" ];then
SYS_NAME="80"
fi
if [ "$SYS_NAME" -lt "70" ];then
SYS_NAME="70"
fi
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=5.0.20
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
if [ "$SYS_NAME" -gt "11" ];then
SYS_NAME="11"
fi
if [ "$SYS_NAME" -lt "10" ];then
SYS_NAME="10"
fi
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
fi
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=5.0.20
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
fi
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
fi
+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=5.0.20
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
SYS_NAME="15"
if [ "$SYS_VERSION_ID" -gt "15" ];then
SYS_NAME="15"
fi
if [ "$SYS_NAME" -lt "12" ];then
SYS_NAME="12"
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=5.0.20
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
if [ "$SYS_NAME" -gt "2004" ];then
SYS_NAME="2004"
fi
if [ "$SYS_NAME" -lt "1804" ];then
SYS_NAME="1804"
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=6.0.9
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" == "1" ];then
SYS_NAME=${SYS_NAME}0
fi
if [ "$SYS_ARCH" == "aarch64" ];then
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "82" ];then
SYS_NAME="82"
fi
else
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "70" ];then
SYS_NAME="70"
fi
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=6.0.9
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
if [ "$SYS_NAME" -gt "11" ];then
SYS_NAME="11"
fi
if [ "$SYS_NAME" -lt "10" ];then
SYS_NAME="10"
fi
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
fi
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=6.0.9
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
fi
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
fi
+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=6.0.9
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
SYS_NAME="15"
if [ "$SYS_VERSION_ID" -gt "15" ];then
SYS_NAME="15"
fi
if [ "$SYS_NAME" -lt "12" ];then
SYS_NAME="12"
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=6.0.9
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
if [ "$SYS_NAME" -gt "2204" ];then
SYS_NAME="2204"
fi
if [ "$SYS_NAME" -lt "1804" ];then
SYS_NAME="1804"
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+59
View File
@@ -0,0 +1,59 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=7.0.0
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
SYS_NAME_LEN=`echo "$SYS_NAME" | wc -L`
if [ "$SYS_NAME_LEN" == "1" ];then
SYS_NAME=${SYS_NAME}0
fi
if [ "$SYS_ARCH" == "aarch64" ];then
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "82" ];then
SYS_NAME="82"
fi
else
if [ "$SYS_NAME" -gt "90" ];then
SYS_NAME="90"
fi
if [ "$SYS_NAME" -lt "70" ];then
SYS_NAME="70"
fi
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-rhel${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+43
View File
@@ -0,0 +1,43 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=7.0.0
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
if [ "$SYS_NAME" -gt "11" ];then
SYS_NAME="11"
fi
if [ "$SYS_NAME" -lt "11" ];then
SYS_NAME="11"
fi
FILE_NAME=mongodb-linux-${SYS_ARCH}-debian${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME_TGZ} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME}} && cp -rf ./bin $serverPath/mongodb
fi
+28
View File
@@ -0,0 +1,28 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=7.0.0
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
if [ ! -f $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz ]; then
wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
echo "wget --no-check-certificate -O $MG_DIR/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz"
fi
if [ ! -d $MG_DIR/mongodb-macos-x86_64-${VERSION} ];then
cd $MG_DIR && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/mongodb-macos-x86_64-${VERSION} && cp -rf ./bin $serverPath/mongodb
fi
+46
View File
@@ -0,0 +1,46 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=7.0.0
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}' | awk -F . '{print $1}'`
SYS_NAME="15"
if [ "$SYS_VERSION_ID" -gt "15" ];then
SYS_NAME="15"
fi
if [ "$SYS_NAME" -lt "12" ];then
SYS_NAME="12"
fi
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse15-4.4.23.tgz
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-suse12-4.4.23.tgz
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-suse${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+44
View File
@@ -0,0 +1,44 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=7.0.0
SYS_ARCH=`arch`
SYS_VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
SYS_NAME=${SYS_VERSION_ID/./}
# https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu2004-4.4.23.tgz
if [ "$SYS_NAME" -gt "2204" ];then
SYS_NAME="2204"
fi
if [ "$SYS_NAME" -lt "2004" ];then
SYS_NAME="2004"
fi
MG_DIR=$serverPath/source/mongodb
mkdir -p $MG_DIR
FILE_NAME=mongodb-linux-${SYS_ARCH}-ubuntu${SYS_NAME}-${VERSION}
FILE_NAME_TGZ=${FILE_NAME}.tgz
if [ ! -f $MG_DIR/${FILE_NAME_TGZ} ]; then
wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}
echo "wget --no-check-certificate -O $MG_DIR/${FILE_NAME_TGZ} https://fastdl.mongodb.org/linux/${FILE_NAME_TGZ}"
fi
if [ ! -d $MG_DIR/${FILE_NAME} ];then
cd $MG_DIR && tar -zxvf ${FILE_NAME_TGZ}
fi
if [ ! -d $serverPath/mongodb/bin ];then
mkdir -p $serverPath/mongodb
cd $MG_DIR/${FILE_NAME} && cp -rf ./bin $serverPath/mongodb
fi
+825
View File
@@ -0,0 +1,825 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import json
import io
sys.path.append(os.getcwd() + "/class/core")
import mw
import oauthlib
import requests
import datetime
from requests_oauthlib import OAuth2Session
DEBUG = False
def setDebug(d=False):
DEBUG = d
class UnauthorizedError(Exception):
pass
class ObjectNotFoundError(Exception):
pass
class msodclient:
plugin_dir = ''
server_dir = ''
credential_file = 'credentials.json'
user_conf = "user.conf"
token_file = 'token.pickle'
def __init__(self, plugin_dir, server_dir):
self.plugin_dir = plugin_dir
self.server_dir = server_dir
self.load()
def setDebug(self, d=False):
DEBUG = d
def load(self):
credential_path = os.path.join(self.plugin_dir, self.credential_file)
credential = json.loads(mw.readFile(credential_path))
# print(credential)
self.credential = credential["onedrive-international"]
self.authorize_url = '{0}{1}'.format(
self.credential['authority'],
self.credential['authorize_endpoint'])
self.token_url = '{0}{1}'.format(
self.credential['authority'],
self.credential['token_endpoint'])
self.token_path = os.path.join(self.server_dir, self.token_file)
self.root_uri = self.credential["api_uri"] + "/me/drive/root"
self.backup_path = 'backup'
def store_token(self, token):
"""存储token"""
enstr = mw.enDoubleCrypt('msodc', json.dumps(token))
mw.writeFile(self.token_path, enstr)
return True
def get_store_token(self):
rdata = mw.readFile(self.token_path)
destr = mw.deDoubleCrypt('msodc', rdata)
return json.loads(destr)
def clear_token(self):
"""清除token记录"""
try:
if os.path.isfile(self.token_path):
os.remove(self.token_path)
except:
if DEBUG:
print("清除token失败。")
def refresh_token(self, origin_token):
"""刷新token"""
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
os.environ['OAUTHLIB_IGNORE_SCOPE_CHANGE'] = '1'
refresh_token = origin_token["refresh_token"]
aad_auth = OAuth2Session(
self.credential["client_id"],
scope=self.credential["scopes"],
redirect_uri=self.credential["redirect_uri"])
new_token = aad_auth.refresh_token(
self.token_url,
refresh_token=refresh_token,
client_id=self.credential["client_id"],
client_secret=self.credential["client_secret"])
return new_token
def get_token_from_authorized_url(self, authorized_url, expected_state=None):
"""通过授权编码获取访问token"""
# 忽略token scope与已请求的scope不一致
os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'
os.environ['OAUTHLIB_IGNORE_SCOPE_CHANGE'] = '1'
aad_auth = OAuth2Session(self.credential["client_id"],
state=expected_state,
scope=self.credential['scopes'],
redirect_uri=self.credential['redirect_uri'])
token = aad_auth.fetch_token(
self.token_url,
client_secret=self.credential["client_secret"],
authorization_response=authorized_url)
return token
def get_token(self):
token = self.get_store_token()
now = time.time()
expire_time = token["expires_at"] - 300
if now >= expire_time:
new_token = self.refresh_token(token)
self.store_token(new_token)
return new_token
return token
def get_sign_in_url(self):
"""生成签名地址"""
# Initialize the OAuth client
aad_auth = OAuth2Session(self.credential["client_id"],
scope=self.credential['scopes'],
redirect_uri=self.credential['redirect_uri'])
sign_in_url, state = aad_auth.authorization_url(self.authorize_url,
prompt='login')
return sign_in_url, state
def get_authorized_header(self):
token_obj = self.get_token()
token = token_obj["access_token"]
header = {
"Authorization": "Bearer " + token,
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/67.0.3396.99 Safari/537.36'
}
return header
def get_user_from_ms(self):
"""查询用户信息"""
try:
headers = self.get_authorized_header()
user_api_base = self.credential["api_uri"] + "/me"
# select_user_info_uri = self.build_uri(base=user_api_base)
response = requests.get(user_api_base, headers=headers)
if DEBUG:
print("Debug get user:")
print(response.status_code)
print(response.text)
if response.status_code == 200:
response_data = response.json()
user_principal_name = response_data["userPrincipalName"]
return user_principal_name
except oauthlib.oauth2.rfc6749.errors.InvalidGrantError:
self.clear_auth()
if DEBUG:
print("用户授权已过期。")
return None
def clear_auth(self):
self.clear_token()
self.clear_user()
def clear_user(self):
try:
# 清空user
path = os.path.join(self.server_dir, self.user_conf)
if os.path.isfile(path):
os.remove(path)
except:
if DEBUG:
print("清除user失败。")
def store_user(self):
"""更新并存储用户信息"""
user = self.get_user_from_ms()
if user:
path = os.path.join(self.server_dir, self.user_conf)
mw.writeFile(path, user)
else:
raise RuntimeError("无法获取用户信息。")
# --------------------- 文件操作功能 ----------------------
# 取目录路径
def get_path(self, path):
sep = ":"
if path == '/':
path = ''
if path[-1:] == '/':
path = path[:-1]
if path[:1] != "/" and path[:1] != sep:
path = "/" + path
if path == '/':
path = ''
# if path[:1] != sep:
# path = sep + path
try:
from urllib.parse import quote
except:
from urllib import quote
# path = quote(path)
return path.replace('//', '/')
def build_uri(self, path="", operate=None, base=None):
"""构建请求URL
API请求URI格式参考:
https://graph.microsoft.com/v1.0/me/drive/root:/bt_backup/:content
--------------------------------------------- ---------- --------
base path operate
各部分之间用“:”连接。
:param path 子资源路径
:param operate 对文件进行的操作,比如content,children
:return 请求url
"""
if base is None:
base = self.root_uri
path = self.get_path(path)
sep = ":"
if operate:
if operate[:1] != "/":
operate = "/" + operate
if path:
uri = base + sep + path
if operate:
uri += sep + operate
else:
uri = base
if operate:
uri += operate
return uri
def get_list(self, path="/"):
"""获取存储空间中的所有文件对象"""
list_uri = self.build_uri(path, operate="/children")
if DEBUG:
print("List uri:")
print(list_uri)
data = []
response = requests.get(list_uri, headers=self.get_authorized_header())
status_code = response.status_code
if status_code == 200:
if DEBUG:
print("DEBUG:")
print(response.json())
response_data = response.json()
drive_items = response_data["value"]
for item in drive_items:
tmp = {}
tmp['name'] = item["name"]
tmp['size'] = item["size"]
if "folder" in item:
# print("{} is folder:".format(item["name"]))
# print(item["folder"])
tmp["type"] = None
tmp['download'] = ""
if "file" in item:
tmp["type"] = "File"
tmp['download'] = item["@microsoft.graph.downloadUrl"]
# print("{} is file:".format(item["name"]))
# print(item["file"])
formats = ["%Y-%m-%dT%H:%M:%S.%fZ", "%Y-%m-%dT%H:%M:%SZ"]
t = None
for time_format in formats:
try:
t = datetime.datetime.strptime(
item["lastModifiedDateTime"], time_format)
break
except:
continue
t += datetime.timedelta(hours=8)
ts = int(
(time.mktime(t.timetuple()) + t.microsecond / 1000000.0))
tmp['time'] = ts
data.append(tmp)
mlist = {'path': path, 'list': data}
return mlist
def get_object(self, object_name):
"""查询对象信息"""
try:
get_uri = self.build_uri(path=object_name)
if DEBUG:
print("Get uri:")
print(get_uri)
response = requests.get(get_uri,
headers=self.get_authorized_header())
if response.status_code in [200]:
response_data = response.json()
if DEBUG:
print("Object info:")
print(response_data)
return response_data
if response.status_code == 404:
if DEBUG:
print("对象不存在。")
if DEBUG:
print("Get Object debug:")
print(response.status_code)
print(response.text)
except Exception as e:
if DEBUG:
print("Get object has excepiton:")
print(e)
return None
def is_folder(self, obj):
if "folder" in obj:
return True
return False
def delete_object_by_os(self, object_name):
"""删除对象
:param object_name:
:return: True 删除成功
其他 删除失败
"""
obj = self.get_object(object_name)
if obj is None:
if DEBUG:
print("对象不存在,删除操作未执行。")
return True
if self.is_folder(obj):
child_count = obj["folder"]["childCount"]
if child_count > 0:
if DEBUG:
print("文件夹不是空文件夹无法删除。")
return False
headers = self.get_authorized_header()
delete_uri = self.build_uri(object_name)
response = requests.delete(delete_uri, headers=headers)
if response.status_code == 204:
if DEBUG:
print("对象: {} 已被删除。".format(object_name))
return True
return False
def delete_object(self, object_name, retries=2):
"""删除对象
:param object_name:
:param retries: 重试次数,默认2次
:return: True 删除成功
其他 删除失败
"""
try:
return self.delete_object_by_os(object_name)
except Exception as e:
print("删除文件异常:")
print(e)
# 重试
if retries > 0:
print("重新尝试删除文件{}...".format(object_name))
return self.delete_object(
object_name,
retries=retries - 1)
return False
def build_object_name(self, data_type, file_name):
"""根据数据类型构建对象存储名称
:param data_type:
:param file_name:
:return:
"""
import re
prefix_dict = {
"site": "web",
"database": "db",
"path": "path",
}
if not prefix_dict.get(data_type):
print("data_type 类型错误!!!")
exit(1)
file_regx = prefix_dict.get(data_type) + "_(.+)_20\d+_\d+(?:\.|_)"
sub_search = re.search(file_regx, file_name)
sub_path_name = ""
if sub_search:
sub_path_name = sub_search.groups()[0]
sub_path_name += '/'
# 构建OS存储路径
object_name = self.backup_path + '/' + \
data_type + '/' + \
sub_path_name + \
file_name
if object_name[:1] == "/":
object_name = object_name[1:]
return object_name
def delete_file(self, file_name, data_type=None):
"""删除文件
根据传入的文件名称和文件数据类型构建对象名称,再删除
:param file_name:
:param data_type: 数据类型 site/database/path
:return: True 删除成功
其他 删除失败
"""
object_name = self.build_object_name(data_type, file_name)
return self.delete_object(object_name)
def create_dir_by_step(self, parent_folder, sub_folder):
create_uri = self.build_uri(path=parent_folder, operate="/children")
if DEBUG:
print("Create dir uri:")
print(create_uri)
post_data = {
"name": sub_folder,
"folder": {"@odata.type": "microsoft.graph.folder"},
"@microsoft.graph.conflictBehavior": "fail"
}
headers = self.get_authorized_header()
headers.update({"Content-type": "application/json"})
response = requests.post(create_uri, headers=headers, json=post_data)
if response.status_code in [201, 409]:
if DEBUG:
if response.status_code == 409:
print("目录:{} 已经存在。".format(sub_folder))
return True
else:
if DEBUG:
print("目录:{} 创建失败:".format(sub_folder))
print(response.status_code)
print(response.text)
return False
def create_dir(self, dir_name):
"""创建远程目录
# API 请求结构
# POST /me/drive/root/children
# or
# POST /me/drive/root:/bt_backup/:/children
# Content - Type: application / json
# {
# "name": "New Folder",
# "folder": {},
# "@microsoft.graph.conflictBehavior": "rename"
# }
# Response: status code == 201 新创建/ 409 已存在
# @microsoft.graph.conflictBehavior: fail/rename/replace
:param dir_name: 目录名称
:param parent_id: 父目录ID
:return: True/False
"""
dir_name = self.get_path(dir_name.strip())
onedrive_business_reserved = r"[\*<>?:|#%]"
if re.search(onedrive_business_reserved, dir_name) \
or dir_name[-1] == "." or dir_name[:1] == "~":
if DEBUG:
print("文件夹名称包含非法字符。")
return False
parent_folder = self.get_path(os.path.split(dir_name)[0])
sub_folder = os.path.split(dir_name)[1]
# print("create_dir:", dir_name)
obj = self.get_object(dir_name)
# 判断对象是否存在
if obj is None:
if not self.create_dir_by_step(parent_folder, sub_folder):
# 兼容OneDrive 商业版文件夹创建
folder_array = dir_name.split("/")
parent_folder = self.get_path(folder_array[0])
for i in range(1, len(folder_array)):
sub_folder = folder_array[i]
if DEBUG:
print("Parent folder: {}".format(parent_folder))
print("Sub folder: {}".format(sub_folder))
if self.create_dir_by_step(parent_folder, sub_folder):
parent_folder += "/" + folder_array[i]
else:
return False
return True
else:
if self.is_folder(obj):
if DEBUG:
print("文件夹已存在。")
return True
def resumable_upload(self,
local_file_name,
object_name=None,
progress_callback=None,
progress_file_name=None,
multipart_threshold=1024 * 1024 * 2,
part_size=1024 * 1024 * 5,
store_dir="/tmp",
auto_cancel=True,
retries=5,
):
"""断点续传
:param local_file_name: 本地文件名称
:param object_name: 指定OS中存储的对象名称
:param part_size: 指定分片上传的每个分片的大小。必须是320*1024的整数倍。
:param multipart_threshold: 文件长度大于该值时,则用分片上传。
:param progress_callback: 进度回调函数,默认是把进度信息输出到标准输出。
:param progress_file_name: 进度信息保存文件,进度格式参见[report_progress]
:param store_dir: 上传分片存储目录, 默认/tmp。
:param auto_cancel: 当备份失败是否自动取消上传记录
:param retries: 上传重试次数
:return: True上传成功/False or None上传失败
"""
try:
file_size_separation_value = 4 * 1024 * 1024
if part_size % 320 != 0:
if DEBUG:
print("Part size 必须是320的整数倍。")
return False
if object_name is None:
temp_file_name = os.path.split(local_file_name)[1]
object_name = os.path.join(self.backup_path, temp_file_name)
# if progress_file_name:
# os.environ[PROGRESS_FILE_NAME] = progress_file_name
# progress_callback = report_progress
print("|-正在上传到 {}...".format(object_name))
dir_name = os.path.split(object_name)[0]
if not self.create_dir(dir_name):
if DEBUG:
print("目录创建失败!")
return False
local_file_size = os.path.getsize(local_file_name)
# if local_file_size < file_size_separation_value:
if False:
# 小文件上传
upload_uri = self.build_uri(path=object_name,
operate="/content")
if DEBUG:
print("Upload uri:")
print(upload_uri)
headers = self.get_authorized_header()
# headers.update({
# "Content-Type": "application/octet-stream"
# })
# files = {"file": (object_name, open(local_file_name, "rb"))}
file_data = open(local_file_name, "rb")
response = requests.put(upload_uri,
headers=headers,
data=file_data)
if DEBUG:
print("status code:")
print(response.status_code)
# print(response.text)
if response.status_code in [201, 200]:
if DEBUG:
print("文件上传成功!")
return True
else:
# 大文件上传
# 1. 创建上传session
create_session_uri = self.build_uri(
path=object_name,
operate="createUploadSession")
headers = self.get_authorized_header()
response = requests.post(create_session_uri, headers=headers)
if response.status_code == 200:
response_data = response.json()
upload_url = response_data["uploadUrl"]
expiration_date_time = response_data["expirationDateTime"]
if DEBUG:
print("上传session已建立。")
print("Upload url: {}".format(upload_url))
print("Expiration datetime: {}".format(
expiration_date_time))
# 2. 分片上传文件
requests.adapters.DEFAULT_RETRIES = 1
session = requests.session()
session.keep_alive = False
# 开始分片上传
import math
parts = int(math.ceil(local_file_size / part_size))
for i in range(parts):
if DEBUG:
if i == parts - 1:
num = "最后"
else:
num = "第{}".format(i + 1)
print("正在上传{}部分...".format(num))
upload_range_start = i * part_size
upload_range_end = min(upload_range_start + part_size,
local_file_size)
content_length = upload_range_end - upload_range_start
headers = {
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/67.0.3396.99 Safari/537.36'
}
# 开发记录
# Content-Range和标准的http请求头中的Range作用有所不同
# Content-Range是OneDrive自定义的分片上传标识,格式也不一样
headers.update({
"Content-Length": repr(content_length),
"Content-Range": "bytes {}-{}/{}".format(
upload_range_start,
upload_range_end - 1,
local_file_size),
"Content-Type": "application/octet-stream"
})
if DEBUG:
print("Headers:")
print(headers)
'''# TODO 优化read的读取占用内存'''
f = io.open(local_file_name, "rb")
f.seek(upload_range_start)
upload_data = f.read(content_length)
sub_response = session.put(upload_url,
headers=headers,
data=upload_data)
expected_status_code = [200, 201, 202]
if sub_response.status_code in expected_status_code:
if DEBUG:
print("Response status code: {}, "
"bytes {}-{} 已上传成功。".format(
sub_response.status_code,
upload_range_start,
upload_range_end - 1)
)
print(sub_response.text)
if sub_response.status_code in [200, 201]:
if DEBUG:
print("文件 {} 上传成功。".format(object_name))
return True
else:
print(sub_response.status_code)
print(sub_response.text)
_error_msg = "Bytes {}-{} 分片上传失败。".format(
upload_range_start,
upload_range_end
)
if self.error_msg:
self.error_msg += r"\n"
self.error_msg += _error_msg
raise RuntimeError(_error_msg)
time.sleep(0.5)
else:
raise RuntimeError("session创建失败。")
except UnauthorizedError as e:
_error_msg = str(e)
if self.error_msg:
self.error_msg += r"\n"
self.error_msg += _error_msg
print(_error_msg)
return False
except Exception as e:
print("文件上传出现错误:")
print(e)
if self.error_msg:
self.error_msg += r"\n"
self.error_msg += "文件{}上传出现错误:{}".format(object_name, str(e))
try:
if upload_url:
if DEBUG:
print("正在清理上传session.")
session.delete(upload_url)
except:
pass
finally:
try:
f.close()
except:
pass
try:
session.close()
except:
pass
# 重试断点续传
if retries > 0:
print("重试上传文件....")
return self.resumable_upload(
local_file_name,
object_name=object_name,
store_dir=store_dir,
part_size=part_size,
multipart_threshold=multipart_threshold,
progress_callback=progress_callback,
progress_file_name=progress_file_name,
retries=retries - 1,
)
else:
if self.error_msg:
self.error_msg += r"\n"
self.error_msg += "文件{}上传失败。".format(object_name)
return False
def upload_abs_file(self, file_name, remote_dir, *args, **kwargs):
"""按照数据类型上传文件
:param file_name: 上传文件名称
:param data_type: 数据类型 site/database/path
:return: True/False
"""
try:
import re
# 根据数据类型提取子分类名称
# 比如data_type=database,子分类名称是数据库的名称。
# 提取方式是从file_name中利用正则规则去提取。
self.error_msg = ""
file_name = os.path.abspath(file_name)
temp_name = os.path.split(file_name)[1]
object_name = 'backup/' + temp_name
print(file_name)
print(object_name)
return self.resumable_upload(file_name,
object_name=object_name,
*args,
**kwargs)
except Exception as e:
if self.error_msg:
self.error_msg += r"\n"
self.error_msg += "文件上传出现错误:{}".format(str(e))
return False
def upload_file(self, file_name, data_type, *args, **kwargs):
"""按照数据类型上传文件
:param file_name: 上传文件名称
:param data_type: 数据类型 site/database/path
:return: True/False
"""
try:
import re
# 根据数据类型提取子分类名称
# 比如data_type=database,子分类名称是数据库的名称。
# 提取方式是从file_name中利用正则规则去提取。
self.error_msg = ""
if not file_name or not data_type:
_error_msg = "文件参数错误。"
print(_error_msg)
self.error_msg = _error_msg
return False
file_name = os.path.abspath(file_name)
temp_name = os.path.split(file_name)[1]
object_name = self.build_object_name(data_type, temp_name)
# dir_name = os.path.dirname(object_name)
# self.create_dir(dir_name)
if DEBUG:
print(file_name)
print(object_name)
print(dir_name)
return self.resumable_upload(file_name,
object_name=object_name,
*args,
**kwargs)
except Exception as e:
if self.error_msg:
self.error_msg += r"\n"
self.error_msg += "文件上传出现错误:{}".format(str(e))
return False
+12
View File
@@ -0,0 +1,12 @@
{
"onedrive-international": {
"client_id": "08125e6b-6502-4ac9-9548-ad682f00848d",
"client_secret": "0WA8Q~sZkZFZKv50ryP4ux~.fpVtbHw7BuTZmbQB",
"authority": "https://login.microsoftonline.com/common",
"token_endpoint": "/oauth2/v2.0/token",
"authorize_endpoint": "/oauth2/v2.0/authorize",
"scopes": "offline_access Files.ReadWrite.All User.Read",
"redirect_uri": "http://localhost",
"api_uri": "https://graph.microsoft.com/v1.0"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

+310
View File
@@ -0,0 +1,310 @@
<style>
.upyunCon {
height: 428px;
}
.up-place {
height: 62px;
border-bottom: 1px solid #ddd;
}
.up-place .btn {
border-radius: 0;
}
.up-place .place-input {
background-color: #f3f3f3;
border: 1px solid #ccc;
height: 30px;
line-height: 28px;
overflow: hidden;
margin: 1px 0 0 -1px;
width: 340px;
}
.place-input ul {
display: inline-block;
position: relative;
width: auto;
}
.place-input ul li {
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
float: left;
padding-left: 10px;
padding-right: 18px;
}
.place-input ul li a {
height: 28px;
cursor: pointer;
display: inline-block;
}
.upyunlist {
height: 516px;
overflow: auto;
}
.up-bottom {
background-color: #fafafa;
border-top: 1px solid #eee;
bottom: 0;
position: absolute;
width: 100%;
}
.up-use {
line-height: 50px
}
.list-list .cursor span {
line-height: 30px;
}
.btn-title {
margin-top: 1px
}
.tip {
font-size: 10px;
font-style: oblique;
color: green;
}
</style>
<div class="upyunCon">
<div class="up-place pd15">
<button id="backBtn" class="btn btn-default btn-sm glyphicon glyphicon-arrow-left pull-left" title="后退"></button>
<input id="myPath" style="display:none;" type="text" value="">
<div class="place-input pull-left">
<div style="width:1400px;height:28px"><ul></ul></div>
</div>
<button class="refreshBtn btn btn-default btn-sm glyphicon glyphicon-refresh pull-left mr20" title="刷新" style="margin-left:-1px;"></button>
<button class="btn btn-default btn-sm pull-right btn-title" onclick="authApi()">授权</button>
<button class="btn btn-default btn-sm pull-right mr20 btn-title" onclick="createDir()">新建文件夹</button>
</div>
<div class="upyunlist pd15">
<div class="divtable" style="margin-bottom:15px">
<table class="table table-hover">
<thead><tr><th>名称</th><th>大小</th><th>更新时间</th><th class="text-right">操作</th></tr></thead>
<tbody class="list-list"></tbody>
</table>
</div>
</div>
</div>
<style type="text/css">
.check_api {
padding: 20px;
}
.up-place {
height: 62px;
border-bottom: 1px solid #ddd;
}
.up-place .btn {
border-radius: 0;
}
.up-place .place-input {
background-color: #f3f3f3;
border: 1px solid #ccc;
height: 30px;
line-height: 28px;
overflow: hidden;
margin: 1px 0 0 -1px;
width: 340px;
}
.place-input ul {
display: inline-block;
position: relative;
width: auto;
}
.place-input ul li {
background: url("/static/img/ico/ico-ltr.png") no-repeat right center;
float: left;
padding-left: 10px;
padding-right: 18px;
}
.place-input ul li a {
height: 28px;
cursor: pointer;
display: inline-block;
}
.upyunlist {
height: 546px;
overflow: auto;
}
.up-bottom {
background-color: #fafafa;
border-top: 1px solid #eee;
bottom: 0;
position: absolute;
width: 100%;
}
.up-use {
line-height: 50px
}
.list-list .cursor span {
line-height: 30px;
}
.btn-title {
margin-top: 1px
}
.step_item{
clear: both;
}
.step_item .serial_box{
display: inline-block;
clear: both;
}
.step_item .serial{
width: 70px;
height: 30px;
line-height: 30px;
text-align: center;
display: inline-block;
float: left;
}
.step_item .serial span{
display: inline-block;
width: 30px;
height: 30px;
text-align: center;
line-height: 28px;
font-size: 11px;
border-radius: 50%;
color: #20a53a;
border: 2px solid #20a53a;
}
.step_item .serial_title{
margin-bottom: 10px;
font-size: 15px;
line-height: 30px;
color: #666;
}
.step_two_url{
display: inline-block;
overflow: hidden;
width: 380px;
/*text-overflow: ellipsis;*/
white-space: nowrap;
height: 35px;
line-height: 35px;
margin-right: 15px;
border-radius: 2px;
padding: 0 10px;
float: left;
width:360px;
padding-right: 35px;
}
.btn_btlink{
display: inline-block;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
text-align: center;
white-space: nowrap;
vertical-align: middle;
cursor: pointer;
border: 1px solid #20a53a;
color: #fff;
background-color: #20a53a;
margin-right:10px;
}
.btn_btlink:hover{
color: #fff;
background-color: #10952a;
border-color: #398439;
}
.btn_btlink a:visited{
color: #fff;
background-color: #10952a;
border-color: #398439;
}
.view_video{
margin-bottom: 10px;
}
.view_video ul li{
line-height: 20px;
font-size: 13px;
}
.setp_one i{
position: absolute;
top: 8px;
left: 25px;
width: 30px;
height: 30px;
}
.OneDrive{
width:465px;
height:100px;
margin-bottom:10px;
}
</style>
<script type="text/html" id="check_api">
<div class="check_api">
<div class="step_two">
<div class="step_item">
<div class="serial"><span>1</span></div>
<div class="serial_box">
<div class="serial_title">阅读简易操作教程:如何获取Microsoft OneDrive授权?</div>
<div class="serial_conter">
<div class="view_video">
<ul>
<li>1. 点击下面第<div class="serial" style="float: none;width: 45px;"><span>2</span></div>步中的 打开授权链接。<li>
<li>2. 在新窗口页面上登录Microsoft账号。阅读授权权限,并同意。<li>
<li>3. 页面跳转后,将浏览器的地址栏地址复制到第<div class="serial" style="float: none;width: 45px;"><span>3</span></div>步的文本框中。<li>
<li>4. 点击 获取授权,随即完成授权。<li>
</ul>
</div>
<hr/>
</div>
</div>
</div>
<div class="step_item pb15">
<div class="serial"><span>2</span></div>
<div class="serial_box">
<div class="serial_title">操作1:👇打开授权链接,根据网页提示对插件进行授权。</div>
<div class="serial_conter step_two" style="width: 500px;">
<input class="bt-input-text mr5 step_two_url" type="text" disabled>
<span class="ico-copy mr10" data-copy="" style="vertical-align: middle;cursor: pointer;margin-left: -37px;margin-right: 20px;"></span>
<a href="" class="btn_btlink open_btlink" target="_blank" style="padding: 7px 10px;">打开授权链接</a>
</div>
</div>
</div>
<div class="step_item">
<div class="serial"><span>3</span></div>
<div class="serial_box">
<div class="serial_title">操作2:复制回浏览器跳转后的地址:</div>
<div class="serial_conter">
<textarea row="3" placeholder="验证URL地址" class="bt-input-text OneDrive" style="resize: none;"/></br>
<button type="button" class="btn btn-success btn-sm set_auth_btn">获取授权</button>
</div>
</div>
</div>
</div>
</div>
</script>
<!-- <script type="text/javascript" src="/plugins/file?name=msonedrive&f=js/msonedrive.js"></script> -->
<script type="text/javascript">
$.getScript( "/plugins/file?name=msonedrive&f=js/msonedrive.js", function(){
odList('/');
});
</script>
+351
View File
@@ -0,0 +1,351 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import json
# print(sys.platform)
if sys.platform != "darwin":
os.chdir("/www/server/mdserver-web")
sys.path.append(os.getcwd() + "/class/core")
import mw
import db
_ver = sys.version_info
is_py2 = (_ver[0] == 2)
is_py3 = (_ver[0] == 3)
DEBUG = False
if is_py2:
reload(sys)
sys.setdefaultencoding('utf-8')
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'msonedrive'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def in_array(name, arr=[]):
for x in arr:
if name == x:
return True
return False
sys.path.append(getPluginDir() + "/class")
from msodclient import msodclient
msodc = msodclient(getPluginDir(), getServerDir())
msodc.setDebug(False)
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
if t.strip() == '':
tmp = []
else:
t = t.split(':', 1)
tmp[t[0]] = t[1]
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':', 1)
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
return 'start'
def isAuthApi():
cfg = getServerDir() + "/user.conf"
if os.path.exists(cfg):
return True
return False
def getConf():
if not isAuthApi():
sign_in_url, state = msodc.get_sign_in_url()
return mw.returnJson(False, "未授权!", {'auth_url': sign_in_url})
return mw.returnJson(True, "OK")
def setAuthUrl():
args = getArgs()
data = checkArgs(args, ['url'])
if not data[0]:
return data[1]
url = args['url']
try:
if url.startswith("http://"):
url = url.replace("http://", "https://")
token = msodc.get_token_from_authorized_url(authorized_url=url)
msodc.store_token(token)
msodc.store_user()
return mw.returnJson(True, "授权成功!")
except Exception as e:
return mw.returnJson(False, "授权失败2!:" + str(e))
return mw.returnJson(False, "授权失败!:" + str(e))
def clearAuth():
cfg = getServerDir() + "/user.conf"
if os.path.exists(cfg):
os.remove(cfg)
token = getServerDir() + "/token.pickle"
if os.path.exists(token):
os.remove(token)
return mw.returnJson(True, "清空授权成功!")
def getList():
cfg = getServerDir() + "/user.conf"
if not os.path.exists(cfg):
return mw.returnJson(False, "未配置,请点击`授权`", [])
args = getArgs()
data = checkArgs(args, ['path'])
if not data[0]:
return data[1]
try:
flist = msodc.get_list(args['path'])
return mw.returnJson(True, "ok", flist)
except Exception as e:
return mw.returnJson(False, str(e), [])
def createDir():
cfg = getServerDir() + "/user.conf"
if not os.path.exists(cfg):
return mw.returnJson(False, "未配置OneDrive,请点击`授权`", [])
args = getArgs()
data = checkArgs(args, ['path', 'name'])
if not data[0]:
return data[1]
file = args['path'] + "/" + args['name']
isok = msodc.create_dir(file)
if isok:
return mw.returnJson(True, "创建成功")
return mw.returnJson(False, "创建失败")
def deleteDir():
args = getArgs()
data = checkArgs(args, ['dir_name', 'path'])
if not data[0]:
return data[1]
file = args['path'] + "/" + args['dir_name']
file = file.strip('/')
isok = msodc.delete_object(file)
if isok:
return mw.returnJson(True, "删除成功")
return mw.returnJson(False, "文件不为空,删除失败!")
def deleteFile():
args = getArgs()
data = checkArgs(args, ['path', 'filename'])
if not data[0]:
return data[1]
file = args['path'] + "/" + args['filename']
file = file.strip('/')
isok = msodc.delete_object(file)
if isok:
return mw.returnJson(True, "删除成功")
return mw.returnJson(False, "删除失败")
def findPathName(path, filename):
f = os.scandir(path)
l = []
for ff in f:
t = {}
if ff.name.find(filename) > -1:
t['filename'] = path + '/' + ff.name
l.append(t)
return l
def backupAllFunc(stype):
if not isAuthApi():
mw.echoInfo("未授权API,无法使用!!!")
return ''
os.chdir(mw.getRunDir())
backup_dir = mw.getBackupDir()
run_dir = mw.getRunDir()
stype = sys.argv[1]
name = sys.argv[2]
num = sys.argv[3]
prefix_dict = {
"site": "web",
"database": "db",
"path": "path",
}
backups = []
sql = db.Sql()
# print("stype:", stype)
# 提前获取-清理多余备份
if stype == 'site':
pid = sql.table('sites').where('name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('0', pid)).field('id,filename').select()
if stype == 'database':
db_path = mw.getServerDir() + '/mysql'
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
if stype == 'path':
backup_path = backup_dir + '/path'
_name = 'path_{}'.format(os.path.basename(name))
backups = findPathName(backup_path, _name)
# 其他类型关系性数据库(mysql类的)
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
db_path = mw.getServerDir() + '/' + plugin_name
pid = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('id')
backups = sql.table('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
args = stype + " " + name + " " + num
cmd = 'python3 ' + run_dir + '/scripts/backup.py ' + args
if stype.find('database_') > -1:
plugin_name = stype.replace('database_', '')
args = "database " + name + " " + num
cmd = 'python3 ' + run_dir + '/plugins/' + \
plugin_name + '/scripts/backup.py ' + args
if stype == 'path':
name = os.path.basename(name)
# print("cmd:", cmd)
os.system(cmd)
# 开始执行上传信息.
if stype.find('database_') > -1:
bk_name = 'database'
plugin_name = stype.replace('database_', '')
bk_prefix = plugin_name + '/db'
stype = 'database'
else:
bk_prefix = prefix_dict[stype]
bk_name = stype
find_path = backup_dir + '/' + bk_name + '/' + bk_prefix + '_' + name
find_new_file = "ls " + find_path + \
"_* | grep '.gz' | cut -d \ -f 1 | awk 'END {print}'"
# print(find_new_file)
filename = mw.execShell(find_new_file)[0].strip()
if filename == "":
mw.echoInfo("not find upload file!")
return False
mw.echoInfo("准备上传文件 {}".format(filename))
mw.echoStart('开始上传')
msodc.upload_file(filename, stype)
mw.echoEnd('上传成功')
# print(backups)
backups = sorted(backups, key=lambda x: x['filename'], reverse=False)
mw.echoStart('开始删除远程备份')
num = int(num)
sep = len(backups) - num
if sep > -1:
for backup in backups:
fn = os.path.basename(backup['filename'])
msodc.delete_file(fn, stype)
mw.echoInfo("---已清理远程过期备份文件:" + fn)
sep -= 1
if sep < 0:
break
mw.echoEnd('结束删除远程备份')
return ''
def installPreInspection():
return 'ok'
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print(status())
elif func == 'start':
print(start())
elif func == 'stop':
print(stop())
elif func == 'restart':
print(restart())
elif func == 'reload':
print(reload())
elif func == 'install_pre_inspection':
print(installPreInspection())
elif func == 'conf':
print(getConf())
elif func == 'set_auth_url':
print(setAuthUrl())
elif func == 'clear_auth':
print(clearAuth())
elif func == "get_list":
print(getList())
elif func == "create_dir":
print(createDir())
elif func == "delete_dir":
print(deleteDir())
elif func == 'delete_file':
print(deleteFile())
elif in_array(func, ['site', 'database', 'path']) or func.find('database_') > -1:
print(backupAllFunc(func))
else:
print('error')

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