创建数据库表时,需判断数据库是否存在

pull/21/merge
ouqiang 2017-04-01 20:28:30 +08:00
parent 4f7807cac8
commit 7e5b84c320
6 changed files with 81 additions and 46 deletions

View File

@ -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{},
} }
@ -16,4 +21,11 @@ func(migration *Migration) Exec() error {
} }
return nil return nil
}
// 创建数据库
func isDatabaseExist(name string) bool {
_, err := Db.Exec("use ?", name)
return err != nil
} }

View File

@ -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不限制

View File

@ -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}
commandArgs = append(commandArgs, args...) if len(args) > 0 {
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")
} }

View File

@ -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) {
@ -91,12 +85,4 @@ func(cronTask *CronTask) Delete(name string) {
cronTask.Lock() cronTask.Lock()
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()
}
} }

View File

@ -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)
} }

View File

@ -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-command任务
type SSHCommandHandler struct {}
func(ssh *SSHCommandHandler) Run(taskModel models.Task) (string, error) {
return execSSHHandler("shell", taskModel)
}
// SSH-script任务
type SSHScriptHandler struct {}
func(ssh *SSHScriptHandler) Run(taskModel models.Task) (string, error) {
return execSSHHandler("script", taskModel)
}
// SSH任务 // SSH任务
type SSHHandler struct {} func execSSHHandler(module string, taskModel models.Task) (string, error) {
var args []string = []string{ taskModel.Command }
func(ssh *SSHHandler) Run(taskModel models.Task) (string, error) {
var args []string = []string{
"-m", "shell",
"-a", 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)