|
|
|
@ -14,12 +14,14 @@ from flask import request |
|
|
|
|
|
|
|
|
|
class crontab_api: |
|
|
|
|
|
|
|
|
|
field = 'id,name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress' |
|
|
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
##### ----- start ----- ### |
|
|
|
|
def listApi(self): |
|
|
|
|
_list = public.M('crontab').where('', ()).field('id,name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress').limit( |
|
|
|
|
_list = public.M('crontab').where('', ()).field(self.field).limit( |
|
|
|
|
'0,5').order('id desc').select() |
|
|
|
|
|
|
|
|
|
data = [] |
|
|
|
@ -71,12 +73,83 @@ class crontab_api: |
|
|
|
|
_ret['page'] = public.getPage(_page) |
|
|
|
|
return public.getJson(_ret) |
|
|
|
|
|
|
|
|
|
# 获取指定任务数据 |
|
|
|
|
def getCrondFindApi(self): |
|
|
|
|
sid = request.form.get('id', '') |
|
|
|
|
data = public.M('crontab').where( |
|
|
|
|
'id=?', (sid,)).field(self.field).find() |
|
|
|
|
return public.getJson(data) |
|
|
|
|
|
|
|
|
|
def modifyCrondApi(self): |
|
|
|
|
sid = request.form.get('id', '') |
|
|
|
|
iname = request.form.get('name', '') |
|
|
|
|
stype = request.form.get('type', '') |
|
|
|
|
week = request.form.get('week', '') |
|
|
|
|
where1 = request.form.get('where1', '') |
|
|
|
|
hour = request.form.get('hour', '') |
|
|
|
|
minute = request.form.get('minute', '') |
|
|
|
|
save = request.form.get('save', '') |
|
|
|
|
backup_to = request.form.get('backup_to', '') |
|
|
|
|
stype = request.form.get('stype', '') |
|
|
|
|
sname = request.form.get('sname', '') |
|
|
|
|
sbody = request.form.get('sbody', '') |
|
|
|
|
urladdress = request.form.get('urladdress', '') |
|
|
|
|
|
|
|
|
|
if len(iname) < 1: |
|
|
|
|
return public.returnJson(False, '任务名称不能为空!') |
|
|
|
|
|
|
|
|
|
params = { |
|
|
|
|
'name': iname, |
|
|
|
|
'type': stype, |
|
|
|
|
'week': week, |
|
|
|
|
'where1': where1, |
|
|
|
|
'hour': hour, |
|
|
|
|
'minute': minute, |
|
|
|
|
'save': save, |
|
|
|
|
'backup_to': backup_to, |
|
|
|
|
'stype': stype, |
|
|
|
|
'sname': sname, |
|
|
|
|
'sbody': sbody, |
|
|
|
|
'urladdress': urladdress, |
|
|
|
|
} |
|
|
|
|
cuonConfig, get, name = self.getCrondCycle(params) |
|
|
|
|
cronInfo = public.M('crontab').where( |
|
|
|
|
'id=?', (sid,)).field(self.field).find() |
|
|
|
|
del(cronInfo['id']) |
|
|
|
|
del(cronInfo['addtime']) |
|
|
|
|
cronInfo['name'] = get['name'] |
|
|
|
|
cronInfo['type'] = get['type'] |
|
|
|
|
cronInfo['where1'] = get['where1'] |
|
|
|
|
cronInfo['where_hour'] = get['hour'] |
|
|
|
|
cronInfo['where_minute'] = get['minute'] |
|
|
|
|
cronInfo['save'] = get['save'] |
|
|
|
|
cronInfo['backup_to'] = get['backup_to'] |
|
|
|
|
cronInfo['sbody'] = get['sbody'] |
|
|
|
|
cronInfo['urladdress'] = get['urladdress'] |
|
|
|
|
|
|
|
|
|
addData = public.M('crontab').where('id=?', (sid,)).save('name,type,where1,where_hour,where_minute,save,backup_to,sbody,urladdress', (get[ |
|
|
|
|
'name'], get['type'], get['where1'], get['hour'], get['minute'], get['save'], get['backup_to'], get['sbody'], get['urladdress'])) |
|
|
|
|
|
|
|
|
|
self.removeForCrond(cronInfo['echo']) |
|
|
|
|
self.syncToCrond(cronInfo) |
|
|
|
|
public.writeLog('计划任务', '修改计划任务[' + cronInfo['name'] + ']成功') |
|
|
|
|
return public.returnJson(True, '修改成功') |
|
|
|
|
|
|
|
|
|
def logsApi(self): |
|
|
|
|
return public.returnJson(False, '添加失败') |
|
|
|
|
sid = request.form.get('id', '') |
|
|
|
|
echo = public.M('crontab').where("id=?", (sid,)).field('echo').find() |
|
|
|
|
print echo |
|
|
|
|
logFile = public.getServerDir() + '/cron/' + echo['echo'] + '.log' |
|
|
|
|
print logFile |
|
|
|
|
if not os.path.exists(logFile): |
|
|
|
|
return public.returnJson(False, '当前日志为空!') |
|
|
|
|
log = public.getNumLines(logFile, 2000) |
|
|
|
|
return public.returnJson(True, log) |
|
|
|
|
|
|
|
|
|
def addApi(self): |
|
|
|
|
name = request.form.get('name', '') |
|
|
|
|
type = request.form.get('type', '') |
|
|
|
|
iname = request.form.get('name', '') |
|
|
|
|
stype = request.form.get('type', '') |
|
|
|
|
week = request.form.get('week', '') |
|
|
|
|
where1 = request.form.get('where1', '') |
|
|
|
|
hour = request.form.get('hour', '') |
|
|
|
|
minute = request.form.get('minute', '') |
|
|
|
@ -87,12 +160,45 @@ class crontab_api: |
|
|
|
|
sBody = request.form.get('sBody', '') |
|
|
|
|
urladdress = request.form.get('urladdress', '') |
|
|
|
|
|
|
|
|
|
if len(name) < 1: |
|
|
|
|
if len(iname) < 1: |
|
|
|
|
return public.returnJson(False, '任务名称不能为空!') |
|
|
|
|
|
|
|
|
|
addData = public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backup_to,stype,sname,sbody,urladdress', |
|
|
|
|
(name, type, where1, hour, minute, name, |
|
|
|
|
time.strftime('%Y-%m-%d %X', time.localtime()), 1, save, backupTo, sType, sName, sBody, urladdress)) |
|
|
|
|
params = { |
|
|
|
|
'name': iname, |
|
|
|
|
'type': stype, |
|
|
|
|
'week': week, |
|
|
|
|
'where1': where1, |
|
|
|
|
'hour': hour, |
|
|
|
|
'minute': minute, |
|
|
|
|
'save': save, |
|
|
|
|
'backupTo': backupTo, |
|
|
|
|
'sType': sType, |
|
|
|
|
'sName': sName, |
|
|
|
|
'sBody': sBody, |
|
|
|
|
'urladdress': urladdress, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# print params |
|
|
|
|
cuonConfig, _params, name = self.getCrondCycle(params) |
|
|
|
|
cronPath = public.getServerDir() + '/cron' |
|
|
|
|
|
|
|
|
|
cronName = self.getShell(params) |
|
|
|
|
# print cuonConfig, _params, name |
|
|
|
|
# print cronPath, cronName |
|
|
|
|
|
|
|
|
|
if type(cronName) == dict: |
|
|
|
|
return cronName |
|
|
|
|
|
|
|
|
|
cuonConfig += ' ' + cronPath + '/' + cronName + \ |
|
|
|
|
' >> ' + cronPath + '/' + cronName + '.log 2>&1' |
|
|
|
|
wRes = self.writeShell(cuonConfig) |
|
|
|
|
|
|
|
|
|
if type(wRes) != bool: |
|
|
|
|
return wRes |
|
|
|
|
|
|
|
|
|
self.crondReload() |
|
|
|
|
addData = public.M('crontab').add(self.field, (iname, stype, where1, hour, minute, cronName, time.strftime( |
|
|
|
|
'%Y-%m-%d %X', time.localtime()), 1, save, backupTo, sType, sName, sBody, urladdress)) |
|
|
|
|
if addData > 0: |
|
|
|
|
return public.returnJson(True, '添加成功') |
|
|
|
|
return public.returnJson(False, '添加失败') |
|
|
|
@ -104,6 +210,9 @@ class crontab_api: |
|
|
|
|
return public.returnJson(True, '添加成功') |
|
|
|
|
except Exception as e: |
|
|
|
|
return public.returnJson(False, '删除失败') |
|
|
|
|
|
|
|
|
|
def delLogsApi(self): |
|
|
|
|
return public.returnJson(True, '删除成功') |
|
|
|
|
##### ----- start ----- ### |
|
|
|
|
|
|
|
|
|
# 转换大写星期 |
|
|
|
@ -121,3 +230,207 @@ class crontab_api: |
|
|
|
|
return wheres[num] |
|
|
|
|
except: |
|
|
|
|
return '' |
|
|
|
|
|
|
|
|
|
def getCrondCycle(self, params): |
|
|
|
|
cuonConfig = '' |
|
|
|
|
name = '' |
|
|
|
|
if params['type'] == "day": |
|
|
|
|
cuonConfig = self.getDay(params) |
|
|
|
|
name = '每天' |
|
|
|
|
elif params['type'] == "day-n": |
|
|
|
|
cuonConfig = self.getDay_N(params) |
|
|
|
|
name = public.getInfo('每{1}天', (params['where1'],)) |
|
|
|
|
elif params['type'] == "hour": |
|
|
|
|
cuonConfig = self.getHour(params) |
|
|
|
|
name = '每小时' |
|
|
|
|
elif params['type'] == "hour-n": |
|
|
|
|
cuonConfig = self.getHour_N(params) |
|
|
|
|
name = '每小时' |
|
|
|
|
elif params['type'] == "minute-n": |
|
|
|
|
cuonConfig = self.minute_N(params) |
|
|
|
|
elif params['type'] == "week": |
|
|
|
|
params['where1'] = params['week'] |
|
|
|
|
cuonConfig = self.week(params) |
|
|
|
|
elif params['type'] == "month": |
|
|
|
|
cuonConfig = self.month(params) |
|
|
|
|
return cuonConfig, params, name |
|
|
|
|
|
|
|
|
|
# 取任务构造Day |
|
|
|
|
def getDay(self, param): |
|
|
|
|
cuonConfig = "{0} {1} * * * ".format(param['minute'], param['hour']) |
|
|
|
|
return cuonConfig |
|
|
|
|
# 取任务构造Day_n |
|
|
|
|
|
|
|
|
|
def getDay_N(self, param): |
|
|
|
|
cuonConfig = "{0} {1} */{2} * * ".format( |
|
|
|
|
param['minute'], param['hour'], param['where1']) |
|
|
|
|
return cuonConfig |
|
|
|
|
|
|
|
|
|
# 取任务构造Hour |
|
|
|
|
def getHour(self, param): |
|
|
|
|
cuonConfig = "{0} * * * * ".format(param['minute']) |
|
|
|
|
return cuonConfig |
|
|
|
|
|
|
|
|
|
# 取任务构造Hour-N |
|
|
|
|
def getHour_N(self, param): |
|
|
|
|
cuonConfig = "{0} */{1} * * * ".format( |
|
|
|
|
param['minute'], param['where1']) |
|
|
|
|
return cuonConfig |
|
|
|
|
|
|
|
|
|
# 取任务构造Minute-N |
|
|
|
|
def minute_N(self, param): |
|
|
|
|
cuonConfig = "*/{0} * * * * ".format(param['where1']) |
|
|
|
|
return cuonConfig |
|
|
|
|
|
|
|
|
|
# 取任务构造week |
|
|
|
|
def week(self, param): |
|
|
|
|
cuonConfig = "{0} {1} * * {2}".format( |
|
|
|
|
param['minute'], param['hour'], param['week']) |
|
|
|
|
return cuonConfig |
|
|
|
|
|
|
|
|
|
# 取任务构造Month |
|
|
|
|
def month(self, param): |
|
|
|
|
cuonConfig = "{0} {1} {2} * * ".format( |
|
|
|
|
param['minute'], param['hour'], param['where1']) |
|
|
|
|
return cuonConfig |
|
|
|
|
|
|
|
|
|
# 取执行脚本 |
|
|
|
|
def getShell(self, param): |
|
|
|
|
# try: |
|
|
|
|
stype = param['stype'] |
|
|
|
|
if stype == 'toFile': |
|
|
|
|
shell = param.sFile |
|
|
|
|
else: |
|
|
|
|
head = "#!/bin/bash\nPATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin\nexport PATH\n" |
|
|
|
|
log = '.log' |
|
|
|
|
|
|
|
|
|
wheres = { |
|
|
|
|
'path': head + "python " + public.getServerDir() + "/panel/script/backup.py path " + param['sname'] + " " + str(param['save']), |
|
|
|
|
'site': head + "python " + public.getServerDir() + "/panel/script/backup.py site " + param['sname'] + " " + str(param['save']), |
|
|
|
|
'database': head + "python " + public.getServerDir() + "/panel/script/backup.py database " + param['sname'] + " " + str(param['save']), |
|
|
|
|
'logs': head + "python " + public.getServerDir() + "/panel/script/logsBackup " + param['sname'] + log + " " + str(param['save']), |
|
|
|
|
'rememory': head + "/bin/bash " + public.getServerDir() + '/panel/script/rememory.sh' |
|
|
|
|
} |
|
|
|
|
if param['backup_to'] != 'localhost': |
|
|
|
|
cfile = public.getServerDir() + "/panel/plugin/" + param[ |
|
|
|
|
'backup_to'] + "/" + param['backup_to'] + "_main.py" |
|
|
|
|
if not os.path.exists(cfile): |
|
|
|
|
cfile = public.getServerDir() + "/panel/script/backup_" + \ |
|
|
|
|
param['backup_to'] + ".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 " + public.getServerDir() + "/panel/script/logsBackup " + param['sname'] + log + " " + str(param['save']), |
|
|
|
|
'rememory': head + "/bin/bash " + public.getServerDir() + '/panel/script/rememory.sh' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
shell = wheres[stype] |
|
|
|
|
except: |
|
|
|
|
if stype == 'toUrl': |
|
|
|
|
shell = head + "curl -sS --connect-timeout 10 -m 60 '" + \ |
|
|
|
|
param['urladdress'] + "'" |
|
|
|
|
else: |
|
|
|
|
shell = head + param['sBody'].replace("\r\n", "\n") |
|
|
|
|
|
|
|
|
|
shell += ''' |
|
|
|
|
echo "----------------------------------------------------------------------------" |
|
|
|
|
endDate=`date +"%Y-%m-%d %H:%M:%S"` |
|
|
|
|
echo "★[$endDate] Successful" |
|
|
|
|
echo "----------------------------------------------------------------------------" |
|
|
|
|
''' |
|
|
|
|
cronPath = public.getServerDir() + '/cron' |
|
|
|
|
if not os.path.exists(cronPath): |
|
|
|
|
public.execShell('mkdir -p ' + cronPath) |
|
|
|
|
if not 'echo' in param: |
|
|
|
|
cronName = public.md5(public.md5(str(time.time()) + '_mw')) |
|
|
|
|
else: |
|
|
|
|
cronName = param['echo'] |
|
|
|
|
file = cronPath + '/' + cronName |
|
|
|
|
public.writeFile(file, self.checkScript(shell)) |
|
|
|
|
public.execShell('chmod 750 ' + file) |
|
|
|
|
return cronName |
|
|
|
|
|
|
|
|
|
# 检查脚本 |
|
|
|
|
def checkScript(self, shell): |
|
|
|
|
keys = ['shutdown', 'init 0', 'mkfs', 'passwd', |
|
|
|
|
'chpasswd', '--stdin', 'mkfs.ext', 'mke2fs'] |
|
|
|
|
for key in keys: |
|
|
|
|
shell = shell.replace(key, '[***]') |
|
|
|
|
return shell |
|
|
|
|
|
|
|
|
|
# 将Shell脚本写到文件 |
|
|
|
|
def writeShell(self, config): |
|
|
|
|
u_file = '/var/spool/cron/crontabs/root' |
|
|
|
|
if not os.path.exists(u_file): |
|
|
|
|
file = '/var/spool/cron/root' |
|
|
|
|
if public.isAppleSystem(): |
|
|
|
|
file = '/etc/crontab' |
|
|
|
|
else: |
|
|
|
|
file = u_file |
|
|
|
|
|
|
|
|
|
if not os.path.exists(file): |
|
|
|
|
public.writeFile(file, '') |
|
|
|
|
conf = public.readFile(file) |
|
|
|
|
conf += config + "\n" |
|
|
|
|
if public.writeFile(file, conf): |
|
|
|
|
if not os.path.exists(u_file): |
|
|
|
|
public.execShell("chmod 600 '" + file + |
|
|
|
|
"' && chown root.root " + file) |
|
|
|
|
else: |
|
|
|
|
public.execShell("chmod 600 '" + file + |
|
|
|
|
"' && chown root.crontab " + file) |
|
|
|
|
return True |
|
|
|
|
return public.returnJson(False, '文件写入失败,请检查是否开启系统加固功能!') |
|
|
|
|
|
|
|
|
|
# 重载配置 |
|
|
|
|
def crondReload(self): |
|
|
|
|
if public.isAppleSystem(): |
|
|
|
|
if os.path.exists('/etc/crontab'): |
|
|
|
|
pass |
|
|
|
|
# public.execShell('/usr/sbin/cron restart') |
|
|
|
|
else: |
|
|
|
|
if os.path.exists('/etc/init.d/crond'): |
|
|
|
|
public.execShell('/etc/init.d/crond reload') |
|
|
|
|
elif os.path.exists('/etc/init.d/cron'): |
|
|
|
|
public.execShell('service cron restart') |
|
|
|
|
else: |
|
|
|
|
public.execShell("systemctl reload crond") |
|
|
|
|
|
|
|
|
|
# 从crond删除 |
|
|
|
|
def removeForCrond(self, echo): |
|
|
|
|
u_file = '/var/spool/cron/crontabs/root' |
|
|
|
|
if not os.path.exists(u_file): |
|
|
|
|
file = '/var/spool/cron/root' |
|
|
|
|
if public.isAppleSystem(): |
|
|
|
|
file = '/etc/crontab' |
|
|
|
|
else: |
|
|
|
|
file = u_file |
|
|
|
|
conf = public.readFile(file) |
|
|
|
|
rep = ".+" + str(echo) + ".+\n" |
|
|
|
|
conf = re.sub(rep, "", conf) |
|
|
|
|
if not public.writeFile(file, conf): |
|
|
|
|
return False |
|
|
|
|
self.crondReload() |
|
|
|
|
return True |
|
|
|
|
|
|
|
|
|
def syncToCrond(self, cronInfo): |
|
|
|
|
if 'status' in cronInfo: |
|
|
|
|
if cronInfo['status'] == 0: |
|
|
|
|
return False |
|
|
|
|
if 'where_hour' in cronInfo: |
|
|
|
|
cronInfo['hour'] = cronInfo['where_hour'] |
|
|
|
|
cronInfo['minute'] = cronInfo['where_minute'] |
|
|
|
|
cronInfo['week'] = cronInfo['where1'] |
|
|
|
|
cuonConfig, cronInfo, name = self.getCrondCycle(cronInfo) |
|
|
|
|
cronPath = public.getServerDir() + '/cron' |
|
|
|
|
cronName = self.getShell(cronInfo) |
|
|
|
|
if type(cronName) == dict: |
|
|
|
|
return cronName |
|
|
|
|
cuonConfig += ' ' + cronPath + '/' + cronName + \ |
|
|
|
|
' >> ' + cronPath + '/' + cronName + '.log 2>&1' |
|
|
|
|
wRes = self.writeShell(cuonConfig) |
|
|
|
|
if type(wRes) != bool: |
|
|
|
|
return False |
|
|
|
|
self.crondReload() |
|
|
|
|