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 @mw_async
def restartMw(): def restartMw():
time.sleep(1) time.sleep(1)
cmd = mw.getRunDir() + '/scripts/init.d/mw reload &' cmd = mw.getPanelDir() + '/scripts/init.d/mw reload &'
mw.execShell(cmd) mw.execShell(cmd)
@ -225,173 +225,15 @@ def siteEdate():
def systemTask(): def systemTask():
from utils.system import monitor
# 系统监控任务 # 系统监控任务
try: 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: while True:
monitor.instance().run() monitor.instance().run()
time.sleep(5) time.sleep(5)
except Exception as ex: except Exception as ex:
print(str(ex))
mw.writeFile('logs/sys_interrupt.pl', str(ex))
restartMw()
time.sleep(30) time.sleep(30)
systemTask2() systemTask()
# -------------------------------------- PHP监控 start --------------------------------------------- # # -------------------------------------- PHP监控 start --------------------------------------------- #
@ -596,7 +438,7 @@ def setDaemon(t):
def run(): def run():
# # 系统监控 # # 系统监控
sysTask = threading.Thread(target=systemTask2) sysTask = threading.Thread(target=systemTask)
sysTask = setDaemon(sysTask) sysTask = setDaemon(sysTask)
sysTask.start() sysTask.start()

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

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

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

@ -19,7 +19,7 @@ from .option import setOption
from .sites import getSitesCount from .sites import getSitesCount
from .task import addTask 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 .task import setTaskStatus,setTaskData
from .user import isLoginCheck 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.query(Option).filter_by(name=name, type=type).update({"value":value})
db.session.commit() db.session.commit()
db.session.close()
return True return True

@ -88,6 +88,26 @@ def getTaskList(
rows.append(t) rows.append(t)
return rows 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 .user import init_admin_user
from .option import init_option from .option import init_option
from .init_db_system import init_db_system 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 配置 # basic auth 配置
model.setOption('basic_auth', json.dumps({'open':False})) model.setOption('basic_auth', json.dumps({'open':False}))
# 开启后台任务 # 开启后台任务
# model.setOption('run_bg_task', 'close') # model.setOption('run_bg_task', 'close')
@ -50,7 +47,10 @@ def init_option():
# 初始化安全路径 # 初始化安全路径
model.setOption('admin_path', mw.getRandomString(8)) 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') 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 from admin.user_login_check import panel_login_required
import core.mw as mw import core.mw as mw
import utils.task as MwTasks
blueprint = Blueprint('task', __name__, url_prefix='/task', template_folder='../../templates/default') blueprint = Blueprint('task', __name__, url_prefix='/task', template_folder='../../templates/default')
@ -98,9 +99,16 @@ def get_task_speed():
data['isDownload'] = False data['isDownload'] = False
data['task'] = model.getTaskList(status=-1) data['task'] = model.getTaskRunList()
return data 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: except Exception as e:
return False return False
def triggerTask():
isTask = getPanelDir() + '/tmp/panelTask.pl'
writeFile(isTask, 'True')
def systemdCfgDir(): def systemdCfgDir():
# ubuntu # ubuntu
@ -263,6 +259,39 @@ def getClientIp():
from flask import request from flask import request
return request.remote_addr.replace('::ffff:', '') 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): def getJson(data):
import json import json
@ -541,13 +570,6 @@ def isNumber(s):
return False return False
def isRestart():
# 检查是否允许重启
num = M('tasks').where('status!=?', ('1',)).count()
if num > 0:
return False
return True
# 检查端口是否占用 # 检查端口是否占用
def isOpenPort(port): def isOpenPort(port):
import socket import socket
@ -633,13 +655,33 @@ def deDoubleCrypt(key, strings):
writeFileLog(getTracebackInfo()) writeFileLog(getTracebackInfo())
return strings 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(): def restartMw():
restart_file = getPanelDir()+'/data/restart.pl' restart_file = getPanelDir()+'/data/restart.pl'
writeFile(restart_file, 'True') writeFile(restart_file, 'True')
return True return True
# ------------------------------ panel end -----------------------------
# ------------------------------ openresty start -----------------------------
def restartWeb(): def restartWeb():
return opWeb("reload") return opWeb("reload")
@ -667,6 +709,7 @@ def opWeb(method):
return True return True
return False return False
def opLuaMake(cmd_name): def opLuaMake(cmd_name):
path = getServerDir() + '/web_conf/nginx/lua/lua.conf' path = getServerDir() + '/web_conf/nginx/lua/lua.conf'
root_dir = getServerDir() + '/web_conf/nginx/lua/' + cmd_name root_dir = getServerDir() + '/web_conf/nginx/lua/' + cmd_name

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