Compare commits

..
670 Commits
Author SHA1 Message Date
Mr Chen 7589c14f81 Merge pull request #224 from midoks/dev
0.10.1
2022-10-29 23:23:23 +08:00
midoks 4344d774c1 Update config_api.py 2022-10-29 23:21:26 +08:00
midoks 4859792096 Update README.md 2022-10-29 22:00:36 +08:00
midoks e55c40e973 优化文件多选的bug 2022-10-29 21:58:29 +08:00
midoks 103beb62a4 Update files_api.py 2022-10-29 20:59:00 +08:00
midoks 76a34578ad Update index.py 2022-10-29 20:36:37 +08:00
midoks f82fdbf939 Update README.md 2022-10-29 20:19:18 +08:00
midoks 4eaf9eb36c phpmyadmin+路径随机 2022-10-29 20:12:01 +08:00
midoks 9c9f9fc42c 初始化卸载脚本 2022-10-29 16:31:59 +08:00
midoks 8301ad6f62 Update ubuntu.sh 2022-10-29 16:19:53 +08:00
midoks d42fb48749 Update mw.tpl 2022-10-29 16:13:23 +08:00
midoks fa49a3dbeb Update README.md 2022-10-29 15:24:28 +08:00
midoks dd1147c891 Update debian.sh 2022-10-29 14:39:06 +08:00
midoks 67b015a50b up 2022-10-29 13:46:16 +08:00
midoks 57831168a3 debian 9 兼容 2022-10-29 13:35:12 +08:00
midoks f6f7cabddc Update debian.sh 2022-10-29 12:18:07 +08:00
midoks dfec241c3f Update README.md 2022-10-29 11:54:58 +08:00
midoks 8a78dff571 Update ubuntu.sh 2022-10-29 11:38:27 +08:00
midoks a9486d4fbe Update ubuntu.sh 2022-10-29 11:38:08 +08:00
midoks 78d3a091cd openresty增加性能调整功能 2022-10-29 02:46:27 +08:00
midoks 314005e478 Update openresty.js 2022-10-28 19:06:27 +08:00
midoks 55fa911485 Update mysql.js 2022-10-28 17:52:43 +08:00
midoks a72046462c Update index.py 2022-10-28 17:49:30 +08:00
midoks 0b8fe15b65 Update index.py 2022-10-28 16:47:53 +08:00
midoks 34f5d12ad9 mysql 部分操作优化 2022-10-28 14:20:12 +08:00
midoks e88544d290 Update mysql.js 2022-10-28 14:08:56 +08:00
midoks a211746de7 mysql导入功能 2022-10-28 14:08:50 +08:00
midoks c417b02844 Update install.sh 2022-10-27 23:44:40 +08:00
Mr Chen 034aaedf48 Merge pull request #223 from midoks/dev
小优化
2022-10-27 15:51:03 +08:00
midoks af0ec79072 统计一下用户量,让我的开发更有激情 2022-10-27 15:44:42 +08:00
midoks 195ccf409e openresty 默认加入ipv6支持 2022-10-27 14:38:44 +08:00
Mr Chen 7cec26b8a3 Merge pull request #222 from midoks/dev
优化logo
2022-10-26 23:47:01 +08:00
midoks aacb816b11 优化logo 2022-10-26 23:40:48 +08:00
Mr Chen 411798f4bf Merge pull request #221 from midoks/dev
0.10.0
2022-10-26 23:25:55 +08:00
midoks 2179db5f8b 0.10.0 2022-10-26 23:24:33 +08:00
midoks dcced8c0fb Update crontab_api.py 2022-10-26 22:08:29 +08:00
midoks 3e0e42d8a1 优化 2022-10-26 19:41:51 +08:00
midoks e5355d3e2f Update ftp_client.py 2022-10-26 18:56:57 +08:00
midoks 0a22e25611 Update ftp_client.py 2022-10-26 18:49:05 +08:00
midoks 5f7a3e5bf6 Update index.py 2022-10-26 18:43:48 +08:00
midoks 3518548c61 backup ftp 80% 2022-10-26 17:47:40 +08:00
midoks 08c4b0845d Update crontab_api.py 2022-10-26 11:34:52 +08:00
midoks 8f5fae8e79 Update index.py 2022-10-26 02:50:11 +08:00
midoks a151db1c30 Update install.sh 2022-10-26 02:48:08 +08:00
midoks 628c69ed22 Update index.html 2022-10-26 02:48:05 +08:00
midoks 13bcbc0f3e Update soft.js 2022-10-26 02:47:57 +08:00
midoks c94838462c backup_ftp 50% 2022-10-26 02:42:10 +08:00
midoks a147ef6962 Update centos.sh 2022-10-25 22:06:32 +08:00
midoks 4ccda15933 Update ftp.js 2022-10-25 14:11:49 +08:00
midoks 01074c743d Update pure-ftpd.conf 2022-10-25 14:10:46 +08:00
midoks 0871fa1763 up 2022-10-25 13:51:24 +08:00
midoks aade0ccd98 Update install.sh 2022-10-25 12:28:57 +08:00
midoks 4aed2f91de Update ftp.js 2022-10-25 12:28:49 +08:00
midoks d49dd9f2ac Update install.sh 2022-10-25 03:37:48 +08:00
midoks cff29194f4 Revert "安装优化"
This reverts commit ecbfb2500f.
2022-10-25 03:34:00 +08:00
midoks ecbfb2500f 安装优化 2022-10-25 03:20:35 +08:00
midoks 9c43170d4b Update install.sh 2022-10-25 03:11:06 +08:00
midoks 1239a2807f up 2022-10-25 02:53:19 +08:00
midoks 1c0a130b49 up 2022-10-25 01:43:29 +08:00
midoks ffb1eb34e0 waf 0.2.3 2022-10-25 00:41:27 +08:00
midoks 82874d1f7a Update url_white.json 2022-10-24 23:42:26 +08:00
midoks 4e05f29fcd OP防火墙-0.2.3 2022-10-24 23:12:45 +08:00
midoks d5f3b0d442 初始安装 ipv6 优化 2022-10-24 21:55:44 +08:00
midoks 81eec04037 Update mw.tpl 2022-10-24 21:44:34 +08:00
midoks 5a5dc43e17 Update mw.tpl 2022-10-24 21:38:10 +08:00
midoks b4eb2b3192 Update mw.tpl 2022-10-24 21:20:04 +08:00
midoks 2d1c070e1b Update mw.tpl 2022-10-24 21:16:17 +08:00
midoks 81364fdfa3 Update common.lua 2022-10-24 21:12:41 +08:00
midoks 9d0d88d465 Update init.lua 2022-10-24 20:56:18 +08:00
midoks 7e2eef8bbf Update init.lua 2022-10-24 20:54:41 +08:00
midoks 8d1315e5be Update init.lua 2022-10-24 20:39:07 +08:00
midoks fe6a51540e Update init.lua 2022-10-24 20:38:24 +08:00
midoks 6e35683505 Update init.lua 2022-10-24 20:35:39 +08:00
midoks 713c0d1a3c up 2022-10-24 20:18:34 +08:00
midoks 8323e0ec73 up 2022-10-24 20:06:38 +08:00
midoks 6eae94658f up 2022-10-24 19:55:09 +08:00
midoks 07d173d2cf up 2022-10-24 19:11:48 +08:00
midoks 23f2b9efac Update index.py 2022-10-24 15:14:14 +08:00
midoks 9b2ab9276c Update common.lua 2022-10-24 14:53:54 +08:00
midoks 7903e1a286 Update common.lua 2022-10-24 14:53:39 +08:00
midoks 662e05511f Update common.lua 2022-10-24 14:51:58 +08:00
midoks 1f8785acbc Update init.lua 2022-10-24 14:49:20 +08:00
midoks 3eb87cf953 Update init.lua 2022-10-24 11:57:46 +08:00
midoks 124b24885e Update op_waf.js 2022-10-24 11:23:35 +08:00
midoks 2196983455 Update ip_white.json 2022-10-24 11:22:39 +08:00
midoks 80a67c4f58 Update webstats_log.lua 2022-10-24 11:10:23 +08:00
midoks ff06f7ef91 Update webstats_common.lua 2022-10-24 11:06:35 +08:00
midoks b16506c8bc #211 优化
phpmyadmin安全设置处修改端口保存后当前用修改后的端口能打开,一旦停止phpmyadmin后,再重启phpmyadmin端口又变为888,需要手工再次改变
2022-10-23 14:07:18 +08:00
midoks 2d3801dcc0 up 2022-10-23 13:49:08 +08:00
Mr Chen 9b83a2ef79 Merge pull request #216 from midoks/dev
0.9.14
2022-10-23 01:12:02 +08:00
midoks 6aefa3b7dc Update config_api.py 2022-10-23 01:11:20 +08:00
midoks 566fabbf24 Update README.md 2022-10-23 01:08:41 +08:00
midoks ea8aa5102b Update common.lua 2022-10-23 00:41:39 +08:00
midoks b8421d36ae up 2022-10-23 00:37:42 +08:00
midoks 24bd8daca0 Update install.sh 2022-10-22 22:57:04 +08:00
midoks d8047b43fa Update install.sh 2022-10-22 22:49:32 +08:00
midoks 016dde04e7 Update my8.0.cnf 2022-10-22 22:36:33 +08:00
midoks df5d86a883 Update README.md 2022-10-22 22:26:55 +08:00
midoks 84077de5d1 Update common.lua 2022-10-22 22:22:53 +08:00
midoks 04ed4b180a up 2022-10-22 21:58:35 +08:00
midoks f980dba7ed up 2022-10-22 21:36:12 +08:00
midoks f702f70f89 up 2022-10-22 20:25:46 +08:00
midoks a8e6ee052c init 2022-10-22 18:32:11 +08:00
midoks b3d0a36dcd up 2022-10-22 16:29:11 +08:00
midoks 96275303c6 Update index.py 2022-10-22 13:30:08 +08:00
midoks 0337a1bded up 2022-10-22 13:19:35 +08:00
midoks 8bd985fca9 up 2022-10-21 19:53:36 +08:00
midoks b6ef8d1625 up 2022-10-21 19:16:07 +08:00
midoks 3dc695508f up 2022-10-21 19:09:34 +08:00
midoks 0c769b02e5 Update op_waf.js 2022-10-21 17:45:30 +08:00
midoks e289037598 up 2022-10-21 17:34:38 +08:00
midoks 63e6a95553 up 2022-10-21 12:08:43 +08:00
midoks 8e1d95bf82 up 2022-10-21 01:33:35 +08:00
midoks 24fe8b6f5f up 2022-10-21 01:25:57 +08:00
midoks 3d366ee774 up 2022-10-20 23:40:28 +08:00
midoks 0428956141 up 2022-10-20 20:59:15 +08:00
midoks 37747427be up 2022-10-20 17:59:16 +08:00
midoks fb94fb8304 up 2022-10-20 16:31:30 +08:00
midoks 65d07d3934 0.2.2 2022-10-20 14:52:51 +08:00
midoks 5e6ffafeb5 Update install.sh 2022-10-20 14:10:20 +08:00
midoks 572f231fae up 2022-10-20 14:03:17 +08:00
midoks 0328dd21e7 Update webstats_common.lua 2022-10-20 13:20:54 +08:00
midoks 597d171733 Update webstats_common.lua 2022-10-20 13:10:40 +08:00
midoks 745ab9dcd0 Update webstats_common.lua 2022-10-20 12:59:26 +08:00
midoks 30323b031c Update webstats_common.lua 2022-10-20 12:58:41 +08:00
midoks f47e6a47df Update webstats_common.lua 2022-10-20 12:57:20 +08:00
midoks 0eccebd9da Update webstats_common.lua 2022-10-20 12:45:24 +08:00
midoks 0ad5e74fae Update webstats_common.lua 2022-10-20 12:38:54 +08:00
midoks 2640ba97c5 Update webstats_common.lua 2022-10-18 18:03:35 +08:00
midoks e5f440ff02 up 2022-10-18 17:41:29 +08:00
midoks 7bc9c44ec1 Update webstats_log.lua 2022-10-18 16:38:18 +08:00
midoks 9cd74db011 Update webstats_common.lua 2022-10-18 03:14:00 +08:00
midoks 5da8e5a7f6 Update webstats_common.lua 2022-10-18 03:07:12 +08:00
midoks 4da895b8df Update webstats_common.lua 2022-10-18 02:54:31 +08:00
midoks 42eca14168 Update webstats_common.lua 2022-10-18 02:13:07 +08:00
midoks 43a3dfd9bd Update webstats_common.lua 2022-10-18 01:48:18 +08:00
midoks 794eba4186 Update webstats_common.lua 2022-10-18 01:41:26 +08:00
midoks a4f533acba Update webstats_common.lua 2022-10-18 01:20:08 +08:00
midoks adb3c5250c Update webstats_common.lua 2022-10-18 01:08:05 +08:00
midoks e4226fcdd4 Update webstats_log.lua 2022-10-18 00:58:08 +08:00
midoks d3e9353589 up 2022-10-18 00:56:31 +08:00
midoks 757284cdf1 up 2022-10-17 23:48:20 +08:00
midoks 58232e10ab Update index.py 2022-10-17 23:40:44 +08:00
midoks fde211e026 Update webstats_log.lua 2022-10-17 23:30:34 +08:00
midoks c9a527e487 up 2022-10-17 23:29:57 +08:00
midoks c501efdfac up 2022-10-17 21:12:42 +08:00
midoks 80c0bbed71 Update webstats_log.lua 2022-10-17 14:54:53 +08:00
midoks 1fb3c30775 Update webstats_log.lua 2022-10-17 14:29:52 +08:00
midoks 24ab203770 Update webstats_log.lua 2022-10-17 14:08:00 +08:00
midoks bd0242db2f Update webstats_common.lua 2022-10-17 14:03:35 +08:00
midoks 42bf5edd1f Update webstats_common.lua 2022-10-17 13:45:21 +08:00
midoks 7b2a011b6a Update webstats_common.lua 2022-10-17 13:44:35 +08:00
midoks 76e01201a2 Update webstats_common.lua 2022-10-17 13:31:36 +08:00
midoks 16e45cabfc Update webstats_common.lua 2022-10-17 13:30:30 +08:00
midoks c08542ff54 Update webstats_common.lua 2022-10-17 13:23:48 +08:00
midoks 5beb76d0b7 Update webstats_common.lua 2022-10-17 13:07:22 +08:00
midoks f16a7e016e up 2022-10-17 13:06:34 +08:00
midoks eb86ac3ee6 Update webstats_common.lua 2022-10-17 12:17:37 +08:00
midoks 14c2606532 Update webstats_common.lua 2022-10-17 12:12:17 +08:00
midoks 86b8939cb8 Update webstats_common.lua 2022-10-17 12:10:15 +08:00
midoks dd28c1ef56 Update webstats_common.lua 2022-10-17 11:43:37 +08:00
midoks 6b24dfc21e Update webstats_common.lua 2022-10-17 11:36:29 +08:00
midoks dc06573125 Update webstats_common.lua 2022-10-17 03:03:32 +08:00
midoks df35e5a780 Update webstats_common.lua 2022-10-17 02:56:28 +08:00
midoks a678d851a0 Update webstats_common.lua 2022-10-17 02:49:16 +08:00
midoks 6a706651e4 Update webstats_common.lua 2022-10-17 02:45:18 +08:00
midoks 1acdfe4368 Update webstats_common.lua 2022-10-17 02:30:36 +08:00
midoks cae245efca up 2022-10-17 02:04:01 +08:00
midoks 238f1e76d8 Update webstats.conf 2022-10-17 01:09:57 +08:00
midoks f3a754d1ae Update webstats_common.lua 2022-10-17 01:06:50 +08:00
midoks 21aab0573a Update webstats_common.lua 2022-10-17 00:58:20 +08:00
midoks 011949ba85 up 2022-10-17 00:44:04 +08:00
midoks f3e7dd1cc0 Update init_worker.lua 2022-10-15 23:44:53 +08:00
midoks b49d2025eb Update install.sh 2022-10-15 23:38:12 +08:00
midoks 556b0869f2 Update config.json 2022-10-15 23:34:20 +08:00
midoks aad6deeb78 Update init_worker.lua 2022-10-15 23:28:36 +08:00
midoks 64601e42c1 up 2022-10-15 23:16:25 +08:00
midoks 6555d927ea Update common.lua 2022-10-15 21:20:40 +08:00
midoks 444ff40570 up 2022-10-15 19:13:01 +08:00
midoks 7bdcd0ac2b up 2022-10-15 17:38:42 +08:00
midoks 6e6a41e6df Update ngx_demo.sh 2022-10-15 10:03:22 +08:00
midoks feca2a6d33 aa 2022-10-15 03:23:08 +08:00
midoks 5e382e7347 Update init.lua 2022-10-15 03:16:02 +08:00
midoks abc778fb52 up 2022-10-15 02:05:29 +08:00
midoks 6b42d35cd4 up 2022-10-15 00:34:14 +08:00
midoks c74a2c9655 Update common.lua 2022-10-14 23:46:10 +08:00
midoks 01543f951a Update init.lua 2022-10-14 23:45:57 +08:00
midoks d78a5d8f27 Update init.lua 2022-10-14 23:45:43 +08:00
midoks 2a1d759cd2 Update config.json 2022-10-14 23:23:08 +08:00
midoks 43889f83f7 up 2022-10-14 21:41:25 +08:00
midoks 79a0a93959 up 2022-10-14 17:50:26 +08:00
midoks 735cf9b872 up 2022-10-14 12:41:32 +08:00
midoks e7c318e560 Update info.json 2022-10-14 12:18:09 +08:00
midoks 78d03754f6 Update install.sh 2022-10-14 12:09:19 +08:00
midoks 67cc1cac86 Update install.sh 2022-10-14 12:08:14 +08:00
midoks 77ec90980a Update install.sh 2022-10-14 12:06:57 +08:00
midoks d07b2babfd up 2022-10-14 12:05:54 +08:00
midoks 4d9ee94038 up 2022-10-14 11:36:54 +08:00
midoks 61479d5db6 Update init.lua 2022-10-13 22:23:46 +08:00
midoks 897c28034d up 2022-10-13 22:18:57 +08:00
midoks b3fef4c104 up 2022-10-13 21:29:28 +08:00
midoks 48cec8ee47 up 2022-10-13 21:05:06 +08:00
midoks 7c369ef19f up 2022-10-13 21:03:26 +08:00
midoks 1411bb1639 up 2022-10-13 20:43:46 +08:00
midoks be875d9d8c Update soft.js 2022-10-13 17:39:41 +08:00
midoks 746dc7ee4d Update soft.js 2022-10-13 17:34:44 +08:00
midoks ea7ba7d461 软件界面优化 2022-10-13 17:29:41 +08:00
midoks 48ed4156b5 Update common.lua 2022-10-13 17:06:42 +08:00
midoks ca73d0e280 Update common.lua 2022-10-13 17:01:57 +08:00
midoks 8cef43d9a7 Update info.json 2022-10-13 16:51:13 +08:00
midoks 75445774a1 test & op 2022-10-13 16:46:44 +08:00
midoks 9b29f19b96 up 2022-10-13 14:59:49 +08:00
midoks 1e6655e7f9 Update readme.md 2022-10-13 14:46:48 +08:00
midoks 363656e06c up 2022-10-13 14:46:29 +08:00
midoks a1860bc4fc up 2022-10-13 14:21:39 +08:00
midoks f8ce39bc74 up 2022-10-13 11:46:03 +08:00
midoks 969d02ef93 Update ngx_debug.sh 2022-10-13 04:35:23 +08:00
midoks a54410df6e up 2022-10-13 04:18:47 +08:00
midoks 01e388ea45 up 2022-10-13 03:12:44 +08:00
midoks ef75f22a86 Update index.py 2022-10-13 01:38:20 +08:00
midoks 97f6b232fd Update ngx_debug.sh 2022-10-13 01:36:53 +08:00
midoks 2506f5e940 Update install.sh 2022-10-13 01:10:03 +08:00
midoks dcb23ada41 Update ngx_debug.sh 2022-10-13 01:06:32 +08:00
midoks 35e1bf048c Update ngx_debug.sh 2022-10-13 00:58:47 +08:00
midoks a9e24f8eaf Update ngx_debug.sh 2022-10-13 00:58:05 +08:00
midoks 2f4ac74f52 Create ngx_debug.sh 2022-10-13 00:42:51 +08:00
midoks 522122feb6 Update common.lua 2022-10-12 20:37:56 +08:00
midoks a3c677a926 Update common.lua 2022-10-12 19:41:35 +08:00
midoks fd1c52530e Update common.lua 2022-10-12 19:35:59 +08:00
midoks 071c690583 Update linux.conf 2022-10-12 18:04:20 +08:00
midoks 67c9cd0277 up 2022-10-12 17:51:50 +08:00
midoks 61292868ad 统计变为ngx.timer.every执行 2022-10-12 17:18:51 +08:00
midoks 54b2a00b23 Update safe_js.html 2022-10-12 16:56:36 +08:00
midoks af6d377664 Update safe_js.html 2022-10-12 16:47:29 +08:00
midoks 6d55e345b0 Update common.lua 2022-10-12 16:39:55 +08:00
midoks fab4e68d8d Update common.lua 2022-10-12 15:42:48 +08:00
midoks 8864e91f21 Update install.sh 2022-10-12 15:31:42 +08:00
midoks f14ce1b66c Update info.json 2022-10-12 15:29:03 +08:00
midoks 48098efd56 Update safe_js.html 2022-10-12 15:28:09 +08:00
midoks 04eba8e33f Update init.lua 2022-10-12 15:26:38 +08:00
midoks 89cf7ffafc Update init.lua 2022-10-12 15:19:08 +08:00
midoks 47544520e8 Update init.lua 2022-10-12 15:03:51 +08:00
midoks bc1fd9a8af Update init.lua 2022-10-12 14:51:46 +08:00
midoks 27efc7ef6e Update config_api.py 2022-10-12 14:38:45 +08:00
midoks 47ead816c0 Update init.lua 2022-10-12 14:37:43 +08:00
midoks 31d36182c3 Update init.lua 2022-10-12 14:37:11 +08:00
midoks c9a58c7ea5 Update init.lua 2022-10-12 14:36:57 +08:00
midoks a6e59ae37c Update init.lua 2022-10-12 14:36:42 +08:00
midoks 328e1b0ff1 up 2022-10-12 14:30:37 +08:00
midoks f76cc5ceb8 Update init.lua 2022-10-12 13:59:30 +08:00
midoks d6c74c3f7d waf demo 3 2022-10-12 13:49:57 +08:00
midoks 4f932c36e7 up 2022-10-12 10:11:55 +08:00
midoks 0d02d0ebea Update init.lua 2022-10-12 00:53:00 +08:00
midoks 9e207ad4d3 添加 强制安全验证 功能 2022-10-12 00:38:23 +08:00
midoks f6cfe29956 Update debian.sh 2022-10-11 18:03:36 +08:00
midoks e439111761 Update mw.py 2022-10-11 17:47:48 +08:00
midoks e576d0b443 listen.backlog = 4096 设置默认 2022-10-11 17:28:07 +08:00
midoks 02e2c42225 up 2022-10-11 17:10:13 +08:00
midoks 45dec0a3d6 ip 2022-10-11 16:35:44 +08:00
midoks 28e2abc829 demo 2022-10-11 16:26:15 +08:00
midoks d59c82b7c8 Update common.lua 2022-10-11 15:46:04 +08:00
midoks 32b2158795 Update common.lua 2022-10-11 15:45:49 +08:00
midoks 5a37305c73 Update common.lua 2022-10-11 15:45:08 +08:00
midoks c043963e8e Update common.lua 2022-10-11 15:43:10 +08:00
midoks 40d755b44e up 2022-10-11 15:39:13 +08:00
midoks 00aa791205 waf debug3 2022-10-11 15:34:02 +08:00
midoks 431b3646af waf debug2 2022-10-11 15:27:08 +08:00
midoks 910aaa81de waf debug1 2022-10-11 15:22:28 +08:00
Mr Chen c4a844cadb Merge pull request #209 from midoks/dev
0.9.13
2022-10-11 12:47:26 +08:00
midoks a88a281175 0.9.13
0.9.13
2022-10-11 12:46:35 +08:00
midoks f3f3b1c6bd Update init.lua 2022-10-11 12:35:59 +08:00
midoks 4259ac51cb up 2022-10-11 11:41:32 +08:00
midoks 4db1357d3d 更新mysql版本 2022-10-11 09:03:53 +08:00
midoks 15873e0824 Update op_waf.js 2022-10-11 00:40:21 +08:00
midoks dcdb07f76d up 2022-10-11 00:35:13 +08:00
midoks 8b70637479 Update index.py 2022-10-10 23:28:36 +08:00
midoks c77085fea4 Update index.py 2022-10-10 23:27:20 +08:00
midoks a265f3d0d5 Update index.py 2022-10-10 23:24:54 +08:00
midoks 7ea486cd1d Update index.py 2022-10-10 23:22:43 +08:00
midoks 0e31e87e28 Update index.py 2022-10-10 23:22:04 +08:00
midoks 8c621c892e Update index.py 2022-10-10 23:16:59 +08:00
midoks 32bcae603c Update index.py 2022-10-10 23:16:48 +08:00
midoks 98ec21446d Update index.py 2022-10-10 22:41:36 +08:00
midoks 0ee3682502 Update redis.service.tpl 2022-10-10 22:11:51 +08:00
midoks c609d1a012 Update redis.service.tpl 2022-10-10 22:05:55 +08:00
midoks 27b1a78879 up 2022-10-10 22:03:21 +08:00
midoks 773de840a5 Update redis.js 2022-10-10 21:55:00 +08:00
midoks 91d6ff3c54 Update index.py 2022-10-10 21:52:11 +08:00
midoks 03376bd42d Update redis.conf 2022-10-10 21:50:04 +08:00
midoks 036c5114c2 Update index.py 2022-10-10 21:35:51 +08:00
midoks a772e70fde Update index.py 2022-10-10 21:33:20 +08:00
midoks 53055bbdef Update index.py 2022-10-10 21:31:43 +08:00
midoks f81d598fcf Update index.py 2022-10-10 21:13:44 +08:00
midoks 3530e83bb9 up 2022-10-10 21:09:35 +08:00
midoks 1271b2f637 Update index.py 2022-10-10 21:00:30 +08:00
midoks 2dc6bc7753 Update index.py 2022-10-10 20:58:45 +08:00
midoks e52d9e3ea3 Update index.py 2022-10-10 20:55:45 +08:00
midoks d8a570e55e Update index.html 2022-10-10 20:46:07 +08:00
midoks f4ceaf667b php-yum更新 2022-10-10 20:43:48 +08:00
midoks 958ba16b85 Update index.html 2022-10-10 20:28:44 +08:00
midoks 73039777bb Update index.py 2022-10-10 20:06:00 +08:00
midoks 864e4c910c PHP添加会话管理功能 2022-10-10 19:54:23 +08:00
midoks 4da57405af Update init.lua 2022-10-10 13:01:27 +08:00
midoks dff638571a Update init.lua 2022-10-10 12:45:31 +08:00
midoks c7d9ec51cc up 2022-10-10 12:36:42 +08:00
midoks 501c575f73 up 2022-10-10 12:13:45 +08:00
midoks 0fd966ca65 up 2022-10-10 02:14:31 +08:00
midoks 172dde2794 Update mariadb.js 2022-10-09 23:26:50 +08:00
midoks 78fdc80652 优化mysql进入phpmyadmin 2022-10-09 23:24:47 +08:00
midoks 01b8c9b8ff Update init.lua 2022-10-09 22:47:28 +08:00
midoks b840086d4d op防火墙更新1 2022-10-09 21:29:40 +08:00
midoks 4c73f13f2d up 2022-10-09 11:36:57 +08:00
midoks f31c1aae96 up 2022-10-09 10:39:46 +08:00
midoks 5c24a831db Update index.py 2022-10-09 02:04:17 +08:00
midoks 91d07eebad Update install.sh 2022-10-09 01:59:17 +08:00
midoks 3b51ef2434 up 2022-10-09 01:49:17 +08:00
midoks 31c5e42b09 Update index.html 2022-10-09 01:38:15 +08:00
midoks b8b3a237ef up 2022-10-09 01:37:14 +08:00
midoks 5cb2aefbbc up 2022-10-09 01:25:53 +08:00
midoks 19173af3e2 Update logs_backup.py 2022-10-09 00:31:15 +08:00
midoks 3dc493108b Update mw.tpl 2022-10-09 00:30:03 +08:00
midoks 55af62000b Update logs_backup.py 2022-10-09 00:26:28 +08:00
midoks a1c8c48761 Update index.js 2022-10-08 22:45:44 +08:00
midoks 8c3ec0a103 Update index.js 2022-10-08 22:40:23 +08:00
midoks 5cbde31105 Update tool_task.py 2022-10-08 18:15:57 +08:00
midoks 04dd94032e Update tool_task.py 2022-10-08 18:12:45 +08:00
midoks 8a11195b0d Update tool_task.py 2022-10-08 18:08:38 +08:00
midoks 1eb76baae7 改变弹框方式 2022-10-08 16:05:24 +08:00
midoks 2669d6f021 Update init.lua 2022-10-08 15:21:17 +08:00
midoks 6f13a03a2c Update config_api.py 2022-10-08 14:24:58 +08:00
Mr Chen 9c97e1c41c Merge pull request #205 from midoks/dev
0.9.12
2022-10-08 14:21:46 +08:00
midoks 37245ca1e8 0.9.12
* 日志清理插件优化。
* 计划任务显示完整。
* 加入gitea插件。
* 融合mw-cli命令。
* 加快php编译速度。
* swap加上调整功能。
* 其他细节优化。
2022-10-08 14:20:47 +08:00
midoks f706a8a2ea up 2022-10-08 14:03:01 +08:00
midoks e6af6b2062 up 2022-10-07 21:29:00 +08:00
midoks f5b056c965 init 2022-10-07 01:00:02 +08:00
midoks 8c768e8a04 Create tool_task.py 2022-10-07 00:47:26 +08:00
midoks 1d6f4feccb Update soft.js 2022-10-07 00:46:32 +08:00
midoks 49c32dc9c1 Update index.py 2022-10-06 17:52:25 +08:00
midoks 17a865c45d Update install.sh 2022-10-06 17:28:37 +08:00
midoks 0090681ab2 Update index.py 2022-10-06 17:25:15 +08:00
midoks 4d3a6c27f7 up 2022-10-06 17:19:36 +08:00
midoks abf39428fc Update index.py 2022-10-06 17:08:46 +08:00
midoks ec11904959 up 2022-10-06 17:07:26 +08:00
midoks d18f16a2b8 up 2022-10-06 15:32:30 +08:00
midoks 7fbe421b0c 加快php编译速度 2022-10-06 14:16:46 +08:00
midoks 81c7929240 Update install.sh 2022-10-06 14:09:46 +08:00
midoks 76c655872b Update install.sh 2022-10-06 14:09:22 +08:00
midoks 7b09776392 Update install.sh 2022-10-06 14:08:52 +08:00
midoks 0b28077e08 up 2022-10-06 14:07:10 +08:00
midoks ccc00e8b5d 更新版本 2022-10-06 13:40:52 +08:00
midoks 202e04c62d Update install.sh 2022-10-06 13:30:50 +08:00
midoks 01cd35305e Update ubuntu.sh 2022-10-06 13:10:44 +08:00
midoks 2f0d7d1d07 融合mw-cli结束2 2022-10-06 11:22:42 +08:00
midoks 714af23627 融合mw-cli结束 2022-10-06 11:13:09 +08:00
midoks 0a9eb721c6 Delete mw-cli 2022-10-06 11:12:18 +08:00
midoks 5e71c20e2a up 2022-10-06 11:12:01 +08:00
midoks 3c24d9f9a9 Update mw.tpl 2022-10-06 09:32:46 +08:00
midoks 78bdcb79c8 Update index.py 2022-10-05 20:51:38 +08:00
midoks aaf3389460 Update index.py 2022-10-05 20:50:39 +08:00
midoks 9f2cb58812 Update index.py 2022-10-05 20:50:31 +08:00
midoks c6099fb7ce Update gitea.service.tpl 2022-10-05 20:45:01 +08:00
midoks 3fb4d88c4a Update gitea.service.tpl 2022-10-05 20:44:43 +08:00
midoks f90fec182c Update install.sh 2022-10-05 20:39:55 +08:00
midoks ba86217a1a Update mw.py 2022-10-05 20:37:02 +08:00
midoks 9a7bcdc1c4 up 2022-10-05 20:34:43 +08:00
midoks 43b1f5ed86 Update gitea.service.tpl 2022-10-05 20:08:41 +08:00
midoks 68ca194c2d Update gitea.service.tpl 2022-10-05 20:05:27 +08:00
midoks 061eaabe79 Update gitea.service.tpl 2022-10-05 19:50:08 +08:00
midoks 420e830ed9 Update crontab_api.py 2022-10-05 17:52:09 +08:00
midoks 8e9cba6646 Update phplib.conf 2022-10-05 14:06:20 +08:00
midoks e0c183c1ac 加入gitea 2022-10-03 12:27:44 +08:00
midoks 18c59da28d Update crontab.js 2022-10-02 15:33:14 +08:00
midoks 71f2d66966 计划任务 显示完整 2022-10-02 15:23:29 +08:00
midoks abd6cdd738 日志清理 插件优化 2022-10-02 15:05:13 +08:00
midoks dd7b1707c3 Update README.md 2022-10-02 09:33:21 +08:00
Mr Chen 1282babb06 Merge pull request #202 from midoks/dev
0.9.11
2022-10-02 09:27:12 +08:00
midoks 71770ec406 0.9.11 2022-10-02 09:25:33 +08:00
midoks f36495f0fd Update app.sh 2022-10-02 02:04:29 +08:00
midoks 1cc4813c52 up 2022-10-01 20:38:28 +08:00
midoks 2ae74d6199 up 2022-10-01 20:14:28 +08:00
midoks 92d83bb82d Update index.py 2022-10-01 20:09:32 +08:00
midoks f14d55fcc6 Update index.py 2022-10-01 20:09:11 +08:00
midoks 062de09b3b Update app.sh 2022-10-01 19:53:11 +08:00
midoks 5cbd53a667 Update mw.tpl 2022-10-01 19:49:00 +08:00
midoks cf645d1f20 Update mw.tpl 2022-10-01 19:45:45 +08:00
midoks 5b8cf7bb0a #201 2022-10-01 18:57:15 +08:00
midoks f5161bca66 随机端口-WEB面板 2022-10-01 17:58:51 +08:00
midoks 5934be02bd Update setting.py 2022-10-01 16:56:18 +08:00
midoks 9e9f10b06f 端口随机 2022-10-01 16:41:55 +08:00
midoks 0fafeabcf0 up 2022-09-30 16:13:49 +08:00
midoks f98e4db019 Update index.py 2022-09-29 23:07:12 +08:00
midoks ec00e9d17e Update index.py 2022-09-29 23:06:53 +08:00
midoks b236bd85c9 up 2022-09-29 22:21:12 +08:00
midoks 40a8620745 Update task.py 2022-09-29 18:56:20 +08:00
midoks 0307828a82 Update index.py 2022-09-28 23:20:38 +08:00
midoks e7d2eddc20 Update install.sh 2022-09-28 19:49:35 +08:00
midoks 8c41b4c3fa Update install.sh 2022-09-28 19:46:22 +08:00
midoks 3ea67beea9 Update install.sh 2022-09-28 19:46:13 +08:00
midoks a346da07ad Update install.sh 2022-09-28 19:45:52 +08:00
midoks 067ee597a7 Update index.py 2022-09-28 19:15:58 +08:00
midoks aac7704208 Update index.py 2022-09-28 19:15:34 +08:00
midoks 3a10aa7809 Update index.py 2022-09-28 19:12:50 +08:00
midoks 1b4582574c Update imail.service.tpl 2022-09-28 19:10:41 +08:00
midoks 51b8738cbc Update index.py 2022-09-28 19:10:22 +08:00
midoks 0dd3c1844e Update index.py 2022-09-28 19:09:46 +08:00
midoks 0dabfdacbd Update imail.tpl 2022-09-28 19:08:21 +08:00
midoks d0166f03bb Update info.json 2022-09-28 19:04:09 +08:00
midoks b102d4dd1f up 2022-09-28 19:02:07 +08:00
midoks 576f553317 Update index.html 2022-09-26 21:44:58 +08:00
midoks 31a0903514 Update public.js 2022-09-26 21:15:26 +08:00
midoks 796c19b5dc Update install.sh 2022-09-26 21:00:52 +08:00
midoks b7902ae2d0 Update install.sh 2022-09-26 21:00:07 +08:00
midoks 7deaf2822a Update index.py 2022-09-26 20:57:37 +08:00
midoks 7e78c2dac4 up 2022-09-26 20:57:26 +08:00
midoks f341c80fbe up imail 2022-09-26 20:51:23 +08:00
midoks b593cc4708 init 2022-09-26 17:04:32 +08:00
midoks 7a8c83ee90 Update index.py 2022-09-25 18:54:47 +08:00
midoks 8c410b272d Update index.py 2022-09-25 17:59:16 +08:00
midoks ecacb44df8 Update index.py 2022-09-25 13:54:48 +08:00
midoks dcfaa1a6c9 Update index.py 2022-09-25 13:52:37 +08:00
midoks c51e50f815 Update index.py 2022-09-25 13:52:21 +08:00
midoks 84b0fbc8ef Update index.py 2022-09-25 13:41:52 +08:00
midoks 4d83c44a73 Update index.py 2022-09-25 13:11:28 +08:00
midoks 4d82835658 mysql 初始化 删除冗余账户 2022-09-25 13:09:19 +08:00
midoks cf863662e0 Update mw.py 2022-09-23 17:09:44 +08:00
midoks 4a66b76963 Update mw.py 2022-09-23 16:54:38 +08:00
midoks 0da43b6ccb 调整接口 2022-09-23 16:10:24 +08:00
midoks c2ad19a4de 后台解压测试 2022-09-22 09:50:18 +08:00
midoks db6538b57c 网站同步优化 2022-09-22 00:27:28 +08:00
Mr Chen 535f6ddc77 Merge pull request #199 from midoks/dev
0.9.10
2022-09-21 23:11:44 +08:00
midoks aa3950ccfe 0.9.10 2022-09-21 23:10:18 +08:00
midoks 8a81f8bb83 Update site_api.py 2022-09-21 17:54:32 +08:00
midoks 55d987c0bd 修复批量添加 2022-09-21 17:42:32 +08:00
midoks 416e9e7cda 如果目录存在,就不初始化 2022-09-21 17:30:59 +08:00
midoks eedaef7eec Update site_api.py 2022-09-21 17:06:19 +08:00
midoks 3265deed3d Update site_api.py 2022-09-21 17:01:41 +08:00
midoks 1c7db0e2ec 优化open_basedir配置2 2022-09-21 16:51:42 +08:00
midoks 7872891797 Update site.js 2022-09-21 16:17:11 +08:00
midoks 8b074090a7 前端配置 2022-09-21 15:37:00 +08:00
midoks 50f198e2d3 优化open_basedir配置 2022-09-21 15:12:10 +08:00
midoks 07e017c9a7 Update lib.sh 2022-09-20 17:46:01 +08:00
midoks ca0aed7240 up 2022-09-20 17:17:47 +08:00
midoks 0126bcb68c Update info.json 2022-09-20 17:14:38 +08:00
midoks 7c37df5dec Update all_test.sh 2022-09-20 17:12:06 +08:00
midoks 33bc6e19e7 up 2022-09-20 17:10:09 +08:00
midoks 35d42a5603 up 2022-09-20 16:32:11 +08:00
midoks 8a79beab89 up 2022-09-20 14:40:45 +08:00
midoks cafff1d522 up 2022-09-20 14:29:46 +08:00
midoks e266d85c91 ip 2022-09-20 12:10:27 +08:00
midoks e873ea8639 Update install.sh 2022-09-20 12:01:02 +08:00
midoks 0cdc23a096 Update install.sh 2022-09-20 11:55:32 +08:00
midoks 2c0231155d 优化 日志读取 2022-09-20 11:30:04 +08:00
midoks 5583db0c70 Update crontab_api.py 2022-09-20 00:24:40 +08:00
midoks 2eeef4d8bd Update mw.py 2022-09-20 00:22:11 +08:00
midoks 5a93b07968 加入开发模式开关 2022-09-19 20:47:12 +08:00
midoks b5195ba685 mail 开发阶段 2022-09-19 20:07:34 +08:00
midoks 4c05747942 移动到:https://github.com/mw-plugin/mail
稳定后,再合并。
2022-09-19 20:05:05 +08:00
midoks 3722f57347 up 2022-09-19 16:16:25 +08:00
midoks b7a3c32d3f ip 2022-09-19 15:01:17 +08:00
midoks 6c0cb42e35 优化 urllib + header 2022-09-19 14:34:47 +08:00
midoks a84e7a16a3 Update index.html 2022-09-19 14:13:18 +08:00
midoks fab1cb1bbe Update install.sh 2022-09-19 13:41:20 +08:00
midoks b46d7c1dee Update mail.js 2022-09-19 13:31:55 +08:00
midoks 8f4dda2d65 up 2022-09-19 11:25:43 +08:00
midoks e21d17e342 up 2022-09-18 21:16:22 +08:00
midoks 87eab46ed6 Update index.py 2022-09-18 20:37:10 +08:00
midoks e0ebed3080 up 2022-09-18 20:00:23 +08:00
midoks 372dbc8995 mail 添加域名 2022-09-18 00:05:45 +08:00
midoks 33faf1e54c Update index.html 2022-09-17 22:39:42 +08:00
midoks 47f67275d5 up 2022-09-17 21:09:53 +08:00
midoks e45ebc5f11 Update index.py 2022-09-16 13:47:57 +08:00
midoks 9ee570e3bb Update config_api.py 2022-09-16 12:15:39 +08:00
midoks cc80ec7839 Update index.js 2022-09-16 12:14:07 +08:00
midoks e7174a2111 Update index.js 2022-09-16 12:13:34 +08:00
midoks ef6adfd82d Update index.js 2022-09-16 12:11:09 +08:00
midoks daf6c9bff8 优化 2022-09-16 12:05:50 +08:00
midoks 9f02092788 Update system_api.py 2022-09-16 11:52:20 +08:00
midoks b314ebeed3 cpu tips 优化
gogs 统计优化
2022-09-16 11:49:20 +08:00
midoks 38f8fe9a38 画丿 2022-09-15 17:59:37 +08:00
midoks c0e1512195 init 2022-09-15 00:16:08 +08:00
midoks b616854baa redis 添加性能调整功能 2022-09-14 20:50:32 +08:00
midoks 1ad9546ae4 Update install.sh 2022-09-13 23:48:01 +08:00
midoks fb3aac37ec Update install.sh 2022-09-13 23:42:54 +08:00
midoks 598f964e91 Update install.sh 2022-09-13 23:41:34 +08:00
midoks d9e46f1065 Update install.sh 2022-09-13 23:34:37 +08:00
midoks 565d011191 Update index.html 2022-09-13 22:04:18 +08:00
midoks 6ae6e5fafc Update info.json 2022-09-13 21:53:30 +08:00
midoks eb1c0efda1 Update gettext.sh 2022-09-13 21:06:11 +08:00
midoks 98bc816b21 up 2022-09-13 21:02:55 +08:00
Mr Chen 85735287c3 Merge pull request #195 from midoks/dev
Update README.md
2022-09-12 10:06:43 +08:00
midoks d59022ae44 Update README.md 2022-09-12 10:02:24 +08:00
Mr Chen 70a17af9d8 Merge pull request #192 from midoks/dev
优化OP反代面板之后显示错误
2022-09-11 20:07:48 +08:00
midoks 09feeb11d2 zhu 2022-09-11 20:00:10 +08:00
midoks d95e1e68c4 优化OP反代面板之后显示错误的错误 2022-09-11 19:58:15 +08:00
Mr Chen 6e484babe9 Merge pull request #191 from h88782481/dev
Update index.py
2022-09-11 19:00:37 +08:00
JiRan d37ff296f6 Update index.py 2022-09-11 18:59:16 +08:00
Mr Chen f95d25f080 Merge pull request #190 from h88782481/dev
Dev
2022-09-11 18:53:16 +08:00
JiRan fd35db3dd8 Update index.py 2022-09-11 18:45:44 +08:00
JiRan f22e10a496 Update mw.py 2022-09-11 18:40:41 +08:00
midoks 52f80ec3b7 Update debian.sh 2022-09-11 17:32:16 +08:00
Mr Chen 41fd11c0f4 Merge pull request #187 from midoks/dev
fix cmd.md
2022-09-10 11:08:36 +08:00
midoks f8a5e7dab5 Update cmd.md 2022-09-10 11:07:33 +08:00
Mr Chen 4b71d6b3d7 Merge pull request #185 from midoks/dev
0.9.9
2022-09-09 21:31:36 +08:00
midoks becb7f8c7f Update README.md 2022-09-09 21:21:33 +08:00
midoks 3da7b57242 Update README.md 2022-09-08 23:39:33 +08:00
midoks 42e8057356 Update memcached.sh 2022-09-08 21:49:03 +08:00
midoks e082baabe8 PHP加入igbinary扩展 2022-09-08 21:16:59 +08:00
midoks 74d565c99a 0.9.9 2022-09-08 15:40:47 +08:00
midoks 750efbf430 Update xhprof.sh 2022-09-07 14:39:43 +08:00
midoks 68112ba978 Update install.sh 2022-09-07 10:16:03 +08:00
midoks e994375fc8 Update cloudfare_real_ip.conf 2022-09-07 09:54:20 +08:00
midoks 998f677ee7 Create cloudfare_real_ip.conf 2022-09-07 09:06:15 +08:00
midoks 8b1b50938d Update README.md 2022-09-06 22:41:11 +08:00
midoks 3dbece0b5e Update README.md 2022-09-06 22:19:57 +08:00
midoks e9f1e522de Update README.md 2022-09-06 22:19:21 +08:00
midoks 8a815159c1 Update README.md 2022-09-06 22:08:42 +08:00
midoks c8af676d6f up 2022-09-06 22:07:12 +08:00
midoks 3bee84a52f Update README.md 2022-09-06 21:54:07 +08:00
midoks 82828aacf6 优化gogs插件 2022-09-06 17:45:56 +08:00
midoks e4de3cff61 更新图标 2022-09-06 15:35:03 +08:00
midoks 4ed7f5d7fd Update index.py 2022-09-05 23:06:31 +08:00
midoks 7b956c73e4 Update index.py 2022-09-05 22:58:53 +08:00
midoks 8535dd2306 up 2022-09-05 22:56:38 +08:00
midoks e13df3ae58 Update index.py 2022-09-05 22:49:57 +08:00
midoks 44fa68f52d Update index.py 2022-09-05 22:48:25 +08:00
midoks d72abb1e30 修复php-yum无法更改性能调整 2022-09-05 22:33:30 +08:00
midoks aad4343a59 Update whmcs.conf 2022-09-05 11:36:00 +08:00
midoks 6b5717b04f 优化的配置模板 2022-09-04 18:16:04 +08:00
midoks 655946a467 Update install.sh 2022-09-04 17:18:45 +08:00
midoks 80f3d98162 Update update_dev.sh 2022-09-04 17:07:51 +08:00
midoks d73be680e2 Update README.md 2022-09-04 17:04:48 +08:00
midoks ad9595b3b2 Update update_dev.sh 2022-09-04 17:01:47 +08:00
midoks 8a337fcfd6 Update site_api.py 2022-09-03 23:37:17 +08:00
midoks 38b1dba395 卸载是停止 2022-09-03 23:08:41 +08:00
midoks 7195de0418 up 2022-09-03 21:31:22 +08:00
midoks 20cb30ba51 Update update_dev.sh 2022-09-03 21:24:26 +08:00
midoks 2a7c96b0f5 Update install_dev.sh 2022-09-03 21:24:08 +08:00
midoks 8503e6ebe9 增加 amazon 2022-09-03 21:21:12 +08:00
midoks be2c2a2436 Update phplib.conf 2022-09-03 19:00:18 +08:00
midoks 8a247c93d4 Update memcached.sh 2022-09-03 17:54:55 +08:00
midoks b4cdc7fc2d Update memcached.sh 2022-09-03 17:43:23 +08:00
midoks cc3f1ed01a Update README.md 2022-09-03 15:53:22 +08:00
midoks 4db4284362 Update README.md 2022-09-03 15:51:03 +08:00
midoks 3c2e517c61 Update README.md 2022-09-03 14:17:01 +08:00
midoks 1d712d1f84 Update README.md 2022-09-03 14:08:17 +08:00
midoks f1e1e3c82c Update README.md 2022-09-03 13:43:18 +08:00
midoks 8e587cf055 Update install.sh 2022-09-02 23:16:41 +08:00
Mr Chen 277b95f74b Merge pull request #183 from itcbx/dev
修复rsyncd在debian或ubuntu下安装失败的bug.
2022-09-01 19:41:19 +08:00
iOSHackers b89b180ee9 修复rsyncd在debian或ubuntu下安装失败的bug. 2022-09-01 19:21:52 +08:00
midoks 3e89c35111 Update phplib.conf 2022-08-31 23:22:34 +08:00
midoks 52f7939b06 Update phplib.conf 2022-08-31 23:21:39 +08:00
midoks 13d038e855 mysql,mariadb删除,不再支持程序删除。 2022-08-31 22:00:23 +08:00
midoks 325046d3c2 Update index.py 2022-08-31 21:53:59 +08:00
midoks 8cb3b578e0 Update index.py 2022-08-31 21:52:19 +08:00
midoks 3b5a5206fc Update index.py 2022-08-31 21:50:03 +08:00
Mr Chen 1517d8d2d7 Merge pull request #181 from midoks/dev
0.9.7
2022-08-29 13:15:36 +08:00
midoks ba55477492 up 2022-08-29 13:14:41 +08:00
midoks e363833437 Update install.sh 2022-08-29 13:12:37 +08:00
midoks 6ec51baedb Update install.sh 2022-08-29 12:48:28 +08:00
midoks 0fdf62499b Update index.py 2022-08-29 12:22:59 +08:00
midoks 1498e23b48 Update haproxy.js 2022-08-29 12:14:13 +08:00
midoks 106ce839d8 Update index.html 2022-08-29 12:13:40 +08:00
midoks eed561dadc Update haproxy.conf 2022-08-29 12:09:13 +08:00
midoks c97ec1cbba up 2022-08-29 12:08:02 +08:00
midoks 29802d8066 up 2022-08-29 11:32:29 +08:00
midoks 9a51bc4b4e Update index.py 2022-08-29 00:35:46 +08:00
midoks 082f697706 Update index.py 2022-08-29 00:34:58 +08:00
midoks 6e026f2998 Update install.sh 2022-08-28 23:35:31 +08:00
midoks c647f0c02d Update haproxy.tpl 2022-08-28 23:26:02 +08:00
midoks da99297253 Update haproxy.service.tpl 2022-08-28 23:25:31 +08:00
midoks 4ab982827e 优化 2022-08-28 23:02:37 +08:00
midoks d3a4db511a haproxy init 2022-08-28 22:50:17 +08:00
midoks fa9e4e3b06 Update index.py 2022-08-24 15:31:44 +08:00
midoks e7cd941f0f Update index.py 2022-08-24 15:16:59 +08:00
midoks c641606ecd #175
统计流量区分类型
2022-08-23 11:13:44 +08:00
Mr Chen 021a360462 Merge pull request #177 from midoks/dev
优化getLocalIp方法
2022-08-23 07:37:59 +08:00
midoks 9104280ff1 不再全部测试 2022-08-23 07:37:11 +08:00
midoks 0ea0f2d13d 优化getLocalIp方法 2022-08-23 07:35:34 +08:00
Mr Chen 289e251480 Merge pull request #176 from midoks/dev
php74版本退回
2022-08-23 07:03:14 +08:00
midoks ce421cfb89 Update install.sh 2022-08-23 06:52:54 +08:00
Mr Chen bec41f2c63 Merge pull request #174 from midoks/dev
代码改变版本号
2022-08-22 13:28:50 +08:00
midoks 3a34974ec9 Update config_api.py 2022-08-22 13:26:48 +08:00
midoks a7c9fff283 up 2022-08-22 11:55:30 +08:00
midoks c36cca61a1 Update centos.sh 2022-08-22 11:52:05 +08:00
Mr Chen 42edf12d01 Merge pull request #172 from midoks/dev
0.9.6
2022-08-22 11:44:39 +08:00
midoks d6799e89c4 0.9.6 2022-08-22 11:43:11 +08:00
midoks 4b4006c9da Update index.html 2022-08-21 12:23:39 +08:00
midoks 33bb042b41 up 2022-08-17 19:16:51 +08:00
midoks be2e91b9ce mariadb up 2022-08-17 19:14:36 +08:00
midoks db424f8912 mariadb up 2022-08-17 19:12:12 +08:00
midoks bfca2e313a Update rsyncd.js 2022-08-17 12:01:28 +08:00
midoks 1de51747e6 Update supervisor.js 2022-08-17 09:28:25 +08:00
midoks 8a623b490b supervisor增加错误查看 2022-08-17 09:25:08 +08:00
midoks b5b8ef7e46 Update .gitignore 2022-08-16 22:08:07 +08:00
midoks daa561b6c4 Update README.md 2022-08-16 18:42:03 +08:00
midoks 9bc30db1ad Update README.md 2022-08-16 18:38:35 +08:00
midoks 1a9d506d61 Update README.md 2022-08-16 18:35:29 +08:00
midoks 62b5d812e2 Update install.sh 2022-08-16 17:29:10 +08:00
midoks 433c9ab5ea Update files_api.py 2022-08-16 11:51:46 +08:00
midoks a7a6976204 增加插件[备份]功能。
1. json: "hook":["backup"]   -- 备份钩子开启
2.crontab的执行周期添加优化。
2022-08-16 04:45:21 +08:00
Mr Chen a1d8523dd9 Merge pull request #165 from midoks/dev
0.9.5
2022-08-15 19:39:36 +08:00
midoks 295e456a20 Update README.md 2022-08-15 19:38:32 +08:00
midoks 453cb4cf14 0.9.5 2022-08-15 19:37:59 +08:00
midoks 56a1ffed2a Update index.py 2022-08-15 16:14:46 +08:00
midoks b94f302fbe gogs 提示更人性 2022-08-15 13:41:01 +08:00
midoks 3a278f4cc6 Update system_api.py 2022-08-15 13:04:52 +08:00
midoks 67b7f9cf43 Update system_api.py 2022-08-15 13:04:32 +08:00
midoks b3dc24428c Update system_api.py 2022-08-15 12:48:29 +08:00
midoks 233e6dfc0f 密码字符修复2 2022-08-15 00:17:27 +08:00
midoks 07e74a8947 密码字符修复。 2022-08-14 22:52:25 +08:00
midoks 4eed1e8a93 Update index.py 2022-08-14 20:53:15 +08:00
midoks 1b91af6f22 Update install.sh 2022-08-14 20:32:42 +08:00
midoks 9bc824906b Update index.py 2022-08-14 20:16:24 +08:00
midoks 394f345764 Update index.py 2022-08-14 20:13:36 +08:00
midoks a10a11817b Update install.sh 2022-08-14 20:11:36 +08:00
midoks 6b82dd5eca Update index.py 2022-08-14 20:04:44 +08:00
midoks a5d976ad36 Update install.sh 2022-08-14 19:43:49 +08:00
midoks 4bb4746a1b Update redis.sh 2022-08-14 18:08:39 +08:00
midoks 9fad06585f Squashed commit of the following:
commit 0cf35955d8
Merge: f99225f1 7fe6744c
Author: midoks <midoks@163.com>
Date:   Sun Aug 14 15:44:39 2022 +0800

    Merge branch 'master' of github.com:midoks/mdserver-web

commit 7fe6744c09
Merge: cd9b0435 beb085e9
Author: Mr Chen <midoks@users.noreply.github.com>
Date:   Sun Aug 14 15:27:42 2022 +0800

    Merge pull request #163 from WankkoRee/master

    修正`MariaDB 10.8`安装后显示为`MariaDB 10.7`的问题

commit beb085e95c
Author: Wankko Ree <wkr@wkr.moe>
Date:   Sun Aug 14 15:19:55 2022 +0800

    修正`MariaDB 10.8`安装后显示为`MariaDB 10.7`的问题
2022-08-14 15:44:53 +08:00
midoks 50ed66d26a Merge branch 'master' into dev 2022-08-14 15:42:11 +08:00
midoks ed17622a0b MySQL&MariaDB导入修复 2022-08-14 15:35:59 +08:00
midoks b8e993cd04 Update index.py 2022-08-14 15:33:08 +08:00
Mr Chen 7fe6744c09 Merge pull request #163 from WankkoRee/master
修正`MariaDB 10.8`安装后显示为`MariaDB 10.7`的问题
2022-08-14 15:27:42 +08:00
Wankko Ree beb085e95c 修正MariaDB 10.8安装后显示为MariaDB 10.7的问题 2022-08-14 15:20:34 +08:00
midoks 657f408a8b Update system_api.py 2022-08-14 10:43:39 +08:00
midoks 3994f1505e Update system_api.py 2022-08-14 10:18:09 +08:00
midoks 0ecc9307f1 Update site_api.py 2022-08-14 10:17:56 +08:00
midoks 93de3dd3ab Update system_api.py 2022-08-14 00:47:39 +08:00
midoks f99225f172 Update system_api.py 2022-08-14 00:46:44 +08:00
Mr Chen cd9b043525 Merge pull request #161 from midoks/dev
0.9.4[2]
2022-08-13 23:58:03 +08:00
midoks 0e5c59dae2 Update config_api.py 2022-08-13 23:56:52 +08:00
Mr Chen 1a5c7b9a3f Merge pull request #160 from midoks/dev
0.9.4
2022-08-13 23:50:46 +08:00
midoks 2282776020 Update README.md 2022-08-13 23:49:37 +08:00
midoks cd2b07f5d2 0.9.4 2022-08-13 23:28:06 +08:00
midoks a5d4d53883 waf 修复 2022-08-13 22:30:30 +08:00
midoks 9e463cec7a 防止信息泄露 2022-08-13 19:27:49 +08:00
midoks e489bd43b8 phpmyadmin访问优化 2022-08-13 19:14:55 +08:00
midoks 983eb38165 mariadb 用户优化 2022-08-13 18:35:30 +08:00
midoks 677894ca35 Update ubuntu.sh 2022-08-13 18:17:49 +08:00
midoks a302ded8b2 Update debian.sh 2022-08-13 17:35:44 +08:00
midoks 3eeee10de6 Update index.py 2022-08-13 15:16:16 +08:00
midoks 160998ba6e Update phpmyadmin.js 2022-08-13 15:13:41 +08:00
midoks 8ece38c082 phpmyadmin支持mariadb。并默认开启安全验证。 2022-08-13 15:12:04 +08:00
midoks 52d4215a80 Update mw-cli 2022-08-13 14:45:26 +08:00
midoks 029b548af0 Update info.json 2022-08-13 10:44:20 +08:00
midoks 4db10d22a7 修复网站密码设置 2022-08-13 09:42:12 +08:00
midoks 1d3ca158cb Merge branch 'master' into dev 2022-08-13 01:59:16 +08:00
midoks 74e19287e4 Merge branch 'master' into dev 2022-08-13 01:58:24 +08:00
Mr Chen ece8dd8b19 Merge pull request #159 from midoks/midoks-patch-1
Update README.md
2022-08-13 01:58:07 +08:00
Mr Chen d082297b25 Update README.md 2022-08-13 01:57:39 +08:00
Mr Chen 1a1e211107 Merge pull request #158 from midoks/dev
0.9.3
2022-08-13 01:35:11 +08:00
midoks 2d32578b5f Update phplib.conf 2022-08-12 23:09:45 +08:00
midoks e07f0fca9c Update phplib.conf 2022-08-12 23:06:49 +08:00
midoks 80344149da Update README.md 2022-08-12 23:03:58 +08:00
midoks 046abc4cba 移动到mw-plugins 不在和行插件维护。 2022-08-12 23:01:00 +08:00
midoks 588ec43543 Update install.sh 2022-08-12 21:35:48 +08:00
midoks ea8a4baba6 Update info.json 2022-08-12 19:54:00 +08:00
midoks bcf3516f22 Update README.md 2022-08-12 19:53:26 +08:00
midoks 16acda5d60 up 2022-08-12 19:52:26 +08:00
midoks 68b9b95d5c 依赖github,自动更新。 2022-08-12 19:47:41 +08:00
midoks e32c4926ca 更改同步信息 2022-08-12 19:18:51 +08:00
midoks f4bb052776 Update info.json 2022-08-12 18:52:40 +08:00
midoks 3cc92a1eab Update info.json 2022-08-12 17:42:08 +08:00
midoks 24b8b1ee7c Update system_api.py 2022-08-12 17:41:04 +08:00
midoks 1996442b56 Update system_api.py 2022-08-12 17:24:55 +08:00
midoks 529ba08aee Update system_api.py 2022-08-12 17:19:09 +08:00
midoks 701b19e0b6 Update info.json 2022-08-12 16:40:05 +08:00
midoks 06f1b34f52 Update system_api.py 2022-08-12 16:35:49 +08:00
midoks 72c5efcc2f Update system_api.py 2022-08-12 15:29:59 +08:00
midoks ac29bb098b Update install.sh 2022-08-12 12:47:58 +08:00
306 changed files with 13189 additions and 12923 deletions
+5
View File
@@ -0,0 +1,5 @@
# These are supported funding model platforms
github: midoks
custom: https://afdian.net/a/mdserver-web
+2 -2
View File
@@ -5,9 +5,9 @@ name: MW APP MySQL55
on:
push:
branches: [ "master" ]
branches: [ "run_test" ]
pull_request:
branches: [ "master" ]
branches: [ "run_test" ]
permissions:
contents: read
+2 -2
View File
@@ -5,9 +5,9 @@ name: MW APP MySQL56
on:
push:
branches: [ "master" ]
branches: [ "run_test" ]
pull_request:
branches: [ "master" ]
branches: [ "run_test" ]
permissions:
contents: read
+2 -2
View File
@@ -5,9 +5,9 @@ name: MW APP MySQL57
on:
push:
branches: [ "master" ]
branches: [ "run_test" ]
pull_request:
branches: [ "master" ]
branches: [ "run_test" ]
permissions:
contents: read
+2 -2
View File
@@ -5,9 +5,9 @@ name: MW APP MySQL80
on:
push:
branches: [ "master" ]
branches: [ "run_test" ]
pull_request:
branches: [ "master" ]
branches: [ "run_test" ]
permissions:
contents: read
+2 -2
View File
@@ -5,9 +5,9 @@ name: MW APP PHP
on:
push:
branches: [ "master" ]
branches: [ "run_test" ]
pull_request:
branches: [ "master" ]
branches: [ "run_test" ]
permissions:
contents: read
+6 -2
View File
@@ -122,12 +122,14 @@ data/datadir.pl
data/502Task.pl
data/default.pl
data/backup.pl
data/debug.pl
data/default_site.pl
lib/python*
bin
pyvenv.cfg
include
share
pip-selfcheck.json
scripts/mdserver-web
@@ -140,16 +142,18 @@ data/restart.pl
data/ssl.pl
data/edate.pl
data/osname.pl
data/only_netio_counters.pl
data/system.db-journal
data/hook_*.json
plugins/l2tp
plugins/openlitespeed
plugins/gdrive
plugins/mtproxy
plugins/zimg
plugins/bk_demo
plugins/mail
debug.out
+56 -8
View File
@@ -1,4 +1,10 @@
### mdserver-web 0.9.2
<p align="center">
<img alt="logo" src="https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/logo.png" height="140" />
<h3 align="center">mdserver-web</h3>
<p align="center">一款简单Linux面板服务</p>
</p>
### 简介
简单的Linux面板,感谢BT.CN写出如此好的web管理软件。我一看到,就知道这是我一直想要的页面化管理方式。
复制了后台管理界面,按照自己想要的方式写了一版。
@@ -59,8 +65,23 @@ phpMyAdmin[5.2.0]支持MySQL[8.0]
PHP[53-72]支持phpMyAdmin[4.4.15]
PHP[72-81]支持phpMyAdmin[5.2.0]
```
# 特别赞助
- [找资源 - 阿里云盘资源搜索引擎](https://zhaoziyuan.la/)
# AD - VPS推荐 - 🙏
- [ZZZ评测](https://www.zzzvps.com/)
| 服务商 | LOGO | 推广地址 | 优惠码 |
| ------------- |----------|-----------|-------|
| digitalvirt |[![digitalvirt](https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg)](https://digitalvirt.com/aff.php?aff=154) | https://digitalvirt.com/aff.php?aff=154 | 9SYDY7UH0U |
| 搬瓦工 |[![搬瓦工](https://bwh81.net/templates/organicbandwagon/images/logo.png)](https://bwh81.net/aff.php?aff=54161) | https://bwh81.net/aff.php?aff=54161 | BWH3HYATVBJW |
# Docker
- 由[DDSRem](https://github.com/DDSRem)开发维护。
@@ -71,10 +92,16 @@ docker run -itd --name mw-server --privileged=true -p 7200:7200 -p 80:80 -p 443:
```
### 版本更新 0.9.2
### 版本更新 0.10.1
* MySQL添加外部导入功能。
* OpenResty添加性能调整功能。
* 优化ubuntu22.04安装过程。
* Debian9友好,【SSH终端 1.0】无法使用。
* phpMyAdmin优化,需要卸载重装。
* 文件管理解压直接覆盖FIX。
* 优化文件多选的BUG。
* 批量域名添加修复。
* 常用命令说明。
### JSDelivr安装地址
@@ -90,6 +117,12 @@ curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/instal
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/update.sh | bash
```
- 卸载脚本
```
curl -fsSL https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/scripts/uninstall.sh | bash
```
### 备用地址
- 初始安装
@@ -105,6 +138,12 @@ curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/update.sh | bash
```
- 卸载脚本
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/master/scripts/uninstall.sh | bash
```
### 通用软件安装[命令行安装]
@@ -120,16 +159,25 @@ curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/qu
```
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/install_dev.sh | bash
curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/update_dev.sh | bash
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/install_dev.sh | bash
curl -fsSL https://gitee.com/midoks/mdserver-web/raw/master/scripts/update_dev.sh | bash
```
### 捐赠地址 USDT(TRC20)
TVbNgrpeGBGZVm5gTLa21ADP7RpnPFhjya
### 微信赞助
[![截图](/route/static/img/weixin_zz.jpg)](/route/static/img/weixin_zz.jpg)
[![截图](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/weixin_zz.jpg)](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/img/weixin_zz.jpg)
### 无图不真相
[![截图](/route/static/mdw.jpg)](/route/static/mdw.jpg)
[![截图](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/mdw.jpg)](https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/route/static/mdw.jpg)
### Stargazers over time
@@ -139,7 +187,7 @@ curl -fsSL https://raw.githubusercontent.com/midoks/mdserver-web/dev/scripts/up
### 感谢开发赞助
[![digitalvirt](https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg)](https://digitalvirt.com/)
[![digitalvirt](https://digitalvirt.com/templates/BlueWhite/img/logo-dark.svg)](https://digitalvirt.com/aff.php?aff=154)
### 授权许可
+1 -1
View File
@@ -85,7 +85,7 @@ def initInitD():
mw.execShell('mkdir -p /etc/init.d')
# initd
if os.path.exists("/etc/init.d"):
if os.path.exists('/etc/init.d'):
initd_bin = '/etc/init.d/mw'
if not os.path.exists(initd_bin):
import shutil
+16 -3
View File
@@ -15,8 +15,7 @@ from flask import request
class config_api:
# mariadb 优化
__version = '0.9.2'
__version = '0.10.1'
def __init__(self):
pass
@@ -208,6 +207,14 @@ class config_api:
mw.execShell("chown root.root " + filename)
return mw.returnJson(True, '面板已关闭!')
def openDebugApi(self):
filename = 'data/debug.pl'
if os.path.exists(filename):
os.remove(filename)
return mw.returnJson(True, '开发模式关闭!')
mw.writeFile(filename, 'True')
return mw.returnJson(True, '开发模式开启!')
def setIpv6StatusApi(self):
ipv6_file = 'data/ipv6.pl'
if os.path.exists('data/ipv6.pl'):
@@ -317,11 +324,17 @@ class config_api:
data['admin_path'] = mw.readFile(admin_path_file)
ipv6_file = 'data/ipv6.pl'
if os.path.exists('data/ipv6.pl'):
if os.path.exists(ipv6_file):
data['ipv6'] = 'checked'
else:
data['ipv6'] = ''
debug_file = 'data/debug.pl'
if os.path.exists(debug_file):
data['debug'] = 'checked'
else:
data['debug'] = ''
ssl_file = 'data/ssl.pl'
if os.path.exists('data/ssl.pl'):
data['ssl'] = 'checked'
+45 -21
View File
@@ -68,8 +68,8 @@ class crontab_api:
_list[i]['where_hour']), str(_list[i]['where_minute'])))
data.append(tmp)
_ret = {}
_ret['data'] = data
rdata = {}
rdata['data'] = data
count = mw.M('crontab').where('', ()).count()
_page = {}
@@ -78,9 +78,17 @@ class crontab_api:
_page['row'] = psize
_page['tojs'] = "getCronData"
_ret['list'] = mw.getPage(_page)
_ret['p'] = p
return mw.getJson(_ret)
rdata['list'] = mw.getPage(_page)
rdata['p'] = p
# backup hock
bh_file = mw.getPanelDataDir() + "/hook_backup.json"
if os.path.exists(bh_file):
hb_data = mw.readFile(bh_file)
hb_data = json.loads(hb_data)
rdata['backup_hook'] = hb_data
return mw.getJson(rdata)
# 设置计划任务状态
def setCronStatusApi(self):
@@ -167,7 +175,7 @@ class crontab_api:
logFile = mw.getServerDir() + '/cron/' + echo['echo'] + '.log'
if not os.path.exists(logFile):
return mw.returnJson(False, '当前日志为空!')
log = mw.getNumLines(logFile, 500)
log = mw.getLastLine(logFile, 500)
return mw.returnJson(True, log)
def addApi(self):
@@ -295,9 +303,18 @@ class crontab_api:
# 取数据列表
def getDataListApi(self):
stype = request.form.get('type', '')
bak_data = []
if stype == 'sites' or stype == 'databases':
hookPath = mw.getPanelDataDir() + "/hook_backup.json"
if os.path.exists(hookPath):
t = mw.readFile(hookPath)
bak_data = json.loads(t)
if stype == 'databases':
db_list = {}
db_list['orderOpt'] = []
db_list['orderOpt'] = bak_data
path = mw.getServerDir() + '/mysql'
if not os.path.exists(path + '/mysql.db'):
db_list['data'] = []
@@ -307,8 +324,9 @@ class crontab_api:
return mw.getJson(db_list)
data = {}
data['orderOpt'] = bak_data
data['data'] = mw.M(stype).field('name,ps').select()
data['orderOpt'] = []
return mw.getJson(data)
##### ----- start ----- ###
@@ -399,28 +417,34 @@ class crontab_api:
shell = param.sFile
else:
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n"
source_bin_activate = '''
MW_PATH=%s/bin/activate
if [ -f $MW_PATH ];then
source $MW_PATH
fi
''' % (mw.getRunDir(),)
head = head + source_bin_activate + "\n"
log = '.log'
script_dir = mw.getServerDir() + "/mdserver-web/scripts"
wheres = {
'path': head + "python " + script_dir + "/backup.py path " + param['sname'] + " " + str(param['save']),
'site': head + "python " + script_dir + "/backup.py site " + param['sname'] + " " + str(param['save']),
'database': head + "python " + script_dir + "/backup.py database " + param['sname'] + " " + str(param['save']),
'logs': head + "python " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
'path': head + "python3 " + script_dir + "/backup.py path " + param['sname'] + " " + str(param['save']),
'site': head + "python3 " + script_dir + "/backup.py site " + param['sname'] + " " + str(param['save']),
'database': head + "python3 " + script_dir + "/backup.py database " + param['sname'] + " " + str(param['save']),
'logs': head + "python3 " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
'rememory': head + "/bin/bash " + script_dir + '/rememory.sh'
}
if param['backup_to'] != 'localhost':
cfile = mw.getServerDir() + "/mdserver-web/plugin/" + \
param['backup_to'] + "/" + param['backup_to'] + "_main.py"
if not os.path.exists(cfile):
cfile = script_dir + "/backup_" + \
param['backup_to'] + ".py"
cfile = mw.getPluginDir() + "/" + \
param['backup_to'] + "/index.py"
wheres = {
'path': head + "python " + cfile + " path " + param['sname'] + " " + str(param['save']),
'site': head + "python " + cfile + " site " + param['sname'] + " " + str(param['save']),
'database': head + "python " + cfile + " database " + param['sname'] + " " + str(param['save']),
'logs': head + "python " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
'path': head + "python3 " + cfile + " path " + param['sname'] + " " + str(param['save']),
'site': head + "python3 " + cfile + " site " + param['sname'] + " " + str(param['save']),
'database': head + "python3 " + cfile + " database " + param['sname'] + " " + str(param['save']),
'logs': head + "python3 " + script_dir + "/logs_backup.py " + param['sname'] + log + " " + str(param['save']),
'rememory': head + "/bin/bash " + script_dir + '/rememory.sh'
}
try:
+5 -6
View File
@@ -36,7 +36,7 @@ class files_api:
return mw.returnJson(False, '文件不存在', (path,))
try:
data = mw.getNumLines(path, int(line))
data = mw.getLastLine(path, int(line))
return mw.returnJson(True, 'OK', data)
except Exception as ex:
return mw.returnJson(False, u'无法正确读取文件!' + str(ex))
@@ -676,8 +676,7 @@ class files_api:
data['encoding'] = 'utf-8'
if char['encoding'] == 'Big5':
data['encoding'] = 'BIG5'
if not char['encoding'] in ['GBK', 'utf-8',
'BIG5']:
if not char['encoding'] in ['GBK', 'utf-8', 'BIG5']:
data['encoding'] = 'utf-8'
try:
if sys.version_info[0] == 2:
@@ -759,8 +758,8 @@ class files_api:
try:
tmps = mw.getRunDir() + '/tmp/panelExec.log'
if stype == 'zip':
os.system("cd " + path + " && unzip -d '" + dfile +
"' '" + sfile + "' > " + tmps + " 2>&1")
os.system("cd " + path + " && unzip -o -d '" + dfile +
"' '" + sfile + "' > " + tmps + " 2>&1 &")
else:
sfiles = ''
for sfile in sfile.split(','):
@@ -768,7 +767,7 @@ class files_api:
continue
sfiles += " '" + sfile + "'"
os.system("cd " + path + " && tar -zxvf " + sfiles +
" -C " + dfile + " > " + tmps + " 2>&1")
" -C " + dfile + " > " + tmps + " 2>&1 &")
self.setFileAccept(dfile)
mw.writeLog("文件管理", '文件解压成功!', (sfile, dfile))
return mw.returnJson(True, '文件解压成功!')
+18 -7
View File
@@ -59,22 +59,30 @@ class firewall_api:
# 添加放行端口
def addAcceptPortApi(self):
if not self.getFwStatus():
return mw.returnJson(False, '防火墙启动时,才能添加规则!')
import re
import time
port = request.form.get('port', '').strip()
ps = request.form.get('ps', '').strip()
stype = request.form.get('type', '').strip()
data = self.addAcceptPortArgs(port, ps, stype)
return mw.getJson(data)
# 添加放行端口
def addAcceptPortArgs(self, port, ps, stype):
import re
import time
if not self.getFwStatus():
self.setFw(0)
rep = "^\d{1,5}(:\d{1,5})?$"
if not re.search(rep, port):
return mw.returnJson(False, '端口范围不正确!')
return mw.returnData(False, '端口范围不正确!')
if mw.M('firewall').where("port=?", (port,)).count() > 0:
return mw.returnJson(False, '您要放行的端口已存在,无需重复放行!')
return mw.returnData(False, '您要放行的端口已存在,无需重复放行!')
msg = mw.getInfo('放行端口[{1}]成功', (port,))
mw.writeLog("防火墙管理", msg)
@@ -83,7 +91,7 @@ class firewall_api:
self.addAcceptPort(port)
self.firewallReload()
return mw.returnJson(True, '添加放行(' + port + ')端口成功!')
return mw.returnData(True, '添加放行(' + port + ')端口成功!')
# 删除IP屏蔽
def delDropAddressApi(self):
@@ -290,6 +298,9 @@ class firewall_api:
return mw.returnJson(True, '开发机不能设置!')
status = request.form.get('status', '1')
return mw.getJson(self.setFw(status))
def setFw(self, status):
if status == '1':
if self.__isUfw:
mw.execShell('/usr/sbin/ufw disable')
@@ -313,7 +324,7 @@ class firewall_api:
mw.execShell('/etc/init.d/iptables save')
mw.execShell('/etc/init.d/iptables restart')
return mw.returnJson(True, '设置成功!')
return mw.returnData(True, '设置成功!')
def delPanelLogsApi(self):
mw.M('logs').where('id>?', (0,)).delete()
+76 -28
View File
@@ -57,10 +57,22 @@ def getPluginDir():
return getRunDir() + '/plugins'
def getPanelDataDir():
return getRunDir() + '/data'
def getServerDir():
return getRootDir() + '/server'
def getLogsDir():
return getRootDir() + '/wwwlogs'
def getBackupDir():
return getRootDir() + '/backup'
def getWwwDir():
file = getRunDir() + '/data/site.pl'
if os.path.exists(file):
@@ -73,14 +85,6 @@ def setWwwDir(wdir):
return writeFile(file, wdir)
def getLogsDir():
return getRootDir() + '/wwwlogs'
def getBackupDir():
return getRootDir() + '/backup'
def setBackupDir(bdir):
file = getRunDir() + '/data/backup.pl'
return writeFile(file, bdir)
@@ -157,19 +161,24 @@ def isInstalledWeb():
def restartWeb():
return opWeb("reload")
def opWeb(method):
if not isInstalledWeb():
return False
# systemd
systemd = '/lib/systemd/system/openresty.service'
if os.path.exists(systemd):
execShell('systemctl restart openresty')
execShell('systemctl ' + method + ' openresty')
return True
# initd
initd = getServerDir() + '/openresty/init.d/openresty'
if os.path.exists(initd):
execShell(initd + ' ' + 'restart')
execShell(initd + ' ' + method)
return True
return False
@@ -402,6 +411,32 @@ def writeFile(filename, str):
return False
def backFile(file, act=None):
"""
@name 备份配置文件
@param file 需要备份的文件
@param act 如果存在,则备份一份作为默认配置
"""
file_type = "_bak"
if act:
file_type = "_def"
# print("cp -p {0} {1}".format(file, file + file_type))
execShell("cp -p {0} {1}".format(file, file + file_type))
def restoreFile(file, act=None):
"""
@name 还原配置文件
@param file 需要还原的文件
@param act 如果存在,则还原默认配置
"""
file_type = "_bak"
if act:
file_type = "_def"
execShell("cp -p {1} {0}".format(file, file + file_type))
def HttpGet(url, timeout=10):
"""
发送GET请求
@@ -524,7 +559,7 @@ def getSpeed():
return json.loads(data)
def getLastLine(inputfile, lineNum):
def getLastLineBk(inputfile, lineNum):
# 读文件指定倒数行数
try:
fp = open(inputfile, 'rb')
@@ -557,7 +592,7 @@ def getLastLine(inputfile, lineNum):
# return getMsg('TASK_SLEEP')
def getNumLines(path, num, p=1):
def getLastLine(path, num, p=1):
pyVersion = sys.version_info[0]
try:
import html
@@ -567,12 +602,14 @@ def getNumLines(path, num, p=1):
count = start_line + num
fp = open(path, 'rb')
buf = ""
fp.seek(-1, 2)
fp.seek(0, 2)
if fp.read(1) == "\n":
fp.seek(-1, 2)
fp.seek(0, 2)
data = []
b = True
n = 0
for i in range(count):
while True:
newline_pos = str.rfind(str(buf), "\n")
@@ -596,7 +633,7 @@ def getNumLines(path, num, p=1):
t_buf = fp.read(to_read)
if pyVersion == 3:
if type(t_buf) == bytes:
t_buf = t_buf.decode('utf-8')
t_buf = t_buf.decode("utf-8", "ignore").strip()
buf = t_buf + buf
fp.seek(-to_read, 1)
if pos - to_read == 0:
@@ -605,7 +642,7 @@ def getNumLines(path, num, p=1):
break
fp.close()
except Exception as e:
return ''
return str(e)
return "\n".join(data)
@@ -646,16 +683,14 @@ def getLocalIp():
try:
ipaddress = readFile(filename)
if not ipaddress or ipaddress == '127.0.0.1':
raise Exception("ip is empty!")
cmd = "curl -4 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
ip = execShell(cmd)
result = ip[0].strip()
if result == '':
raise Exception("ipv4 is empty!")
writeFile(filename, result)
return result
return ipaddress
except Exception as e:
cmd = "curl -4 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
ip = execShell(cmd)
result = ip[0].strip()
if result == '':
raise e
writeFile(filename, result)
return result
except Exception as e:
cmd = "curl -6 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
ip = execShell(cmd)
@@ -664,6 +699,8 @@ def getLocalIp():
return '127.0.0.1'
writeFile(filename, result)
return result
finally:
pass
return '127.0.0.1'
@@ -689,7 +726,7 @@ def checkIp(ip):
def checkPort(port):
# 检查端口是否合法
ports = ['21', '25', '7200', '888']
ports = ['21', '25', '443', '888']
if port in ports:
return False
intport = int(port)
@@ -710,13 +747,24 @@ def getStrBetween(startStr, endStr, srcStr):
def getCpuType():
cpuType = ''
if isAppleSystem():
cmd = "system_profiler SPHardwareDataType | grep 'Processor Name' | awk -F ':' '{print $2}'"
cpuinfo = execShell(cmd)
return cpuinfo[0].strip()
# 取CPU类型
cpuinfo = open('/proc/cpuinfo', 'r').read()
rep = "model\s+name\s+:\s+(.+)"
tmp = re.search(rep, cpuinfo)
cpuType = None
tmp = re.search(rep, cpuinfo, re.I)
if tmp:
cpuType = tmp.groups()[0]
else:
cpuinfo = execShell('LANG="en_US.UTF-8" && lscpu')[0]
rep = "Model\s+name:\s+(.+)"
tmp = re.search(rep, cpuinfo, re.I)
if tmp:
cpuType = tmp.groups()[0]
return cpuType
+53 -4
View File
@@ -114,6 +114,7 @@ class plugins_api:
return mw.returnJson(False, '配置文件不存在!', ())
pluginInfo = json.loads(mw.readFile(infoJsonPos))
self.hookInstall(pluginInfo)
execstr = "cd " + os.getcwd() + "/plugins/" + \
name + " && /bin/bash " + pluginInfo["shell"] \
@@ -131,6 +132,55 @@ class plugins_api:
mw.triggerTask()
return mw.returnJson(True, '已将安装任务添加到队列!')
def hookInstallFile(self, hook_name, info):
hookPath = mw.getPanelDataDir() + "/hook_" + hook_name + ".json"
data = []
if os.path.exists(hookPath):
t = mw.readFile(hookPath)
data = json.loads(t)
isNeedAdd = True
for x in range(len(data)):
if data[x]['title'] == info['title'] and data[x]['name'] == info['name']:
isNeedAdd = False
if isNeedAdd:
tmp = {}
tmp['title'] = info['title']
tmp['name'] = info['name']
data.append(tmp)
mw.writeFile(hookPath, json.dumps(data))
def hookUninstallFile(self, hook_name, info):
hookPath = mw.getPanelDataDir() + "/hook_" + hook_name + ".json"
data = []
if os.path.exists(hookPath):
t = mw.readFile(hookPath)
data = json.loads(t)
for idx in range(len(data)):
if data[idx]['title'] == info['title'] and data[idx]['name'] == info['name']:
data.remove(data[idx])
mw.writeFile(hookPath, json.dumps(data))
def hookInstall(self, info):
if 'hook' in info:
hooks = info['hook']
for x in hooks:
if x in ['backup']:
self.hookInstallFile(x, info)
return True
return False
def hookUninstall(self, info):
if 'hook' in info:
hooks = info['hook']
for x in hooks:
if x in ['backup']:
self.hookUninstallFile(x, info)
return True
return False
def uninstallOldApi(self):
rundir = mw.getRunDir()
name = request.form.get('name', '')
@@ -147,7 +197,6 @@ class plugins_api:
return mw.returnJson(False, "配置文件不存在!", ())
pluginInfo = json.loads(mw.readFile(infoJsonPos))
execstr = "cd " + os.getcwd() + "/plugins/" + \
name + " && /bin/bash " + pluginInfo["shell"] \
+ " uninstall " + version
@@ -175,13 +224,13 @@ class plugins_api:
return mw.returnJson(False, "配置文件不存在!", ())
pluginInfo = json.loads(mw.readFile(infoJsonPos))
self.hookUninstall(pluginInfo)
execstr = "cd " + os.getcwd() + "/plugins/" + \
name + " && /bin/bash " + pluginInfo["shell"] \
+ " uninstall " + version
data = mw.execShell(execstr)
if mw.isAppleSystem():
if mw.isDebugMode():
print(execstr)
print(data[0], data[1])
self.removeIndex(name, version)
@@ -793,7 +842,7 @@ class plugins_api:
print('getIndexList:', e)
# 使用gevent模式时,无法使用多进程
#plist = self.checkStatusMProcess(plist)
# plist = self.checkStatusMProcess(plist)
plist = self.checkStatusMThreads(plist)
return plist
+43 -28
View File
@@ -340,10 +340,16 @@ class site_api:
name = mw.M('sites').where("id=?", (mid,)).getField('name')
data = {}
data['logs'] = self.getLogsStatus(name)
data['runPath'] = self.getSiteRunPath(mid)
data['userini'] = False
if os.path.exists(path + '/.user.ini'):
data['userini'] = True
data['runPath'] = self.getSiteRunPath(mid)
if data['runPath']['runPath'] != '/':
if os.path.exists(path + data['runPath']['runPath'] + '/.user.ini'):
data['userini'] = True
data['pass'] = self.getHasPwd(name)
data['path'] = path
data['name'] = name
@@ -351,15 +357,18 @@ class site_api:
def setDirUserIniApi(self):
path = request.form.get('path', '')
runPath = request.form.get('runPath', '')
filename = path + '/.user.ini'
self.delUserInI(path)
if os.path.exists(filename):
self.delUserInI(path)
mw.execShell("which chattr && chattr -i " + filename)
os.remove(filename)
return mw.returnJson(True, '已清除防跨站设置!')
mw.writeFile(filename, 'open_basedir=' + path +
'/:/www/server/php:/tmp/:/proc/')
self.setDirUserINI(path, runPath)
mw.execShell("which chattr && chattr +i " + filename)
return mw.returnJson(True, '已打开防跨站设置!')
def logsOpenApi(self):
@@ -497,7 +506,7 @@ class site_api:
certName = request.form.get('certName', '')
siteName = request.form.get('siteName', '')
try:
path = self.sslDir + siteName
path = self.sslDir + siteName.strip()
if not os.path.exists(path):
return mw.returnJson(False, '证书不存在!')
@@ -730,11 +739,11 @@ class site_api:
if conf.find('ssl_certificate') == -1:
return mw.returnJson(False, '当前未开启SSL')
to = """#error_page 404/404.html;
#HTTP_TO_HTTPS_START
# HTTP_TO_HTTPS_START
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
#HTTP_TO_HTTPS_END"""
# HTTP_TO_HTTPS_END"""
conf = conf.replace('#error_page 404/404.html;', to)
mw.writeFile(file, conf)
@@ -1095,6 +1104,7 @@ class site_api:
sitePath = mw.M('sites').where('id=?', (mid,)).getField('path')
newPath = sitePath + runPath
# 处理Nginx
filename = self.getHostConf(siteName)
if os.path.exists(filename):
@@ -1104,8 +1114,7 @@ class site_api:
conf = conf.replace(path, newPath)
mw.writeFile(filename, conf)
self.delUserInI(sitePath)
self.setDirUserINI(newPath)
self.setDirUserINI(sitePath, runPath)
mw.restartWeb()
return mw.returnJson(True, '设置成功!')
@@ -1140,10 +1149,10 @@ class site_api:
if conf.find(rep) == -1:
rep = '#error_page 404/404.html;'
data = '''
# AUTH_START
#AUTH_START
auth_basic "Authorization";
auth_basic_user_file %s;
# AUTH_END''' % (filename,)
#AUTH_END''' % (filename,)
conf = conf.replace(rep, rep + data)
mw.writeFile(configFile, conf)
# 写密码配置
@@ -1562,7 +1571,7 @@ class site_api:
# location ~* ^{from}(.*)$ {
tpl = """
# PROXY-START/
#PROXY-START/
location ^~ {from} {
proxy_pass {to};
proxy_set_header Host {host};
@@ -1585,7 +1594,7 @@ location ^~ {from} {
add_header Cache-Control no-cache;
}
}
# PROXY-END/
#PROXY-END/
"""
# replace
@@ -1829,13 +1838,13 @@ location ^~ {from} {
logPath = mw.getLogsDir() + '/' + siteName + '.log'
if not os.path.exists(logPath):
return mw.returnJson(False, '日志为空')
return mw.returnJson(True, mw.getNumLines(logPath, 100))
return mw.returnJson(True, mw.getLastLine(logPath, 100))
def getErrorLogs(self, siteName):
logPath = mw.getLogsDir() + '/' + siteName + '.error.log'
if not os.path.exists(logPath):
return mw.returnJson(False, '日志为空')
return mw.returnJson(True, mw.getNumLines(logPath, 100))
return mw.returnJson(True, mw.getLastLine(logPath, 100))
# 取日志状态
def getLogsStatus(self, siteName):
@@ -2026,7 +2035,7 @@ location ^~ {from} {
return 404;
}
}
# SECURITY-END
#SECURITY-END
include %s/enable-php-''' % (fix.strip().replace(',', '|'), domains.strip().replace(',', ' '), pre_path)
conf = re.sub(re_path, rconf, conf)
mw.writeLog('网站管理', '站点[' + name + ']已开启防盗链!')
@@ -2094,12 +2103,16 @@ location ^~ {from} {
return rewriteList
def createRootDir(self, path):
autoInit = False
if not os.path.exists(path):
autoInit = True
os.makedirs(path)
if not mw.isAppleSystem():
mw.execShell('chown -R www:www ' + path)
mw.writeFile(path + '/index.html', 'Work has started!!!')
mw.execShell('chmod -R 755 ' + path)
if autoInit:
mw.writeFile(path + '/index.html', 'Work has started!!!')
mw.execShell('chmod -R 755 ' + path)
def nginxAddDomain(self, webname, domain, port):
file = self.getHostConf(webname)
@@ -2182,19 +2195,16 @@ location ^~ {from} {
return mw.returnJson(False, '您添加的域名已存在!')
mw.M('domain').where('pid=?', (opid,)).delete()
self.createRootDir(self.sitePath)
self.nginxAddConf()
# 添加更多域名
for domain in siteMenu['domainlist']:
sdomain = domain
swebname = self.siteName
spid = str(pid)
self.addDomain(domain, webname, pid)
self.addDomain(domain, self.siteName, pid)
mw.M('domain').add('pid,name,port,addtime',
(pid, self.siteName, self.sitePort, mw.getDate()))
self.createRootDir(self.sitePath)
self.nginxAddConf()
data = {}
data['siteStatus'] = False
mw.restartWeb()
@@ -2350,7 +2360,9 @@ location ^~ {from} {
return True
# 设置目录防御
def setDirUserINI(self, newPath):
def setDirUserINI(self, sitePath, runPath):
newPath = sitePath + runPath
filename = newPath + '/.user.ini'
if os.path.exists(filename):
mw.execShell("chattr -i " + filename)
@@ -2358,8 +2370,11 @@ location ^~ {from} {
return mw.returnJson(True, '已清除防跨站设置!')
self.delUserInI(newPath)
mw.writeFile(filename, 'open_basedir=' +
newPath + '/:/www/server/php:/tmp/:/proc/')
openPath = 'open_basedir={}/:{}/'.format(newPath, sitePath)
if runPath == '/':
openPath = 'open_basedir={}/'.format(sitePath)
mw.writeFile(filename, openPath + ':/www/server/php:/tmp/:/proc/')
mw.execShell("chattr +i " + filename)
return mw.returnJson(True, '已打开防跨站设置!')
+93 -69
View File
@@ -162,7 +162,7 @@ class system_api:
except:
port = mw.readFile('data/port.pl')
except:
port = '8888'
port = '7200'
domain = ''
if os.path.exists('data/domain.conf'):
domain = mw.readFile('data/domain.conf')
@@ -201,9 +201,9 @@ class system_api:
def getLoadAverage(self):
c = os.getloadavg()
data = {}
data['one'] = float(c[0])
data['five'] = float(c[1])
data['fifteen'] = float(c[2])
data['one'] = round(float(c[0]), 2)
data['five'] = round(float(c[1]), 2)
data['fifteen'] = round(float(c[2]), 2)
data['max'] = psutil.cpu_count() * 2
data['limit'] = data['max']
data['safe'] = data['max'] * 0.75
@@ -276,8 +276,17 @@ class system_api:
def getCpuInfo(self, interval=1):
# 取CPU信息
cpuCount = psutil.cpu_count()
cpuLogicalNum = psutil.cpu_count(logical=False)
used = psutil.cpu_percent(interval=interval)
return used, cpuCount
if os.path.exists('/proc/cpuinfo'):
c_tmp = mw.readFile('/proc/cpuinfo')
d_tmp = re.findall("physical id.+", c_tmp)
cpuLogicalNum = len(set(d_tmp))
used_all = psutil.cpu_percent(percpu=True)
cpu_name = mw.getCpuType() + " * {}".format(cpuLogicalNum)
return used, cpuCount, used_all, cpu_name, cpuCount, cpuLogicalNum
def getMemInfo(self):
# 取内存信息
@@ -437,12 +446,35 @@ class system_api:
os.system('echo > /tmp/panelBoot.pl')
return total, count
def psutilNetIoCounters(self):
'''
统计网卡流量
'''
stat_pl = 'data/only_netio_counters.pl'
if os.path.exists(stat_pl):
local_lo = (0, 0, 0, 0)
ioName = psutil.net_io_counters(pernic=True).keys()
for x in ioName:
if x.find("lo") > -1:
local_lo = psutil.net_io_counters(
pernic=True).get(x)[:4]
all_io = psutil.net_io_counters()[:4]
result_io = tuple([all_io[i] - local_lo[i]
for i in range(0, len(all_io))])
# print(local_lo)
# print(all_io)
# print(result_io)
return result_io
return psutil.net_io_counters()[:4]
def getNetWork(self):
# return self.GetNetWorkApi(get);
# 取网络流量信息
try:
# 取网络流量信息
networkIo = psutil.net_io_counters()[:4]
networkIo = self.psutilNetIoCounters()
if not "otime" in session:
session['up'] = networkIo[0]
session['down'] = networkIo[1]
@@ -470,38 +502,7 @@ class system_api:
return networkInfo
except Exception as e:
# print(e)
return None
def getNetWorkApi(self):
# 取网络流量信息
try:
tmpfile = 'data/network.temp'
networkIo = psutil.net_io_counters()[:4]
if not os.path.exists(tmpfile):
mw.writeFile(tmpfile, str(
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
lastValue = mw.readFile(tmpfile).split('|')
ntime = time.time()
networkInfo = {}
networkInfo['upTotal'] = networkIo[0]
networkInfo['downTotal'] = networkIo[1]
networkInfo['up'] = round(
float(networkIo[0] - int(lastValue[0])) / 1024 / (ntime - int(lastValue[2])), 2)
networkInfo['down'] = round(
float(networkIo[1] - int(lastValue[1])) / 1024 / (ntime - int(lastValue[2])), 2)
networkInfo['downPackets'] = networkIo[3]
networkInfo['upPackets'] = networkIo[2]
mw.writeFile(tmpfile, str(
networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time())))
# networkInfo['cpu'] = self.GetCpuInfo(0.1)
return networkInfo
except:
print("getNetWork error:", e)
return None
def getNetWorkIoData(self, start, end):
@@ -567,14 +568,19 @@ class system_api:
def setControl(self, stype, day):
filename = 'data/control.conf'
stat_pl = 'data/only_netio_counters.pl'
if stype == '0':
mw.execShell("rm -f " + filename)
mw.execShell("rm -rf " + filename)
elif stype == '1':
_day = int(day)
if _day < 1:
return mw.returnJson(False, "设置失败!")
mw.writeFile(filename, day)
elif stype == '2':
mw.execShell("rm -rf " + stat_pl)
elif stype == '3':
mw.execShell("echo 'True' > " + stat_pl)
elif stype == 'del':
if not mw.isRestart():
return mw.returnJson(False, '请等待所有安装任务完成再执行')
@@ -597,6 +603,12 @@ class system_api:
else:
data['day'] = 30
data['status'] = False
if os.path.exists(stat_pl):
data['stat_all_status'] = True
else:
data['stat_all_status'] = False
return mw.getJson(data)
return mw.returnJson(True, "设置成功!")
@@ -625,13 +637,13 @@ class system_api:
def getServerInfo(self):
import urllib.request
import ssl
upAddr = 'https://cdn.jsdelivr.net/gh/midoks/mdserver-web@latest/version/info.json'
upAddr = 'https://api.github.com/repos/midoks/mdserver-web/releases/latest'
try:
context = ssl._create_unverified_context()
req = urllib.request.urlopen(upAddr, context=context, timeout=3)
result = req.read().decode('utf-8')
version = json.loads(result)
return version[0]
return version
except Exception as e:
print('getServerInfo', e)
return {}
@@ -642,58 +654,70 @@ class system_api:
if not mw.isRestart():
return mw.returnJson(False, '请等待所有安装任务完成再执行!')
version_new_info = self.getServerInfo()
version_now = config_api.config_api().getVersion()
new_ver = version_new_info['name']
if stype == 'check':
version_now = config_api.config_api().getVersion()
version_new_info = self.getServerInfo()
if not 'version' in version_new_info:
if not 'name' in version_new_info:
return mw.returnJson(False, '服务器数据或网络有问题!')
diff = self.versionDiff(
version_now, version_new_info['version'])
diff = self.versionDiff(version_now, new_ver)
if diff == 'new':
return mw.returnJson(True, '有新版本!', version_new_info['version'])
return mw.returnJson(True, '有新版本!', new_ver)
elif diff == 'test':
return mw.returnJson(True, '有测试版本!', version_new_info['version'])
return mw.returnJson(True, '有测试版本!', new_ver)
else:
return mw.returnJson(False, '已经是最新,无需更新!')
if stype == 'info':
version_new_info = self.getServerInfo()
version_now = config_api.config_api().getVersion()
if not 'version' in version_new_info:
if not 'name' in version_new_info:
return mw.returnJson(False, '服务器数据有问题!')
diff = self.versionDiff(
version_now, version_new_info['version'])
return mw.returnJson(True, '更新信息!', version_new_info)
diff = self.versionDiff(version_now, new_ver)
data = {}
data['version'] = new_ver
data['content'] = version_new_info[
'body'].replace("\n", "<br/>")
return mw.returnJson(True, '更新信息!', data)
if stype == 'update':
if version == '':
return mw.returnJson(False, '缺少版本信息!')
v_new_info = self.getServerInfo()
if v_new_info['version'] != version:
if new_ver != version:
return mw.returnJson(False, '更新失败,请重试!')
if not 'path' in v_new_info or v_new_info['path'] == '':
return mw.returnJson(False, '下载地址不存在!')
newUrl = v_new_info['path']
toPath = mw.getRootDir() + '/temp'
if not os.path.exists(toPath):
mw.execShell('mkdir -p ' + toPath)
mw.execShell('wget -O ' + toPath + '/mw.zip ' + newUrl)
newUrl = "https://github.com/midoks/mdserver-web/archive/refs/tags/" + version + ".zip"
mw.execShell('unzip -o ' + toPath + '/mw.zip' + ' -d ./')
mw.execShell('unzip -o mw.zip -d ./')
mw.execShell('rm -f mw.zip')
return mw.returnJson(True, '安装更新成功,需自己重启!')
dist_mw = toPath + '/mw.zip'
if not os.path.exists(dist_mw):
mw.execShell(
'wget --no-check-certificate -O ' + dist_mw + ' ' + newUrl)
dist_to = toPath + "/mdserver-web-" + version
if not os.path.exists(dist_to):
os.system('unzip -o ' + toPath +
'/mw.zip' + ' -d ' + toPath)
cmd_cp = 'cp -rf ' + toPath + '/mdserver-web-' + \
version + '/* ' + mw.getServerDir() + '/mdserver-web'
mw.execShell(cmd_cp)
mw.execShell('rm -rf ' + toPath + '/mdserver-web-' + version)
mw.execShell('rm -rf ' + toPath + '/mw.zip')
self.restartMw()
return mw.returnJson(True, '安装更新成功!')
return mw.returnJson(False, '已经是最新,无需更新!')
except Exception as ex:
print('updateServer', ex)
return mw.returnJson(False, "连接服务器失败!")
# print('updateServer', ex)
return mw.returnJson(False, "连接服务器失败!" + str(ex))
# 修复面板
def repPanel(self, get):
+11
View File
@@ -11,6 +11,7 @@ class ORM:
__DB_PASS = None
__DB_USER = 'root'
__DB_PORT = 3306
__DB_NAME = ''
__DB_HOST = 'localhost'
__DB_CONN = None
__DB_CUR = None
@@ -27,21 +28,25 @@ class ORM:
if os.path.exists(self.__DB_SOCKET):
try:
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
database=self.__DB_NAME,
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
unix_socket=self.__DB_SOCKET, cursorclass=pymysql.cursors.DictCursor)
except Exception as e:
self.__DB_HOST = '127.0.0.1'
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
database=self.__DB_NAME,
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
unix_socket=self.__DB_SOCKET, cursorclass=pymysql.cursors.DictCursor)
else:
try:
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
database=self.__DB_NAME,
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
cursorclass=pymysql.cursors.DictCursor)
except Exception as e:
self.__DB_HOST = '127.0.0.1'
self.__DB_CONN = pymysql.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
database=self.__DB_NAME,
port=int(self.__DB_PORT), charset=self.__DB_CHARSET, connect_timeout=1,
cursorclass=pymysql.cursors.DictCursor)
@@ -63,12 +68,18 @@ class ORM:
def setPort(self, port):
self.__DB_PORT = port
def setUser(self, user):
self.__DB_USER = user
def setPwd(self, pwd):
self.__DB_PASS = pwd
def getPwd(self):
return self.__DB_PASS
def setDbName(self, name):
self.__DB_NAME = name
def execute(self, sql):
# 执行SQL语句返回受影响行
if not self.__Conn():
+6
View File
@@ -77,6 +77,12 @@ class ORM:
def getPwd(self):
return self.__DB_PASS
def setDbName(self, name):
self.__DB_NAME = name
def setUser(self, user):
self.__DB_USER = user
def execute(self, sql):
# 执行SQL语句返回受影响行
if not self.__Conn():
+1 -1
View File
@@ -9,7 +9,7 @@ if [ -f bin/activate ];then
source bin/activate
fi
# export LC_ALL="en_US.UTF-8"
export LC_ALL="en_US.UTF-8"
mw_start_task()
+8 -8
View File
@@ -13,7 +13,7 @@ service mw [start|stop|reload|restart|status]
```
sytemctl [start|stop|reload|restart|status] openresty
systemctl [start|stop|reload|restart|status] openresty
```
@@ -21,7 +21,7 @@ sytemctl [start|stop|reload|restart|status] openresty
```
sytemctl [start|stop|reload|restart|status] mysql
systemctl [start|stop|reload|restart|status] mysql
```
@@ -29,7 +29,7 @@ sytemctl [start|stop|reload|restart|status] mysql
```
sytemctl [start|stop|reload|restart|status] mariadb
systemctl [start|stop|reload|restart|status] mariadb
```
@@ -37,16 +37,16 @@ sytemctl [start|stop|reload|restart|status] mariadb
```
sytemctl [start|stop|reload|restart|status] php[54-81]
systemctl [start|stop|reload|restart|status] php[54-81]
sytemctl start php71
systemctl start php71
```
- Redis
```
sytemctl [start|stop|reload|restart|status] redis
systemctl [start|stop|reload|restart|status] redis
```
@@ -54,7 +54,7 @@ sytemctl [start|stop|reload|restart|status] redis
```
sytemctl [start|stop|reload|restart|status] memcached
systemctl [start|stop|reload|restart|status] memcached
```
@@ -63,6 +63,6 @@ sytemctl [start|stop|reload|restart|status] memcached
```
sytemctl [start|stop|reload|restart|status] sphinx
systemctl [start|stop|reload|restart|status] sphinx
```
+3 -4
View File
@@ -46,10 +46,9 @@ CREATE TABLE IF NOT EXISTS `firewall` (
INSERT INTO `firewall` (`id`, `port`, `ps`, `addtime`) VALUES
(1, '80', '网站默认端口', '0000-00-00 00:00:00'),
(2, '7200', 'WEB面板', '0000-00-00 00:00:00'),
(3, '22', 'SSH远程管理服务', '0000-00-00 00:00:00'),
(4, '888', 'phpMyAdmin默认端口', '0000-00-00 00:00:00'),
(5, '443', 'HTTPS', '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');
+1
View File
@@ -1,6 +1,7 @@
server
{
listen {$PORT};
listen [::]:{$PORT};
server_name {$SERVER_NAME};
index index.php index.html index.htm default.php default.htm default.html;
root {$ROOT_DIR};
-81
View File
@@ -1,81 +0,0 @@
#!/www/server/mdserver-web/bin/python
# description: mdserver-web cli tools
# ln -s /www/server/mdserver-web/mw-cli /usr/bin/mw-cli
import os
import sys
def mw_start():
"""
Start mdserver-web
"""
os.system('systemctl start mw')
print("服务已启动")
def mw_stop():
"""
stop mdserver-web
"""
os.system('systemctl stop mw')
print("服务已停止")
def mw_restart():
"""
restart mdserver-web
"""
os.system('systemctl restart mw')
print("服务已重启")
def mw_reset_username():
"""
reset mdserver-web username
"""
from tools import set_panel_username
user_name = input("请输入新的用户名: ")
set_panel_username(user_name)
def mw_reset_pwd():
"""
reset mdserver-web password
"""
from tools import set_panel_pwd
pwd = input("请输入新的密码: ")
set_panel_pwd(pwd, True)
if __name__ == '__main__':
os.chdir("/www/server/mdserver-web")
sys.path.append(os.getcwd() + "/class/core")
try:
str = '''
==== mdserver-web cli tools ====
1. 启动服务 2. 停止服务
3. 重启服务 4. 修改用户名
5. 修改密码
=================================
'''
if len(sys.argv) == 2:
sw = sys.argv[1]
else:
print(str)
sw = input("请输入您要进行的操作: ")
if sw == '1':
mw_start()
elif sw == '2':
mw_stop()
elif sw == '3':
mw_restart()
elif sw == '4':
mw_reset_username()
elif sw == '5':
mw_reset_pwd()
else:
print("操作不存在")
except KeyboardInterrupt:
print("\n操作已终止")
+418
View File
@@ -0,0 +1,418 @@
# coding:utf-8
'''
doc: https://docs.python.org/zh-cn/3/library/ftplib.html
'''
import sys
import io
import os
import time
import re
import json
import paramiko
import ftplib
sys.path.append(os.getcwd() + "/class/core")
import mw
DEBUG = True
BLOCK_SIZE = 1024 * 1024 * 2
# BLOCK_SIZE = 50
PROGRESS_FILE_NAME = "PROGRESS_FILE_NAME"
"""
=============自定义异常===================
"""
class OsError(Exception):
"""OS端异常"""
class ObjectNotFound(OsError):
"""对象不存在时抛出的异常"""
def __init__(self, *args, **kwargs):
message = "文件对象不存在。"
super(ObjectNotFound, self).__init__(message, *args, **kwargs)
class APIError(Exception):
"""API参数错误异常"""
def __init__(self, *args, **kwargs):
_api_error_msg = 'API资料校验失败,请核实!'
super(APIError, self).__init__(_api_error_msg, *args, **kwargs)
class FtpPSClient:
_title = "FTP"
_name = "ftp"
__host = None
__port = None
__user = None
__password = None
default_port = 21
default_backup_path = "/backup/"
config_file = "cfg.json"
def __init__(self, load_config=True, timeout=10):
self.timeout = timeout
if load_config:
data = self.get_config()
self.injection_config(data)
def get_config(self):
default_config = {
"ftp_host": '',
"ftp_user": '',
"ftp_pass": '',
"backup_path": self.default_backup_path
}
cfg = mw.getServerDir() + "/backup_ftp/" + self.config_file
if os.path.exists(cfg):
data = mw.readFile(cfg)
return json.loads(data)
else:
return default_config
def injection_config(self, data):
host = data["ftp_host"].strip()
if host.find(':') == -1:
self.__port = self.default_port
self.__host = data['ftp_host'].strip()
self.__user = data['ftp_user'].strip()
self.__password = data['ftp_pass'].strip()
bp = data['backup_path'].strip()
if bp:
self.backup_path = self.getPath(bp)
else:
self.backup_path = self.getPath(self.default_backup_path)
def authorize(self):
try:
if self.timeout is not None:
ftp = ftplib.FTP(timeout=self.timeout)
else:
ftp = ftplib.FTP()
debuglevel = 0
# if DEBUG:
# debuglevel = 3
ftp.set_debuglevel(debuglevel)
# ftp.set_pasv(True)
ftp.connect(self.__host, int(self.__port))
ftp.login(self.__user, self.__password)
return ftp
except Exception as e:
raise OsError("无法连接FTP客户端,请检查配置参数是否正确!")
# 取目录路径
def getPath(self, path):
if path[-1:] != '/':
path += '/'
if path[:1] != '/':
path = '/' + path
return path.replace('//', '/')
def generateDownloadUrl(self, object_name):
return 'ftp://' + \
self.__user + ':' + \
self.__password + '@' + \
self.__host + ':' + \
"/" + object_name
def buildDirName(self, data_type, file_name):
import re
prefix_dict = {
"site": "web",
"database": "db",
"path": "path",
}
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
return object_name
def uploadFile(self, filename, data_type=None, *args, **kwargs):
client = self.authorize()
local_file_name = filename
filename = os.path.abspath(filename)
dirname = os.path.dirname(filename)
temp_name = os.path.split(filename)[1]
object_name = self.buildDirName(data_type, temp_name)
upload_tmp_dir = os.path.join(dirname, ".upload_tmp")
if not os.path.exists(upload_tmp_dir):
os.mkdir(upload_tmp_dir)
print("|-正在上传文件到 {}".format(object_name))
total_bytes = os.path.getsize(filename)
object_md5_name = mw.md5(object_name)
pg_file = os.path.join(upload_tmp_dir, object_md5_name + ".pl")
block_size = BLOCK_SIZE
if kwargs.get("block_size"):
try:
block_size = float(kwargs.get("block_size"))
except:
pass
remote_file_size = None
if not os.path.exists(pg_file):
# import uuid
# uid = str(uuid.uuid1())
progress_info = {
"filename": local_file_name,
"total_bytes": total_bytes,
"uploaded_bytes": 0,
}
mw.writeFile(pg_file, json.dumps(progress_info))
else:
progress_info = json.loads(public.readFile(pg_file))
if total_bytes == progress_info.get("total_bytes"):
# 取远程文件大小
_max_loop = 10
while _max_loop > 0:
try:
time.sleep(1)
remote_file_size = client.size(object_name)
if remote_file_size > total_bytes:
remote_file_size = None
break
except Exception as e:
if DEBUG:
print(type(e))
print(e)
_max_loop -= 1
else:
remote_file_size = None
uploaded_bytes = 0 if remote_file_size is None else remote_file_size
dir_name = os.path.split(object_name)[0]
if dir_name:
self.createDirP(dir_name)
upload_start = time.time()
try:
if total_bytes > 1024 * 1024 * 1024:
with open(local_file_name, 'rb') as file_handler:
if remote_file_size is not None:
file_handler.seek(remote_file_size)
client.voidcmd("TYPE I")
datasock = ''
esize = ''
datasock, esize = client.ntransfercmd(
"STOR " + object_name, remote_file_size)
while True:
buf = file_handler.read(block_size)
if not len(buf):
break
datasock.sendall(buf)
uploaded_bytes += len(buf)
if DEBUG:
print('\ruploading %.2f%%' %
(float(uploaded_bytes) / total_bytes * 100))
print("uploaded_bytes", uploaded_bytes)
if uploaded_bytes == total_bytes:
break
datasock.close()
if DEBUG:
print('close data handle')
try:
client.voidcmd('NOOP')
except Exception as e:
if DEBUG:
print("Send NOOP command error:")
print(e)
else:
if DEBUG:
print('keep alive cmd success')
client.voidresp()
if DEBUG:
print('No loop cmd')
else:
# 小于1G文件直接上传
file_handler = open(local_file_name, "rb")
client.storbinary('STOR %s' % object_name,
file_handler, blocksize=block_size)
file_handler.close()
except Exception as e:
print(str(e))
completed_file_size = None
_max_loop = 10
while _max_loop > 0:
try:
time.sleep(1)
completed_file_size = client.size(object_name)
break
except Exception as e:
_max_loop -= 1
if DEBUG:
print("size error:" + str(e))
# 上传完成
if completed_file_size == total_bytes:
if DEBUG:
upload_completed = time.time()
upload_diff = upload_completed - upload_start
print("文件上传成功, 耗时: {}s。".format(upload_diff))
if os.path.exists(pg_file):
os.remove(pg_file)
return True
else:
if os.path.exists(pg_file):
os.remove(pg_file)
print("文件上传后大小不一致!")
print("completed_file_size:" + str(completed_file_size))
print("total_bytes:", total_bytes)
print("object_md5_name:", object_md5_name)
print("pg_file:", pg_file)
print("filename:", filename)
print("dirname:", dirname)
print("object_name:", object_name)
return False
def createDirP(self, dir_name):
"""创建远程目录
:param dir_name: 目录名称
:return:
"""
try:
dirnames = dir_name.split('/')
ftp = self.authorize()
# ftp.cwd(get.path);
for dirname in dirnames:
if not dirname or not dirname.strip():
continue
try:
flist = ftp.nlst()
if not dirname in flist:
ftp.mkd(dirname)
except:
# print("mlsd mode.")
try:
flist = list(ftp.mlsd())[1:]
for f in flist:
if dirname == f[0]:
break
else:
ftp.mkd(dirname)
except:
return False
ftp.cwd(dirname)
return True
except:
return False
def createDir(self, path, name):
ftp = self.authorize()
path = self.getPath(path)
ftp.cwd(path)
try:
ftp.mkd(name)
ftp.close()
return True
except Exception as e:
print(str(e))
ftp.close()
return False
def deleteDir(self, path, dir_name):
try:
ftp = self.authorize()
ftp.rmd(dir_name)
return True
except ftplib.error_perm as e:
print(str(e) + ":" + dir_name)
except Exception as e:
print(e)
return False
def deleteFile(self, filename):
try:
ftp = self.authorize()
ftp.delete(filename)
return True
except Exception as e:
print(str(e))
return False
def getList(self, path="/"):
ftp = self.authorize()
path = self.getPath(path)
ftp.cwd(path)
mlsd = False
try:
files = list(ftp.mlsd())
mlsd = True
except:
try:
files = ftp.nlst(path)
mlsd = False
except:
raise RuntimeError("FTP服务器数据返回异常!")
ftp.close()
# print(files)
f_list = []
dirs = []
data = []
default_time = '1971/01/01 01:01:01'
for dt in files:
# print(dt)
if mlsd:
dt_name = dt[0]
dt_info = dt[1]
else:
if dt.find("/") >= 0:
dt = dt.split("/")[-1]
tmp = {}
tmp['name'] = dt_name
if dt_name == '.' or dt_name == '..':
continue
tmp['time'] = dt_info['modify']
try:
tmp['size'] = dt_info['size']
tmp['type'] = "File"
tmp['download'] = self.generateDownloadUrl(path + dt_name)
f_list.append(tmp)
except:
tmp['size'] = dt_info['sizd']
tmp['type'] = None
tmp['download'] = ''
dirs.append(tmp)
data = dirs + f_list
mlist = {}
mlist['path'] = path
mlist['list'] = data
return mlist
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

+101
View File
@@ -0,0 +1,101 @@
<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="upyunApi()">帐户设置</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>
<script type="text/javascript">
$.getScript( "/plugins/file?name=backup_ftp&f=js/backup_ftp.js", function(){
osList('/');
});
</script>
+250
View File
@@ -0,0 +1,250 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
_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 'backup_ftp'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
sys.path.append(getPluginDir() + "/class")
from ftp_client import FtpPSClient
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getArgs():
args = sys.argv[2:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def status():
return 'start'
def getConf():
cfg = getServerDir() + "/cfg.json"
if not os.path.exists(cfg):
return mw.returnJson(False, "未配置", [])
data = mw.readFile(cfg)
data = json.loads(data)
return mw.returnJson(True, "OK", data)
def setConf():
args = getArgs()
data = checkArgs(args, ['use_sftp', 'ftp_user',
'ftp_pass', 'ftp_host', 'backup_path'])
if not data[0]:
return data[1]
cfg = getServerDir() + "/cfg.json"
values = ['ftp_user',
'ftp_pass',
'ftp_host']
for v in values:
if args[v] == '':
return mw.returnJson(False, '必填资料不能为空,请核实!', [])
if args['backup_path'] == '':
args['backup_path'] = "/backup"
try:
ftp = FtpPSClient(load_config=False)
ftp.injection_config(args)
data = ftp.getList("/")
if data:
mw.writeFile(cfg, mw.getJson(args))
return mw.returnJson(True, '设置成功', [])
except Exception as e:
return mw.returnJson(False, "FTP校验失败,请核实!\n" + str(e), [])
def getList():
cfg = getServerDir() + "/cfg.json"
if not os.path.exists(cfg):
return mw.returnJson(False, "未配置FTP,请点击`账户设置`", [])
args = getArgs()
data = checkArgs(args, ['path'])
if not data[0]:
return data[1]
try:
ftp = FtpPSClient()
flist = ftp.getList(args['path'])
return mw.returnJson(True, "ok", flist)
except Exception as e:
return mw.returnJson(False, str(e), [])
def createDir():
cfg = getServerDir() + "/cfg.json"
if not os.path.exists(cfg):
return mw.returnJson(False, "未配置FTP,请点击`账户设置`", [])
args = getArgs()
data = checkArgs(args, ['path', 'name'])
if not data[0]:
return data[1]
ftp = FtpPSClient()
isok = ftp.createDir(args['path'], args['name'])
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]
ftp = FtpPSClient()
isok = ftp.deleteDir(args['path'], 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]
ftp = FtpPSClient()
isok = ftp.deleteFile(args['path'] + "/" + args['filename'])
if isok:
return mw.returnJson(True, "删除成功")
return mw.returnJson(False, "删除失败")
def backupAllFunc(stype):
os.chdir(mw.getRunDir())
name = sys.argv[2]
num = sys.argv[3]
args = stype + " " + name + " " + num
cmd = 'python3 ' + mw.getRunDir() + '/scripts/backup.py ' + args
os.system(cmd)
# 开始执行上传信息
prefix_dict = {
"site": "web",
"database": "db",
"path": "path",
}
find_path = mw.getBackupDir() + '/' + stype + '/' + \
prefix_dict[stype] + '_' + name
find_new_file = "ls " + find_path + \
"_* | grep tar.gz | cut -d \ -f 1 | awk 'END {print}'"
filename = mw.execShell(find_new_file)[0].strip()
# print("filename:", filename)
ftp = FtpPSClient()
ftp.uploadFile(filename, stype)
return True
def backupSite():
# 备份站点
pass
def in_array(name, arr=[]):
for x in arr:
if name == x:
return True
return False
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_config':
print(setConf())
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']):
print(backupAllFunc(func))
else:
print('error')
+17
View File
@@ -0,0 +1,17 @@
{
"title":"FTP存储空间",
"hook":["backup"],
"tip":"soft",
"name":"backup_ftp",
"type":"运行环境",
"ps":"将网站或数据库打包备份到FTP存储空间",
"versions":["1.0"],
"install_pre_inspection":false,
"shell":"install.sh",
"checks":"server/backup_ftp",
"path": "server/backup_ftp",
"author":"midoks",
"home":"",
"date":"2022-10-23",
"pid": "4"
}
+32
View File
@@ -0,0 +1,32 @@
#!/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_os=`uname`
Install_App()
{
mkdir -p ${serverPath}/backup_ftp
echo "${1}" > ${serverPath}/backup_ftp/version.pl
echo '安装完成' > $install_tmp
}
Uninstall_App()
{
rm -rf ${serverPath}/backup_ftp
}
action=$1
if [ "${1}" == 'install' ];then
Install_App $2
else
Uninstall_App $2
fi
+258
View File
@@ -0,0 +1,258 @@
function bkfPost(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:'backup_ftp', 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 getFtpLocalTime(data){
var str = data.slice(0,4)+"/"+data.slice(4,6)+"/"+data.slice(6,8)
+ " " + data.slice(8,10)+":"+data.slice(10,12)+":"+data.slice(12,14);
return str;
}
// 自定义部分
var i = null;
//设置API
function upyunApi(){
bkfPost('conf', {}, function(rdata){
var rdata = $.parseJSON(rdata.data);
var token = rdata.data;
var check_status = token.use_sftp;
var sftp_checked = check_status === "true" ? " checked=\"checked\"" : "";
if (typeof(token.ftp_host) == 'undefined'){
token.ftp_host = '';
}
if (typeof(token.ftp_user) == 'undefined'){
token.ftp_user = '';
}
if (typeof(token.ftp_pass) == 'undefined'){
token.ftp_pass = '';
}
if (typeof(token.backup_path) == 'undefined'){
token.backup_path = '';
}
var apicon = '<div class="bingfa mtb15" style="padding-bottom:0px;">\
<p>\
<span class="span_tit">使用SFTP:</span>\ <input style="width: 20px; vertical-align:middle;" type="checkbox" name="use_sftp"'+sftp_checked+'> 是否使用SFTP进行数据传输 \
</p>\
<p>\
<span class="span_tit">Host:</span>\
<input placeholder="请输入主机地址" style="width: 200px;" type="text" name="upyun_service" value="'+token.ftp_host+'"> *服务器地址,FTP默认端口21, SFTP默认端口22\
</p>\
<p>\
<span class="span_tit">用户名:</span>\
<input style="width: 200px;" type="text" name="ftp_username" value="'+token.ftp_user+'"> *指定用户名\
</p>\
<p>\
<span class="span_tit">密码:</span>\
<input style="width: 200px;" type="password" name="ftp_password" value="'+token.ftp_pass+'"> *登录密码\
</p>\
<p>\
<span class="span_tit">存储位置:</span>\
<input placeholder="请输入存储位置" style="width: 200px;" type="text" name="backup_path" value="'+token.backup_path+'"> *相对于根目录的路径,默认是/backup\
</p>\
</div>';
layer.open({
type: 1,
area: "600px",
title: "FTP/SFTP帐户设置",
closeBtn: 1,
shift: 5,
shadeClose: false,
btn: ['确定','取消'],
content:apicon,
yes:function(index,layero){
var data = {
use_sftp:$("input[name='use_sftp']").prop('checked'),
ftp_user:$("input[name='ftp_username']").val(),
ftp_pass:$("input[name='ftp_password']").val(),
ftp_host:$("input[name='upyun_service']").val(),
backup_path:$("input[name='backup_path']").val()
}
bkfPost('set_config', data, function(rdata){
var rdata = $.parseJSON(rdata.data);
if (rdata.status){
showMsg(rdata.msg,function(){
layer.close(index);
osList("/");
},{icon:1},2000);
} else{
layer.msg(rdata.msg,{icon:2});
}
})
},
});
});
}
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 path = $("#myPath").val();
var dirname = name;
// var loadT = layer.msg('正在创建目录['+dirname+']...',{icon:16,time:0,shade: [0.3, '#000']});
bkfPost('create_dir', {path:path,name:dirname}, function(data){
var rdata = $.parseJSON(data.data);
if(rdata.status) {
showMsg(rdata.msg, function(){
layer.close(index);
osList(path);
} ,{icon:1}, 2000);
} else{
layer.msg(rdata.msg,{icon:2});
}
});
}
});
}
//删除文件
function deleteFile(name, is_dir){
if (is_dir === false){
safeMessage('删除文件','删除后将无法恢复,真的要删除['+name+']吗?',function(){
var path = $("#myPath").val();
var filename = name;
bkfPost('delete_file', {filename:filename,path:path}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
osList(path);
},{icon:rdata.status?1:2},2000);
});
});
} else {
safeMessage('删除文件夹','删除后将无法恢复,真的要删除['+name+']吗?',function(){
var path = $("#myPath").val();
bkfPost('delete_dir', {dir_name:name,path:path}, function(rdata){
var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg,function(){
osList(path);
},{icon:rdata.status?1:2},2000);
});
});
}
}
function osList(path){
bkfPost('get_list', {path:path}, function(rdata){
var rdata = $.parseJSON(rdata.data);
if(rdata.status === false){
showMsg(rdata.msg,function(){
upyunApi();
},{icon:2},2000);
return;
}
var mlist = rdata.data;
// console.log(mlist);
var listBody = ''
var listFiles = ''
for(var i=0;i<mlist.list.length;i++){
if(mlist.list[i].type == null){
listBody += '<tr><td class="cursor" onclick="osList(\''+(path+'/'+mlist.list[i].name).replace('//','/')+'\')"><span class="ico ico-folder"></span>\<span>'+mlist.list[i].name+'</span></td>\
<td>-</td>\
<td>-</td>\
<td class="text-right"><a class="btlink" onclick="deleteFile(\''+mlist.list[i].name+'\', true)">删除</a></td></tr>'
}else{
listFiles += '<tr><td class="cursor"><span class="ico ico-file"></span>\<span>'+mlist.list[i].name+'</span></td>\
<td>'+toSize(mlist.list[i].size)+'</td>\
<td>'+getFtpLocalTime(mlist.list[i].time)+'</td>\
<td class="text-right"><a target="_blank" href="'+mlist.list[i].download+'" class="btlink">下载</a> | <a class="btlink" onclick="deleteFile(\''+mlist.list[i].name+'\', false)">删除</a></td></tr>'
}
}
listBody += listFiles;
var pathLi='';
var tmp = path.split('/')
var pathname = '';
var n = 0;
for(var i=0;i<tmp.length;i++){
if(n > 0 && tmp[i] == '') continue;
var dirname = tmp[i];
if(dirname == '') {
dirname = '根目录';
n++;
}
pathname += '/' + tmp[i];
pathname = pathname.replace('//','/');
pathLi += '<li><a title="'+pathname+'" onclick="osList(\''+pathname+'\')">'+dirname+'</a></li>';
}
var um = 1;
if(tmp[tmp.length-1] == '') um = 2;
var backPath = tmp.slice(0,tmp.length-um).join('/') || '/';
$('#myPath').val(path);
$(".upyunCon .place-input ul").html(pathLi);
$(".upyunlist .list-list").html(listBody);
upPathLeft();
$('#backBtn').unbind().click(function() {
osList(backPath);
});
$('.upyunCon .refreshBtn').unbind().click(function(){
osList(path);
});
});
}
//计算当前目录偏移
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)
}
}
// $('.layui-layer-page').css('height','670px');
+5 -1
View File
@@ -3,6 +3,7 @@
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('clean');">服务</p>
<p onclick="pluginConfig('clean');">配置修改</p>
<p onclick="pluginLogs('clean',null,'run_log');">运行日志</p>
<p onclick="pRead()">说明</p>
</div>
<div class="bt-w-con pd15">
@@ -16,7 +17,10 @@ pluginService('clean');
function pRead(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/clean/index.py clean</li>';
readme += '<li>启动后,假如到计划中[2:30]执行。</li>';
readme += '<li>【*】代表要删除。</li>';
readme += '<li>添加/删除清除日志,可在`配置修改`中添加/删除。</li>';
readme += '<li>如果是目录,会寻找【.log】后缀的文件清空。</li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
+96 -70
View File
@@ -53,34 +53,95 @@ def getArgs():
return tmp
def getLockFile():
return getServerDir() + "/installed_lock.pl"
def runLog():
return getServerDir() + "/clean.log"
def status():
if os.path.exists(getConf()):
initConf()
if os.path.exists(getLockFile()):
return "start"
return 'stop'
def initConf():
conf = getConf()
if not os.path.exists(conf):
content = ""
clog = [
"/var/log/cron-*",
"/var/log/maillog-*",
"/var/log/secure-*",
"/var/log/spooler-*",
"/var/log/yum.log-*",
"/var/log/messages-*",
"/var/log/btmp-*",
"/var/log/audit/audit.log.*",
"/var/log/rhsm/rhsm.log-*",
"/var/log/rhsm/rhsmcertd.log-*",
"/tmp/yum_save_*",
"/tmp/tmp.*",
]
for i in clog:
content += i + "\n"
# 常用日志
clogcom = [
"/var/log/messages",
"/var/log/btmp",
"/var/log/wtmp",
"/var/log/secure",
"/var/log/lastlog",
"/var/log/cron",
"/www/server/cron"
]
for i in clogcom:
if os.path.exists(i):
content += i + "\n"
# 清理日志
rootDir = "/var/log"
l = os.listdir(rootDir)
for x in range(len(l)):
abspath = rootDir + "/" + l[x]
content += abspath + "\n"
mw.writeFile(conf, content)
def start():
file = initDreplace()
data = mw.execShell(file + ' start')
if data[1] == '':
initConf()
lock_file = getLockFile()
if not os.path.exists(lock_file):
mw.writeFile(lock_file, "")
import tool_task
tool_task.createBgTask()
return 'ok'
return 'fail'
def stop():
file = initDreplace()
data = mw.execShell(file + ' stop')
if data[1] == '':
initConf()
lock_file = getLockFile()
if os.path.exists(lock_file):
os.remove(lock_file)
import tool_task
tool_task.removeBgTask()
return 'ok'
return 'fail'
def reload():
file = initDreplace()
data = mw.execShell(file + ' reload')
if data[1] == '':
return 'ok'
return 'fail'
return 'ok'
def get_filePath_fileName_fileExt(filename):
@@ -93,15 +154,20 @@ def cleanFileLog(path):
filepath, shotname, extension = get_filePath_fileName_fileExt(path)
if extension == ".log":
cmd = "echo \"\" > " + path
tmp = mw.execShell(cmd)
if tmp[1] != "":
cmd += " | error:" + tmp[1].strip()
print(cmd)
print(mw.execShell(cmd))
def cleanSelfFileLog(path):
filepath, shotname, extension = get_filePath_fileName_fileExt(path)
cmd = "echo \"\" > " + path
print(cmd)
print(mw.execShell(cmd))
if extension == ".log":
cmd = "echo \"\" > " + path
tmp = mw.execShell(cmd)
if tmp[1] != "":
cmd += " | error:" + tmp[1].strip()
print(cmd)
def cleanDirLog(path):
@@ -115,70 +181,28 @@ def cleanDirLog(path):
def cleanLog():
# 清理日志
rootDir = "/var/log"
print("clean start")
clog = [
"rm -rf /var/log/cron-*",
"rm -rf /var/log/maillog-*",
"rm -rf /var/log/secure-*",
"rm -rf /var/log/spooler-*",
"rm -rf /var/log/yum.log-*",
"rm -rf /var/log/messages-*",
"rm -rf /var/log/btmp-*",
"rm -rf /var/log/audit/audit.log.*",
"rm -rf /var/log/rhsm/rhsm.log-*",
"rm -rf /var/log/rhsm/rhsmcertd.log-*",
"rm -rf /tmp/yum_save_*",
"rm -rf /tmp/tmp.*",
]
for i in clog:
print(i)
mw.execShell(i)
# 常用日志
clogcom = [
"/var/log/messages",
"/var/log/btmp",
"/var/log/wtmp",
"/var/log/secure",
"/var/log/lastlog",
"/var/log/cron",
]
for i in clogcom:
if os.path.exists(i):
mw.execShell("echo \"\" > " + i)
l = os.listdir(rootDir)
for x in range(len(l)):
abspath = rootDir + "/" + l[x]
if os.path.isfile(abspath):
cleanFileLog(abspath)
if os.path.isdir(abspath):
cleanDirLog(abspath)
print("conf clean")
confFile = getServerDir()
# mw.readFile()
confFile = confFile + "/clean.conf"
clist = mw.readFile(confFile).strip()
conf = getConf()
clist = mw.readFile(conf).strip()
clist = clist.split("\n")
for x in clist:
abspath = x.strip()
if abspath.find('*') > 1:
cmd = 'rm -rf ' + abspath
print(cmd)
data = mw.execShell(cmd)
# print(data)
continue
if os.path.exists(abspath):
if os.path.isfile(abspath):
cleanSelfFileLog(abspath)
continue
if os.path.isdir(abspath):
cleanDirLog(abspath)
print("conf clean end")
print("clean end")
continue
if __name__ == "__main__":
func = sys.argv[1]
@@ -194,6 +218,8 @@ if __name__ == "__main__":
print(reload())
elif func == 'conf':
print(getConf())
elif func == 'run_log':
print(runLog())
elif func == 'clean':
cleanLog()
else:
+6 -2
View File
@@ -13,20 +13,24 @@ serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
VERSION=$2
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
Install_app()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/clean
echo "" > $serverPath/clean/clean.conf
cd ${rootPath} && python3 ${rootPath}/plugins/clean/index.py start
echo "${VERSION}" > $serverPath/clean/version.pl
echo '安装完成' > $install_tmp
}
Uninstall_app()
{
cd ${rootPath} && python3 ${rootPath}/plugins/clean/index.py stop
rm -rf $serverPath/clean
echo "Uninstall_clean" > $install_tmp
}
+156
View File
@@ -0,0 +1,156 @@
# coding:utf-8
import sys
import io
import os
import time
import json
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'clean'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
def getTaskConf():
conf = getServerDir() + "/task_config.json"
return conf
def getConfigData():
try:
return json.loads(mw.readFile(getTaskConf()))
except:
pass
return []
def getConfigTpl():
tpl = {
"name": "",
"task_id": -1,
}
return tpl
def createBgTask():
removeBgTask()
args = {
"period": "day",
"hour": "2",
"minute": "30",
}
createBgTaskByName(getPluginName(), args)
def createBgTaskByName(name, args):
cfg = getConfigTpl()
_name = "[勿删]日志清理[" + name + "]"
res = mw.M("crontab").field("id, name").where("name=?", (_name,)).find()
if res:
return True
if "task_id" in cfg.keys() and cfg["task_id"] > 0:
res = mw.M("crontab").field("id, name").where(
"id=?", (cfg["task_id"],)).find()
if res and res["id"] == cfg["task_id"]:
print("计划任务已经存在!")
return True
import crontab_api
api = crontab_api.crontab_api()
period = args['period']
_hour = ''
_minute = ''
_where1 = ''
_type_day = "day"
if period == 'day':
_type_day = 'day'
_hour = args['hour']
_minute = args['minute']
elif period == 'minute-n':
_type_day = 'minute-n'
_where1 = args['minute-n']
_minute = ''
mw_dir = mw.getRunDir()
cmd = '''
mw_dir=%s
rname=%s
plugin_path=%s
script_path=%s
logs_file=$plugin_path/${rname}.log
''' % (mw_dir, name, getServerDir(), getPluginDir())
cmd += 'echo "★【`date +"%Y-%m-%d %H:%M:%S"`】 STSRT★" >> $logs_file' + "\n"
cmd += 'echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" >> $logs_file' + "\n"
cmd += 'echo "python3 $script_path/index.py clean >> $logs_file 2>&1"' + "\n"
cmd += 'cd $mw_dir && python3 $script_path/index.py clean >> $logs_file 2>&1' + "\n"
cmd += 'echo "【`date +"%Y-%m-%d %H:%M:%S"`】 END★" >> $logs_file' + "\n"
cmd += 'echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" >> $logs_file' + "\n"
params = {
'name': _name,
'type': _type_day,
'week': "",
'where1': _where1,
'hour': _hour,
'minute': _minute,
'save': "",
'backup_to': "",
'stype': "toShell",
'sname': '',
'sbody': cmd,
'urladdress': '',
}
task_id = api.add(params)
if task_id > 0:
cfg["task_id"] = task_id
cfg["name"] = name
_dd = getConfigData()
_dd.append(cfg)
mw.writeFile(getTaskConf(), json.dumps(_dd))
def removeBgTask():
cfg_list = getConfigData()
for x in range(len(cfg_list)):
cfg = cfg_list[x]
if "task_id" in cfg.keys() and cfg["task_id"] > 0:
res = mw.M("crontab").field("id, name").where(
"id=?", (cfg["task_id"],)).find()
if res and res["id"] == cfg["task_id"]:
import crontab_api
api = crontab_api.crontab_api()
data = api.delete(cfg["task_id"])
if data[0]:
cfg["task_id"] = -1
cfg_list[x] = cfg
mw.writeFile(getTaskConf(), '[]')
return True
return False
if __name__ == "__main__":
if len(sys.argv) > 1:
action = sys.argv[1]
if action == "remove":
removeBgTask()
elif action == "add":
createBgTask()
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
echo `date`
GITADDR="{$GITROOTURL}/{$USERNAME}/{$PROJECT}.git"
GIT_SDIR="{$CODE_DIR}"
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
git config --global credential.helper store
# echo $GIT_PROJECT_DIR
if [ ! -d $GIT_PROJECT_DIR ];then
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
git clone $GITADDR
fi
unset GIT_DIR
cd $GIT_PROJECT_DIR && git pull
# func 2
# cd $GIT_PROJECT_DIR && env -i git pull origin master
#更新的目的地址
WEB_PATH={$WEB_ROOT}/{$USERNAME}/{$PROJECT}
mkdir -p $WEB_PATH
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
sysName=`uname`
if [ $sysName == 'Darwin' ]; then
USER=$(who | sed -n "2,1p" |awk '{print $1}')
chown -R $USER:staff $WEB_PATH
else
chown -R www:www $WEB_PATH
fi
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
echo `date`
GITADDR="{$GITROOTURL}/{$USERNAME}/{$PROJECT}"
GIT_SDIR="{$CODE_DIR}"
GIT_USER_DIR="${GIT_SDIR}/{$USERNAME}"
GIT_PROJECT_DIR="${GIT_USER_DIR}/{$PROJECT}"
# echo $GIT_PROJECT_DIR
if [ ! -d $GIT_PROJECT_DIR ];then
mkdir -p $GIT_USER_DIR && cd $GIT_USER_DIR
git clone $GITADDR
fi
unset GIT_DIR
cd $GIT_PROJECT_DIR && git pull
# func 2
# cd $GIT_PROJECT_DIR && env -i git pull origin master
WEB_PATH={$WEB_ROOT}/{$USERNAME}/{$PROJECT}
mkdir -p $WEB_PATH
rsync -vauP --delete --exclude=".*" $GIT_PROJECT_DIR/ $WEB_PATH
sysName=`uname`
if [ $sysName == 'Darwin' ]; then
USER=$(who | sed -n "2,1p" |awk '{print $1}')
chown -R $USER:staff $WEB_PATH
else
chown -R www:www $WEB_PATH
fi
+3
View File
@@ -0,0 +1,3 @@
#!/bin/bash
sh -x {$PATH}/commit 2>{$PATH}/sh.log
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

+24
View File
@@ -0,0 +1,24 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('gitea');">服务</p>
<p onclick="pluginInitD('gitea');">自启动</p>
<!-- <p onclick="pluginConfig('gitea',null, 'init_conf');">启动配置</p> -->
<p onclick="gogsEdit();">手动编辑</p>
<p onclick="pluginConfig('gitea',null, 'conf');">配置文件</p>
<p onclick="gogsSetConfig();">配置修改</p>
<p onclick="giteaUserList();">用户列表</p>
<p onclick="pluginLogs('gitea',null,'run_log');">运行日志</p>
<p onclick="pluginLogs('gitea',null,'post_receive_log');" title="提交post-receive日志">提交日志</p>
<p onclick="giteaRead();">使用说明</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=gitea&f=js/gitea.js",function(){
pluginService('gitea');
});
</script>
@@ -11,11 +11,10 @@ sys.path.append(os.getcwd() + "/class/core")
import mw
cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
info = mw.execShell(cmd)
p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
sys.path.append(p)
import psutil
# cmd = 'ls /usr/local/lib/ | grep python | cut -d \\ -f 1 | awk \'END {print}\''
# info = mw.execShell(cmd)
# p = "/usr/local/lib/" + info[0].strip() + "/site-packages"
# sys.path.append(p)
app_debug = False
@@ -24,15 +23,12 @@ if mw.isAppleSystem():
def getPluginName():
return 'gogs'
return 'gitea'
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
sys.path.append(getPluginDir() + "/class")
import mysqlDb
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
@@ -61,18 +57,28 @@ def getArgs():
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def getInitdConfTpl():
path = getPluginDir() + "/init.d/gogs.tpl"
path = getPluginDir() + "/init.d/gitea.tpl"
return path
def getInitdConf():
path = getServerDir() + "/init.d/gogs"
path = getServerDir() + "/init.d/gitea"
return path
def getConf():
path = getServerDir() + "/custom/conf/app.ini"
if not os.path.exists(path):
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
return path
@@ -95,7 +101,7 @@ def getHomeDir():
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return '/Users/' + user
else:
return '/root'
return 'git'
def getRunUser():
@@ -104,7 +110,7 @@ def getRunUser():
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return user
else:
return 'root'
return 'git'
__SR = '''#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
@@ -140,13 +146,16 @@ def initDreplace():
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
conf_bin = getConf()
if not os.path.exists(conf_bin):
mw.execShell('mkdir -p ' + getServerDir() + '/custom/conf')
conf_tpl = getConfTpl()
content = mw.readFile(conf_tpl)
content = contentReplace(content)
mw.writeFile(conf_bin, content)
# systemd
systemDir = mw.systemdCfgDir()
systemService = systemDir + '/gitea.service'
systemServiceTpl = getPluginDir() + '/init.d/gitea.service.tpl'
if os.path.exists(systemDir) and not os.path.exists(systemService):
service_path = mw.getServerDir()
se_content = mw.readFile(systemServiceTpl)
se_content = se_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(systemService, se_content)
mw.execShell('systemctl daemon-reload')
log_path = getServerDir() + '/log'
if not os.path.exists(log_path):
@@ -159,9 +168,14 @@ def getRootUrl():
content = mw.readFile(getConf())
rep = 'ROOT_URL\s*=\s*(.*)'
tmp = re.search(rep, content)
if not tmp:
return ''
return tmp.groups()[0]
if tmp:
return tmp.groups()[0]
rep = 'EXTERNAL_URL\s*=\s*(.*)'
tmp = re.search(rep, content)
if tmp:
return tmp.groups()[0]
return ''
def getSshPort():
@@ -192,8 +206,11 @@ def getRootPath():
def getDbConfValue():
content = mw.readFile(getConf())
conf = getConf()
if not os.path.exists(conf):
return {}
content = mw.readFile(conf)
rep_scope = "\[database\](.*?)\["
tmp = re.findall(rep_scope, content, re.S)
@@ -207,18 +224,72 @@ def getDbConfValue():
return r
def pMysqlDb():
conf = getDbConfValue()
def pMysqlDb(conf):
host = conf['HOST'].split(':')
conn = mysqlDb.mysqlDb()
# pymysql
db = mw.getMyORM()
# MySQLdb |
# db = mw.getMyORMDb()
conn.setHost(host[0])
conn.setUser(conf['USER'])
conn.setPwd(conf['PASSWD'])
conn.setPort(int(host[1]))
conn.setDb(conf['NAME'])
return conn
db.setPort(int(host[1]))
db.setUser(conf['USER'])
if 'PASSWD' in conf:
db.setPwd(conf['PASSWD'])
else:
db.setPwd(conf['PASSWORD'])
db.setDbName(conf['NAME'])
# db.setSocket(getSocketFile())
db.setCharset("utf8")
return db
def pSqliteDb(conf):
# print(conf)
import db
psDb = db.Sql()
# 默认
gsdir = getServerDir() + '/data'
dbname = 'gitea'
if conf['PATH'][0] == '/':
# 绝对路径
pass
else:
path = conf['PATH'].split('/')
gsdir = getServerDir() + '/' + path[0]
dbname = path[1].split('.')[0]
# print(gsdir, dbname)
psDb.dbPos(gsdir, dbname)
return psDb
def getGiteaDbType(conf):
if 'DB_TYPE' in conf:
return conf['DB_TYPE']
if 'TYPE' in conf:
return conf['TYPE']
return 'NONE'
def pQuery(sql):
conf = getDbConfValue()
gtype = getGiteaDbType(conf)
if gtype == 'sqlite3':
db = pSqliteDb(conf)
data = db.query(sql, []).fetchall()
return data
elif gtype == 'mysql':
db = pMysqlDb(conf)
return db.query(sql)
print("仅支持mysql|sqlite3配置")
exit(0)
def isSqlError(mysqlMsg):
@@ -244,93 +315,66 @@ def isSqlError(mysqlMsg):
return mw.returnData(True, 'OK')
def start():
is_frist = True
conf_bin = getConf()
if os.path.exists(conf_bin):
is_frist = False
def appOp(method):
file = initDreplace()
if is_frist:
return "第一次启动Gogs,默认使用MySQL连接!<br>可以在配置文件中重新设置,再启动!"
if not mw.isAppleSystem():
data = mw.execShell('systemctl ' + method + ' ' + getPluginName())
if data[1] == '':
return 'ok'
return 'fail'
conn = pMysqlDb()
list_table = conn.query('show tables')
data = isSqlError(list_table)
if not data['status']:
return data['msg']
data = mw.execShell(__SR + file + ' start')
data = mw.execShell(__SR + file + ' ' + method)
if data[1] == '':
return 'ok'
return data[0]
def start():
return appOp('start')
def stop():
file = initDreplace()
data = mw.execShell(__SR + file + ' stop')
if data[1] == '':
return 'ok'
return data[1]
return appOp('stop')
def restart():
file = initDreplace()
data = mw.execShell(__SR + file + ' restart')
if data[1] == '':
return 'ok'
return data[1]
return appOp('restart')
def reload():
file = initDreplace()
data = mw.execShell(__SR + file + ' reload')
if data[1] == '':
return 'ok'
return data[1]
return appOp('reload')
def initdStatus():
if not app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
initd_bin = getInitDFile()
if os.path.exists(initd_bin):
return 'ok'
return 'fail'
if mw.isAppleSystem():
return "Apple Computer does not support"
shell_cmd = 'systemctl status gitea | grep loaded | grep "enabled;"'
data = mw.execShell(shell_cmd)
if data[0] == '':
return 'fail'
return 'ok'
def initdInstall():
import shutil
if not app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
if mw.isAppleSystem():
return "Apple Computer does not support"
mem_bin = initDreplace()
initd_bin = getInitDFile()
shutil.copyfile(mem_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
mw.execShell('chkconfig --add ' + getPluginName())
mw.execShell('systemctl enable gitea')
return 'ok'
def initdUinstall():
if not app_debug:
os_name = mw.getOs()
if os_name == 'darwin':
return "Apple Computer does not support"
initd_bin = getInitDFile()
os.remove(initd_bin)
mw.execShell('chkconfig --del ' + getPluginName())
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl disable gitea')
return 'ok'
def runLog():
log_path = getServerDir() + '/log/gogs.log'
log_path = getServerDir() + '/log/gitea.log'
return log_path
@@ -340,6 +384,10 @@ def postReceiveLog():
def getGogsConf():
conf = getConf()
if not os.path.exists(conf):
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
gets = [
{'name': 'DOMAIN', 'type': -1, 'ps': '服务器域名'},
{'name': 'ROOT_URL', 'type': -1, 'ps': '公开的完整URL路径'},
@@ -360,7 +408,7 @@ def getGogsConf():
{'name': 'SHOW_FOOTER_VERSION', 'type': 2, 'ps': 'Gogs版本信息'},
{'name': 'SHOW_FOOTER_TEMPLATE_LOAD_TIME', 'type': 2, 'ps': 'Gogs模板加载时间'},
]
conf = mw.readFile(getConf())
conf = mw.readFile(conf)
result = []
for g in gets:
@@ -370,7 +418,7 @@ def getGogsConf():
continue
g['value'] = tmp.groups()[0]
result.append(g)
return mw.getJson(result)
return mw.returnJson(True, 'OK', result)
def submitGogsConf():
@@ -402,18 +450,27 @@ def submitGogsConf():
def userList():
conf = getConf()
if not os.path.exists(conf):
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
conf = getDbConfValue()
gtype = getGiteaDbType(conf)
if gtype != 'mysql':
return mw.returnJson(False, "仅支持mysql数据操作!")
import math
args = getArgs()
page = 1
page_size = 10
data = checkArgs(args, ['page', 'page_size'])
if not data[0]:
return data[1]
page = int(args['page'])
page_size = int(args['page_size'])
tojs = args['tojs']
search = ''
if 'page' in args:
page = int(args['page'])
if 'page_size' in args:
page_size = int(args['page_size'])
if 'search' in args:
search = args['search']
@@ -421,17 +478,14 @@ def userList():
data['root_url'] = getRootUrl()
pm = pMysqlDb()
start = (page - 1) * page_size
list_count = pm.query('select count(id) as num from user')
count = list_count[0][0]
list_count = pQuery('select count(id) as num from user')
list_data = pm.query(
count = list_count[0]["num"]
list_data = pQuery(
'select id,name,email from user order by id desc limit ' + str(start) + ',' + str(page_size))
page_info = {'count': count, 'p': page,
'row': page_size, 'tojs': 'gogsUserList'}
data['list'] = mw.getPage(page_info)
data['list'] = mw.getPage(
{'count': count, 'p': page, 'row': page_size, 'tojs': tojs})
data['page'] = page
data['page_size'] = page_size
data['page_count'] = int(math.ceil(count / page_size))
@@ -556,8 +610,8 @@ def projectScriptLoad():
cc_content = mw.readFile(commit_tpl)
sshUrl = 'http://127.0.0.1:' + getHttpPort()
cc_content = cc_content.replace('{$GITROOTURL}', sshUrl)
gitPath = getRootPath()
cc_content = cc_content.replace('{$GITROOTURL}', gitPath)
cc_content = cc_content.replace('{$CODE_DIR}', codeDir)
cc_content = cc_content.replace('{$USERNAME}', user)
cc_content = cc_content.replace('{$PROJECT}', args['name'])
@@ -570,11 +624,9 @@ def projectScriptLoad():
def projectScriptUnload():
args = getArgs()
if not 'user' in args:
return mw.returnJson(True, 'username missing')
if not 'name' in args:
return mw.returnJson(True, 'project name missing')
data = checkArgs(args, ['user', 'name'])
if not data[0]:
return data[1]
user = args['user']
name = args['name'] + '.git'
@@ -591,11 +643,10 @@ def projectScriptUnload():
def projectScriptDebug():
args = getArgs()
if not 'user' in args:
return mw.returnJson(True, 'username missing')
data = checkArgs(args, ['user', 'name'])
if not data[0]:
return data[1]
if not 'name' in args:
return mw.returnJson(True, 'project name missing')
user = args['user']
name = args['name'] + '.git'
commit_log = getRootPath() + '/' + user + '/' + name + \
@@ -634,14 +685,8 @@ def getTotalStatistics():
st = status()
data = {}
if st.strip() == 'start':
pm = pMysqlDb()
list_count = pm.query('select count(id) as num from repository')
if list_count.find("error") > -1:
data['status'] = False
data['count'] = 0
return mw.returnJson(False, 'fail', data)
list_count = pQuery('select count(id) as num from repository')
count = list_count[0]["num"]
data['status'] = True
data['count'] = count
data['ver'] = mw.readFile(getServerDir() + '/version.pl').strip()
+16
View File
@@ -0,0 +1,16 @@
{
"ps": "Gitea 是一个开源社区驱动的轻量级代码托管解决方案。",
"name": "gitea",
"title": "Gitea",
"versions": ["1.17.2"],
"tip": "soft",
"checks": "server/gitea",
"path":"server/gitea",
"author": "gitea",
"date": "2022-10-03",
"home": "https://dl.gitea.io/",
"type": "Git服务器",
"shell": "install.sh",
"pid": "3",
"sort": 7
}
+20
View File
@@ -0,0 +1,20 @@
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory={$SERVER_PATH}/gitea
ExecStart={$SERVER_PATH}/gitea/gitea web
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
RemainAfterExit=yes
#AmbientCapabilities=CAP_NET_BIND_SERVICE
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
+110
View File
@@ -0,0 +1,110 @@
#!/bin/sh
#
# /etc/rc.d/init.d/Gitea
#
# Runs the Gogs
#
#
# chkconfig: - 85 15
#
### BEGIN INIT INFO
# Provides: Gitea
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: mysql postgresql
# Should-Stop: mysql postgresql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start Gitea at boot time.
# Description: Control Gitea.
### END INIT INFO
# Source function library.
if [ -f /etc/init.d/functions ];then
. /etc/init.d/functions
fi
if [ -f /etc/rc.d/init.d/functions ];then
. /etc/rc.d/init.d/functions
fi
# Default values
export HOME={$HOME_DIR}
export USER={$RUN_USER}
NAME=gitea
GOGS_HOME={$SERVER_PATH}/gitea
GOGS_PATH=${GOGS_HOME}/$NAME
GOGS_USER={$RUN_USER}
SERVICENAME="gitea"
LOCKFILE=/tmp/gitea.lock
LOGPATH=${GOGS_HOME}/log
LOGFILE=${LOGPATH}/gitea.log
RETVAL=0
[ -r /etc/sysconfig/$NAME ] && . /etc/sysconfig/$NAME
DAEMON_OPTS="--check $NAME"
[ ! -z "$GOGS_USER" ] && DAEMON_OPTS="$DAEMON_OPTS --user=${GOGS_USER}"
status(){
isStart=`ps -ef|grep 'gitea web' |grep -v grep|awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "${SERVICENAME} not running"
else
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
start() {
isStart=`ps -ef|grep 'gitea web' |grep -v grep|awk '{print $2}'`
if [ "$isStart" != '' ];then
echo "${SERVICENAME}(pid $(echo $isStart)) already running"
return $RETVAL
fi
cd ${GOGS_HOME}
echo -e "Starting ${SERVICENAME}: \c"
${GOGS_PATH} web > ${LOGFILE} 2>&1 &
RETVAL=$?
[ $RETVAL = 0 ] && touch ${LOCKFILE} && echo -e "\033[32mdone\033[0m"
return $RETVAL
}
stop() {
pids=`ps -ef|grep 'gitea web' |grep -v grep|awk '{print $2}'`
arr=($pids)
echo -e "Stopping gitea... \c"
for p in ${arr[@]}
do
kill -9 $p
done
echo -e "\033[32mdone\033[0m"
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
restart)
stop
start
;;
reload)
stop
start
;;
*)
echo "Usage: ${NAME} {start|stop|status|restart}"
exit 1
;;
esac
exit $RETVAL
+111
View File
@@ -0,0 +1,111 @@
#!/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
if [ -f ${rootPath}/bin/activate ];then
source ${rootPath}/bin/activate
fi
URL_DOWNLOAD=https://dl.gitea.io/
getOs(){
os=`uname`
if [ "Darwin" == "$os" ];then
echo 'darwin'
else
echo 'linux'
fi
return 0
}
getBit(){
echo `getconf LONG_BIT`
}
Install_App()
{
mkdir -p $serverPath/source/gitea
if id git &> /dev/null ;then
echo "git UID is `id -u git`"
echo "git Shell is `grep "^git:" /etc/passwd |cut -d':' -f7 `"
else
groupadd git
useradd -g git git
fi
echo '正在安装脚本文件...' > $install_tmp
version=$1
os=`getOs`
git config --global push.default simple
if [ "darwin" == "$os" ];then
file=gitea-${version}-darwin-10.12-amd64
else
file=gitea-${version}-linux-amd64
fi
file_xz="${file}.xz"
echo "wget -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}"
if [ ! -f $serverPath/source/gitea/$file_xz ];then
wget -O $serverPath/source/gitea/$file_xz ${URL_DOWNLOAD}/gitea/${version}/${file_xz}
fi
cd $serverPath/source/gitea && xz -k -d $file_xz
if [ -f $file ];then
mkdir -p $serverPath/gitea
mv $serverPath/source/gitea/$file $serverPath/gitea/gitea
chmod +x $serverPath/gitea/gitea
chown -R git:git $serverPath/gitea
fi
if [ -d $serverPath/gitea ];then
echo $version > $serverPath/gitea/version.pl
cd ${rootPath} && python3 plugins/gitea/index.py start
cd ${rootPath} && python3 plugins/gitea/index.py initd_install
fi
echo 'install success' > $install_tmp
}
Uninstall_App()
{
if [ -f /usr/lib/systemd/system/gitea.service ];then
systemctl stop gitea
systemctl disable gitea
rm -rf /usr/lib/systemd/system/gitea.service
systemctl daemon-reload
fi
if [ -f $serverPath/gitea/initd/gitea ];then
$serverPath/gitea/initd/gitea stop
fi
rm -rf $serverPath/gitea
echo 'uninstall success' > $install_tmp
}
action=$1
version=$2
if [ "${1}" == 'install' ];then
Install_App $version
else
Uninstall_App $version
fi
+353
View File
@@ -0,0 +1,353 @@
function str2Obj(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
}
function gogsPost(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
} else {
_args = JSON.stringify(args);
}
var _title = '正在获取...';
if (typeof(title) != 'undefined'){
_title = title;
}
var loadT = layer.msg(_title, { icon: 16, time: 0, shade: 0.3 });
$.post('/plugins/run', {name:'gitea', func:method, args:_args}, function(data) {
layer.close(loadT);
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function gogsSetConfig(){
gogsPost('get_gogs_conf', '', function(data){
var rrdata = $.parseJSON(data.data);
if (!rrdata.status){
layer.msg(rrdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
var rdata = rrdata.data;
var mlist = '';
for (var i = 0; i < rdata.length; i++) {
var w = '140';
if (rdata[i].name == 'error_reporting') w = '250';
var ibody = '<input style="width: ' + w + 'px;" class="bt-input-text mr5" name="' + rdata[i].name + '" value="' + rdata[i].value + '" type="text" >';
switch (rdata[i].type) {
case 0:
var selected_1 = (rdata[i].value == 1) ? 'selected' : '';
var selected_0 = (rdata[i].value == 0) ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="1" ' + selected_1 + '>开启</option>\
<option value="0" ' + selected_0 + '>关闭</option>\
</select>';
break;
case 1:
var selected_1 = (rdata[i].value == 'On') ? 'selected' : '';
var selected_0 = (rdata[i].value == 'Off') ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="On" ' + selected_1 + '>开启</option>\
<option value="Off" ' + selected_0 + '>关闭</option></select>'
break;
case 2:
var selected_1 = (rdata[i].value == 'true') ? 'selected' : '';
var selected_0 = (rdata[i].value == 'false') ? 'selected' : '';
ibody = '<select class="bt-input-text mr5" name="' + rdata[i].name + '" style="width: ' + w + 'px;">\
<option value="true" ' + selected_1 + '>开启</option>\
<option value="false" ' + selected_0 + '>关闭</option></select>'
break;
}
mlist += '<p><span>' + rdata[i].name + '</span>' + ibody + ', <font>' + rdata[i].ps + '</font></p>'
}
var html = '<style>.conf_p p{margin-bottom: 2px}</style><div class="conf_p" style="margin-bottom:0">\
' + mlist + '\
<div style="margin-top:10px; padding-right:15px" class="text-right">\
<button class="btn btn-success btn-sm mr5" onclick="gogsSetConfig()">刷新</button>\
<button class="btn btn-success btn-sm" onclick="submitGogsConf()">保存</button></div>\
</div>';
$(".soft-man-con").html(html);
});
}
//提交PHP配置
function submitGogsConf() {
var data = {
DOMAIN: $("input[name='DOMAIN']").val(),
ROOT_URL: $("input[name='ROOT_URL']").val(),
HTTP_ADDR: $("select[name='HTTP_ADDR']").val(),
HTTP_PORT: $("input[name='HTTP_PORT']").val(),
START_SSH_SERVER: $("select[name='START_SSH_SERVER']").val() || 'false',
SSH_PORT: $("input[name='SSH_PORT']").val(),
REQUIRE_SIGNIN_VIEW: $("select[name='REQUIRE_SIGNIN_VIEW']").val() || 'false',
ENABLE_CAPTCHA: $("select[name='ENABLE_CAPTCHA']").val() || 'true',
DISABLE_REGISTRATION: $("select[name='DISABLE_REGISTRATION']").val() || 'false',
ENABLE_NOTIFY_MAIL: $("select[name='ENABLE_NOTIFY_MAIL']").val() || 'false',
FORCE_PRIVATE: $("select[name='FORCE_PRIVATE']").val() || 'false',
SHOW_FOOTER_BRANDING: $("select[name='SHOW_FOOTER_BRANDING']").val() || 'false',
SHOW_FOOTER_VERSION: $("select[name='SHOW_FOOTER_VERSION']").val() || 'false',
SHOW_FOOTER_TEMPLATE_LOAD_TIME: $("select[name='SHOW_FOOTER_TEMPLATE_LOAD_TIME']").val() || 'false',
};
gogsPost('submit_gogs_conf', data, function(ret_data){
var rdata = $.parseJSON(ret_data.data);
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
gogsSetConfig();
});
}
function gogsEdit(){
gogsPost('gogs_edit',{} , function(data){
// console.log(data);
var rdata = $.parseJSON(data.data);
var edit = '<p class="status">通用的手动编辑:</p>';
edit +='<div class="sfm-opt">\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['post_receive']+'\');">post-receive.tpl</button>\
<button class="btn btn-default btn-sm" onclick="onlineEditFile(0,\''+rdata['commit']+'\');">commit.tpl</button>\
</div>';
$(".soft-man-con").html(edit);
});
}
function giteaUserList(page, search) {
var _data = {};
if (typeof(page) =='undefined'){
var page = 1;
}
_data['page'] = page;
_data['page_size'] = 10;
if(typeof(search) != 'undefined'){
_data['search'] = search;
}
_data['tojs'] = 'giteaUserList';
gogsPost('user_list', _data, function(data){
var rdata = $.parseJSON(data.data);
if (!rdata.status){
layer.msg(rdata.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
content = '<div class="finduser"><input class="bt-input-text mr5 outline_no" type="text" placeholder="查找用户名" id="find_user" style="height: 28px; border-radius: 3px;width: 435px;">';
content += '<button class="btn btn-success btn-sm" onclick="userFind();">查找</button></div>';
content += '<div class="divtable" style="margin-top:5px;"><table class="table table-hover" width="100%" cellspacing="0" cellpadding="0" border="0">';
content += '<thead><tr>';
content += '<th>序号</th>';
content += '<th>用户或组织</th>';
content += '<th>邮件地址</th>';
content += '<th>操作(<a href="'+rdata['data']['root_url']+'" class="btlink" target="_blank">WEB管理</a>)</th>';
content += '</tr></thead>';
content += '<tbody>';
ulist = rdata['data']['data'];
for (i in ulist){
email = ulist[i]["email"] == '' ? '无' : ulist[i]["email"];
content += '<tr><td>'+ulist[i]["id"]+'</td>'+
'<td>'+ulist[i]["name"]+'</td>'+
'<td>'+email+'</td>'+
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i]["name"]+'\')">项目管理</a></td>'+
'</tr>';
}
content += '</tbody>';
content += '</table></div>';
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata['data']['list'];
page += '</div></ul></div>';
content += page;
$(".soft-man-con").html(content);
});
}
function userProjectList(user, search){
var req = {};
if (!isNaN(user)){
req['page'] = user;
req['name'] = user = getCookie('gogsUserSelected');
} else {
req['page'] = 1;
req['name'] = user;
setCookie('gogsUserSelected', user);
}
req['page_size'] = 5;
req['search'] = '';
if(typeof(search) != 'undefined'){
req['search'] = search;
}
$('.layui-layer-close1').click();
gogsPost('user_project_list', req, function(data){
var rdata = [];
try {
rdata = $.parseJSON(data.data);
} catch(e){}
if (!rdata['status']){
layer.msg(rdata['msg'], { icon: 2 });
return;
}
var list = '';
// console.log(rdata);
var project_list = rdata['data']['data'];
for (i in project_list) {
var name = project_list[i]['name'];
list += '<tr><td>'+name+'</td>\
<td>\
<a class="btlink" target="_blank" href="'+rdata['data']['root_url']+user+'/'+name+'">源码</a> | \
<a class="btlink" onclick="projectScript(\''+user+'\',\''+name+'\','+project_list[i]['has_hook']+');">脚本</a>\
</td>\
</tr>';
}
var page = '<div class="dataTables_paginate paging_bootstrap pagination" style="margin-top:0px;"><ul id="softPage" class="page"><div>';
page += rdata['data']['list'];
page += '</div></ul></div>';
var loadOpen = layer.open({
type: 1,
title: '用户('+user+')项目列表',
area: '500px',
content:"<div class='bt-form pd20 c6'>\
<div>\
<div class='divtable' style='margin-top:5px;'>\
<table class='table table-hover'>\
<thead><tr><th>项目</th><th>操作</th></tr></thead>\
<tbody>" + list + "</tbody>\
</table>" +
page +
"</div></div></div>"
});
});
}
function projectScript(user, name,has_hook){
// console.log(user,name,has_hook);
var html = '';
if (has_hook){
html += '<button onclick="projectScriptEdit(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">手动编辑</button>';
html += '<button onclick="projectScriptDebug(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">调试日志</button>';
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">重新加载</button>';
html += '<button onclick="projectScriptUnload(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">卸载脚本</button>';
} else {
html += '<button onclick="projectScriptLoad(\''+user+'\',\''+name+'\')" class="btn btn-default btn-sm">加载脚本</button>';
}
var loadOpen = layer.open({
type: 1,
title: '['+user+']['+name+']脚本设置',
area: '240px',
content:'<div class="change-default pd20">'+html+'</div>'
});
}
function projectScriptEdit(user,name){
gogsPost('project_script_edit', {'user':user,'name':name}, function(data){
var rdata = $.parseJSON(data.data);
if (rdata['status']){
onlineEditFile(0, rdata['data']['path']);
} else {
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
}
});
}
function projectScriptLoad(user,name){
gogsPost('project_script_load', {'user':user,'name':name}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
layer.msg('加载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
setTimeout(function(){
userProjectList(1);
}, 2000);
});
}
function projectScriptUnload(user,name){
gogsPost('project_script_unload', {'user':user,'name':name}, function(data){
if (data.data != 'ok'){
layer.msg(data.data,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
layer.msg('卸载成功!',{icon:1,time:2000,shade: [0.3, '#000']});
setTimeout(function(){
userProjectList(1);
}, 2000);
});
}
function projectScriptDebug(user,name){
gogsPost('project_script_debug', {'user':user,'name':name}, function(data){
var rdata = $.parseJSON(data.data);
if (rdata['status']){
onlineEditFile(0, rdata['path']);
} else {
layer.msg(rdata.msg,{icon:1,time:2000,shade: [0.3, '#000']});
}
});
}
function getRsaPublic(){
gogsPost('get_rsa_public', {}, function(data){
var rdata = $.parseJSON(data.data);
var con = '<div class="tab-con">\
<div class="myKeyCon ptb15">\
<textarea style="margin:0px;width:580px;height:110px;outline:none;" spellcheck="false">'+rdata.mw+'</textarea>\
</div>\
<ul class="help-info-text c7 pull-left"></ul>\
</div>'
layer.open({
type: 1,
area: "600px",
title: '本机公钥',
closeBtn: 2,
shift: 5,
shadeClose: false,
content:con
});
});
}
function giteaRead(){
var readme = '<ul class="help-info-text c7">';
readme += '<li>默认使用MySQL,第一个启动加载各种配置,并修改成正确的数据库配置</li>';
readme += '<li>邮件端口使用456,gogs仅支持使用STARTTLS的SMTP协议</li>';
readme += '<li>如果使用项目中脚本本地同步,<a target="_blank" href="https://github.com/midoks/mdserver-web/wiki/%E6%8F%92%E4%BB%B6%E7%AE%A1%E7%90%86%5Bgogs%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E%5D#%E5%90%AF%E5%8A%A8gogs%E5%90%8E%E5%A6%82%E6%9E%9C%E8%A6%81%E4%BD%BF%E7%94%A8hook%E8%84%9A%E6%9C%AC%E5%90%8C%E6%AD%A5%E4%BB%A3%E7%A0%81%E9%9C%80%E8%A6%81%E5%BC%80%E5%90%AFssh%E7%AB%AF%E5%8F%A3">点击查看</></li>';
readme += '<li><a href="#" onclick="getRsaPublic();">点击查看本机公钥</></li>';
readme += '</ul>';
$('.soft-man-con').html(readme);
}
-91
View File
@@ -1,91 +0,0 @@
# coding: utf-8
import re
import os
import sys
# sys.path.append("/usr/local/lib/python3.6/site-packages")
class mysqlDb:
__DB_PASS = None
__DB_USER = 'root'
__DB_PORT = 3306
__DB_HOST = 'localhost'
__DB_NAME = 'test'
__DB_CONN = None
__DB_CUR = None
__DB_ERR = None
__DB_CNF = '/etc/my.cnf'
def __Conn(self):
'''连接MYSQL数据库'''
try:
socket = '/www/server/mysql/mysql.sock'
try:
import MySQLdb
except Exception as ex:
self.__DB_ERR = ex
return False
try:
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
port=self.__DB_PORT, db=self.__DB_NAME, charset="utf8", connect_timeout=10, unix_socket=socket)
except MySQLdb.Error as e:
self.__DB_HOST = '127.0.0.1'
self.__DB_CONN = MySQLdb.connect(host=self.__DB_HOST, user=self.__DB_USER, passwd=self.__DB_PASS,
port=self.__DB_PORT, db=self.__DB_NAME, charset="utf8", connect_timeout=10, unix_socket=socket)
self.__DB_CUR = self.__DB_CONN.cursor()
return True
except MySQLdb.Error as e:
self.__DB_ERR = e
return False
def setHost(self, host):
self.__DB_HOST = host
def setPwd(self, pwd):
self.__DB_PASS = pwd
def setUser(self, user):
self.__DB_USER = user
def setPort(self, port):
self.__DB_PORT = port
def setDb(self, name):
self.__DB_NAME = name
def getPwd(self):
return self.__DB_PASS
def execute(self, sql):
# 执行SQL语句返回受影响行
if not self.__Conn():
return self.__DB_ERR
try:
result = self.__DB_CUR.execute(sql)
self.__DB_CONN.commit()
self.__Close()
return result
except Exception as ex:
return ex
def query(self, sql):
# 执行SQL语句返回数据集
if not self.__Conn():
return self.__DB_ERR
try:
self.__DB_CUR.execute(sql)
result = self.__DB_CUR.fetchall()
# 将元组转换成列表
# data = map(list, result)
self.__Close()
return result
except Exception as ex:
return "error: " + str(ex)
# 关闭连接
def __Close(self):
self.__DB_CUR.close()
self.__DB_CONN.close()
+25 -20
View File
@@ -31,9 +31,6 @@ def getPluginName():
def getPluginDir():
return mw.getPluginDir() + '/' + getPluginName()
sys.path.append(getPluginDir() + "/class")
import mysqlDb
def getServerDir():
return mw.getServerDir() + '/' + getPluginName()
@@ -235,16 +232,24 @@ def getDbConfValue():
def pMysqlDb(conf):
host = conf['HOST'].split(':')
conn = mysqlDb.mysqlDb()
# pymysql
db = mw.getMyORM()
# MySQLdb |
# db = mw.getMyORMDb()
conn.setHost(host[0])
conn.setUser(conf['USER'])
conn.setPwd(conf['PASSWD'])
conn.setPort(int(host[1]))
conn.setDb(conf['NAME'])
return conn
db.setPort(int(host[1]))
db.setUser(conf['USER'])
if 'PASSWD' in conf:
db.setPwd(conf['PASSWD'])
else:
db.setPwd(conf['PASSWORD'])
db.setDbName(conf['NAME'])
# db.setSocket(getSocketFile())
db.setCharset("utf8")
return db
def pSqliteDb(conf):
@@ -388,7 +393,7 @@ def postReceiveLog():
def getGogsConf():
conf = getConf()
if not os.path.exists(conf):
return mw.returnJson(False, "请先安装初始化!")
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
gets = [
{'name': 'DOMAIN', 'type': -1, 'ps': '服务器域名'},
@@ -455,7 +460,12 @@ def userList():
conf = getConf()
if not os.path.exists(conf):
return mw.returnJson(False, "请先安装初始化!")
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":3000")
conf = getDbConfValue()
gtype = getGogsDbType(conf)
if gtype != 'mysql':
return mw.returnJson(False, "仅支持mysql数据操作!")
import math
args = getArgs()
@@ -476,7 +486,7 @@ def userList():
start = (page - 1) * page_size
list_count = pQuery('select count(id) as num from user')
count = list_count[0][0]
count = list_count[0]["num"]
list_data = pQuery(
'select id,name,email from user order by id desc limit ' + str(start) + ',' + str(page_size))
data['list'] = mw.getPage({'count': count, 'p': page,
@@ -681,12 +691,7 @@ def getTotalStatistics():
data = {}
if st.strip() == 'start':
list_count = pQuery('select count(id) as num from repository')
if list_count.find("error") > -1:
data['status'] = False
data['count'] = 0
return mw.returnJson(False, 'fail', data)
count = list_count[0]["num"]
data['status'] = True
data['count'] = count
data['ver'] = mw.readFile(getServerDir() + '/version.pl').strip()
+1
View File
@@ -29,6 +29,7 @@ getBit(){
Install_gogs()
{
mkdir -p $serverPath/source/gogs
echo '正在安装脚本文件...' > $install_tmp
+4 -4
View File
@@ -163,11 +163,11 @@ function gogsUserList(page, search) {
ulist = rdata['data']['data'];
for (i in ulist){
email = ulist[i][2] == '' ? '无' : ulist[i][2];
content += '<tr><td>'+ulist[i][0]+'</td>'+
'<td>'+ulist[i][1]+'</td>'+
email = ulist[i]["email"] == '' ? '无' : ulist[i]["email"];
content += '<tr><td>'+ulist[i]["id"]+'</td>'+
'<td>'+ulist[i]["name"]+'</td>'+
'<td>'+email+'</td>'+
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i][1]+'\')">项目管理</a></td>'+
'<td><a class="btlink" onclick="userProjectList(\''+ulist[i]["name"]+'\')">项目管理</a></td>'+
'</tr>';
}
+37
View File
@@ -0,0 +1,37 @@
global
daemon
log 127.0.0.1 local0
pidfile /tmp/haproxy.pid
maxconn 4000
user haproxy
group haproxy
defaults
mode http
log global
option httplog
timeout connect 10s
timeout client 15s
timeout server 15s
listen stats
mode http
bind *:10800
stats enable
stats uri /haproxy
stats realm Haproxy\ Statistics
stats auth admin:admin
frontend http-in
bind *:1080
default_backend servers
option forwardfor
option httpclose
backend servers
balance roundrobin
server web1 0.0.0.0:9090 check
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

+18
View File
@@ -0,0 +1,18 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('haproxy');">服务</p>
<p onclick="pluginInitD('haproxy');">自启动</p>
<p onclick="pluginConfigTpl('haproxy');">配置修改</p>
<p onclick="pluginLogs('haproxy','','run_log',30);">运行日志</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=haproxy&f=js/haproxy.js", function(){
pluginService('haproxy');
});
</script>
+253
View File
@@ -0,0 +1,253 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import string
import subprocess
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
def getPluginName():
return 'haproxy'
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 getConfTpl():
path = getPluginDir() + "/conf/haproxy.conf"
return path
def getConf():
path = getServerDir() + "/haproxy.conf"
return path
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('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def checkArgs(data, ck=[]):
for i in range(len(ck)):
if not ck[i] in data:
return (False, mw.returnJson(False, '参数:(' + ck[i] + ')没有!'))
return (True, mw.returnJson(True, 'ok'))
def configTpl():
path = getPluginDir() + '/tpl'
pathFile = os.listdir(path)
tmp = []
for one in pathFile:
file = path + '/' + one
tmp.append(file)
return mw.getJson(tmp)
def readConfigTpl():
args = getArgs()
data = checkArgs(args, ['file'])
if not data[0]:
return data[1]
content = mw.readFile(args['file'])
content = contentReplace(content)
return mw.returnJson(True, 'ok', content)
def contentReplace(content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$SERVER_APP}', service_path + '/haproxy')
return content
def status():
data = mw.execShell(
"ps -ef|grep haproxy |grep -v grep | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def initDreplace():
file_tpl = getInitDTpl()
service_path = os.path.dirname(os.getcwd())
initD_path = getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
file_bin = initD_path + '/' + getPluginName()
# initd replace
if not os.path.exists(file_bin):
content = mw.readFile(file_tpl)
content = contentReplace(content)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
# config replace
conf_bin = getConf()
if not os.path.exists(conf_bin):
conf_content = mw.readFile(getConfTpl())
conf_content = contentReplace(conf_content)
mw.writeFile(getServerDir() + '/haproxy.conf', conf_content)
# systemd
systemDir = mw.systemdCfgDir()
systemService = systemDir + '/haproxy.service'
systemServiceTpl = getPluginDir() + '/init.d/haproxy.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
def haOp(method):
file = initDreplace()
if not mw.isAppleSystem():
data = mw.execShell('systemctl ' + method + ' haproxy')
if data[1] == '':
return 'ok'
return 'fail'
data = mw.execShell(file + ' ' + method)
if data[1] == '':
return 'ok'
return data[1]
def start():
return haOp('start')
def stop():
return haOp('stop')
def restart():
return haOp('restart')
def reload():
return haOp('reload')
def initdStatus():
if mw.isAppleSystem():
return "Apple Computer does not support"
shell_cmd = 'systemctl status haproxy | grep loaded | grep "enabled;"'
data = mw.execShell(shell_cmd)
if data[0] == '':
return 'fail'
return 'ok'
def initdInstall():
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl enable haproxy')
return 'ok'
def initdUinstall():
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl disable haproxy')
return 'ok'
def runLog():
path = getConf()
content = mw.readFile(path)
rep = 'log\s*=\s*(.*)'
tmp = re.search(rep, content)
return tmp.groups()[0]
def getPort():
path = getConf()
content = mw.readFile(path)
rep = 'listen\s*=\s*(.*)'
tmp = re.search(rep, content)
return tmp.groups()[0]
if __name__ == "__main__":
func = sys.argv[1]
if func == 'status':
print(status())
elif func == 'start':
print(start())
elif func == 'stop':
print(stop())
elif func == 'restart':
print(restart())
elif func == 'reload':
print(reload())
elif func == 'initd_status':
print(initdStatus())
elif func == 'initd_install':
print(initdInstall())
elif func == 'initd_uninstall':
print(initdUinstall())
elif func == 'conf':
print(getConf())
elif func == 'config_tpl':
print(configTpl())
elif func == 'read_config_tpl':
print(readConfigTpl())
elif func == 'run_log':
print(runLog())
elif func == 'query_log':
print(queryLog())
else:
print('error')
+19
View File
@@ -0,0 +1,19 @@
{
"sort": 7,
"ps": "可靠、高性能的TCP/HTTP负载平衡器",
"name": "haproxy",
"title": "haproxy",
"shell": "install.sh",
"versions":["2.6"],
"updates":["2.6"],
"tip": "soft",
"checks": "server/haproxy",
"path": "server/haproxy",
"display": 1,
"author": "midoks",
"date": "2022-08-26",
"home": "https://www.haproxy.org/",
"doc1": "https://www.haproxy.org/",
"type": 0,
"pid": "4"
}
@@ -0,0 +1,13 @@
[Unit]
Description=he Reliable, High Performance TCP/HTTP Load Balancer
After=network.target
[Service]
Type=forking
ExecStartPre={$SERVER_PATH}/haproxy/sbin/haproxy -c -f {$SERVER_PATH}/haproxy/haproxy.conf
ExecStart={$SERVER_PATH}/haproxy/sbin/haproxy -D -f {$SERVER_PATH}/haproxy/haproxy.conf
ExecReload={$SERVER_PATH}/haproxy/sbin/haproxy -f {$SERVER_PATH}/haproxy/haproxy.conf -c -q
Restart=on-failure
[Install]
WantedBy=multi-user.target
+119
View File
@@ -0,0 +1,119 @@
#!/bin/sh
#
# chkconfig: - 85 15
# description: HA-Proxy is a TCP/HTTP reverse proxy which is particularly suited \
# for high availability environments.
# processname: haproxy
# config: /etc/haproxy/haproxy.cfg
# pidfile: /var/run/haproxy.pid
# Script Author: Simon Matter <simon.matter@invoca.ch>
# Version: 2004060600
# Source function library.
if [ -f /etc/init.d/functions ]; then
. /etc/init.d/functions
elif [ -f /etc/rc.d/init.d/functions ] ; then
. /etc/rc.d/init.d/functions
else
echo ".."
fi
# Source networking configuration.
if [ -f /etc/sysconfig/network ];then
. /etc/sysconfig/network
fi
# Check that networking is up.
# [ ${NETWORKING} = "no" ] && exit 0
HAPROXYDIR={$SERVER_PATH}/haproxy
BASENAME=haproxy
# This is our service name
#BASENAME=`basename $0`
#if [ -L $0 ]; then
# BASENAME=`find $0 -name $BASENAME -printf %l`
# BASENAME=`basename $BASENAME`
#fi
[ -f $HAPROXYDIR/etc/$BASENAME.conf ] || exit 1
RETVAL=0
start() {
$HAPROXYDIR/sbin/$BASENAME -c -q -f $HAPROXYDIR/etc/$BASENAME.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with '$BASENAME check'."
return 1
fi
echo -n "Starting $BASENAME: "
daemon $HAPROXYDIR/sbin/$BASENAME -D -f $HAPROXYDIR/etc/$BASENAME.conf
RETVAL=$?
# echo
# [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$BASENAME
return $RETVAL
}
stop() {
echo -n "Shutting down $BASENAME: "
killproc $BASENAME -USR1
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$BASENAME
[ $RETVAL -eq 0 ] && rm -f /var/run/$BASENAME.pid
return $RETVAL
}
restart() {
$HAPROXYDIR/sbin/$BASENAME -c -q -f $HAPROXYDIR/etc/$BASENAME.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with '$BASENAME check'."
return 1
fi
stop
start
}
reload() {
$HAPROXYDIR/sbin/$BASENAME -c -q -f $HAPROXYDIR/etc/$BASENAME.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with '$BASENAME check'."
return 1
fi
$HAPROXYDIR/sbin/$BASENAME -D -f $HAPROXYDIR/$BASENAME.conf -p /var/run/$BASENAME.pid -sf $(cat /var/run/$BASENAME.pid)
}
check() {
$HAPROXYDIR/sbin/$BASENAME -c -q -V -f $HAPROXYDIR/etc/$BASENAME.conf
}
rhstatus() {
status $BASENAME
}
condrestart() {
[ -e /var/lock/subsys/$BASENAME ] && restart || :
}
# See how we were called.
case "$1" in
start) start ;;
stop) stop ;;
restart) restart;;
reload) reload;;
condrestart) condrestart ;;
status) rhstatus ;;
check) check ;;
*)
echo $"Usage: $BASENAME {start|stop|restart|reload|condrestart|status|check}"
exit 1
esac
exit $?
+52
View File
@@ -0,0 +1,52 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
type=$2
echo $action $type
if id haproxy &> /dev/null ;then
echo "haproxy UID is `id -u haproxy`"
echo "haproxy Shell is `grep "^haproxy:" /etc/passwd |cut -d':' -f7 `"
else
groupadd haproxy
useradd -g haproxy haproxy
fi
if [ "${2}" == "" ];then
echo '缺少安装脚本...' > $install_tmp
exit 0
fi
if [ ! -d $curPath/versions/$2 ];then
echo '缺少安装脚本2...' > $install_tmp
exit 0
fi
if [ "${action}" == "uninstall" ];then
if [ -f /usr/lib/systemd/system/haproxy.service ] || [ -f /lib/systemd/system/haproxy.service ];then
systemctl stop haproxy
systemctl disable haproxy
rm -rf /usr/lib/systemd/system/haproxy.service
rm -rf /lib/systemd/system/haproxy.service
systemctl daemon-reload
fi
fi
sh -x $curPath/versions/$2/install.sh $1
if [ "${action}" == "install" ] && [ -d $serverPath/haproxy ];then
#初始化
cd ${rootPath} && python3 ${rootPath}/plugins/haproxy/index.py start ${type}
cd ${rootPath} && python3 ${rootPath}/plugins/haproxy/index.py initd_install ${type}
fi
+53
View File
@@ -0,0 +1,53 @@
function spPostMin(method, args, callback){
var req_data = {};
req_data['name'] = 'haproxy';
req_data['func'] = method;
if (typeof(args) != 'undefined' && args!=''){
req_data['args'] = JSON.stringify(args);
}
$.post('/plugins/run', req_data, function(data) {
if (!data.status){
layer.msg(data.msg,{icon:0,time:2000,shade: [0.3, '#000']});
return;
}
if(typeof(callback) == 'function'){
callback(data);
}
},'json');
}
function spPost(method, args, callback){
var loadT = layer.msg('正在获取...', { icon: 16, time: 0, shade: 0.3 });
spPostMin(method,args,function(data){
layer.close(loadT);
if(typeof(callback) == 'function'){
callback(data);
}
});
}
function secToTime(s) {
var t;
if(s > -1){
var hour = Math.floor(s/3600);
var min = Math.floor(s/60) % 60;
var sec = s % 60;
if(hour < 10) {
t = '0'+ hour + ":";
} else {
t = hour + ":";
}
if(min < 10){t += "0";}
t += min + ":";
if(sec < 10){t += "0";}
t += sec.toFixed(2);
}
return t;
}
+70
View File
@@ -0,0 +1,70 @@
#!/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")
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
VERSION=2.6.4
MIN_VERSION=2.6
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/haproxy
APP_DIR=${serverPath}/source/haproxy
mkdir -p $APP_DIR
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
if [ $sysName == 'Darwin' ]; then
wget -O ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
else
curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
fi
fi
if [ ! -f ${APP_DIR}/haproxy-${VERSION}.tar.gz ];then
curl -sSLo ${APP_DIR}/haproxy-${VERSION}.tar.gz https://www.haproxy.org/download/${MIN_VERSION}/src/haproxy-${VERSION}.tar.gz
fi
cd ${APP_DIR} && tar -zxvf haproxy-${VERSION}.tar.gz
if [ "$OSNAME" == "macos" ];then
cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=osx && make install PREFIX=$serverPath/haproxy
else
cd ${APP_DIR}/haproxy-${VERSION} && make TARGET=linux-glibc && make install PREFIX=$serverPath/haproxy
fi
echo $MIN_VERSION > $serverPath/haproxy/version.pl
echo 'Install_HA' > $install_tmp
}
Uninstall_App()
{
if [ -f $serverPath/haproxy/initd/haproxy ];then
$serverPath/haproxy/initd/haproxy stop
fi
rm -rf $serverPath/haproxy
echo "Uninstall_HA" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_App
else
Uninstall_App
fi
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

+20
View File
@@ -0,0 +1,20 @@
<div class="bt-form">
<div class="bt-w-main">
<div class="bt-w-menu">
<p class="bgw" onclick="pluginService('imail');">服务</p>
<p onclick="pluginInitD('imail');">自启动</p>
<p onclick="pluginConfig('imail',null, 'conf');">配置文件</p>
<p onclick="pluginLogs('imail',null,'run_log', 50);">运行日志</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<script type="text/javascript">
$.getScript( "/plugins/file?name=imail&f=js/imail.js", function(){
mail.init();
pluginService('imail');
});
</script>
+218
View File
@@ -0,0 +1,218 @@
# coding:utf-8
import sys
import io
import os
import time
import re
import socket
import json
from datetime import datetime
sys.path.append(os.getcwd() + "/class/core")
import mw
app_debug = False
if mw.isAppleSystem():
app_debug = True
class App:
__setupPath = '/www/server/imail'
__SR = ''
def __init__(self):
self.__setupPath = self.getServerDir()
self.__SR = '''#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
export USER=%s
export HOME=%s && ''' % ( self.getRunUser(), self.getHomeDir())
def getArgs(self):
args = sys.argv[3:]
tmp = {}
args_len = len(args)
if args_len == 1:
t = args[0].strip('{').strip('}')
t = t.split(':')
tmp[t[0]] = t[1]
elif args_len > 1:
for i in range(len(args)):
t = args[i].split(':')
tmp[t[0]] = t[1]
return tmp
def __release_port(self, port):
from collections import namedtuple
try:
import firewall_api
firewall_api.firewall_api().addAcceptPortArgs(port, 'IMail-Server', 'port')
return port
except Exception as e:
return "Release failed {}".format(e)
def openPort(self):
for i in ["25", "110", "143", "465", "995", "993", "587"]:
self.__release_port(i)
return True
def getPluginName(self):
return 'imail'
def getPluginDir(self):
return mw.getPluginDir() + '/' + self.getPluginName()
def getServerDir(self):
return mw.getServerDir() + '/' + self.getPluginName()
def getInitdConfTpl(self):
path = self.getPluginDir() + "/init.d/imail.tpl"
return path
def getHomeDir(self):
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return '/Users/' + user
else:
return '/root'
def getRunUser(self):
if mw.isAppleSystem():
user = mw.execShell(
"who | sed -n '2, 1p' |awk '{print $1}'")[0].strip()
return user
else:
return 'root'
def status(self):
data = mw.execShell(
"ps -ef|grep " + self.getPluginName() + " |grep -v grep | grep -v python | awk '{print $2}'")
if data[0] == '':
return 'stop'
return 'start'
def contentReplace(self, content):
service_path = mw.getServerDir()
content = content.replace('{$ROOT_PATH}', mw.getRootDir())
content = content.replace('{$SERVER_PATH}', service_path)
content = content.replace('{$RUN_USER}', self.getRunUser())
content = content.replace('{$HOME_DIR}', self.getHomeDir())
return content
def initDreplace(self):
file_tpl = self.getInitdConfTpl()
service_path = mw.getServerDir()
initD_path = self.getServerDir() + '/init.d'
if not os.path.exists(initD_path):
os.mkdir(initD_path)
self.openPort()
file_bin = initD_path + '/' + self.getPluginName()
if not os.path.exists(file_bin):
content = mw.readFile(file_tpl)
content = self.contentReplace(content)
mw.writeFile(file_bin, content)
mw.execShell('chmod +x ' + file_bin)
# systemd
systemDir = mw.systemdCfgDir()
systemService = systemDir + '/imail.service'
systemServiceTpl = self.getPluginDir() + '/init.d/imail.service.tpl'
if os.path.exists(systemDir) and not os.path.exists(systemService):
service_path = mw.getServerDir()
se_content = mw.readFile(systemServiceTpl)
se_content = se_content.replace('{$SERVER_PATH}', service_path)
mw.writeFile(systemService, se_content)
mw.execShell('systemctl daemon-reload')
log_path = self.getServerDir() + '/logs'
if not os.path.exists(log_path):
os.mkdir(log_path)
return file_bin
def imOp(self, method):
file = self.initDreplace()
if not mw.isAppleSystem():
cmd = 'systemctl {} {}'.format(method, self.getPluginName())
data = mw.execShell(cmd)
if data[1] == '':
return 'ok'
return 'fail'
data = mw.execShell(self.__SR + file + ' ' + method)
if data[1] == '':
return 'ok'
return data[0]
def start(self):
return self.imOp('start')
def stop(self):
return self.imOp('stop')
def restart(self):
return self.imOp('restart')
def reload(self):
return self.imOp('reload')
def initd_status(self):
if mw.isAppleSystem():
return "Apple Computer does not support"
cmd = 'systemctl status imail | grep loaded | grep "enabled;"'
data = mw.execShell(cmd)
if data[0] == '':
return 'fail'
return 'ok'
def initd_install(self):
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl enable imail')
return 'ok'
def initd_uinstall(self):
if mw.isAppleSystem():
return "Apple Computer does not support"
mw.execShell('systemctl disable imail')
return 'ok'
def conf(self):
conf_path = self.getServerDir() + '/custom/conf/app.conf'
if not os.path.exists(conf_path):
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":1080")
return self.getServerDir() + '/custom/conf/app.conf'
def run_log(self):
ilog = self.getServerDir() + '/logs/imail.log'
if not os.path.exists(ilog):
return mw.returnJson(False, "请先安装初始化!<br/>默认地址:http://" + mw.getLocalIp() + ":1080")
return self.getServerDir() + '/logs/imail.log'
if __name__ == "__main__":
func = sys.argv[1]
classApp = App()
try:
data = eval("classApp." + func + "()")
print(data)
except Exception as e:
print('error:' + str(e))
+18
View File
@@ -0,0 +1,18 @@
{
"sort": 7,
"ps": "简单邮件服务[DEV]",
"name": "imail",
"title": "邮件服务",
"shell": "install.sh",
"versions":["0.0.17"],
"updates":["0.0.17"],
"tip": "soft",
"checks": "server/imail",
"path": "server/imail",
"display": 1,
"author": "midoks",
"date": "2022-09-26",
"home": "https://github.com/midoks/mdserver-web",
"type": 0,
"pid": "5"
}
+12
View File
@@ -0,0 +1,12 @@
[Unit]
Description=Imail Simple Mail Server
After=network.target
[Service]
Type=forking
ExecStart={$SERVER_PATH}/imail/init.d/imail start
ExecStop={$SERVER_PATH}/imail/init.d/imail stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
+89
View File
@@ -0,0 +1,89 @@
#!/bin/bash
# chkconfig: 2345 55 25
# description: Imail Service
### BEGIN INIT INFO
# Provides: bt
# Required-Start: $all
# Required-Stop: $all
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts Imail
# Description: starts the Imail
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
# Source function library.
if [ -f /etc/init.d/functions ];then
. /etc/init.d/functions
fi
if [ -f /etc/rc.d/init.d/functions ];then
. /etc/rc.d/init.d/functions
fi
app_path={$SERVER_PATH}/imail
SERVICENAME="imail"
im_start(){
isStart=`ps -ef|grep 'imail service' |grep -v grep|awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "Starting imail... \c"
cd $app_path && ${app_path}/imail service &
isStart=""
while [[ "$isStart" == "" ]];
do
echo -e ".\c"
sleep 0.5
isStart=$(lsof -n -P -i:25|grep LISTEN|grep -v grep|awk '{print $2}'|xargs)
let n+=1
if [ $n -gt 15 ];then
break;
fi
done
if [ "$isStart" == '' ];then
echo -e "\033[31mfailed\033[0m"
echo '------------------------------------------------------'
tail -n 20 ${app_path}/logs/run_away.log
echo '------------------------------------------------------'
echo -e "\033[31mError: ${SERVICENAME} service startup failed.\033[0m"
return;
fi
echo -e "\033[32mdone\033[0m"
else
echo "Starting ${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
im_stop(){
pids=`ps -ef|grep 'imail service' |grep -v grep|awk '{print $2}'`
arr=($pids)
echo -e "Stopping ${SERVICENAME}... \c"
for p in ${arr[@]}
do
kill -9 $p
done
echo -e "\033[32mdone\033[0m"
}
im_status(){
isStart=`ps -ef|grep 'imail service' |grep -v grep|awk '{print $2}'`
if [ "$isStart" == '' ];then
echo -e "${SERVICENAME} not running"
else
echo -e "${SERVICENAME}(pid $(echo $isStart)) already running"
fi
}
case "$1" in
'start') im_start;;
'stop') im_stop;;
'status') im_status;;
'reload')
im_stop
im_start;;
'restart')
im_stop
im_start;;
esac
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
type=$2
if [ "${2}" == "" ];then
echo '缺少安装脚本...' > $install_tmp
exit 0
fi
if [ ! -d $curPath/versions/$2 ];then
echo '缺少安装脚本2...' > $install_tmp
exit 0
fi
sh -x $curPath/versions/$2/install.sh $1
+95
View File
@@ -0,0 +1,95 @@
var mail = {
plugin_name: 'imail',
init: function () {
var _this = this;
},
str2Obj:function(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
},
send:function(info){
var tips = info['tips'];
var method = info['method'];
var args = info['data'];
var callback = info['success'];
var loadT = layer.msg(tips, { icon: 16, time: 0, shade: 0.3 });
var data = {};
data['name'] = 'mail';
data['func'] = method;
data['version'] = $('.plugin_version').attr('version');
if (typeof(args) == 'string'){
data['args'] = JSON.stringify(this.str2Obj(args));
} else {
data['args'] = JSON.stringify(args);
}
$.post('/plugins/run', data, function(res) {
layer.close(loadT);
if (!res.status){
layer.msg(res.msg,{icon:2,time:10000});
return;
}
var ret_data = $.parseJSON(res.data);
console.log("send:",ret_data);
// if (!ret_data.status){
// layer.msg(ret_data.msg,{icon:2,time:2000});
// return;
// }
// console.log("send2:",ret_data);
if(typeof(callback) == 'function'){
callback(ret_data);
}
},'json');
},
postCallback:function(info){
var tips = info['tips'];
var method = info['method'];
var args = info['data'];
var callback = info['success'];
var loadT = layer.msg(tips, { icon: 16, time: 0, shade: 0.3 });
var data = {};
data['name'] = 'mail';
data['func'] = method;
data['version'] = $('.plugin_version').attr('version');
if (typeof(args) == 'string'){
data['args'] = JSON.stringify(this.str2Obj(args));
} else {
data['args'] = JSON.stringify(args);
}
$.post('/plugins/callback', data, function(res) {
layer.close(loadT);
if (!res.status){
layer.msg(res.msg,{icon:2,time:10000});
return;
}
var ret_data = $.parseJSON(res.data);
if (!ret_data.status){
layer.msg(ret_data.msg,{icon:2,time:2000});
return;
}
if(typeof(callback) == 'function'){
callback(res);
}
},'json');
}
}
+109
View File
@@ -0,0 +1,109 @@
#!/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=0.0.17
# bash install.sh install 0.0.16
## cd /www/server/mdserver-web/plugins/imail && bash install.sh install 0.0.16
bash ${rootPath}/scripts/getos.sh
OSNAME=`cat ${rootPath}/data/osname.pl`
OSNAME_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
ARCH="amd64"
get_arch() {
TMP_ARCH=`arch`
if [ "$TMP_ARCH" == "x86_64" ];then
ARCH="amd64"
fi
}
load_vars() {
OS=$(uname | tr '[:upper:]' '[:lower:]')
TARGET_DIR="$serverPath/imail"
}
get_download_url() {
DOWNLOAD_URL="https://github.com/midoks/imail/releases/download/$VERSION/imail_${VERSION}_${OS}_${ARCH}.tar.gz"
}
# download file
download_file() {
url="${1}"
destination="${2}"
printf "Fetching ${url} \n\n"
if test -x "$(command -v curl)"; then
code=$(curl --connect-timeout 15 -w '%{http_code}' -L "${url}" -o "${destination}")
elif test -x "$(command -v wget)"; then
code=$(wget -t2 -T15 -O "${destination}" --server-response "${url}" 2>&1 | awk '/^ HTTP/{print $2}' | tail -1)
else
printf "\e[1;31mNeither curl nor wget was available to perform http requests.\e[0m\n"
exit 1
fi
if [ "${code}" != 200 ]; then
printf "\e[1;31mRequest failed with code %s\e[0m\n" $code
exit 1
else
printf "\n\e[1;33mDownload succeeded\e[0m\n"
fi
}
Install_App()
{
echo '正在安装脚本文件...' > $install_tmp
mkdir -p $serverPath/source
load_vars
get_arch
get_download_url
DOWNLOAD_FILE="$(mktemp).tar.gz"
download_file $DOWNLOAD_URL $DOWNLOAD_FILE
if [ ! -d "$TARGET_DIR" ]; then
mkdir -p "$TARGET_DIR"
fi
tar -C "$TARGET_DIR" -zxf $DOWNLOAD_FILE
rm -rf $DOWNLOAD_FILE
pushd "$TARGET_DIR/scripts" >/dev/null 2>&1
bash make.sh
if [ -d $serverPath/imail ];then
echo "$VERSION" > $serverPath/imail/version.pl
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py start
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py initd_install
fi
echo 'install successful' > $install_tmp
}
Uninstall_App()
{
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py initd_uninstall
cd ${rootPath} && python3 ${rootPath}/plugins/imail/index.py stop
rm -rf $serverPath/imail
echo "install fail" > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_App
else
Uninstall_App
fi
+1 -1
View File
@@ -45,11 +45,11 @@ skip-name-resolve = on
log-bin=mysql-bin
binlog_format=mixed
expire_logs_days = 10
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=3
#log_queries_not_using_indexes=on
binlog-expire-logs-seconds = 2592000
relay-log=mdserver
relay-log-index=mdserver
+59 -29
View File
@@ -150,7 +150,7 @@ def pSqliteDb(dbname='databases'):
return conn
def pMysqlDb():
def pMysqlDb(name=''):
# pymysql
db = mw.getMyORM()
# MySQLdb |
@@ -159,6 +159,7 @@ def pMysqlDb():
db.setDbConf(getConf())
db.setPort(getDbPort())
db.setSocket(getSocketFile())
db.setDbName(name)
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
db.setPwd(pwd)
@@ -303,7 +304,7 @@ def getErrorLog():
if 'close' in args:
mw.writeFile(filename, '')
return mw.returnJson(False, '日志已清空')
info = mw.getNumLines(filename, 18)
info = mw.getLastLine(filename, 18)
return mw.returnJson(True, 'OK', info)
@@ -342,6 +343,7 @@ def initMariaDbPwd():
time.sleep(5)
serverdir = getServerDir()
myconf = serverdir + "/etc/my.cnf"
pwd = mw.getRandomString(16)
db_option = "-S " + serverdir + "/mysql.sock"
@@ -362,6 +364,16 @@ def initMariaDbPwd():
pwd + ' -e "drop database test";'
mw.execShell(drop_test_db)
# 删除冗余账户
hostname = mw.execShell('hostname')[0].strip()
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
mw.execShell(drop_hostname)
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
mw.execShell(drop_root_hostname)
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
return True
@@ -631,7 +643,7 @@ def isSqlError(mysqlMsg):
def __createUser(dbname, username, password, address):
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
if username == 'root':
dbname = '*'
@@ -691,8 +703,8 @@ def importDbBackup():
mw.execShell(cmd)
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
mysql_cmd = mw.getRootDir() + '/server/mysql/bin/mysql -uroot -p' + pwd + \
sock = getSocketFile()
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
' ' + name + ' < ' + file_path_sql
# print(mysql_cmd)
@@ -797,7 +809,7 @@ def syncGetDatabases():
if isError != None:
return isError
users = pdb.query(
"select User,Host from mysql.user where User!='root' AND Host!='localhost' AND Host!=''")
"select User,Host from user where User!='root' AND Host!='localhost' AND Host!=''")
nameArr = ['information_schema', 'performance_schema', 'mysql', 'sys']
n = 0
@@ -893,16 +905,19 @@ def setRootPwd(version=''):
password = args['password']
try:
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
result = pdb.query("show databases")
isError = isSqlError(result)
if isError != None:
return isError
result = pdb.execute(
"update mysql.user set Password=password('" + password + "') where User='root'")
pdb.execute("flush privileges")
cmd = "ALTER USER 'root'@'localhost' IDENTIFIED BY '" + password + "';"
r = pdb.execute(cmd)
# print(r)
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (password,))
orm = pMysqlDb()
orm.execute("flush privileges")
return mw.returnJson(True, '数据库root密码修改成功!')
except Exception as ex:
return mw.returnJson(False, '修改错误:' + str(ex))
@@ -910,7 +925,7 @@ def setRootPwd(version=''):
def setUserPwd(version=''):
args = getArgs()
data = checkArgs(args, ['password', 'name'])
data = checkArgs(args, ['password', 'name', 'id'])
if not data[0]:
return data[1]
@@ -920,16 +935,28 @@ def setUserPwd(version=''):
try:
pdb = pMysqlDb()
psdb = pSqliteDb('databases')
name = psdb.where('id=?', (uid,)).getField('name')
data = psdb.field('id,name,accept').where('id=?', (uid,)).find()
result = pdb.execute("update mysql.user set Password=password('" +
newpassword + "') where User='" + username + "'")
cmd = "SET PASSWORD FOR '" + username + \
"'@'localhost' = PASSWORD('" + newpassword + "')"
r = pdb.execute(cmd)
# print(cmd, r)
accept = data['accept']
alist = accept.split(',')
for x in alist:
cmd = "SET PASSWORD FOR '" + username + \
"'@'" + x + "' = PASSWORD('" + newpassword + "')"
r = pdb.execute(cmd)
# print(cmd, r)
pdb.execute("flush privileges")
psdb.where("id=?", (uid,)).setField('password', newpassword)
return mw.returnJson(True, mw.getInfo('修改数据库[{1}]密码成功!', (name,)))
orm = pMysqlDb()
orm.execute("flush privileges")
return mw.returnJson(True, mw.getInfo('修改数据库[{1}]密码成功!', (data['name'],)))
except Exception as ex:
return mw.returnJson(False, mw.getInfo('修改数据库[{1}]密码失败[{2}]!', (name, str(ex),)))
return mw.returnJson(False, mw.getInfo('修改数据库[{1}]密码失败[{2}]!', (data['name'], str(ex),)))
def setDbPs():
@@ -1022,7 +1049,7 @@ def delDb():
id = args['id']
name = args['name']
psdb = pSqliteDb('databases')
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
find = psdb.where("id=?", (id,)).field(
'id,pid,name,username,password,accept,ps,addtime').find()
accept = find['accept']
@@ -1031,7 +1058,7 @@ def delDb():
# 删除MYSQL
result = pdb.execute("drop database `" + name + "`")
users = pdb.query("select Host from mysql.user where User='" +
users = pdb.query("select Host from user where User='" +
username + "' AND Host!='localhost'")
pdb.execute("drop user '" + username + "'@'localhost'")
for us in users:
@@ -1051,9 +1078,9 @@ def getDbAccess():
if not data[0]:
return data[1]
username = args['username']
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
users = pdb.query("select Host from mysql.user where User='" +
users = pdb.query("select Host from user where User='" +
username + "' AND Host!='localhost'")
if len(users) < 1:
@@ -1072,7 +1099,7 @@ def setDbAccess():
return data[1]
name = args['username']
access = args['access']
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
psdb = pSqliteDb('databases')
dbname = psdb.where('username=?', (name,)).getField('name')
@@ -1083,7 +1110,7 @@ def setDbAccess():
else:
password = psdb.where("username=?", (name,)).getField('password')
users = pdb.query("select Host from mysql.user where User='" +
users = pdb.query("select Host from user where User='" +
name + "' AND Host!='localhost'")
for us in users:
@@ -1105,11 +1132,11 @@ def setDbRw(version=''):
uid = args['id']
rw = args['rw']
pdb = pMysqlDb()
pdb = pMysqlDb('mysql')
psdb = pSqliteDb('databases')
dbname = psdb.where("id=?", (uid,)).getField('name')
users = pdb.query(
"select Host from mysql.user where User='" + username + "'")
"select Host from user where User='" + username + "'")
# show grants for demo@"127.0.0.1";
for x in users:
@@ -1374,7 +1401,7 @@ def setDbMasterAccess():
pdb = pMysqlDb()
psdb = pSqliteDb('master_replication_user')
password = psdb.where("username=?", (username,)).getField('password')
users = pdb.query("select Host from mysql.user where User='" +
users = pdb.query("select Host from user where User='" +
username + "' AND Host!='localhost'")
for us in users:
pdb.execute("drop user '" + username + "'@'" + us["Host"] + "'")
@@ -1706,7 +1733,7 @@ def delMasterRepSlaveUser(version=''):
pdb.execute("drop user '" + name + "'@'%'")
pdb.execute("drop user '" + name + "'@'localhost'")
users = pdb.query("select Host from mysql.user where User='" +
users = pdb.query("select Host from user where User='" +
name + "' AND Host!='localhost'")
for us in users:
pdb.execute("drop user '" + name + "'@'" + us["Host"] + "'")
@@ -2164,8 +2191,11 @@ def installPreInspection(version):
def uninstallPreInspection(version):
# return "请手动删除MySQL[{}]".format(version)
return 'ok'
stop(version)
if mw.isDebugMode():
return 'ok'
return "请手动删除MariaDB[{}]<br/> rm -rf {}".format(version, getServerDir())
if __name__ == "__main__":
func = sys.argv[1]
+31 -19
View File
@@ -445,10 +445,9 @@ function syncToDatabase(type){
function setRootPwd(type, pwd){
if (type==1){
var data = $("#mod_pwd").serialize();
myPost('set_root_pwd', data, function(data){
var password = $("#MyPassword").val();
myPost('set_root_pwd', {password:password}, function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
showMsg(rdata.msg,function(){
dbList();
$('.layui-layer-close1').click();
@@ -459,26 +458,23 @@ function setRootPwd(type, pwd){
var index = layer.open({
type: 1,
skin: 'demo-class',
area: '500px',
title: '修改数据库密码',
closeBtn: 1,
shift: 5,
btn:["提交","关闭"],
shadeClose: true,
content: "<form class='bt-form pd20 pb70' id='mod_pwd'>\
content: "<form class='bt-form pd20' id='mod_pwd'>\
<div class='line'>\
<span class='tname'>root密码</span>\
<div class='info-r'><input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+pwd+"' /><span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
</div>\
<div class='bt-form-submit-btn'>\
<button id='my_mod_close' type='button' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' class='btn btn-success btn-sm btn-title' onclick=\"setRootPwd(1)\" >提交</button>\
<span class='tname'>root密码</span>\
<div class='info-r'><input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+pwd+"' />\
<span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span>\
</div>\
</div>\
</form>",
});
$('#my_mod_close').click(function(){
$('.layui-layer-close1').click();
yes:function(){
setRootPwd(1);
}
});
}
@@ -632,12 +628,17 @@ function setDbPass(id, username, password){
</div>\
<div class='line'>\
<span class='tname'>密码</span>\
<div class='info-r'><input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+password+"' /><span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
<div class='info-r'>\
<input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+password+"' />\
<span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
</div>\
<input type='hidden' name='id' value='"+id+"'>\
</form>",
yes:function(index){
var data = $("#mod_pwd").serialize();
var data = {};
data['name'] = $('input[name=name]').val();
data['password'] = $('#MyPassword').val();
data['id'] = $('input[name=id]').val();
myPost('set_user_pwd', data, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
@@ -809,14 +810,25 @@ function openPhpmyadmin(name,username,password){
layer.msg('phpMyAdmin未启动',{icon:2,shade: [0.3, '#000']});
return;
}
// console.log(data);
data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'get_cfg'});
var rdata = $.parseJSON(data.data);
if (rdata.choose != 'mariadb'){
layer.msg('当前为['+rdata.choose+']模式,若要使用请切换模式.',{icon:2,shade: [0.3, '#000']});
return;
}
var phpmyadmin_cfg = rdata;
data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'get_home_page'});
var rdata = $.parseJSON(data.data);
if (!rdata.status){
layer.msg(rdata.msg,{icon:2,shade: [0.3, '#000']});
return;
}
$("#toPHPMyAdmin").attr('action',rdata.data);
var home_page = rdata.data;
home_page = home_page.replace("http://","http://"+phpmyadmin_cfg['username']+":"+phpmyadmin_cfg['password']+"@");
$("#toPHPMyAdmin").attr('action',home_page);
if($("#toPHPMyAdmin").attr('action').indexOf('phpmyadmin') == -1){
layer.msg('请先安装phpMyAdmin',{icon:2,shade: [0.3, '#000']});
+16 -6
View File
@@ -14,7 +14,7 @@ sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
mariadbDir=${serverPath}/source/mariadb
MY_VER=10.6.8
MY_VER=10.6.9
Install_app()
{
@@ -57,10 +57,15 @@ Install_app()
fi
# ----- cpu end ------
# https://mirrors.aliyun.com/mariadb/mariadb-10.8.3/source/mariadb-10.8.3.tar.gz
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
# https://mirrors.aliyun.com/mariadb/mariadb-10.8.3/source/mariadb-10.8.3.tar.gz
wget -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
# wget -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
# https://downloads.mariadb.org/interstitial/mariadb-10.6.8/source/mariadb-10.6.8.tar.gz
if [ "$?" != "0" ];then
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
@@ -71,10 +76,15 @@ Install_app()
if [ "$sysName" == "Darwin" ];then
OPTIONS='-DPLUGIN_TOKUDB=NO'
fi
INSTALL_CMD=cmake
CMAKE3=`which cmake3`
if [ "$?" == "0" ];then
INSTALL_CMD=cmake3
fi
if [ ! -d $serverPath/mariadb ];then
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
cd ${mariadbDir}/mariadb-${MY_VER} && $INSTALL_CMD \
-DCMAKE_INSTALL_PREFIX=$serverPath/mariadb \
-DMYSQL_DATADIR=$serverPath/mariadb/data/ \
-DMYSQL_USER=mysql \
+6 -4
View File
@@ -14,7 +14,7 @@ sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
mariadbDir=${serverPath}/source/mariadb
MY_VER=10.7.4
MY_VER=10.7.5
Install_app()
{
@@ -58,14 +58,16 @@ Install_app()
# ----- cpu end ------
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
wget -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
# wget -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
if [ "$?" != "0" ];then
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
cd ${mariadbDir} && tar -zxvf ${mariadbDir}/mariadb-${MY_VER}.tar.gz
fi
if [ ! -d $serverPath/mariadb ];then
cd ${mariadbDir}/mariadb-${MY_VER} && cmake \
+7 -4
View File
@@ -14,7 +14,7 @@ sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
mariadbDir=${serverPath}/source/mariadb
MY_VER=10.8.3
MY_VER=10.8.4
Install_app()
{
@@ -58,8 +58,11 @@ Install_app()
# ----- cpu end ------
if [ ! -f ${mariadbDir}/mariadb-${MY_VER}.tar.gz ];then
wget -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
# wget -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://mirrors.aliyun.com/mariadb/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
if [ "$?" != "0" ];then
wget --no-check-certificate -O ${mariadbDir}/mariadb-${MY_VER}.tar.gz --tries=3 https://downloads.mariadb.org/interstitial/mariadb-${MY_VER}/source/mariadb-${MY_VER}.tar.gz
fi
if [ ! -d ${mariadbDir}/mariadb-${MY_VER} ];then
@@ -86,7 +89,7 @@ Install_app()
make -j${cpuCore} && make install && make clean
if [ -d $serverPath/mariadb ];then
echo '10.7' > $serverPath/mariadb/version.pl
echo '10.8' > $serverPath/mariadb/version.pl
echo '安装完成' > $install_tmp
else
# rm -rf ${mariadbDir}/mariadb-${MY_VER}
+16 -4
View File
@@ -21,14 +21,26 @@ 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()
{
if [ ! -f $serverPath/source/mongodb-macos-x86_64-${VERSION}.tgz ];then
wget -O $serverPath/source/mongodb-macos-x86_64-${VERSION}.tgz https://fastdl.mongodb.org/osx/mongodb-macos-x86_64-${VERSION}.tgz
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
cd $serverPath/source && tar -zxvf mongodb-macos-x86_64-${VERSION}.tgz
cd mongodb-macos-x86_64-${VERSION} && mv ./* $serverPath/mongodb
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
}
-97
View File
@@ -1,97 +0,0 @@
[client]
user = root
#password = your_password
port = 3376
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 3376
mysqlx_port = 33760
socket = {$SERVER_APP_PATH}/mysql.sock
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
default_storage_engine = MyISAM
key_buffer_size = 8M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
read_buffer_size = 128K
read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=0
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
#skip-external-locking
#skip-grant-tables
#loose-skip-innodb
#skip-networking
#skip-name-resolve
log-bin=mysql-bin
binlog_format=mixed
server-id = 1
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=3
#log_queries_not_using_indexes=on
relay-log=mdserver
relay-log-index=mdserver
#master
#binlog-do-db
binlog-ignore-db = test
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log-slave-updates
#replicate-do-db
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table=1
binlog_expire_logs_seconds=2592000
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
-28
View File
@@ -1,28 +0,0 @@
CREATE TABLE IF NOT EXISTS `config` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`mysql_root` TEXT
);
INSERT INTO `config` (`id`, `mysql_root`) VALUES (1, 'admin');
CREATE TABLE IF NOT EXISTS `databases` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`pid` INTEGER,
`name` TEXT,
`username` TEXT,
`password` TEXT,
`accept` TEXT,
`ps` TEXT,
`addtime` TEXT
);
CREATE TABLE IF NOT EXISTS `master_replication_user` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`username` TEXT,
`password` TEXT,
`accept` TEXT,
`ps` TEXT,
`addtime` TEXT
);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

-58
View File
@@ -1,58 +0,0 @@
<div class="bt-form">
<div class='plugin_version'></div>
<div class="bt-w-main">
<div class="bt-w-menu">
<script type="text/javascript">console.log($('.plugin_version').attr('version'));</script>
<p class="bgw" onclick="pluginService('mysql-yum', $('.plugin_version').attr('version'));">服务</p>
<p onclick="pluginInitD('mysql-yum', $('.plugin_version').attr('version'));">自启动</p>
<p onclick="pluginConfig('mysql-yum', $('.plugin_version').attr('version'));">配置文件</p>
<p onclick="myDbPos();">存储位置</p>
<p onclick="myPort();">端口</p>
<p onclick="runInfo();">当前状态</p>
<p onclick="myPerfOpt();">性能优化</p>
<p onclick="myLogs();">日志</p>
<p onclick="pluginLogs('mysql-yum',$('.plugin_version').attr('version'),'error_log');">错误日志</p>
<p onclick="pluginLogs('mysql-yum',$('.plugin_version').attr('version'),'show_log');">慢日志</p>
<p onclick="dbList()">管理列表</p>
</div>
<div class="bt-w-con pd15">
<div class="soft-man-con"></div>
</div>
</div>
</div>
<style type="text/css">
.db_list{
padding: 0px 0 10px 0;
font-size: 13px;
line-height: 35px;
height: 45px;
}
.db_list a{
margin-right: 15px;
color: #555;
font-weight: 600;
}
.db_list span:nth-child(1){
display: block;
float: left;
padding-left: 15px;
background: #ececec;
border-radius: 3px;
}
#db_tools button {
margin-right: 10px;
}
#db_tools button:last-child{
margin-right: 0;
}
</style>
<script type="text/javascript">
resetPluginWinWidth(800);
$.getScript( "/plugins/file?name=mysql-yum&f=js/mysql-yum.js", function(){
pluginService('mysql-yum',$('.plugin_version').attr('version'));
});
</script>
File diff suppressed because it is too large Load Diff
-17
View File
@@ -1,17 +0,0 @@
{
"title":"MySQL[YUM]",
"tip":"soft",
"name":"mysql-yum",
"type":"运行环境",
"ps":"一种关系数据库管理系统(极速安装)[YUM]!",
"todo_versions":["5.7","8.0"],
"versions":["5.7","8.0"],
"shell":"install.sh",
"install_pre_inspection":true,
"checks":"server/mysql-yum",
"path":"server/mysql-yum",
"author":"mysql",
"home":"https://dev.mysql.com/downloads/mysql",
"date":"2022-06-29",
"pid": "6"
}
@@ -1,63 +0,0 @@
# It's not recommended to modify this file in-place, because it will be
# overwritten during package upgrades. If you want to customize, the
# best way is to use systemctl edit:
#
# $ systemctl edit mysqld.service
#
# this will create file
#
# /etc/systemd/system/mysqld.service.d/override.conf
#
# which be parsed after the file mysqld.service itself is parsed.
#
# For example, if you want to increase mysql's open-files-limit to 20000
# add following when editing with command above:
#
# [Service]
# LimitNOFILE=20000
#
# Or if you require to execute pre and post scripts in the unit file as root, set
# PermissionsStartOnly=true
#
# For more info about custom unit files, see systemd.unit(5) or
# http://fedoraproject.org/wiki/Systemd#How_do_I_customize_a_unit_file.2F_add_a_custom_unit_file.3F
#
# Don't forget to reload systemd daemon after you change unit configuration:
# root> systemctl --system daemon-reload
[Unit]
Description=MySQL 8.0 database server
After=syslog.target
After=network.target
[Service]
Type=notify
User=mysql
Group=mysql
ExecStartPre=/usr/libexec/mysql-check-socket
ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
# per bug #547485
ExecStart=/usr/libexec/mysqld --defaults-file={$SERVER_PATH}/mysql-ya/etc/my.cnf --basedir=/usr --user=mysql
ExecStartPost=/usr/libexec/mysql-check-upgrade
ExecStopPost=/usr/libexec/mysql-wait-stop
# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300
# Place temp files in a secure directory, not /tmp
PrivateTmp=false
Restart=on-failure
RestartPreventExitStatus=1
# Sets open_files_limit
LimitNOFILE = 10000
# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.
Environment=MYSQLD_PARENT_PID=1
[Install]
WantedBy=multi-user.target
-46
View File
@@ -1,46 +0,0 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
# cd /www/server/mdserver-web/plugins/mysql-yum && bash install.sh install 8.0
# cd /www/server/mdserver-web/plugins/mysql-yum && bash install.sh uninstall 8.0
# cd /www/server/mdserver-web && python3 /www/server/mdserver-web/plugins/mysql-yum/index.py start 8.0
install_tmp=${rootPath}/tmp/mw_install.pl
action=$1
type=$2
if [ "${2}" == "" ];then
echo '缺少安装脚本...' > $install_tmp
exit 0
fi
if [ ! -d $curPath/versions/$2 ];then
echo '缺少安装脚本2...' > $install_tmp
exit 0
fi
if [ "${action}" == "uninstall" ];then
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-yum/index.py stop ${type}
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-yum/index.py initd_uninstall ${type}
cd $curPath
fi
sh -x $curPath/versions/$2/install.sh $1
if [ "${action}" == "install" ];then
# #初始化
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-yum/index.py start ${type}
cd ${rootPath} && python3 ${rootPath}/plugins/mysql-yum/index.py initd_install ${type}
fi
File diff suppressed because it is too large Load Diff
-119
View File
@@ -1,119 +0,0 @@
# coding: utf-8
#-----------------------------
# 网站备份工具
#-----------------------------
import sys
import os
if sys.platform != 'darwin':
os.chdir('/www/server/mdserver-web')
chdir = os.getcwd()
sys.path.append(chdir + '/class/core')
# reload(sys)
# sys.setdefaultencoding('utf-8')
import mw
import db
import time
class backupTools:
def backupDatabase(self, name, count):
db_path = mw.getServerDir() + '/mysql-ya'
db_name = 'mysql'
name = mw.M('databases').dbPos(db_path, 'mysql').where(
'name=?', (name,)).getField('name')
startTime = time.time()
if not name:
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]不存在!"
print("★[" + endDate + "] " + log)
print(
"----------------------------------------------------------------------------")
return
backup_path = mw.getRootDir() + '/backup/database'
if not os.path.exists(backup_path):
mw.execShell("mkdir -p " + backup_path)
filename = backup_path + "/db_" + name + "_" + \
time.strftime('%Y%m%d_%H%M%S', time.localtime()) + ".sql.gz"
import re
mysql_root = mw.M('config').dbPos(db_path, db_name).where(
"id=?", (1,)).getField('mysql_root')
mycnf = mw.readFile(db_path + '/etc/my.cnf')
rep = "\[mysqldump\]\nuser=root"
sea = "[mysqldump]\n"
subStr = sea + "user=root\npassword=" + mysql_root + "\n"
mycnf = mycnf.replace(sea, subStr)
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
mw.execShell(
db_path + "/bin/mysqldump --opt --default-character-set=utf8 " + name + " | gzip > " + filename)
if not os.path.exists(filename):
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
log = "数据库[" + name + "]备份失败!"
print("★[" + endDate + "] " + log)
print(
"----------------------------------------------------------------------------")
return
mycnf = mw.readFile(db_path + '/etc/my.cnf')
mycnf = mycnf.replace(subStr, sea)
if len(mycnf) > 100:
mw.writeFile(db_path + '/etc/my.cnf', mycnf)
endDate = time.strftime('%Y/%m/%d %X', time.localtime())
outTime = time.time() - startTime
pid = mw.M('databases').dbPos(db_path, db_name).where(
'name=?', (name,)).getField('id')
mw.M('backup').add('type,name,pid,filename,addtime,size', (1, os.path.basename(
filename), pid, filename, endDate, os.path.getsize(filename)))
log = "数据库[" + name + "]备份成功,用时[" + str(round(outTime, 2)) + u"]秒"
mw.writeLog('计划任务', log)
print("★[" + endDate + "] " + log)
print("|---保留最新的[" + count + "]份备份")
print("|---文件名:" + filename)
# 清理多余备份
backups = mw.M('backup').where(
'type=? and pid=?', ('1', pid)).field('id,filename').select()
num = len(backups) - int(count)
if num > 0:
for backup in backups:
mw.execShell("rm -f " + backup['filename'])
mw.M('backup').where('id=?', (backup['id'],)).delete()
num -= 1
print("|---已清理过期备份文件:" + backup['filename'])
if num < 1:
break
def backupDatabaseAll(self, save):
db_path = mw.getServerDir() + '/mysql-ya'
db_name = 'mysql'
databases = mw.M('databases').dbPos(
db_path, db_name).field('name').select()
for database in databases:
self.backupDatabase(database['name'], save)
if __name__ == "__main__":
backup = backupTools()
type = sys.argv[1]
if type == 'database':
if sys.argv[2] == 'ALL':
backup.backupDatabaseAll(sys.argv[3])
else:
backup.backupDatabase(sys.argv[2], sys.argv[3])
-119
View File
@@ -1,119 +0,0 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#https://dev.mysql.com/downloads/mysql/5.7.html
#https://dev.mysql.com/downloads/file/?id=489855
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
mysqlDir=${serverPath}/source/mysql
_os=`uname`
if [ ${_os} == "Darwin" ]; then
OSNAME='macos'
elif grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
OSNAME='centos'
elif grep -Eqi "Rocky" /etc/issue || grep -Eq "Rocky" /etc/*-release; then
OSNAME='rocky'
elif grep -Eqi "Red Hat Enterprise Linux Server" /etc/issue || grep -Eq "Red Hat Enterprise Linux Server" /etc/*-release; then
OSNAME='rhel'
elif grep -Eqi "Aliyun" /etc/issue || grep -Eq "Aliyun" /etc/*-release; then
OSNAME='aliyun'
elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
OSNAME='fedora'
elif grep -Eqi "Amazon Linux AMI" /etc/issue || grep -Eq "Amazon Linux AMI" /etc/*-release; then
OSNAME='amazon'
elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
OSNAME='debian'
elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
OSNAME='ubuntu'
elif grep -Eqi "Raspbian" /etc/issue || grep -Eq "Raspbian" /etc/*-release; then
OSNAME='raspbian'
elif grep -Eqi "Deepin" /etc/issue || grep -Eq "Deepin" /etc/*-release; then
OSNAME='deepin'
else
OSNAME='unknow'
fi
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
YUM_INSTALL()
{
#######
#http://repo.mysql.com/
if [ "${OSNAME}" == "centos" ] && [ "${VERSION_ID}" -le "7" ] ;then
wget -O /tmp/mysql57-community-release-el${VERSION_ID}.rpm http://repo.mysql.com/mysql57-community-release-el${VERSION_ID}.rpm
rpm -ivh /tmp/mysql57-community-release-el${VERSION_ID}.rpm
yum -y install mysql-server
rm -rf /tmp/mysql57-community-release-el${VERSION_ID}.rpm
fi
#######
}
YUM_UNINSTALL()
{
### YUM卸载 START ########
yum remove -y mysql-server
### YUM卸载 END ########
}
Install_mysql()
{
echo '正在安装脚本文件...' > $install_tmp
if id mysql &> /dev/null ;then
echo "mysql UID is `id -u mysql`"
echo "mysql Shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
else
groupadd mysql
useradd -g mysql mysql
fi
isYum=`which yum`
if [ "$isYum" != "" ];then
YUM_INSTALL
fi
if [ "$?" == "0" ];then
mkdir -p $serverPath/mysql-yum
echo '5.7' > $serverPath/mysql-yum/version.pl
echo '安装完成' > $install_tmp
else
echo "暂时不支持该系统" > $install_tmp
fi
}
Uninstall_mysql()
{
isYum=`which yum`
if [ "$isYum" != "" ];then
YUM_UNINSTALL
fi
rm -rf $serverPath/mysql-yum
echo '卸载完成' > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_mysql
else
Uninstall_mysql
fi
-121
View File
@@ -1,121 +0,0 @@
# -*- coding: utf-8 -*-
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
#https://dev.mysql.com/downloads/mysql/5.7.html
#https://dev.mysql.com/downloads/file/?id=489855
curPath=`pwd`
rootPath=$(dirname "$curPath")
rootPath=$(dirname "$rootPath")
serverPath=$(dirname "$rootPath")
sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
mysqlDir=${serverPath}/source/mysql
_os=`uname`
if [ ${_os} == "Darwin" ]; then
OSNAME='macos'
elif grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
OSNAME='centos'
elif grep -Eqi "Rocky" /etc/issue || grep -Eq "Rocky" /etc/*-release; then
OSNAME='rocky'
elif grep -Eqi "Red Hat Enterprise Linux Server" /etc/issue || grep -Eq "Red Hat Enterprise Linux Server" /etc/*-release; then
OSNAME='rhel'
elif grep -Eqi "Aliyun" /etc/issue || grep -Eq "Aliyun" /etc/*-release; then
OSNAME='aliyun'
elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
OSNAME='fedora'
elif grep -Eqi "Amazon Linux AMI" /etc/issue || grep -Eq "Amazon Linux AMI" /etc/*-release; then
OSNAME='amazon'
elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
OSNAME='debian'
elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
OSNAME='ubuntu'
elif grep -Eqi "Raspbian" /etc/issue || grep -Eq "Raspbian" /etc/*-release; then
OSNAME='raspbian'
elif grep -Eqi "Deepin" /etc/issue || grep -Eq "Deepin" /etc/*-release; then
OSNAME='deepin'
else
OSNAME='unknow'
fi
VERSION_ID=`cat /etc/*-release | grep VERSION_ID | awk -F = '{print $2}' | awk -F "\"" '{print $2}'`
YUM_INSTALL()
{
#######
if [ "${OSNAME}" == "centos" ];then
wget -O /tmp/mysql80-community-release.rpm http://repo.mysql.com/mysql80-community-release-el${VERSION}.rpm
else
wget -O /tmp/mysql80-community-release.rpm http://repo.mysql.com/mysql80-community-release-el8.rpm
fi
rpm -ivh /tmp/mysql80-community-release.rpm
yum -y install mysql-server
rm -rf /tmp/mysql80-community-release.rpm
#######
}
YUM_UNINSTALL()
{
### YUM卸载 START ########
yum -y remove mysql-server
### YUM卸载 END ########
}
Install_mysql()
{
echo '正在安装脚本文件...' > $install_tmp
if id mysql &> /dev/null ;then
echo "mysql UID is `id -u mysql`"
echo "mysql Shell is `grep "^mysql:" /etc/passwd |cut -d':' -f7 `"
else
groupadd mysql
useradd -g mysql mysql
fi
isYum=`which yum`
if [ "$isYum" != "" ];then
YUM_INSTALL
fi
if [ "$?" == "0" ];then
mkdir -p $serverPath/mysql-yum
echo '8.0' > $serverPath/mysql-yum/version.pl
echo '安装完成' > $install_tmp
else
echo "暂时不支持该系统" > $install_tmp
fi
}
Uninstall_mysql()
{
isYum=`which yum`
if [ "$isYum" != "" ];then
YUM_UNINSTALL
fi
rm -rf $serverPath/mysql-ya
echo '卸载完成' > $install_tmp
}
action=$1
if [ "${1}" == 'install' ];then
Install_mysql
else
Uninstall_mysql
fi
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,22 +1,26 @@
[client]
user = root
#password = your_password
port = 3386
port = 3306
socket = {$SERVER_APP_PATH}/mysql.sock
default-character-set = UTF8MB4
[mysqld]
default_authentication_plugin=mysql_native_password
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
port = 3386
mysqlx_port = 33860
port = 3306
socket = {$SERVER_APP_PATH}/mysql.sock
basedir = {$SERVER_APP_PATH}
datadir = {$SERVER_APP_PATH}/data
log-error = {$SERVER_APP_PATH}/data/error.log
default_storage_engine = MyISAM
server-id = {$SERVER_ID}
default_storage_engine = InnoDB
key_buffer_size = 8M
max_allowed_packet = 100M
table_open_cache = 32
sort_buffer_size = 256K
net_buffer_length = 4K
@@ -25,27 +29,28 @@ read_rnd_buffer_size = 256K
myisam_sort_buffer_size = 4M
thread_cache_size = 4
lower_case_table_names=0
query_cache_size = 4M
tmp_table_size = 8M
character-set-server = UTF8MB4
max_connections = 500
max_connect_errors = 100
open_files_limit = 2560
max_allowed_packet = 128M
open_files_limit = 65535
#skip-external-locking
skip-name-resolve=1
#skip-grant-tables
#loose-skip-innodb
#skip-networking
#skip-name-resolve
#skip-external-locking
#loose-skip-innodb
log-bin=mysql-bin
binlog_format=mixed
server-id = 1
slow_query_log=1
slow-query-log-file={$SERVER_APP_PATH}/data/mysql-slow.log
long_query_time=3
long_query_time=10
#log_queries_not_using_indexes=on
#log_slow_admin_statements=1
#log_slow_slave_statements=1
expire_logs_days=30
relay-log=mdserver
relay-log-index=mdserver
@@ -58,32 +63,36 @@ binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
#slave
log_replica_updates
log-slave-updates = 1
skip-slave-start = 1
#replicate-do-db
replicate-ignore-db = information_schema
replicate-ignore-db = performance_schema
replicate-ignore-db = mysql
replicate-ignore-db = test
default_storage_engine = InnoDB
innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_flush_log_at_trx_commit = 2
innodb_lock_wait_timeout = 120
innodb_max_dirty_pages_pct = 90
innodb_read_io_threads = 1
innodb_write_io_threads = 1
innodb_file_per_table=1
binlog_expire_logs_seconds=2592000
innodb_large_prefix = 1
secure-file-priv={$SERVER_APP_PATH}/tmp
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
@@ -7,8 +7,8 @@ socket = {$SERVER_APP_PATH}/mysql.sock
[mysqld]
!include {$SERVER_APP_PATH}/etc/mode/classic.cnf
;sha256_password_private_key_path=mysql.pem
;sha256_password_public_key_path=mysql.pub
sha256_password_private_key_path=mysql.pem
sha256_password_public_key_path=mysql.pub
pid-file = {$SERVER_APP_PATH}/data/mysql.pid
user = mysql
+2 -1
View File
@@ -80,7 +80,8 @@ innodb_data_home_dir = {$SERVER_APP_PATH}/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = {$SERVER_APP_PATH}/data
innodb_buffer_pool_size = 16M
innodb_log_file_size = 5M
#innodb_log_file_size = 5M
innodb_redo_log_capacity=10485760
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 2
innodb_lock_wait_timeout = 120
+1 -1
View File
@@ -53,7 +53,7 @@
.conf_p span {
display: inline-block;
margin-right: 10px;
width: 95px;
width: 135px;
text-align: right;
}
</style>
+139 -9
View File
@@ -333,7 +333,7 @@ def getErrorLog():
if 'close' in args:
mw.writeFile(filename, '')
return mw.returnJson(False, '日志已清空')
info = mw.getNumLines(filename, 18)
info = mw.getLastLine(filename, 18)
return mw.returnJson(True, 'OK', info)
@@ -404,6 +404,7 @@ def initMysqlPwd():
time.sleep(5)
serverdir = getServerDir()
myconf = serverdir + "/etc/my.cnf"
pwd = mw.getRandomString(16)
# cmd_pass = serverdir + '/bin/mysqladmin -uroot password ' + pwd
@@ -426,6 +427,17 @@ def initMysqlPwd():
pwd + ' -e "drop database test";'
mw.execShell(drop_test_db)
# 删除冗余账户
hostname = mw.execShell('hostname')[0].strip()
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
mw.execShell(drop_hostname)
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
mw.execShell(drop_root_hostname)
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
return True
@@ -468,6 +480,17 @@ def initMysql8Pwd():
myconf + ' -uroot -p' + pwd + ' -e "drop database test";'
mw.execShell(drop_test_db)
# 删除冗余账户
hostname = mw.execShell('hostname')[0].strip()
drop_hostname = serverdir + '/bin/mysql --defaults-file=' + \
myconf + ' -uroot -p' + pwd + ' -e "drop user \'\'@\'' + hostname + '\'";'
mw.execShell(drop_hostname)
drop_root_hostname = serverdir + '/bin/mysql --defaults-file=' + \
myconf + ' -uroot -p' + pwd + ' -e "drop user \'root\'@\'' + hostname + '\'";'
mw.execShell(drop_root_hostname)
pSqliteDb('config').where('id=?', (1,)).save('mysql_root', (pwd,))
return True
@@ -475,7 +498,7 @@ def initMysql8Pwd():
def myOp(version, method):
# import commands
init_file = initDreplace()
init_file = initDreplace(version)
try:
isInited = initMysqlData()
if not isInited:
@@ -804,6 +827,69 @@ def setDbBackup():
return mw.returnJson(True, 'ok')
def importDbExternal():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
if not data[0]:
return data[1]
file = args['file']
name = args['name']
import_dir = mw.getRootDir() + '/backup/import/'
file_path = import_dir + file
if not os.path.exists(file_path):
return mw.returnJson(False, '文件突然消失?')
exts = ['sql', 'gz', 'zip']
tmp = file.split('.')
ext = tmp[len(tmp) - 1]
if ext not in exts:
return mw.returnJson(False, '导入数据库格式不对!')
tmp = file.split('/')
tmpFile = tmp[len(tmp) - 1]
tmpFile = tmpFile.replace('.sql.' + ext, '.sql')
tmpFile = tmpFile.replace('.' + ext, '.sql')
tmpFile = tmpFile.replace('tar.', '')
# print(tmpFile)
import_sql = ""
if file.find("sql.gz") > -1:
cmd = 'cd ' + import_dir + ' && gzip -dc ' + \
file + " > " + import_dir + tmpFile
info = mw.execShell(cmd)
if info[1] == "":
import_sql = import_dir + tmpFile
if file.find(".zip") > -1:
cmd = 'cd ' + import_dir + ' && unzip -o ' + file
mw.execShell(cmd)
import_sql = import_dir + tmpFile
if file.find("tar.gz") > -1:
cmd = 'cd ' + import_dir + ' && tar -zxvf ' + file
mw.execShell(cmd)
import_sql = import_dir + tmpFile
if import_sql == "":
return mw.returnJson(False, '未找SQL文件')
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
sock = getSocketFile()
os.environ["MYSQL_PWD"] = pwd
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + \
pwd + ' ' + name + ' < ' + import_sql
# print(mysql_cmd)
os.system(mysql_cmd)
os.remove(import_sql)
return mw.returnJson(True, 'ok')
def importDbBackup():
args = getArgs()
data = checkArgs(args, ['file', 'name'])
@@ -821,8 +907,8 @@ def importDbBackup():
mw.execShell(cmd)
pwd = pSqliteDb('config').where('id=?', (1,)).getField('mysql_root')
mysql_cmd = mw.getRootDir() + '/server/mysql/bin/mysql -uroot -p' + pwd + \
sock = getSocketFile()
mysql_cmd = getServerDir() + '/bin/mysql -S ' + sock + ' -uroot -p' + pwd + \
' ' + name + ' < ' + file_path_sql
# print(mysql_cmd)
@@ -832,13 +918,17 @@ def importDbBackup():
def deleteDbBackup():
args = getArgs()
data = checkArgs(args, ['filename'])
data = checkArgs(args, ['filename', 'path'])
if not data[0]:
return data[1]
path = args['path']
full_file = ""
bkDir = mw.getRootDir() + '/backup/database'
os.remove(bkDir + '/' + args['filename'])
full_file = bkDir + '/' + args['filename']
if path != "":
full_file = path + "/" + args['filename']
os.remove(full_file)
return mw.returnJson(True, 'ok')
@@ -870,6 +960,39 @@ def getDbBackupList():
return mw.returnJson(True, 'ok', rr)
def getDbBackupImportList():
bkImportDir = mw.getRootDir() + '/backup/import'
if not os.path.exists(bkImportDir):
os.mkdir(bkImportDir)
blist = os.listdir(bkImportDir)
rr = []
for x in range(0, len(blist)):
name = blist[x]
p = bkImportDir + '/' + name
data = {}
data['name'] = name
rsize = os.path.getsize(p)
data['size'] = mw.toSize(rsize)
t = os.path.getctime(p)
t = time.localtime(t)
data['time'] = time.strftime('%Y-%m-%d %H:%M:%S', t)
rr.append(data)
data['file'] = p
rdata = {
"list": rr,
"upload_dir": bkImportDir,
}
return mw.returnJson(True, 'ok', rdata)
def getDbList():
args = getArgs()
page = 1
@@ -2338,8 +2461,11 @@ def installPreInspection(version):
def uninstallPreInspection(version):
# return "请手动删除MySQL[{}]".format(version)
return 'ok'
stop(version)
if mw.isDebugMode():
return 'ok'
return "请手动删除MySQL[{}]<br/> rm -rf {}".format(version, getServerDir())
if __name__ == "__main__":
func = sys.argv[1]
@@ -2401,10 +2527,14 @@ if __name__ == "__main__":
print(setDbBackup())
elif func == 'import_db_backup':
print(importDbBackup())
elif func == 'import_db_external':
print(importDbExternal())
elif func == 'delete_db_backup':
print(deleteDbBackup())
elif func == 'get_db_backup_list':
print(getDbBackupList())
elif func == 'get_db_backup_import_list':
print(getDbBackupImportList())
elif func == 'add_db':
print(addDb())
elif func == 'del_db':
+1 -1
View File
@@ -11,7 +11,7 @@
"path": "server/mysql/VERSION",
"todo_versions":["5.6","5.7","8.0"],
"versions":["5.5", "5.6", "5.7","8.0"],
"updates":["5.5.62","5.6.50", "5.7.32","8.0.22"],
"updates":["5.5.62","5.6.50", "5.7.32","8.0.30"],
"shell":"install.sh",
"checks":"server/mysql",
"path":"server/mysql",
+243 -95
View File
@@ -1,18 +1,9 @@
function str2Obj(str){
var data = {};
kv = str.split('&');
for(i in kv){
v = kv[i].split('=');
data[v[0]] = v[1];
}
return data;
}
function myPost(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
@@ -40,7 +31,7 @@ function myPostN(method,args,callback, title){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
@@ -59,7 +50,7 @@ function myPostN(method,args,callback, title){
function myAsyncPost(method,args){
var _args = null;
if (typeof(args) == 'string'){
_args = JSON.stringify(str2Obj(args));
_args = JSON.stringify(toArrayObject(args));
} else {
_args = JSON.stringify(args);
}
@@ -68,6 +59,26 @@ function myAsyncPost(method,args){
return syncPost('/plugins/run', {name:'mysql', func:method, args:_args});
}
function vaildPhpmyadmin(url,username,password){
console.log("Authorization: Basic " + btoa(username + ":" + password));
$.ajax({
type: "GET",
url: url,
dataType: 'json',
async: false,
username:username,
password:password,
headers: {
"Authorization": "Basic " + btoa(username + ":" + password)
},
data: 'vaild',
success: function (){
alert('Thanks for your comment!');
}
});
}
function runInfo(){
myPost('run_info','',function(data){
@@ -445,10 +456,9 @@ function syncToDatabase(type){
function setRootPwd(type, pwd){
if (type==1){
var data = $("#mod_pwd").serialize();
myPost('set_root_pwd', data, function(data){
var password = $("#MyPassword").val();
myPost('set_root_pwd', {password:password}, function(data){
var rdata = $.parseJSON(data.data);
// console.log(rdata);
showMsg(rdata.msg,function(){
dbList();
$('.layui-layer-close1').click();
@@ -459,26 +469,23 @@ function setRootPwd(type, pwd){
var index = layer.open({
type: 1,
skin: 'demo-class',
area: '500px',
title: '修改数据库密码',
closeBtn: 1,
shift: 5,
btn:["提交","关闭"],
shadeClose: true,
content: "<form class='bt-form pd20 pb70' id='mod_pwd'>\
content: "<form class='bt-form pd20' id='mod_pwd'>\
<div class='line'>\
<span class='tname'>root密码</span>\
<div class='info-r'><input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+pwd+"' /><span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
</div>\
<div class='bt-form-submit-btn'>\
<button id='my_mod_close' type='button' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' class='btn btn-success btn-sm btn-title' onclick=\"setRootPwd(1)\" >提交</button>\
<span class='tname'>root密码</span>\
<div class='info-r'><input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+pwd+"' />\
<span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span>\
</div>\
</div>\
</form>",
});
$('#my_mod_close').click(function(){
$('.layui-layer-close1').click();
yes:function(){
setRootPwd(1);
}
});
}
@@ -590,7 +597,7 @@ function setDbAccess(username){
yes:function(index){
var data = $("#set_db_access").serialize();
data = decodeURIComponent(data);
var dataObj = str2Obj(data);
var dataObj = toArrayObject(data);
if(!dataObj['access']){
dataObj['access'] = dataObj['dataAccess'];
if ( dataObj['dataAccess'] == 'ip'){
@@ -632,12 +639,18 @@ function setDbPass(id, username, password){
</div>\
<div class='line'>\
<span class='tname'>密码</span>\
<div class='info-r'><input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+password+"' /><span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
<div class='info-r'>\
<input class='bt-input-text mr5' type='text' name='password' id='MyPassword' style='width:330px' value='"+password+"' />\
<span title='随机密码' class='glyphicon glyphicon-repeat cursor' onclick='repeatPwd(16)'></span></div>\
</div>\
<input type='hidden' name='id' value='"+id+"'>\
</form>",
yes:function(index){
var data = $("#mod_pwd").serialize();
// var data = $("#mod_pwd").serialize();
var data = {};
data['name'] = $('input[name=name]').val();
data['password'] = $('#MyPassword').val();
data['id'] = $('input[name=id]').val();
myPost('set_user_pwd', data, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
@@ -650,33 +663,15 @@ function setDbPass(id, username, password){
}
function addDatabase(type){
if (type==1){
var data = $("#add_db").serialize();
data = decodeURIComponent(data);
var dataObj = str2Obj(data);
if(!dataObj['address']){
dataObj['address'] = dataObj['dataAccess'];
}
myPost('add_db', dataObj, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
if (rdata.status){
dbList();
}
$('.layui-layer-close1').click();
},{icon: rdata.status ? 1 : 2},600);
});
return;
}
var index = layer.open({
layer.open({
type: 1,
skin: 'demo-class',
area: '500px',
title: '添加数据库',
closeBtn: 1,
shift: 5,
shadeClose: true,
content: "<form class='bt-form pd20 pb70' id='add_db'>\
btn:["提交","关闭"],
content: "<form class='bt-form pd20' id='add_db'>\
<div class='line'>\
<span class='tname'>数据库名</span>\
<div class='info-r'><input name='name' class='bt-input-text mr5' placeholder='新的数据库名称' type='text' style='width:65%' value=''>\
@@ -704,28 +699,39 @@ function addDatabase(type){
</div>\
</div>\
<input type='hidden' name='ps' value='' />\
<div class='bt-form-submit-btn'>\
<button id='my_mod_close' type='button' class='btn btn-danger btn-sm btn-title'>关闭</button>\
<button type='button' class='btn btn-success btn-sm btn-title' onclick=\"addDatabase(1)\" >提交</button>\
</div>\
</form>",
});
success:function(){
$("input[name='name']").keyup(function(){
var v = $(this).val();
$("input[name='db_user']").val(v);
$("input[name='ps']").val(v);
});
$("input[name='name']").keyup(function(){
var v = $(this).val();
$("input[name='db_user']").val(v);
$("input[name='ps']").val(v);
});
$('#my_mod_close').click(function(){
$('.layui-layer-close1').click();
});
$('select[name="dataAccess"]').change(function(){
var v = $(this).val();
if (v == 'ip'){
$(this).after("<input id='dataAccess_subid' class='bt-input-text mr5' type='text' name='address' placeholder='多个IP使用逗号(,)分隔' style='width: 230px; display: inline-block;'>");
} else {
$('#dataAccess_subid').remove();
$('select[name="dataAccess"]').change(function(){
var v = $(this).val();
if (v == 'ip'){
$(this).after("<input id='dataAccess_subid' class='bt-input-text mr5' type='text' name='address' placeholder='多个IP使用逗号(,)分隔' style='width: 230px; display: inline-block;'>");
} else {
$('#dataAccess_subid').remove();
}
});
},
yes:function(index) {
var data = $("#add_db").serialize();
data = decodeURIComponent(data);
var dataObj = toArrayObject(data);
if(!dataObj['address']){
dataObj['address'] = dataObj['dataAccess'];
}
myPost('add_db', dataObj, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
if (rdata.status){
layer.close(index);
dbList();
}
},{icon: rdata.status ? 1 : 2},600);
});
}
});
}
@@ -737,7 +743,6 @@ function delDb(id, name){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
dbList();
$('.layui-layer-close1').click();
},{icon: rdata.status ? 1 : 2}, 600);
});
});
@@ -809,15 +814,26 @@ function openPhpmyadmin(name,username,password){
layer.msg('phpMyAdmin未启动',{icon:2,shade: [0.3, '#000']});
return;
}
// console.log(data);
data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'get_cfg'});
var rdata = $.parseJSON(data.data);
if (rdata.choose == 'mariadb'){
layer.msg('当前为[mariadb]模式,若要使用请切换模式.',{icon:2,shade: [0.3, '#000']});
return;
}
var phpmyadmin_cfg = rdata;
data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'get_home_page'});
var rdata = $.parseJSON(data.data);
if (!rdata.status){
layer.msg(rdata.msg,{icon:2,shade: [0.3, '#000']});
return;
}
$("#toPHPMyAdmin").attr('action',rdata.data);
var home_page = rdata.data;
home_page = home_page.replace("http://","http://"+phpmyadmin_cfg['username']+":"+phpmyadmin_cfg['password']+"@")
$("#toPHPMyAdmin").attr('action',home_page);
if($("#toPHPMyAdmin").attr('action').indexOf('phpmyadmin') == -1){
layer.msg('请先安装phpMyAdmin',{icon:2,shade: [0.3, '#000']});
setTimeout(function(){ window.location.href = '/soft'; },3000);
@@ -826,7 +842,7 @@ function openPhpmyadmin(name,username,password){
//检查版本
data = syncPost('/plugins/run',{'name':'phpmyadmin','func':'version'});
bigVer = data.data.split('.')[0]
bigVer = data.data.split('.')[0];
if (bigVer>=4.5){
setTimeout(function(){
@@ -848,8 +864,11 @@ function openPhpmyadmin(name,username,password){
}
}
function delBackup(filename,name){
myPost('delete_db_backup',{filename:filename},function(){
function delBackup(filename,name,path){
if(typeof(path) == "undefined"){
path = "";
}
myPost('delete_db_backup',{filename:filename,path:path},function(){
layer.msg('执行成功!');
setTimeout(function(){
$('.layui-layer-close2').click();
@@ -869,6 +888,132 @@ function importBackup(file,name){
});
}
function importDbExternal(file,name){
myPost('import_db_external',{file:file,name:name}, function(data){
layer.msg('执行成功!');
});
}
function setLocalImport(db_name){
//上传文件
function uploadDbFiles(upload_dir){
var up_db = layer.open({
type:1,
closeBtn: 1,
title:"上传导入文件["+upload_dir+']',
area: ['500px','300px'],
shadeClose:false,
content:'<div class="fileUploadDiv">\
<input type="hidden" id="input-val" value="'+upload_dir+'" />\
<input type="file" id="file_input" multiple="true" autocomplete="off" />\
<button type="button" id="opt" autocomplete="off">添加文件</button>\
<button type="button" id="up" autocomplete="off" >开始上传</button>\
<span id="totalProgress" style="position: absolute;top: 7px;right: 147px;"></span>\
<span style="float:right;margin-top: 9px;">\
<font>文件编码:</font>\
<select id="fileCodeing" >\
<option value="byte">二进制</option>\
<option value="utf-8">UTF-8</option>\
<option value="gb18030">GB2312</option>\
</select>\
</span>\
<button type="button" id="filesClose" autocomplete="off">关闭</button>\
<ul id="up_box"></ul>\
</div>',
success:function(){
$('#filesClose').click(function(){
layer.close(up_db);
});
}
});
uploadStart(function(){
getList();
});
}
function getList(){
myPost('get_db_backup_import_list',{}, function(data){
var rdata = $.parseJSON(data.data);
var file_list = rdata.data.list;
var upload_dir = rdata.data.upload_dir;
var tbody = '';
for (var i = 0; i < file_list.length; i++) {
tbody += '<tr>\
<td><span> ' + file_list[i]['name'] + '</span></td>\
<td><span> ' + file_list[i]['size'] + '</span></td>\
<td><span> ' + file_list[i]['time'] + '</span></td>\
<td style="text-align: right;">\
<a class="btlink" onclick="importDbExternal(\'' + file_list[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
<a class="btlink del" index="'+i+'">删除</a>\
</td>\
</tr>';
}
$('#import_db_file_list').html(tbody);
$('input[name="upload_dir"]').val(upload_dir);
$("#import_db_file_list .del").on('click',function(){
var index = $(this).attr('index');
var filename = file_list[index]["name"];
myPost('delete_db_backup',{filename:filename,path:upload_dir},function(){
showMsg('执行成功!', function(){
getList();
},{icon:1},2000);
});
});
});
}
var layerIndex = layer.open({
type: 1,
title: "从文件导入数据",
area: ['600px', '380px'],
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15">\
<div class="db_list">\
<button id="btn_file_upload" class="btn btn-success btn-sm" type="button">从本地上传</button>\
</div >\
<div class="divtable">\
<input type="hidden" name="upload_dir" value=""> \
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
<table class="table table-hover "style="border:none">\
<thead>\
<tr>\
<th>文件名称</th>\
<th>文件大小</th>\
<th>备份时间</th>\
<th style="text-align: right;">操作</th>\
</tr>\
</thead>\
<tbody id="import_db_file_list" class="gztr"></tbody>\
</table>\
</div>\
<ul class="help-info-text c7">\
<li>仅支持sql、zip、sql.gz、(tar.gz|gz|tgz)</li>\
<li>zip、tar.gz压缩包结构:test.zip或test.tar.gz压缩包内,必需包含test.sql</li>\
<li>若文件过大,您还可以使用SFTP工具,将数据库文件上传到/www/backup/import</li>\
</ul>\
</div>\
</div>',
success:function(index){
$('#btn_file_upload').click(function(){
var upload_dir = $('input[name="upload_dir"]').val();
uploadDbFiles(upload_dir);
});
getList();
},
});
}
function setBackup(db_name,obj){
myPost('get_db_backup_list', {name:db_name}, function(data){
@@ -881,21 +1026,21 @@ function setBackup(db_name,obj){
<td><span> ' + rdata.data[i]['time'] + '</span></td>\
<td style="text-align: right;">\
<a class="btlink" onclick="importBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">导入</a> | \
<a class="btlink" onclick="downloadBackup(\'' + rdata.data[i]['file'] + '\')">下载</a> | \
<a class="btlink" onclick="delBackup(\'' + rdata.data[i]['name'] + '\',\'' +db_name+ '\')">删除</a>\
</td>\
</tr> ';
}
var s = layer.open({
var layerIndex = layer.open({
type: 1,
title: "数据库备份详情",
area: ['600px', '280px'],
closeBtn: 2,
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15">\
<div class="db_list">\
<button id="btn_backup" class="btn btn-success btn-sm" type="button">备份</button>\
<button id="btn_local_import" class="btn btn-success btn-sm" type="button">外部导入</button>\
</div >\
<div class="divtable">\
<div id="database_fix" style="height:150px;overflow:auto;border:#ddd 1px solid">\
@@ -912,18 +1057,21 @@ function setBackup(db_name,obj){
</table>\
</div>\
</div>\
</div>'
});
</div>',
success:function(index){
$('#btn_backup').click(function(){
myPost('set_db_backup',{name:db_name}, function(data){
showMsg('执行成功!', function(){
layer.close(layerIndex);
setBackup(db_name,obj);
}, {icon:1}, 2000);
});
});
$('#btn_backup').click(function(){
myPost('set_db_backup',{name:db_name}, function(data){
layer.msg('执行成功!');
setTimeout(function(){
layer.close(s);
setBackup(db_name,obj);
},2000);
});
$('#btn_local_import').click(function(){
setLocalImport(db_name);
});
},
});
});
}
@@ -1204,7 +1352,7 @@ function repTools(db_name, res){
type: 1,
title: "MySQL工具箱【" + db_name + "】",
area: ['780px', '580px'],
closeBtn: 2,
closeBtn: 1,
shadeClose: false,
content: '<div class="pd15">\
<div class="db_list">\
@@ -1299,7 +1447,7 @@ function addMasterRepSlaveUser(){
yes:function(index){
var data = $("#add_master").serialize();
data = decodeURIComponent(data);
var dataObj = str2Obj(data);
var dataObj = toArrayObject(data);
if(!dataObj['address']){
dataObj['address'] = dataObj['dataAccess'];
}
@@ -1344,7 +1492,7 @@ function updateMasterRepSlaveUser(username){
$('#submit_update_master').click(function(){
var data = $("#update_master").serialize();
data = decodeURIComponent(data);
var dataObj = str2Obj(data);
var dataObj = toArrayObject(data);
myPost('update_master_rep_slave_user', data, function(data){
var rdata = $.parseJSON(data.data);
showMsg(rdata.msg,function(){
@@ -1455,7 +1603,7 @@ function setDbMasterAccess(username){
yes:function(index){
var data = $("#set_db_access").serialize();
data = decodeURIComponent(data);
var dataObj = str2Obj(data);
var dataObj = toArrayObject(data);
if(!dataObj['access']){
dataObj['access'] = dataObj['dataAccess'];
if ( dataObj['dataAccess'] == 'ip'){
+1 -1
View File
@@ -74,7 +74,7 @@ Install_mysql()
OPENSSL_VERSION=`openssl version|awk '{print $2}'|awk -F '.' '{print $1}'`
if [ "${OPENSSL_VERSION}" -ge "3" ];then
#openssl version to high
cd $serverPath/mdserver-web/plugins/php/lib && /bin/bash openssl.sh
cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh
export PKG_CONFIG_PATH=$serverPath/lib/openssl/lib/pkgconfig
OPTIONS="-DWITH_SSL=${serverPath}/lib/openssl"
fi
+6 -6
View File
@@ -17,7 +17,7 @@ sysName=`uname`
install_tmp=${rootPath}/tmp/mw_install.pl
mysqlDir=${serverPath}/source/mysql
VERSION="5.7.37"
VERSION=5.7.39
Install_mysql()
@@ -61,14 +61,14 @@ Install_mysql()
fi
# ----- cpu end ------
cd $serverPath/mdserver-web/plugins/mysql/lib && /bin/bash rpcgen.sh
cd ${rootPath}/plugins/mysql/lib && /bin/bash rpcgen.sh
if [ ! -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/Downloads/MySQL-5.7/mysql-boost-${VERSION}.tar.gz
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
fi
#检测文件是否损坏.
md5_mysql_ok=d0489fc3880248a58759c50bfb286dbb
md5_mysql_ok=d949b0ef81c3f52f7ef0874066244221
if [ -f ${mysqlDir}/mysql-boost-${VERSION}.tar.gz ];then
md5_mysql=`md5sum ${mysqlDir}/mysql-boost-${VERSION}.tar.gz | awk '{print $1}'`
if [ "${md5_mysql_ok}" == "${md5_mysql}" ]; then
@@ -76,7 +76,7 @@ Install_mysql()
else
# 重新下载
rm -rf ${mysqlDir}/mysql-${VERSION}
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/Downloads/MySQL-5.7/mysql-boost-${VERSION}.tar.gz
wget -O ${mysqlDir}/mysql-boost-${VERSION}.tar.gz --tries=3 https://cdn.mysql.com/archives/mysql-5.7/mysql-boost-${VERSION}.tar.gz
fi
fi
@@ -89,7 +89,7 @@ Install_mysql()
OPENSSL_VERSION=`openssl version|awk '{print $2}'|awk -F '.' '{print $1}'`
if [ "${OPENSSL_VERSION}" -ge "3" ];then
#openssl version to high
cd $serverPath/mdserver-web/plugins/php/lib && /bin/bash openssl.sh
cd ${rootPath}/plugins/php/lib && /bin/bash openssl.sh
export PKG_CONFIG_PATH=$serverPath/lib/openssl/lib/pkgconfig
OPTIONS="-DWITH_SSL=${serverPath}/lib/openssl"
fi

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