mirror of https://github.com/openspug/spug
A 任务计划支持Python执行
parent
9ac14e2f9e
commit
cc664887a6
|
@ -38,7 +38,10 @@ def host_executor(host, command):
|
|||
|
||||
|
||||
def schedule_worker_handler(job):
|
||||
history_id, host_id, command = json.loads(job)
|
||||
history_id, host_id, interpreter, command = json.loads(job)
|
||||
if interpreter == 'python':
|
||||
attach = 'INTERPRETER=python\ncommand -v python3 &> /dev/null && INTERPRETER=python3'
|
||||
command = f'{attach}\n$INTERPRETER << EOF\n# -*- coding: UTF-8 -*-\n{command}\nEOF'
|
||||
if host_id == 'local':
|
||||
code, duration, out = local_executor(command)
|
||||
else:
|
||||
|
|
|
@ -37,6 +37,7 @@ class Task(models.Model, ModelMixin):
|
|||
)
|
||||
name = models.CharField(max_length=50)
|
||||
type = models.CharField(max_length=50)
|
||||
interpreter = models.CharField(max_length=20, default='sh')
|
||||
command = models.TextField()
|
||||
targets = models.TextField()
|
||||
trigger = models.CharField(max_length=20, choices=TRIGGERS)
|
||||
|
|
|
@ -62,7 +62,7 @@ class Scheduler:
|
|||
self.scheduler.add_job(auto_run_by_day, 'cron', hour=1, minute=20)
|
||||
self.scheduler.add_job(auto_run_by_minute, 'interval', minutes=1)
|
||||
|
||||
def _dispatch(self, task_id, command, targets):
|
||||
def _dispatch(self, task_id, interpreter, command, targets):
|
||||
output = {x: None for x in targets}
|
||||
history = History.objects.create(
|
||||
task_id=task_id,
|
||||
|
@ -73,7 +73,7 @@ class Scheduler:
|
|||
Task.objects.filter(pk=task_id).update(latest_id=history.id)
|
||||
rds_cli = get_redis_connection()
|
||||
for t in targets:
|
||||
rds_cli.rpush(SCHEDULE_WORKER_KEY, json.dumps([history.id, t, command]))
|
||||
rds_cli.rpush(SCHEDULE_WORKER_KEY, json.dumps([history.id, t, interpreter, command]))
|
||||
connections.close_all()
|
||||
|
||||
def _init(self):
|
||||
|
@ -86,7 +86,7 @@ class Scheduler:
|
|||
self._dispatch,
|
||||
trigger,
|
||||
id=str(task.id),
|
||||
args=(task.id, task.command, json.loads(task.targets)),
|
||||
args=(task.id, task.interpreter, task.command, json.loads(task.targets)),
|
||||
)
|
||||
connections.close_all()
|
||||
except DatabaseError:
|
||||
|
@ -106,7 +106,7 @@ class Scheduler:
|
|||
self._dispatch,
|
||||
trigger,
|
||||
id=str(task.id),
|
||||
args=(task.id, task.command, task.targets),
|
||||
args=(task.id, task.interpreter, task.command, task.targets),
|
||||
replace_existing=True
|
||||
)
|
||||
elif task.action == 'remove':
|
||||
|
|
|
@ -27,6 +27,7 @@ class Schedule(View):
|
|||
Argument('id', type=int, required=False),
|
||||
Argument('type', help='请输入任务类型'),
|
||||
Argument('name', help='请输入任务名称'),
|
||||
Argument('interpreter', help='请选择执行解释器'),
|
||||
Argument('command', help='请输入任务内容'),
|
||||
Argument('rst_notify', type=dict, help='请选择执行失败通知方式'),
|
||||
Argument('targets', type=list, filter=lambda x: len(x), help='请选择执行对象'),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useState } from 'react';
|
||||
import { observer } from 'mobx-react';
|
||||
import { Form, Input, Select, Modal, Button } from 'antd';
|
||||
import { Form, Input, Select, Modal, Button, Radio } from 'antd';
|
||||
import { ExclamationCircleOutlined } from '@ant-design/icons';
|
||||
import { LinkButton, ACEditor } from 'components';
|
||||
import TemplateSelector from '../exec/task/TemplateSelector';
|
||||
|
@ -11,6 +11,7 @@ export default observer(function () {
|
|||
const [form] = Form.useForm();
|
||||
const [showTmp, setShowTmp] = useState(false);
|
||||
const [command, setCommand] = useState(store.record.command || '');
|
||||
const [interpreter, setInterpreter] = useState(store.record.interpreter || 'sh');
|
||||
|
||||
function handleAddZone() {
|
||||
let type;
|
||||
|
@ -79,10 +80,16 @@ export default observer(function () {
|
|||
<Input placeholder="请输入任务名称"/>
|
||||
</Form.Item>
|
||||
<Form.Item required label="任务内容" extra={<LinkButton onClick={() => setShowTmp(true)}>从模板添加</LinkButton>}>
|
||||
<ACEditor mode="sh" value={command} width="100%" height="150px" onChange={setCommand}/>
|
||||
<Form.Item noStyle name="interpreter" initialValue="sh">
|
||||
<Radio.Group buttonStyle="solid" style={{marginBottom: 12}} onChange={e => setInterpreter(e.target.value)}>
|
||||
<Radio.Button value="sh" style={{width: 80, textAlign: 'center'}}>Shell</Radio.Button>
|
||||
<Radio.Button value="python" style={{width: 80, textAlign: 'center'}}>Python</Radio.Button>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
<ACEditor mode={interpreter} value={command} width="100%" height="150px" onChange={setCommand}/>
|
||||
</Form.Item>
|
||||
<Form.Item label="失败通知" extra={(
|
||||
<span>
|
||||
<span>
|
||||
任务执行失败告警通知,
|
||||
<a target="_blank" rel="noopener noreferrer"
|
||||
href="https://spug.cc/docs/use-problem#use-dd">钉钉收不到通知?</a>
|
||||
|
|
|
@ -20,7 +20,7 @@ export default observer(function () {
|
|||
return message.error('任务执行时间不能早于当前时间')
|
||||
}
|
||||
setLoading(true)
|
||||
const formData = lds.pick(store.record, ['id', 'name', 'type', 'command', 'desc', 'rst_notify']);
|
||||
const formData = lds.pick(store.record, ['id', 'name', 'type', 'interpreter', 'command', 'desc', 'rst_notify']);
|
||||
formData['targets'] = store.targets.filter(x => x);
|
||||
formData['trigger'] = trigger;
|
||||
formData['trigger_args'] = _parse_args();
|
||||
|
|
Loading…
Reference in New Issue