mirror of https://github.com/ouqiang/gocron
创建数据库表时,需判断数据库是否存在
parent
4f7807cac8
commit
7e5b84c320
|
@ -1,10 +1,15 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
// 创建数据库表
|
// 创建数据库表
|
||||||
|
|
||||||
type Migration struct {}
|
type Migration struct {}
|
||||||
|
|
||||||
func(migration *Migration) Exec() error {
|
func(migration *Migration) Exec(dbName string) error {
|
||||||
|
if !isDatabaseExist(dbName) {
|
||||||
|
return errors.New("数据库不存在")
|
||||||
|
}
|
||||||
tables := []interface{}{
|
tables := []interface{}{
|
||||||
&User{}, &Task{}, &TaskLog{},&Host{},
|
&User{}, &Task{}, &TaskLog{},&Host{},
|
||||||
}
|
}
|
||||||
|
@ -17,3 +22,10 @@ func(migration *Migration) Exec() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建数据库
|
||||||
|
func isDatabaseExist(name string) bool {
|
||||||
|
_, err := Db.Exec("use ?", name)
|
||||||
|
|
||||||
|
return err != nil
|
||||||
|
}
|
|
@ -10,7 +10,8 @@ type TaskType int8
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HTTP Protocol = 1
|
HTTP Protocol = 1
|
||||||
SSH Protocol = 2
|
SSHCommand Protocol = 2
|
||||||
|
SSHScript Protocol = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -23,7 +24,7 @@ type Task struct {
|
||||||
Id int `xorm:"int pk autoincr"`
|
Id int `xorm:"int pk autoincr"`
|
||||||
Name string `xorm:"varchar(64) notnull"` // 任务名称
|
Name string `xorm:"varchar(64) notnull"` // 任务名称
|
||||||
Spec string `xorm:"varchar(64) notnull"` // crontab 时间格式
|
Spec string `xorm:"varchar(64) notnull"` // crontab 时间格式
|
||||||
Protocol Protocol `xorm:"tinyint notnull"` // 协议 1:http 2:ssh
|
Protocol Protocol `xorm:"tinyint notnull"` // 协议 1:http 2:ssh-command 3:ssh-script
|
||||||
Type TaskType `xorm:"tinyint notnull default 1"` // 任务类型 1: 定时任务 2: 延时任务
|
Type TaskType `xorm:"tinyint notnull default 1"` // 任务类型 1: 定时任务 2: 延时任务
|
||||||
Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令
|
Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令
|
||||||
Timeout int `xorm:"mediumint notnull default 0"` // 任务执行超时时间(单位秒),0不限制
|
Timeout int `xorm:"mediumint notnull default 0"` // 任务执行超时时间(单位秒),0不限制
|
||||||
|
|
|
@ -13,17 +13,34 @@ import (
|
||||||
* 执行ad-hoc
|
* 执行ad-hoc
|
||||||
* hosts 主机名或主机别名 逗号分隔
|
* hosts 主机名或主机别名 逗号分隔
|
||||||
* hostFile 主机名文件
|
* hostFile 主机名文件
|
||||||
* module 调用模块
|
* module 模块
|
||||||
* args 传递给模块的参数
|
* args 传递给module的参数
|
||||||
*/
|
*/
|
||||||
func ExecCommand(hosts string, hostFile string, args... string) (output string, err error) {
|
func ExecCommand(hosts string, hostFile string, module string, args... string) (output string, err error) {
|
||||||
if hosts== "" || hostFile == "" || len(args) == 0 {
|
if hosts== "" || hostFile == "" || module == "" {
|
||||||
err = errors.New("参数不完整")
|
err = errors.New("参数不完整")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
commandArgs := []string{hosts, "-i", hostFile}
|
commandArgs := []string{hosts, "-i", hostFile, "-m", module}
|
||||||
|
if len(args) > 0 {
|
||||||
commandArgs = append(commandArgs, args...)
|
commandArgs = append(commandArgs, args...)
|
||||||
|
}
|
||||||
output, err = utils.ExecShell("ansible", commandArgs...)
|
output, err = utils.ExecShell("ansible", commandArgs...)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 执行shell命令
|
||||||
|
func Shell(hosts string, hostFile string, args... string) (output string, err error) {
|
||||||
|
return ExecCommand(hosts, hostFile, "shell", args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制本地脚本到远程执行
|
||||||
|
func Script(hosts string, hostFile string, args... string) (output string, err error) {
|
||||||
|
return ExecCommand(hosts, hostFile, "script", args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 测试主机是否可通
|
||||||
|
func Ping(hosts string, hostFile string) (output string, err error) {
|
||||||
|
return ExecCommand(hosts, hostFile, "ping")
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ func(cronTask *CronTask) Add(name string, spec string, cmd cron.FuncJob ) (err e
|
||||||
for _, item := range(specs) {
|
for _, item := range(specs) {
|
||||||
err = cronTask.tasks[name].AddFunc(item, cmd)
|
err = cronTask.tasks[name].AddFunc(item, cmd)
|
||||||
}
|
}
|
||||||
|
cronTask.tasks[name].Start()
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -71,13 +72,6 @@ func(cronTask *CronTask) IsExist(name string) bool {
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
// 启动任务
|
|
||||||
func(cronTask *CronTask) Start(name string) {
|
|
||||||
if cronTask.IsExist(name) {
|
|
||||||
cronTask.tasks[name].Start()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 停止任务
|
// 停止任务
|
||||||
func(cronTask *CronTask) Stop(name string) {
|
func(cronTask *CronTask) Stop(name string) {
|
||||||
if cronTask.IsExist(name) {
|
if cronTask.IsExist(name) {
|
||||||
|
@ -92,11 +86,3 @@ func(cronTask *CronTask) Delete(name string) {
|
||||||
defer cronTask.Unlock()
|
defer cronTask.Unlock()
|
||||||
delete(cronTask.tasks, name)
|
delete(cronTask.tasks, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 运行所有任务
|
|
||||||
func(cronTask *CronTask) Run() {
|
|
||||||
for _, cron := range cronTask.tasks {
|
|
||||||
// cron内部有开启goroutine,此处不用新建goroutine
|
|
||||||
cron.Start()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -46,22 +46,16 @@ func Install(ctx *macaron.Context, form InstallForm) string {
|
||||||
utils.RecordLog(err)
|
utils.RecordLog(err)
|
||||||
return json.Failure(utils.ResponseFailure, "数据库配置写入文件失败")
|
return json.Failure(utils.ResponseFailure, "数据库配置写入文件失败")
|
||||||
}
|
}
|
||||||
// 创建安装锁
|
|
||||||
err = app.CreateInstallLock()
|
|
||||||
if err != nil {
|
|
||||||
utils.RecordLog(err)
|
|
||||||
return json.Failure(utils.ResponseFailure, "创建文件安装锁失败")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 初始化Db
|
||||||
app.InitDb()
|
app.InitDb()
|
||||||
// 初始化配置, DB, 定时任务, 创建数据库表
|
// 创建数据库表
|
||||||
migration := new(models.Migration)
|
migration := new(models.Migration)
|
||||||
err = migration.Exec()
|
err = migration.Exec(form.DbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.RecordLog(err)
|
utils.RecordLog(err)
|
||||||
return json.Failure(utils.ResponseFailure, "创建数据库表失败")
|
return json.Failure(utils.ResponseFailure, "创建数据库表失败")
|
||||||
}
|
}
|
||||||
app.InitResource()
|
|
||||||
|
|
||||||
// 创建管理员账号
|
// 创建管理员账号
|
||||||
err = createAdminUser(form)
|
err = createAdminUser(form)
|
||||||
|
@ -70,6 +64,16 @@ func Install(ctx *macaron.Context, form InstallForm) string {
|
||||||
return json.Failure(utils.ResponseFailure, "创建管理员账号失败")
|
return json.Failure(utils.ResponseFailure, "创建管理员账号失败")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 创建安装锁
|
||||||
|
err = app.CreateInstallLock()
|
||||||
|
if err != nil {
|
||||||
|
utils.RecordLog(err)
|
||||||
|
return json.Failure(utils.ResponseFailure, "创建文件安装锁失败")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化定时任务等
|
||||||
|
app.InitResource()
|
||||||
|
|
||||||
return json.Success("安装成功", nil)
|
return json.Success("安装成功", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ func(task *Task) Initialize() {
|
||||||
for _, item := range(taskList) {
|
for _, item := range(taskList) {
|
||||||
task.Add(item)
|
task.Add(item)
|
||||||
}
|
}
|
||||||
crontask.DefaultCronTask.Run()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -92,22 +91,36 @@ func(h *HTTPHandler) Run(taskModel models.Task) (result string, err error) {
|
||||||
return string(body),err
|
return string(body),err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SSH任务
|
// SSH-command任务
|
||||||
type SSHHandler struct {}
|
type SSHCommandHandler struct {}
|
||||||
|
|
||||||
func(ssh *SSHHandler) Run(taskModel models.Task) (string, error) {
|
func(ssh *SSHCommandHandler) Run(taskModel models.Task) (string, error) {
|
||||||
|
return execSSHHandler("shell", taskModel)
|
||||||
var args []string = []string{
|
|
||||||
"-m", "shell",
|
|
||||||
"-a", taskModel.Command,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SSH-script任务
|
||||||
|
type SSHScriptHandler struct {}
|
||||||
|
|
||||||
|
func(ssh *SSHScriptHandler) Run(taskModel models.Task) (string, error) {
|
||||||
|
return execSSHHandler("script", taskModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSH任务
|
||||||
|
func execSSHHandler(module string, taskModel models.Task) (string, error) {
|
||||||
|
var args []string = []string{ taskModel.Command }
|
||||||
if (taskModel.Timeout > 0) {
|
if (taskModel.Timeout > 0) {
|
||||||
// -B 异步执行超时时间, -P 轮询时间
|
// -B 异步执行超时时间, -P 轮询时间
|
||||||
args = append(args, "-B", strconv.Itoa(taskModel.Timeout), "-P", "10")
|
args = append(args, "-B", strconv.Itoa(taskModel.Timeout), "-P", "10")
|
||||||
}
|
}
|
||||||
result, err := ansible.ExecCommand(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
|
if module == "shell" {
|
||||||
|
return ansible.Shell(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
|
||||||
|
}
|
||||||
|
if module == "script" {
|
||||||
|
return ansible.Script(taskModel.SshHosts, ansible.DefaultHosts.GetFilename(), args...)
|
||||||
|
}
|
||||||
|
|
||||||
return result, err
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTaskLog(taskId int) (int, error) {
|
func createTaskLog(taskId int) (int, error) {
|
||||||
|
@ -142,8 +155,10 @@ func createHandlerJob(taskModel models.Task) cron.FuncJob {
|
||||||
switch taskModel.Protocol {
|
switch taskModel.Protocol {
|
||||||
case models.HTTP:
|
case models.HTTP:
|
||||||
handler = new(HTTPHandler)
|
handler = new(HTTPHandler)
|
||||||
case models.SSH:
|
case models.SSHCommand:
|
||||||
handler = new(SSHHandler)
|
handler = new(SSHCommandHandler)
|
||||||
|
case models.SSHScript:
|
||||||
|
handler = new(SSHScriptHandler)
|
||||||
}
|
}
|
||||||
taskFunc := func() {
|
taskFunc := func() {
|
||||||
taskLogId, err := createTaskLog(taskModel.Id)
|
taskLogId, err := createTaskLog(taskModel.Id)
|
||||||
|
|
Loading…
Reference in New Issue