2017-04-07 01:13:36 +00:00
|
|
|
|
{{{ template "common/header" . }}}
|
|
|
|
|
<div class="ui grid">
|
|
|
|
|
{{{template "task/menu" .}}}
|
|
|
|
|
<div class="twelve wide column">
|
2017-04-07 09:26:46 +00:00
|
|
|
|
<div class="pageHeader">
|
|
|
|
|
<div class="segment">
|
|
|
|
|
<h3 class="ui dividing header">
|
|
|
|
|
<div class="content">
|
2017-04-17 10:04:30 +00:00
|
|
|
|
{{{.Title}}}
|
2017-04-07 09:26:46 +00:00
|
|
|
|
</div>
|
|
|
|
|
</h3>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
<form class="ui form fluid vertical segment">
|
2017-04-17 10:04:30 +00:00
|
|
|
|
<input type="hidden" name="id" value="{{{.Task.Id}}}">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
<div class="two fields">
|
|
|
|
|
<div class="field">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<label>
|
|
|
|
|
<div class="content">任务名称</div>
|
|
|
|
|
</label>
|
2017-04-23 06:11:53 +00:00
|
|
|
|
<div class="ui small input">
|
2017-04-21 05:36:45 +00:00
|
|
|
|
<input type="text" name="name" value="{{{.Task.Task.Name}}}">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="two fields">
|
|
|
|
|
<div class="field">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<label>
|
|
|
|
|
<div class="content">
|
|
|
|
|
crontab表达式
|
|
|
|
|
<div class="ui blue message">
|
2017-04-26 08:17:18 +00:00
|
|
|
|
Linux-crontab时间表达式语法, 支持秒级任务定义 <br>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
格式: 秒 分 时 天 月 周 <br>
|
2017-04-26 08:17:18 +00:00
|
|
|
|
示例:<br>
|
|
|
|
|
1 * * * * * 每分钟第一秒运行 <br>
|
|
|
|
|
*/20 * * * * * 每隔20秒运行一次 <br>
|
|
|
|
|
0 30 21 * * * 每天晚上21:30:00运行一次 <br>
|
|
|
|
|
0 0 23 * * 6 每周六晚上23:00:00 运行一次 <br>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
快捷语法: <br>
|
|
|
|
|
@yearly 每年运行一次 <br>
|
|
|
|
|
@monthly 每月运行一次 <br>
|
|
|
|
|
@weekly 每周运行一次 <br>
|
|
|
|
|
@daily 每天运行一次 <br>
|
|
|
|
|
@midnight 每天午夜运行一次<br>
|
|
|
|
|
@hourly 每小时运行一次 <br>
|
|
|
|
|
@every 30s 每隔30秒运行一次 <br>
|
|
|
|
|
@every 1m20s 每隔1分钟20秒运行一次 <br>
|
|
|
|
|
@every 3h5m10s 每隔3小时5分钟10秒运行一次 <br>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</label>
|
2017-04-25 09:22:54 +00:00
|
|
|
|
<div class="ui small input">
|
2017-04-26 08:17:18 +00:00
|
|
|
|
<input type="text" name="spec" value="{{{.Task.Spec}}}" placeholder="秒 分 时 天 月 周"/>
|
2017-04-22 15:39:33 +00:00
|
|
|
|
</div>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<div class="three fields">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
<div class="field">
|
|
|
|
|
<label>协议</label>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<div class="ui blue message">
|
|
|
|
|
系统命令: 调用本机系统命令 <br>
|
|
|
|
|
SSH: 通过SSH执行远程命令 <br>
|
|
|
|
|
HTTP: 执行HTTP-GET请求 <br>
|
|
|
|
|
</div>
|
2017-04-22 15:39:33 +00:00
|
|
|
|
<select name="protocol" id="protocol">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<option value="3" {{{if .Task}}} {{{if eq .Task.Protocol 3}}}selected{{{end}}} {{{end}}}>系统命令</option>
|
2017-04-22 15:39:33 +00:00
|
|
|
|
<option value="2" {{{if .Task}}} {{{if eq .Task.Protocol 2}}}selected{{{end}}} {{{end}}} data-match="host_id" data-validate-type="selectProtocol">SSH</option>
|
|
|
|
|
<option value="1" {{{if .Task}}} {{{if eq .Task.Protocol 1}}}selected{{{end}}} {{{end}}}>HTTP</option>
|
|
|
|
|
</select>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
</div>
|
2017-04-28 03:54:46 +00:00
|
|
|
|
<div class="three fields" id="hostField">
|
2017-04-23 06:11:53 +00:00
|
|
|
|
<div class="field">
|
|
|
|
|
<label>主机</label>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<div class="ui blue message">
|
|
|
|
|
<pre>选择SSH协议时,需选择执行主机</pre>
|
|
|
|
|
</div>
|
2017-04-23 06:11:53 +00:00
|
|
|
|
<select name="host_id" id="hostId">
|
|
|
|
|
<option value="">选择主机</option>
|
|
|
|
|
{{{range $i, $v := .Hosts}}}
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<option value="{{{.Id}}}" {{{if $.Task}}}{{{if eq $.Task.HostId .Id }}} selected {{{end}}} {{{end}}}>{{{.Alias}}}-{{{.Name}}}</option>
|
2017-04-23 11:30:53 +00:00
|
|
|
|
{{{end}}}
|
2017-04-24 05:57:39 +00:00
|
|
|
|
</select> <a class="ui blue button" href="/host/create">添加主机</a>
|
2017-04-28 03:54:46 +00:00
|
|
|
|
|
|
|
|
|
</div>
|
2017-04-23 06:11:53 +00:00
|
|
|
|
</div>
|
2017-04-21 05:36:45 +00:00
|
|
|
|
<div class="two fields">
|
|
|
|
|
<div class="field">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<label>命令</label>
|
|
|
|
|
<div class="ui blue message">
|
|
|
|
|
根据选择的协议输入相应的命令 <br>
|
2017-04-30 17:12:07 +00:00
|
|
|
|
系统命令 - ifconfig -a <br>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
SSH - netstat -natpu <br>
|
2017-04-30 17:12:07 +00:00
|
|
|
|
HTTP - URL地址 例: http://golang.org <br>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
</div>
|
2017-04-21 05:36:45 +00:00
|
|
|
|
<textarea rows="5" name="command">{{{.Task.Command}}}</textarea>
|
|
|
|
|
</div>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
2017-04-23 11:17:29 +00:00
|
|
|
|
<div class="three fields">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
<div class="field">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<label>任务超时时间(秒)</label>
|
|
|
|
|
<div class="ui blue message">
|
|
|
|
|
默认0,不限制超时
|
|
|
|
|
</div>
|
2017-04-21 05:36:45 +00:00
|
|
|
|
<input type="text" name="timeout" value="{{{.Task.Timeout}}}">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
2017-04-24 05:57:39 +00:00
|
|
|
|
</div>
|
|
|
|
|
<div class="two fields">
|
2017-04-21 06:50:40 +00:00
|
|
|
|
<div class="field">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<label>任务重试次数</label>
|
|
|
|
|
<div class="ui blue message">
|
2017-04-30 17:12:07 +00:00
|
|
|
|
无法连接远程主机,shell返回值非0, http响应码非200等异常返回,可重复执行任务,
|
|
|
|
|
重试时间间隔 重试次数 * 分钟, 按1分钟、2分钟、3分钟.....的间隔进行重试
|
2017-04-24 05:57:39 +00:00
|
|
|
|
取值范围1-10, 默认0,不重试
|
|
|
|
|
</div>
|
2017-04-28 03:54:46 +00:00
|
|
|
|
<input type="text" name="retry_times" value="{{{.Task.RetryTimes}}}">
|
2017-04-21 06:50:40 +00:00
|
|
|
|
</div>
|
2017-04-13 09:35:59 +00:00
|
|
|
|
</div>
|
2017-04-25 17:47:38 +00:00
|
|
|
|
<div class="three fields">
|
|
|
|
|
<div class="field">
|
2017-04-26 08:17:18 +00:00
|
|
|
|
<label>允许多实例同时运行</label>
|
|
|
|
|
<div class="ui blue message">
|
|
|
|
|
前次任务未执行完成,本次任务是否执行
|
|
|
|
|
</div>
|
2017-04-25 17:47:38 +00:00
|
|
|
|
<select name="multi">
|
|
|
|
|
<option value="1"{{{if .Task}}} {{{if eq .Task.Multi 1}}}selected{{{end}}} {{{end}}}>是</option>
|
|
|
|
|
<option value="2" {{{if .Task}}} {{{if eq .Task.Multi 0}}}selected{{{end}}} {{{end}}}>否</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2017-04-21 09:41:59 +00:00
|
|
|
|
<div class="three fields">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
<div class="field">
|
2017-04-24 05:57:39 +00:00
|
|
|
|
<label>任务状态</label>
|
|
|
|
|
<div class="ui blue message">
|
|
|
|
|
任务添加成功后,是否立即调度
|
|
|
|
|
</div>
|
2017-04-22 15:39:33 +00:00
|
|
|
|
<select name="status">
|
2017-04-25 17:47:38 +00:00
|
|
|
|
<option value="2"{{{if .Task}}} {{{if eq .Task.Status 0}}}selected{{{end}}} {{{end}}}>暂停</option>
|
2017-04-22 15:39:33 +00:00
|
|
|
|
<option value="1" {{{if .Task}}} {{{if eq .Task.Status 1}}}selected{{{end}}} {{{end}}}>激活</option>
|
|
|
|
|
</select>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2017-04-30 17:12:07 +00:00
|
|
|
|
<div class="three fields">
|
|
|
|
|
<div class="field">
|
|
|
|
|
<label>任务通知</label>
|
|
|
|
|
<select name="notify_status" id="task-status">
|
|
|
|
|
<option value="1"{{{if .Task}}} {{{if eq .Task.NotifyStatus 0}}}selected{{{end}}} {{{end}}}>不通知</option>
|
|
|
|
|
<option value="2" {{{if .Task}}} {{{if eq .Task.NotifyStatus 1}}}selected{{{end}}} {{{end}}}>失败通知</option>
|
|
|
|
|
<option value="3" {{{if .Task}}} {{{if eq .Task.NotifyStatus 2}}}selected{{{end}}} {{{end}}}>执行结束通知</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="two fields" style="display: none" id="task-notify-type">
|
|
|
|
|
<div class="field" >
|
|
|
|
|
<label>通知类型</label>
|
|
|
|
|
<select name="notify_type">
|
|
|
|
|
<option value="1"{{{if .Task}}} {{{if eq .Task.NotifyType 0}}}selected{{{end}}} {{{end}}}>请选择</option>
|
|
|
|
|
<option value="2" {{{if .Task}}} {{{if eq .Task.NotifyType 1}}}selected{{{end}}} {{{end}}}>邮件</option>
|
|
|
|
|
<option value="3" {{{if .Task}}} {{{if eq .Task.NotifyType 2}}}selected{{{end}}} {{{end}}}>Slack</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="inline fields" style="display: none" id="receiver-id"></div>
|
2017-04-21 05:36:45 +00:00
|
|
|
|
<div class="two fields">
|
2017-04-07 01:13:36 +00:00
|
|
|
|
<div class="field">
|
|
|
|
|
<label>备注</label>
|
2017-04-21 05:36:45 +00:00
|
|
|
|
<textarea rows="5" name="remark">{{{.Task.Remark}}}</textarea>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2017-04-17 10:04:30 +00:00
|
|
|
|
<div class="ui primary submit button">保存</div>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</form>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2017-04-30 17:12:07 +00:00
|
|
|
|
<script type="x-handlerbar-template" id="mail-template">
|
|
|
|
|
{{#each MailUsers}}
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="ui checkbox">
|
|
|
|
|
<input type="checkbox" name="receiver[]" {{#if checked}}checked{{/if}} value="{{Id}}" />
|
|
|
|
|
<label>{{Username}}-{{Email}}</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{else}}
|
2017-04-30 23:12:39 +00:00
|
|
|
|
<a class="ui blue button" href="/manage/mail/edit">邮箱配置</a><br><br>
|
2017-04-30 17:12:07 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script type="x-handlervar-template" id="slack-template">
|
|
|
|
|
{{#each Channels}}
|
|
|
|
|
<div class="field">
|
|
|
|
|
<div class="ui checkbox">
|
|
|
|
|
<input type="checkbox" name="receiver[]" {{#if checked}}checked{{/if}} value="{{Id}}" />
|
|
|
|
|
<label>{{Name}}</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{{else}}
|
2017-04-30 23:12:39 +00:00
|
|
|
|
<a class="ui blue button" href="/manage/slack/edit">Slack配置</a>
|
2017-04-30 17:12:07 +00:00
|
|
|
|
{{/each}}
|
|
|
|
|
</script>
|
2017-04-07 01:13:36 +00:00
|
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
2017-04-26 08:17:18 +00:00
|
|
|
|
$(function() {
|
|
|
|
|
changeProtocol();
|
2017-04-30 17:12:07 +00:00
|
|
|
|
showNotify();
|
2017-04-26 08:17:18 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#protocol').change(function() {
|
|
|
|
|
changeProtocol();
|
|
|
|
|
});
|
|
|
|
|
|
2017-04-30 17:12:07 +00:00
|
|
|
|
$('#task-status').change(function() {
|
|
|
|
|
var selected = $(this).val();
|
|
|
|
|
if (selected == 1) {
|
|
|
|
|
$('#task-notify-type').hide();
|
|
|
|
|
$('#receiver-id').hide();
|
|
|
|
|
$('#task-notify-type').find('select').val('1');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
$('#task-notify-type').show();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#task-notify-type').change(function() {
|
|
|
|
|
changeNotify();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function showNotify() {
|
|
|
|
|
var notifyStatus = {{{.Task.NotifyStatus}}};
|
|
|
|
|
if (notifyStatus > 0) {
|
|
|
|
|
$('#task-notify-type').show();
|
|
|
|
|
}
|
|
|
|
|
var notifyReceiverIds = '{{{.Task.NotifyReceiverId}}}'.split(',');
|
|
|
|
|
changeNotify(notifyReceiverIds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function changeNotify(notifyReceiverIds) {
|
|
|
|
|
var selectedId = $('#task-notify-type').find('select').val();
|
|
|
|
|
if (selectedId == 1) {
|
|
|
|
|
$('#receiver-id').hide();
|
|
|
|
|
$('#receiver-id').html('');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (selectedId == 2) {
|
|
|
|
|
showMail(notifyReceiverIds);
|
|
|
|
|
} else if (selectedId == 3) {
|
|
|
|
|
showSlack(notifyReceiverIds);
|
|
|
|
|
}
|
|
|
|
|
$('#receiver-id').show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showMail(notifyReceiverIds) {
|
2017-04-30 23:12:39 +00:00
|
|
|
|
util.get("/manage/mail", function(code, message, data) {
|
2017-04-30 17:12:07 +00:00
|
|
|
|
renderReceiver(notifyReceiverIds, $('#mail-template'), data, 'MailUsers');
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showSlack(notifyReceiverIds) {
|
2017-04-30 23:12:39 +00:00
|
|
|
|
util.get("/manage/slack", function(code, message, data) {
|
2017-04-30 17:12:07 +00:00
|
|
|
|
renderReceiver(notifyReceiverIds, $('#slack-template'), data, 'Channels');
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function renderReceiver(notifyReceiverIds, $element, data, key) {
|
|
|
|
|
if (notifyReceiverIds !== undefined && notifyReceiverIds) {
|
|
|
|
|
console.log(data[key]);
|
|
|
|
|
for (i in data[key]) {
|
|
|
|
|
if ($.inArray(data[key][i].Id + '', notifyReceiverIds) != -1) {
|
|
|
|
|
data[key][i].checked = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var html = util.renderTemplate($($element), data);
|
|
|
|
|
$('#receiver-id').html(html);
|
|
|
|
|
$('.ui.checkbox').checkbox();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-26 08:17:18 +00:00
|
|
|
|
function changeProtocol() {
|
|
|
|
|
var protocol = $('#protocol').val();
|
|
|
|
|
if (protocol == 2) {
|
|
|
|
|
$('#hostField').show();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$('#hostField').hide();
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-07 09:26:46 +00:00
|
|
|
|
$('.ui.checkbox')
|
|
|
|
|
.checkbox()
|
|
|
|
|
;
|
2017-04-30 17:12:07 +00:00
|
|
|
|
|
|
|
|
|
function validateNotify() {
|
|
|
|
|
var selectedId = $('#task-status').val();
|
|
|
|
|
if (selectedId == 1) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var checkedLength = $('#receiver-id input:checked').length;
|
|
|
|
|
if (checkedLength == 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function parseNotifyReceiver() {
|
|
|
|
|
var receivers = [];
|
|
|
|
|
$('#receiver-id input:checked').each(function() {
|
|
|
|
|
receivers.push($(this).val());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return receivers.join(",");
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-22 15:39:33 +00:00
|
|
|
|
var $uiForm = $('.ui.form');
|
|
|
|
|
registerSelectFormValidation("selectProtocol", $uiForm, $('#protocol'), 'protocol');
|
|
|
|
|
$($uiForm).form(
|
2017-04-07 09:26:46 +00:00
|
|
|
|
{
|
|
|
|
|
onSuccess: function(event, fields) {
|
2017-04-30 17:12:07 +00:00
|
|
|
|
if (!validateNotify()) {
|
|
|
|
|
swal('错误提示', '请至少选择一个接收者', 'error');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
fields.notify_receiver_id = parseNotifyReceiver();
|
2017-04-07 09:26:46 +00:00
|
|
|
|
util.post('/task/store', fields, function(code, message) {
|
2017-04-08 09:15:30 +00:00
|
|
|
|
location.href = "/task"
|
2017-04-07 09:26:46 +00:00
|
|
|
|
});
|
2017-04-07 01:13:36 +00:00
|
|
|
|
|
2017-04-07 09:26:46 +00:00
|
|
|
|
return false;
|
|
|
|
|
},
|
|
|
|
|
fields: {
|
|
|
|
|
name: {
|
|
|
|
|
identifier : 'name',
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
type : 'empty',
|
|
|
|
|
prompt : '请输入任务名称'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
spec: {
|
|
|
|
|
identifier : 'spec',
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
type : 'empty',
|
|
|
|
|
prompt : '请输入crontab格式表达式'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
command: {
|
|
|
|
|
identifier : 'command',
|
|
|
|
|
rules: [
|
|
|
|
|
{
|
|
|
|
|
type : 'empty',
|
|
|
|
|
prompt : '请输入任务命令'
|
|
|
|
|
}
|
|
|
|
|
]
|
2017-04-22 15:39:33 +00:00
|
|
|
|
},
|
|
|
|
|
hosts: {
|
|
|
|
|
identifier : 'host_id',
|
2017-04-07 09:26:46 +00:00
|
|
|
|
rules: [
|
|
|
|
|
{
|
2017-04-22 15:39:33 +00:00
|
|
|
|
type : 'selectProtocol',
|
2017-04-07 09:26:46 +00:00
|
|
|
|
prompt : '请选择主机'
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
inline : true
|
|
|
|
|
});
|
2017-04-07 01:13:36 +00:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
{{{ template "common/footer" . }}}
|