mdserver-web/panel_task.py

362 lines
11 KiB
Python
Raw Normal View History

2024-10-27 07:29:09 -04:00
# coding: utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
# ---------------------------------------------------------------------------------
# 计划任务
# ---------------------------------------------------------------------------------
import sys
import os
import json
import time
import threading
import psutil
web_dir = os.getcwd() + "/web"
os.chdir(web_dir)
sys.path.append(web_dir)
import core.mw as mw
2024-11-04 11:58:40 -05:00
import thisdb
2024-10-27 07:29:09 -04:00
2024-11-28 06:48:36 -05:00
from admin import setup
setup.init()
2024-12-09 14:14:06 -05:00
g_log_file = mw.getPanelTaskExecLog()
2024-10-27 15:13:10 -04:00
if not os.path.exists(g_log_file):
os.system("touch " + g_log_file)
2024-10-27 07:29:09 -04:00
def execShell(cmdstring, cwd=None, timeout=None, shell=True):
2024-11-03 10:44:05 -05:00
cmd = cmdstring + ' > ' + g_log_file + ' 2>&1'
return mw.execShell(cmd)
2024-10-27 07:29:09 -04:00
2024-11-04 11:59:38 -05:00
def writeLogs(data):
# 写输出日志
try:
fp = open(g_log_file, 'w+')
fp.write(data)
fp.close()
except:
pass
2024-10-27 07:29:09 -04:00
def downloadFile(url, filename):
# 下载文件
try:
import urllib
import socket
socket.setdefaulttimeout(300)
2024-10-27 15:13:10 -04:00
headers = ('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36')
2024-10-27 07:29:09 -04:00
opener = urllib.request.build_opener()
opener.addheaders = [headers]
urllib.request.install_opener(opener)
2024-10-27 15:13:10 -04:00
urllib.request.urlretrieve(url, filename=filename, reporthook=downloadHook)
2024-10-27 07:29:09 -04:00
if not mw.isAppleSystem():
os.system('chown www.www ' + filename)
2024-11-25 11:37:55 -05:00
writeLogs(filename + ' download success!')
2024-10-27 07:29:09 -04:00
except Exception as e:
writeLogs(str(e))
2024-10-27 15:13:10 -04:00
return True
2024-10-27 07:29:09 -04:00
def downloadHook(count, blockSize, totalSize):
# 下载文件进度回调
used = count * blockSize
2024-11-25 11:37:55 -05:00
pre = int((100.0 * used / totalSize))
speed = {'total': totalSize, 'used': used, 'pre': pre}
2024-10-27 07:29:09 -04:00
writeLogs(json.dumps(speed))
2024-10-29 06:47:46 -04:00
def runPanelTask():
2024-11-25 09:16:19 -05:00
# 站点过期检查
siteEdateCheck()
2024-11-25 11:37:55 -05:00
lock_file = mw.getTriggerTaskLockFile()
2024-10-29 06:47:46 -04:00
try:
2024-11-25 11:37:55 -05:00
if os.path.exists(lock_file):
bash_list = thisdb.getTaskList(status=-1)
for task in bash_list:
thisdb.setTaskStatus(task['id'], 0)
run_list = thisdb.getTaskList(status=0)
for run_task in run_list:
start = int(time.time())
thisdb.setTaskData(run_task['id'], start=start)
thisdb.setTaskStatus(run_task['id'], -1)
if run_task['type'] == 'download':
argv = run_task['cmd'].split('|mw|')
downloadFile(argv[0], argv[1])
elif run_task['type'] == 'execshell':
execShell(run_task['cmd'])
end = int(time.time())
thisdb.setTaskData(run_task['id'], end=end)
thisdb.setTaskStatus(run_task['id'], 1)
2024-11-28 16:19:53 -05:00
if thisdb.getTaskUnexecutedCount() < 1:
os.remove(lock_file)
2024-10-29 06:47:46 -04:00
except Exception as e:
print('runPanelTask:',mw.getTracebackInfo())
2024-10-27 07:29:09 -04:00
2024-10-29 06:47:46 -04:00
# 网站到期处理
2024-11-25 09:13:45 -05:00
def siteEdateCheck():
2024-10-27 07:29:09 -04:00
try:
2024-11-25 09:13:45 -05:00
from utils.site import sites as MwSites
website_edate = thisdb.getOption('website_edate', default='0000-00-00')
now_time_ymd = time.strftime('%Y-%m-%d', time.localtime())
if website_edate == now_time_ymd:
2024-10-27 07:29:09 -04:00
return False
2024-11-25 09:13:45 -05:00
site_list = thisdb.getSitesEdateList(now_time_ymd)
for site in site_list:
MwSites.instance().stop(site['id'])
thisdb.setOption('website_edate', now_time_ymd)
2024-10-27 07:29:09 -04:00
except Exception as e:
print('siteEdateCheck:',mw.getTracebackInfo())
2024-10-27 07:29:09 -04:00
2024-11-25 09:16:19 -05:00
# 任务队列
def startPanelTask():
try:
while True:
runPanelTask()
time.sleep(5)
except Exception as e:
print('startPanelTask:',mw.getTracebackInfo())
2024-11-25 09:16:19 -05:00
time.sleep(30)
startPanelTask()
2024-10-27 07:29:09 -04:00
def systemTask():
# 系统监控任务
2024-11-03 10:44:05 -05:00
from utils.system import monitor
2024-10-27 07:29:09 -04:00
try:
2024-11-02 12:59:26 -04:00
while True:
2024-12-13 07:50:03 -05:00
monitor_status = thisdb.getOption('monitor_status',type='monitor',default='open')
2024-12-13 07:34:36 -05:00
if monitor_status == 'open':
monitor.instance().run()
2024-11-02 12:59:26 -04:00
time.sleep(5)
except Exception as ex:
print('systemTask:',mw.getTracebackInfo())
2024-11-02 12:59:26 -04:00
time.sleep(30)
2024-11-03 05:14:25 -05:00
systemTask()
2024-11-02 12:59:26 -04:00
def panelPluginStatusCheck():
# 系统监控任务
from utils.plugin import plugin
try:
while True:
2024-12-09 02:52:21 -05:00
# start_t = time.time()
plugin.instance().autoCachePluginStatus()
2024-12-09 02:52:21 -05:00
# end_t = time.time()
time.sleep(60)
except Exception as ex:
print('panelPluginStatusCheck:',mw.getTracebackInfo())
time.sleep(120)
panelPluginStatusCheck()
2024-10-27 07:29:09 -04:00
# -------------------------------------- PHP监控 start --------------------------------------------- #
# 502错误检查线程
def check502Task():
try:
2024-11-03 10:44:05 -05:00
check_file = mw.getPanelDir() + '/data/502Task.pl'
2024-10-27 07:29:09 -04:00
while True:
2024-11-03 10:44:05 -05:00
if os.path.exists(check_file):
2024-10-27 07:29:09 -04:00
check502()
2024-11-03 10:44:05 -05:00
time.sleep(10)
2024-10-27 07:29:09 -04:00
except:
time.sleep(30)
check502Task()
def check502():
try:
verlist = [
'52', '53', '54', '55', '56', '70',
'71', '72', '73', '74', '80', '81',
2026-05-01 06:53:42 -04:00
'82', '83', '84', '85'
2024-10-27 07:29:09 -04:00
]
for ver in verlist:
2024-11-03 10:44:05 -05:00
server_dir = mw.getServerDir()
php_path = server_dir + '/php/' + ver + '/sbin/php-fpm'
2024-10-27 07:29:09 -04:00
if not os.path.exists(php_path):
continue
if checkPHPVersion(ver):
continue
if startPHPVersion(ver):
print('检测到PHP-' + ver + '处理异常,已自动修复!')
mw.writeLog('PHP守护程序', '检测到PHP-' + ver + '处理异常,已自动修复!')
2024-11-03 10:44:05 -05:00
2024-10-27 07:29:09 -04:00
except Exception as e:
2024-11-03 10:44:05 -05:00
mw.writeLog('PHP守护程序', '自动修复异常:'+str(e))
2024-10-27 07:29:09 -04:00
# 处理指定PHP版本
def startPHPVersion(version):
2024-11-03 10:44:05 -05:00
server_dir = mw.getServerDir()
2024-10-27 07:29:09 -04:00
try:
# system
phpService = mw.systemdCfgDir() + '/php' + version + '.service'
if os.path.exists(phpService):
mw.execShell("systemctl restart php" + version)
if checkPHPVersion(version):
return True
# initd
2024-11-03 10:44:05 -05:00
fpm = server_dir + '/php/init.d/php' + version
php_path = server_dir + '/php/' + version + '/sbin/php-fpm'
2024-10-27 07:29:09 -04:00
if not os.path.exists(php_path):
if os.path.exists(fpm):
os.remove(fpm)
return False
if not os.path.exists(fpm):
return False
# 尝试重载服务
os.system(fpm + ' reload')
if checkPHPVersion(version):
return True
# 尝试重启服务
cgi = '/tmp/php-cgi-' + version + '.sock'
2024-11-09 13:26:15 -05:00
pid = server_dir + '/php/' + version + '/var/run/php-fpm.pid'
2024-10-27 07:29:09 -04:00
data = mw.execShell("ps -ef | grep php/" + version +" | grep -v grep|grep -v python |awk '{print $2}'")
if data[0] != '':
os.system("ps -ef | grep php/" + version + " | grep -v grep|grep -v python |awk '{print $2}' | xargs kill ")
time.sleep(0.5)
if not os.path.exists(cgi):
os.system('rm -f ' + cgi)
if not os.path.exists(pid):
os.system('rm -f ' + pid)
os.system(fpm + ' start')
if checkPHPVersion(version):
return True
# 检查是否正确启动
if os.path.exists(cgi):
return True
except Exception as e:
print('startPHPVersion:',mw.getTracebackInfo())
2024-11-03 10:44:05 -05:00
mw.writeLog('PHP守护程序', '自动修复异常:'+str(e))
2024-10-27 07:29:09 -04:00
return True
def checkPHPVersion(version):
# 检查指定PHP版本
try:
2024-11-03 10:44:05 -05:00
sock = mw.getFpmAddress(version)
2024-10-27 07:29:09 -04:00
data = mw.requestFcgiPHP(sock, '/phpfpm_status_' + version + '?json')
result = str(data, encoding='utf-8')
except Exception as e:
result = 'Bad Gateway'
# 检查openresty
if result.find('Bad Gateway') != -1:
return False
if result.find('HTTP Error 404: Not Found') != -1:
return False
# 检查Web服务是否启动
if result.find('Connection refused') != -1:
return False
return True
2024-11-03 10:44:05 -05:00
# -------------------------------------- PHP监控 end --------------------------------------------- #
2024-10-27 07:29:09 -04:00
# --------------------------------------OpenResty Auto Restart Start --------------------------------------------- #
# 解决acme.sh续签后,未起效。
def openrestyAutoRestart():
try:
while True:
# 检查是否安装
odir = mw.getServerDir() + '/openresty'
if not os.path.exists(odir):
time.sleep(86400)
continue
2024-11-03 10:44:05 -05:00
mw.opWeb('reload')
2024-10-27 07:29:09 -04:00
time.sleep(86400)
except Exception as e:
2024-11-03 10:44:05 -05:00
mw.writeLog('OpenResty检测', '自动修复异常:'+str(e))
2024-10-27 07:29:09 -04:00
time.sleep(86400)
# --------------------------------------OpenResty Auto Restart End --------------------------------------------- #
# ------------------------------------ OpenResty Restart At Once Start ------------------------------------------ #
def openrestyRestartAtOnce():
2024-11-03 10:44:05 -05:00
restart_nginx_tip = mw.getPanelDir()+'/data/restart_nginx.pl'
2024-10-27 07:29:09 -04:00
while True:
if os.path.exists(restart_nginx_tip):
os.remove(restart_nginx_tip)
2024-11-03 10:44:05 -05:00
mw.opWeb('reload')
2024-10-27 07:29:09 -04:00
time.sleep(1)
# ----------------------------------- OpenResty Restart At Once End ------------------------------------------ #
# --------------------------------------Panel Restart Start --------------------------------------------- #
def restartPanelService():
2024-11-26 02:47:22 -05:00
restart_tip = mw.getPanelDir()+'/data/restart.pl'
2024-10-27 07:29:09 -04:00
while True:
2024-11-26 02:47:22 -05:00
if os.path.exists(restart_tip):
print("restart panel")
os.remove(restart_tip)
2024-11-03 10:44:05 -05:00
mw.panelCmd('restart_panel')
2024-10-27 07:29:09 -04:00
time.sleep(1)
# --------------------------------------Panel Restart End --------------------------------------------- #
def setDaemon(t):
if sys.version_info.major == 3 and sys.version_info.minor >= 10:
t.daemon = True
else:
t.setDaemon(True)
return t
2024-10-27 15:13:10 -04:00
def run():
2024-11-04 12:03:37 -05:00
# 系统监控
sysTask = threading.Thread(target=systemTask)
sysTask = setDaemon(sysTask)
sysTask.start()
2024-10-27 07:29:09 -04:00
2024-11-04 12:03:37 -05:00
# PHP 502错误检查线程
php502 = threading.Thread(target=check502Task)
php502 = setDaemon(php502)
php502.start()
2024-10-27 07:29:09 -04:00
2024-11-04 12:03:37 -05:00
# OpenResty Restart At Once Start
oraos = threading.Thread(target=openrestyRestartAtOnce)
oraos = setDaemon(oraos)
oraos.start()
2024-10-27 07:29:09 -04:00
2024-11-04 12:03:37 -05:00
# OpenResty Auto Restart Start
oar = threading.Thread(target=openrestyAutoRestart)
oar = setDaemon(oar)
oar.start()
2024-10-27 07:29:09 -04:00
# Panel Plugin Status Check
pps = threading.Thread(target=panelPluginStatusCheck)
pps = setDaemon(pps)
pps.start()
2024-11-04 12:03:37 -05:00
# Panel Restart Start
rps = threading.Thread(target=restartPanelService)
rps = setDaemon(rps)
rps.start()
2024-10-27 07:29:09 -04:00
2024-10-27 15:13:10 -04:00
# 面板后台任务
startPanelTask()
2024-10-27 07:29:09 -04:00
2024-10-27 15:13:10 -04:00
if __name__ == "__main__":
2024-11-04 06:08:39 -05:00
run()
2024-10-27 15:13:10 -04:00