pull/632/head
Mr Chen 6 months ago
parent ed90f9a087
commit 3ce1289c44
  1. 166
      panel_task.py
  2. 8
      panel_tools.py
  3. 6
      web/admin/__init__.py
  4. 6
      web/admin/dashboard/__init__.py
  5. 2
      web/admin/model/__init__.py
  6. 1
      web/admin/model/option.py
  7. 20
      web/admin/model/task.py
  8. 1
      web/admin/setup/__init__.py
  9. 54
      web/admin/setup/init_cmd.py
  10. 8
      web/admin/setup/option.py
  11. 10
      web/admin/task/__init__.py
  12. 67
      web/core/mw.py
  13. 2
      web/static/app/public.js
  14. 11
      web/thisdb/__init__.py
  15. 28
      web/thisdb/option.py
  16. 54
      web/utils/task.py

@ -117,7 +117,7 @@ def mw_async(f):
@mw_async
def restartMw():
time.sleep(1)
cmd = mw.getRunDir() + '/scripts/init.d/mw reload &'
cmd = mw.getPanelDir() + '/scripts/init.d/mw reload &'
mw.execShell(cmd)
@ -225,173 +225,15 @@ def siteEdate():
def systemTask():
from utils.system import monitor
# 系统监控任务
try:
import system_api
import psutil
sm = system_api.system_api()
filename = 'data/control.conf'
sql = db.Sql().dbfile('system')
csql = mw.readFile('data/sql/system.sql')
csql_list = csql.split(';')
for index in range(len(csql_list)):
sql.execute(csql_list[index], ())
cpuIo = cpu = {}
cpuCount = psutil.cpu_count()
used = count = 0
reloadNum = 0
network_up = network_down = diskio_1 = diskio_2 = networkInfo = cpuInfo = diskInfo = None
while True:
if not os.path.exists(filename):
time.sleep(10)
continue
day = 30
try:
day = int(mw.readFile(filename))
if day < 1:
time.sleep(10)
continue
except:
day = 30
tmp = {}
# 取当前CPU Io
tmp['used'] = psutil.cpu_percent(interval=1)
if tmp['used'] > 80:
panel_title = mw.getConfig('title')
ip = mw.getHostAddr()
now_time = mw.getDateFromNow()
msg = now_time + '|节点[' + panel_title + ':' + ip + \
']处于高负载[' + str(tmp['used']) + '],请排查原因!'
mw.notifyMessage(msg, '面板监控', 600)
if not cpuInfo:
tmp['mem'] = sm.getMemUsed()
cpuInfo = tmp
if cpuInfo['used'] < tmp['used']:
tmp['mem'] = sm.getMemUsed()
cpuInfo = tmp
# 取当前网络Io
networkIo = sm.psutilNetIoCounters()
if not network_up:
network_up = networkIo[0]
network_down = networkIo[1]
tmp = {}
tmp['upTotal'] = networkIo[0]
tmp['downTotal'] = networkIo[1]
tmp['up'] = round(float((networkIo[0] - network_up) / 1024), 2)
tmp['down'] = round(float((networkIo[1] - network_down) / 1024), 2)
tmp['downPackets'] = networkIo[3]
tmp['upPackets'] = networkIo[2]
network_up = networkIo[0]
network_down = networkIo[1]
if not networkInfo:
networkInfo = tmp
if (tmp['up'] + tmp['down']) > (networkInfo['up'] + networkInfo['down']):
networkInfo = tmp
# 取磁盘Io
# if os.path.exists('/proc/diskstats'):
diskio_2 = psutil.disk_io_counters()
if not diskio_1:
diskio_1 = diskio_2
tmp = {}
tmp['read_count'] = diskio_2.read_count - diskio_1.read_count
tmp['write_count'] = diskio_2.write_count - diskio_1.write_count
tmp['read_bytes'] = diskio_2.read_bytes - diskio_1.read_bytes
tmp['write_bytes'] = diskio_2.write_bytes - diskio_1.write_bytes
tmp['read_time'] = diskio_2.read_time - diskio_1.read_time
tmp['write_time'] = diskio_2.write_time - diskio_1.write_time
if not diskInfo:
diskInfo = tmp
else:
diskInfo['read_count'] += tmp['read_count']
diskInfo['write_count'] += tmp['write_count']
diskInfo['read_bytes'] += tmp['read_bytes']
diskInfo['write_bytes'] += tmp['write_bytes']
diskInfo['read_time'] += tmp['read_time']
diskInfo['write_time'] += tmp['write_time']
diskio_1 = diskio_2
# print diskInfo
if count >= 12:
try:
addtime = int(time.time())
deltime = addtime - (day * 86400)
data = (cpuInfo['used'], cpuInfo['mem'], addtime)
sql.table('cpuio').add('pro,mem,addtime', data)
sql.table('cpuio').where("addtime<?", (deltime,)).delete()
data = (networkInfo['up'] / 5, networkInfo['down'] / 5, networkInfo['upTotal'], networkInfo[
'downTotal'], networkInfo['downPackets'], networkInfo['upPackets'], addtime)
sql.table('network').add(
'up,down,total_up,total_down,down_packets,up_packets,addtime', data)
sql.table('network').where(
"addtime<?", (deltime,)).delete()
# if os.path.exists('/proc/diskstats'):
data = (diskInfo['read_count'], diskInfo['write_count'], diskInfo['read_bytes'], diskInfo[
'write_bytes'], diskInfo['read_time'], diskInfo['write_time'], addtime)
sql.table('diskio').add(
'read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime', data)
sql.table('diskio').where(
"addtime<?", (deltime,)).delete()
# LoadAverage
load_average = sm.getLoadAverage()
lpro = round((load_average['one'] / load_average['max']) * 100, 2)
if lpro > 100:
lpro = 100
sql.table('load_average').add('pro,one,five,fifteen,addtime', (lpro, load_average['one'], load_average['five'], load_average['fifteen'], addtime))
lpro = None
load_average = None
cpuInfo = None
networkInfo = None
diskInfo = None
count = 0
reloadNum += 1
if reloadNum > 1440:
reloadNum = 0
mw.writeFile('logs/sys_interrupt.pl',
"reload num:" + str(reloadNum))
restartMw()
except Exception as ex:
print(str(ex))
mw.writeFile('logs/sys_interrupt.pl', str(ex))
del(tmp)
time.sleep(5)
count += 1
except Exception as ex:
print(str(ex))
mw.writeFile('logs/sys_interrupt.pl', str(ex))
restartMw()
time.sleep(30)
systemTask()
def systemTask2():
# 系统监控任务
try:
from utils.system import monitor
while True:
monitor.instance().run()
time.sleep(5)
except Exception as ex:
print(str(ex))
mw.writeFile('logs/sys_interrupt.pl', str(ex))
restartMw()
time.sleep(30)
systemTask2()
systemTask()
# -------------------------------------- PHP监控 start --------------------------------------------- #
@ -596,7 +438,7 @@ def setDaemon(t):
def run():
# # 系统监控
sysTask = threading.Thread(target=systemTask2)
sysTask = threading.Thread(target=systemTask)
sysTask = setDaemon(sysTask)
sysTask.start()

@ -26,6 +26,7 @@ sys.path.append(web_dir)
from admin import app
from admin import model
import thisdb
import core.mw as mw
import core.db as db
@ -241,7 +242,7 @@ def show_panel_pwd():
print("password has been changed!")
def show_panel_adminpath():
admin_path = model.getOption('admin_path')
admin_path = thisdb.getOption('admin_path')
print('/'+admin_path)
@ -289,6 +290,8 @@ def main():
set_panel_username()
elif method == 'password':
show_panel_pwd()
elif method == 'test':
thisdb.getOption('admin_path')
elif method == 'admin_path':
show_panel_adminpath()
elif method == 'getServerIp':
@ -305,5 +308,4 @@ def main():
print('ERROR: Parameter error')
if __name__ == "__main__":
with app.app_context():
main()
main()

@ -93,8 +93,10 @@ with app.app_context():
if setup_db_required:
setup.init_admin_user()
setup.init_option()
setup.init_cmd()
setup.init_db_system()
app.config['BASIC_AUTH_OPEN'] = False
with app.app_context():
basic_auth = model.getOptionByJson('basic_auth', default={'open':False})
@ -155,6 +157,7 @@ def page_unauthorized(error):
# 设置模板全局变量
@app.context_processor
def inject_global_variables():
start_t = time.time()
ver = config.APP_VERSION;
if mw.isDebugMode():
ver = ver + str(time.time())
@ -165,6 +168,9 @@ def inject_global_variables():
'title' : 'MW面板',
'ip' : '127.0.0.1'
}
end_t = time.time()
print("cos:"+str(end_t-start_t))
return dict(config=g_config, data=data)

@ -36,6 +36,10 @@ def index():
@blueprint.route('/<path>',endpoint='admin_safe_path',methods=['GET'])
def admin_safe_path(path):
db_path = model.getOption('admin_path')
if isLogined():
return redirect('/')
if db_path == path:
return render_template('default/login.html')
@ -63,7 +67,7 @@ def webhook():
wh_install_path = mw.getServerDir() + '/webhook'
if not os.path.exists(wh_install_path):
return mw.returnJson(False, '请先安装WebHook插件!')
return mw.returnData(False, '请先安装WebHook插件!')
package = mw.getPanelDir() + "/plugins/webhook"
if not package in sys.path:

@ -19,7 +19,7 @@ from .option import setOption
from .sites import getSitesCount
from .task import addTask
from .task import getTaskCount,getTaskUnexecutedCount,getTaskList,getTaskFirstByRun
from .task import getTaskCount,getTaskUnexecutedCount,getTaskList,getTaskFirstByRun,getTaskRunList
from .task import setTaskStatus,setTaskData
from .user import isLoginCheck

@ -71,5 +71,4 @@ def setOption(name, value,
db.session.query(Option).filter_by(name=name, type=type).update({"value":value})
db.session.commit()
db.session.close()
return True

@ -88,6 +88,26 @@ def getTaskList(
rows.append(t)
return rows
def getTaskRunList(
page: int | None = 1,
size: int | None = 10,
):
pagination = Tasks.query.filter(Tasks.status!=1).order_by(Tasks.id.asc()).paginate(page=int(page), per_page=int(size))
rows = []
for item in pagination.items:
t = {}
t['id'] = item.id
t['name'] = item.name
t['type'] = item.type
t['cmd'] = item.cmd
t['start'] = item.start
t['end'] = item.end
t['status'] = item.status
t['add_time'] = item.add_time
rows.append(t)
return rows

@ -11,4 +11,5 @@
from .user import init_admin_user
from .option import init_option
from .init_db_system import init_db_system
from .init_cmd import init_cmd

@ -0,0 +1,54 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
import os
import shutil
import core.mw as mw
def contentReplace(src, dst):
content = mw.readFile(src)
content = content.replace("{$SERVER_PATH}", mw.getFatherDir())
content += "\n# make:{0}".format(mw.formatDate())
mw.writeFile(dst, content)
def init_cmd():
script = mw.getPanelDir() + '/scripts/init.d/mw.tpl'
script_bin = mw.getPanelDir() + '/scripts/init.d/mw'
contentReplace(script, script_bin)
mw.execShell('chmod +x ' + script_bin)
# 在linux系统中,确保/etc/init.d存在
if not mw.isAppleSystem() and not os.path.exists("/etc/rc.d/init.d"):
mw.execShell('mkdir -p /etc/rc.d/init.d')
if not mw.isAppleSystem() and not os.path.exists("/etc/init.d"):
mw.execShell('mkdir -p /etc/init.d')
# initd
if os.path.exists('/etc/rc.d/init.d'):
initd_bin = '/etc/rc.d/init.d/mw'
if not os.path.exists(initd_bin):
shutil.copyfile(script_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
# 加入自启动
mw.execShell('which chkconfig && chkconfig --add mw')
if os.path.exists('/etc/init.d'):
initd_bin = '/etc/init.d/mw'
if not os.path.exists(initd_bin):
import shutil
shutil.copyfile(script_bin, initd_bin)
mw.execShell('chmod +x ' + initd_bin)
# 加入自启动
mw.execShell('which update-rc.d && update-rc.d -f mw defaults')
return True

@ -34,9 +34,6 @@ def init_option():
# basic auth 配置
model.setOption('basic_auth', json.dumps({'open':False}))
# 开启后台任务
# model.setOption('run_bg_task', 'close')
@ -50,7 +47,10 @@ def init_option():
# 初始化安全路径
model.setOption('admin_path', mw.getRandomString(8))
model.setOption('server_ip', '127.0.0.1')
ip = mw.getLocalIp()
model.setOption('server_ip', ip)
# 默认备份目录
model.setOption('backup_path', mw.getFatherDir()+'/backup')

@ -17,6 +17,7 @@ from admin.model import db,Tasks
from admin.user_login_check import panel_login_required
import core.mw as mw
import utils.task as MwTasks
blueprint = Blueprint('task', __name__, url_prefix='/task', template_folder='../../templates/default')
@ -98,9 +99,16 @@ def get_task_speed():
data['isDownload'] = False
data['task'] = model.getTaskList(status=-1)
data['task'] = model.getTaskRunList()
return data
@blueprint.route('/remove_task', endpoint='remove_task', methods=['POST'])
@panel_login_required
def remove_task():
task_id = request.form.get('id', '')
if task_id == '':
return mw.returnData(False, '任务ID不能为空!')
return MwTasks.removeTask(task_id)

@ -199,10 +199,6 @@ def writeFile(filename, content, mode='w+'):
except Exception as e:
return False
def triggerTask():
isTask = getPanelDir() + '/tmp/panelTask.pl'
writeFile(isTask, 'True')
def systemdCfgDir():
# ubuntu
@ -263,6 +259,39 @@ def getClientIp():
from flask import request
return request.remote_addr.replace('::ffff:', '')
def getLocalIp():
filename = getPanelDir()+'/data/iplist.txt'
try:
ipaddress = readFile(filename)
if not ipaddress or ipaddress == '127.0.0.1':
cmd = "curl --insecure -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 --insecure -6 -sS --connect-timeout 5 -m 60 https://v6r.ipip.net/?format=text"
ip = execShell(cmd)
result = ip[0].strip()
if result == '':
return '127.0.0.1'
writeFile(filename, result)
return result
finally:
pass
return '127.0.0.1'
def inArray(arrays, searchStr):
# 搜索数据中是否存在
for key in arrays:
if key == searchStr:
return True
return False
def getJson(data):
import json
@ -541,13 +570,6 @@ def isNumber(s):
return False
def isRestart():
# 检查是否允许重启
num = M('tasks').where('status!=?', ('1',)).count()
if num > 0:
return False
return True
# 检查端口是否占用
def isOpenPort(port):
import socket
@ -633,13 +655,33 @@ def deDoubleCrypt(key, strings):
writeFileLog(getTracebackInfo())
return strings
# ------------------------------ openresty start -----------------------------
# ------------------------------ panel start -----------------------------
def isRestart():
# 检查是否允许重启
num = M('tasks').where('status!=?', ('1',)).count()
if num > 0:
return False
return True
def triggerTask():
isTask = getPanelDir() + '/tmp/panelTask.pl'
writeFile(isTask, 'True')
def restartTask():
initd = getPanelDir() + '/scripts/init.d/mw'
if os.path.exists(initd):
cmd = initd + ' ' + 'restart_task'
os.system(cmd)
return True
def restartMw():
restart_file = getPanelDir()+'/data/restart.pl'
writeFile(restart_file, 'True')
return True
# ------------------------------ panel end -----------------------------
# ------------------------------ openresty start -----------------------------
def restartWeb():
return opWeb("reload")
@ -667,6 +709,7 @@ def opWeb(method):
return True
return False
def opLuaMake(cmd_name):
path = getServerDir() + '/web_conf/nginx/lua/lua.conf'
root_dir = getServerDir() + '/web_conf/nginx/lua/' + cmd_name

@ -941,7 +941,7 @@ function removeTask(b) {
time: 0,
shade: [0.3, "#000"]
});
$.post("/files/remove_task", "id=" + b, function(c) {
$.post("/task/remove_task", "id=" + b, function(c) {
layer.close(a);
layer.msg(c.msg, {
icon: c.status ? 1 : 5

@ -0,0 +1,11 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
from .option import *

@ -0,0 +1,28 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
import core.mw as mw
def getOption(name,
type: str | None = 'common',
default : str | None = None
) -> str:
'''
获取配置的值
:name -> str 名称 (必填)
:type -> str 类型 (可选|默认common)
:default -> str 默认值 (可选)
'''
data = mw.M('option').field('name').where('name=? and type=?',(name, type,)).getField('value')
if len(data) == 0:
return default
return data

@ -0,0 +1,54 @@
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
import os
import pwd
import time
import core.mw as mw
# 删除进程下的所有进程
def removeTaskRecursion(pid):
cmd = "ps -ef|grep %s | grep -v grep |sed -n '2,1p' | awk '{print $2}'" % pid
sub_pid = mw.execShell(cmd)
if sub_pid[0].strip() == '':
return 'ok'
if sub_pid[0].strip() == pid :
return 'ok'
removeTaskRecursion(sub_pid[0].strip())
mw.execShell('kill -9 ' + sub_pid[0].strip())
return sub_pid[0].strip()
# 删除任务
def removeTask(task_id):
try:
name = mw.M('tasks').where('id=?', (task_id,)).getField('name')
status = mw.M('tasks').where('id=?', (task_id,)).getField('status')
mw.M('tasks').delete(task_id)
if str(status) == '-1':
cmd = "ps aux | grep 'panel_task.py' | grep -v grep |awk '{print $2}'"
task_pid = mw.execShell(cmd)
task_list = task_pid[0].strip().split("\n")
for i in range(len(task_list)):
removeTaskRecursion(task_list[i])
t = mw.execShell('kill -9 ' + task_list[i])
print(t)
mw.triggerTask()
mw.restartTask()
except Exception as e:
mw.restartTask()
# 删除日志
task_log = mw.getPanelDir() + "/tmp/panelTask.pl"
if os.path.exists(task_log):
os.remove(task_log)
return mw.returnData(True, '任务已删除!')
Loading…
Cancel
Save