mirror of https://github.com/ouqiang/gocron
系统安装成功后, 自动创建2个测试任务
parent
f699a72c28
commit
0be9269b8c
|
@ -93,12 +93,12 @@ func setEnvironment(ctx *cli.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch env {
|
switch env {
|
||||||
case "prod":
|
|
||||||
macaron.Env = macaron.PROD
|
|
||||||
case "test":
|
case "test":
|
||||||
macaron.Env = macaron.TEST
|
macaron.Env = macaron.TEST
|
||||||
case "dev":
|
case "dev":
|
||||||
macaron.Env = macaron.DEV
|
macaron.Env = macaron.DEV
|
||||||
|
default:
|
||||||
|
macaron.Env = macaron.PROD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,9 @@ func (migration *Migration) Exec(dbName string) error {
|
||||||
return errors.New("数据库不存在")
|
return errors.New("数据库不存在")
|
||||||
}
|
}
|
||||||
setting := new(Setting)
|
setting := new(Setting)
|
||||||
|
task := new(Task)
|
||||||
tables := []interface{}{
|
tables := []interface{}{
|
||||||
&User{}, &Task{}, &TaskLog{}, &Host{}, setting,&LoginLog{},
|
&User{}, task, &TaskLog{}, &Host{}, setting,&LoginLog{},
|
||||||
}
|
}
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
exist, err:= Db.IsTableExist(table)
|
exist, err:= Db.IsTableExist(table)
|
||||||
|
@ -30,6 +31,7 @@ func (migration *Migration) Exec(dbName string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setting.InitBasicField()
|
setting.InitBasicField()
|
||||||
|
task.CreateTestTask()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
"github.com/ouqiang/gocron/modules/ssh"
|
"github.com/ouqiang/gocron/modules/ssh"
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TaskProtocol int8
|
type TaskProtocol int8
|
||||||
|
@ -29,9 +30,9 @@ type Task struct {
|
||||||
NotifyType int8 `xorm:"smallint notnull default 0"` // 通知类型 1: 邮件 2: slack
|
NotifyType int8 `xorm:"smallint notnull default 0"` // 通知类型 1: 邮件 2: slack
|
||||||
NotifyReceiverId string `xorm:"varchar(256) notnull default '' "` // 通知接受者ID, setting表主键ID,多个ID逗号分隔
|
NotifyReceiverId string `xorm:"varchar(256) notnull default '' "` // 通知接受者ID, setting表主键ID,多个ID逗号分隔
|
||||||
Remark string `xorm:"varchar(100) notnull default ''"` // 备注
|
Remark string `xorm:"varchar(100) notnull default ''"` // 备注
|
||||||
|
Status Status `xorm:"tinyint notnull default 0"` // 状态 1:正常 0:停止
|
||||||
Created time.Time `xorm:"datetime notnull created"` // 创建时间
|
Created time.Time `xorm:"datetime notnull created"` // 创建时间
|
||||||
Deleted time.Time `xorm:"datetime deleted"` // 删除时间
|
Deleted time.Time `xorm:"datetime deleted"` // 删除时间
|
||||||
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:正常 0:停止
|
|
||||||
BaseModel `xorm:"-"`
|
BaseModel `xorm:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +59,33 @@ func (task *Task) Create() (insertId int, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增测试任务
|
||||||
|
func (task *Task) CreateTestTask() {
|
||||||
|
// HTTP任务
|
||||||
|
task.Name = "测试HTTP任务"
|
||||||
|
task.Protocol = TaskHTTP
|
||||||
|
task.Spec = "*/30 * * * * *"
|
||||||
|
// 查询IP地址区域信息
|
||||||
|
task.Command = "http://ip.taobao.com/service/getIpInfo.php?ip=117.27.140.253"
|
||||||
|
task.Status = Enabled
|
||||||
|
task.Create()
|
||||||
|
|
||||||
|
// 系统命令
|
||||||
|
task.Id = 0
|
||||||
|
task.Name = "测试系统命令任务"
|
||||||
|
task.Protocol = TaskLocalCommand
|
||||||
|
task.Spec = "@every 1m"
|
||||||
|
task.Status = Enabled
|
||||||
|
if utils.IsWindows() {
|
||||||
|
task.Command = "dir"
|
||||||
|
} else {
|
||||||
|
task.Command = "ls"
|
||||||
|
}
|
||||||
|
task.Create()
|
||||||
|
}
|
||||||
|
|
||||||
func (task *Task) UpdateBean(id int) (int64, error) {
|
func (task *Task) UpdateBean(id int) (int64, error) {
|
||||||
return Db.ID(id).Cols("name,spec,protocol,command,timeout,multi,retry_times,host_id,remark,status,notify_status,notify_type,notify_receiver_id").Update(task)
|
return Db.ID(id).Cols("name,spec,protocol,command,timeout,multi,retry_times,host_id,remark,notify_status,notify_type,notify_receiver_id").Update(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
|
|
|
@ -66,7 +66,7 @@ func (mail *Mail) send(mailSetting models.Mail, toUsers []string, msg Message)
|
||||||
i += 1
|
i += 1
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
if i < maxTimes {
|
if i < maxTimes {
|
||||||
logger.Error("mail#发送消息失败#%s#消息内容-%s", err.Error(), msg["content"])
|
logger.Errorf("mail#发送消息失败#%s#消息内容-%s", err.Error(), msg["content"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (slack *Slack) send(msg Message, slackUrl string, channel string) {
|
||||||
i += 1
|
i += 1
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
if i < maxTimes {
|
if i < maxTimes {
|
||||||
logger.Error("slack#发送消息失败#%s#消息内容-%s", resp.Body, msg["content"])
|
logger.Errorf("slack#发送消息失败#%s#消息内容-%s", resp.Body, msg["content"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"html/template"
|
"html/template"
|
||||||
"github.com/ouqiang/gocron/routers/base"
|
"github.com/ouqiang/gocron/routers/base"
|
||||||
"github.com/go-macaron/binding"
|
"github.com/go-macaron/binding"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TaskForm struct {
|
type TaskForm struct {
|
||||||
|
@ -26,7 +27,6 @@ type TaskForm struct {
|
||||||
RetryTimes int8
|
RetryTimes int8
|
||||||
HostId int16
|
HostId int16
|
||||||
Remark string
|
Remark string
|
||||||
Status models.Status `binding:"In(1,2)"`
|
|
||||||
NotifyStatus int8 `binding:In(1,2,3)`
|
NotifyStatus int8 `binding:In(1,2,3)`
|
||||||
NotifyType int8 `binding:In(1,2)`
|
NotifyType int8 `binding:In(1,2)`
|
||||||
NotifyReceiverId string
|
NotifyReceiverId string
|
||||||
|
@ -82,11 +82,6 @@ func Create(ctx *macaron.Context) {
|
||||||
// 编辑页面
|
// 编辑页面
|
||||||
func Edit(ctx *macaron.Context) {
|
func Edit(ctx *macaron.Context) {
|
||||||
id := ctx.ParamsInt(":id")
|
id := ctx.ParamsInt(":id")
|
||||||
hostModel := new(models.Host)
|
|
||||||
hosts, err := hostModel.List(models.CommonMap{})
|
|
||||||
if err != nil || len(hosts) == 0 {
|
|
||||||
logger.Error(err)
|
|
||||||
}
|
|
||||||
taskModel := new(models.Task)
|
taskModel := new(models.Task)
|
||||||
task, err := taskModel.Detail(id)
|
task, err := taskModel.Detail(id)
|
||||||
if err != nil || task.Id != id {
|
if err != nil || task.Id != id {
|
||||||
|
@ -95,11 +90,7 @@ func Edit(ctx *macaron.Context) {
|
||||||
}
|
}
|
||||||
ctx.Data["Task"] = task
|
ctx.Data["Task"] = task
|
||||||
ctx.Data["Title"] = "编辑"
|
ctx.Data["Title"] = "编辑"
|
||||||
ctx.Data["Hosts"] = hosts
|
setHostsToTemplate(ctx)
|
||||||
if len(hosts) > 0 {
|
|
||||||
ctx.Data["FirstHostName"] = hosts[0].Name
|
|
||||||
ctx.Data["FirstHostId"] = hosts[0].Id
|
|
||||||
}
|
|
||||||
ctx.HTML(200, "task/task_form")
|
ctx.HTML(200, "task/task_form")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,12 +125,8 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
taskModel.Command = form.Command
|
taskModel.Command = form.Command
|
||||||
taskModel.Timeout = form.Timeout
|
taskModel.Timeout = form.Timeout
|
||||||
taskModel.Remark = form.Remark
|
taskModel.Remark = form.Remark
|
||||||
taskModel.Status = form.Status
|
|
||||||
taskModel.Multi = form.Multi
|
taskModel.Multi = form.Multi
|
||||||
taskModel.RetryTimes = form.RetryTimes
|
taskModel.RetryTimes = form.RetryTimes
|
||||||
if taskModel.Status != models.Enabled {
|
|
||||||
taskModel.Status = models.Disabled
|
|
||||||
}
|
|
||||||
if taskModel.Multi != 1 {
|
if taskModel.Multi != 1 {
|
||||||
taskModel.Multi = 0
|
taskModel.Multi = 0
|
||||||
}
|
}
|
||||||
|
@ -151,6 +138,10 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
return json.CommonFailure("请至少选择一个接收者")
|
return json.CommonFailure("请至少选择一个接收者")
|
||||||
}
|
}
|
||||||
if taskModel.Protocol == models.TaskHTTP {
|
if taskModel.Protocol == models.TaskHTTP {
|
||||||
|
command := strings.ToLower(taskModel.Command)
|
||||||
|
if !strings.HasPrefix(command, "http://") && !strings.HasPrefix(command, "https://") {
|
||||||
|
return json.CommonFailure("请输入正确的URL地址")
|
||||||
|
}
|
||||||
if taskModel.Timeout == -1 {
|
if taskModel.Timeout == -1 {
|
||||||
return json.CommonFailure("HTTP任务不支持后台运行")
|
return json.CommonFailure("HTTP任务不支持后台运行")
|
||||||
}
|
}
|
||||||
|
@ -159,10 +150,15 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if taskModel.RetryTimes > 10 || taskModel.RetryTimes < 0 {
|
if taskModel.RetryTimes > 10 || taskModel.RetryTimes < 0 {
|
||||||
return json.CommonFailure("任务重试次数取值0-10")
|
return json.CommonFailure("任务重试次数取值0-10")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if taskModel.Protocol != models.TaskSSH {
|
||||||
|
taskModel.HostId = 0
|
||||||
|
}
|
||||||
|
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
id, err = taskModel.Create()
|
id, err = taskModel.Create()
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,11 +168,6 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
return json.CommonFailure("保存失败", err)
|
return json.CommonFailure("保存失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 任务处于激活状态,加入调度管理
|
|
||||||
if (taskModel.Status == models.Enabled) {
|
|
||||||
addTaskToTimer(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return json.Success("保存成功", nil)
|
return json.Success("保存成功", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,8 +271,4 @@ func setHostsToTemplate(ctx *macaron.Context) {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
}
|
}
|
||||||
ctx.Data["Hosts"] = hosts
|
ctx.Data["Hosts"] = hosts
|
||||||
if len(hosts) > 0 {
|
|
||||||
ctx.Data["FirstHostName"] = hosts[0].Name
|
|
||||||
ctx.Data["FirstHostId"] = hosts[0].Id
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -90,9 +90,17 @@
|
||||||
$('.ui.form').form(
|
$('.ui.form').form(
|
||||||
{
|
{
|
||||||
onSuccess: function(event, fields) {
|
onSuccess: function(event, fields) {
|
||||||
|
swal({
|
||||||
|
title: '',
|
||||||
|
text: "系统安装中.......",
|
||||||
|
type: 'info',
|
||||||
|
showConfirmButton: false
|
||||||
|
});
|
||||||
util.post('/install/store', fields, function(code, message) {
|
util.post('/install/store', fields, function(code, message) {
|
||||||
swal('安装成功');
|
swal('安装成功');
|
||||||
|
setTimeout(function() {
|
||||||
location.href = "/";
|
location.href = "/";
|
||||||
|
}, 2000)
|
||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<div class="four fields">
|
<div class="four fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>
|
<label>
|
||||||
主机名
|
SMTP服务器
|
||||||
</label>
|
</label>
|
||||||
<div class="ui small input">
|
<div class="ui small input">
|
||||||
<input type="text" name="host" value="{{{.Mail.Host}}}">
|
<input type="text" name="host" value="{{{.Mail.Host}}}">
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
<div class="two fields">
|
<div class="two fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>命令</label>
|
<label>命令</label>
|
||||||
<textarea rows="5" name="command">{{{.Task.Command}}}</textarea>
|
<textarea rows="5" name="command" placeholder="请输入系统命令" id="command">{{{.Task.Command}}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="six fields">
|
<div class="six fields">
|
||||||
|
@ -81,27 +81,12 @@
|
||||||
<div class="three fields">
|
<div class="three fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>允许多实例同时运行</label>
|
<label>允许多实例同时运行</label>
|
||||||
<div class="ui blue message">
|
|
||||||
前次任务未执行完成,本次任务是否执行
|
|
||||||
</div>
|
|
||||||
<select name="multi">
|
<select name="multi">
|
||||||
<option value="1"{{{if .Task}}} {{{if eq .Task.Multi 1}}}selected{{{end}}} {{{end}}}>是</option>
|
<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>
|
<option value="2" {{{if .Task}}} {{{if eq .Task.Multi 0}}}selected{{{end}}} {{{end}}}>否</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="three fields">
|
|
||||||
<div class="field">
|
|
||||||
<label>任务状态</label>
|
|
||||||
<div class="ui blue message">
|
|
||||||
任务添加成功后,是否立即调度
|
|
||||||
</div>
|
|
||||||
<select name="status">
|
|
||||||
<option value="2"{{{if .Task}}} {{{if eq .Task.Status 0}}}selected{{{end}}} {{{end}}}>停止</option>
|
|
||||||
<option value="1" {{{if .Task}}} {{{if eq .Task.Status 1}}}selected{{{end}}} {{{end}}}>激活</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="three fields">
|
<div class="three fields">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>任务通知</label>
|
<label>任务通知</label>
|
||||||
|
@ -162,14 +147,18 @@
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function() {
|
$(function() {
|
||||||
|
changeCommandPlaceholder();
|
||||||
changeProtocol();
|
changeProtocol();
|
||||||
showNotify();
|
showNotify();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#protocol').change(function() {
|
$('#protocol').change(function() {
|
||||||
|
changeCommandPlaceholder();
|
||||||
changeProtocol();
|
changeProtocol();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$('#task-status').change(function() {
|
$('#task-status').change(function() {
|
||||||
var selected = $(this).val();
|
var selected = $(this).val();
|
||||||
if (selected == 1) {
|
if (selected == 1) {
|
||||||
|
@ -185,6 +174,21 @@
|
||||||
changeNotify();
|
changeNotify();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function changeCommandPlaceholder() {
|
||||||
|
var selectedId = $('#protocol').val();
|
||||||
|
switch (selectedId) {
|
||||||
|
case '1':
|
||||||
|
$('#command').attr('placeholder', '请输入URL地址');
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
$('#command').attr('placeholder', '请输入shell命令');
|
||||||
|
break;
|
||||||
|
case '3':
|
||||||
|
$('#command').attr('placeholder', '请输入系统命令');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showNotify() {
|
function showNotify() {
|
||||||
var notifyStatus = {{{.Task.NotifyStatus}}};
|
var notifyStatus = {{{.Task.NotifyStatus}}};
|
||||||
if (notifyStatus > 0) {
|
if (notifyStatus > 0) {
|
||||||
|
|
Loading…
Reference in New Issue