diff --git a/models/migration.go b/models/migration.go index 76dd1a0..5ec02ea 100644 --- a/models/migration.go +++ b/models/migration.go @@ -1,10 +1,15 @@ package models +import "errors" + // 创建数据库表 type Migration struct {} -func(migration *Migration) Exec() error { +func(migration *Migration) Exec(dbName string) error { + if !isDatabaseExist(dbName) { + return errors.New("数据库不存在") + } tables := []interface{}{ &User{}, &Task{}, &TaskLog{},&Host{}, } @@ -16,4 +21,11 @@ func(migration *Migration) Exec() error { } return nil +} + +// 创建数据库 +func isDatabaseExist(name string) bool { + _, err := Db.Exec("use ?", name) + + return err != nil } \ No newline at end of file diff --git a/models/task.go b/models/task.go index 3b78660..5d04973 100644 --- a/models/task.go +++ b/models/task.go @@ -10,7 +10,8 @@ type TaskType int8 const ( HTTP Protocol = 1 - SSH Protocol = 2 + SSHCommand Protocol = 2 + SSHScript Protocol = 3 ) const ( @@ -23,7 +24,7 @@ type Task struct { Id int `xorm:"int pk autoincr"` Name string `xorm:"varchar(64) notnull"` // 任务名称 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: 延时任务 Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令 Timeout int `xorm:"mediumint notnull default 0"` // 任务执行超时时间(单位秒),0不限制 diff --git a/modules/ansible/ansible.go b/modules/ansible/ansible.go index 2b1a40d..004e717 100644 --- a/modules/ansible/ansible.go +++ b/modules/ansible/ansible.go @@ -13,17 +13,34 @@ import ( * 执行ad-hoc * hosts 主机名或主机别名 逗号分隔 * hostFile 主机名文件 - * module 调用模块 - * args 传递给模块的参数 + * module 模块 + * args 传递给module的参数 */ -func ExecCommand(hosts string, hostFile string, args... string) (output string, err error) { - if hosts== "" || hostFile == "" || len(args) == 0 { +func ExecCommand(hosts string, hostFile string, module string, args... string) (output string, err error) { + if hosts== "" || hostFile == "" || module == "" { err = errors.New("参数不完整") return } - commandArgs := []string{hosts, "-i", hostFile} - commandArgs = append(commandArgs, args...) + commandArgs := []string{hosts, "-i", hostFile, "-m", module} + if len(args) > 0 { + commandArgs = append(commandArgs, args...) + } output, err = utils.ExecShell("ansible", commandArgs...) 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") } \ No newline at end of file diff --git a/modules/crontask/cron_task.go b/modules/crontask/cron_task.go index a322a23..efe517d 100644 --- a/modules/crontask/cron_task.go +++ b/modules/crontask/cron_task.go @@ -48,6 +48,7 @@ func(cronTask *CronTask) Add(name string, spec string, cmd cron.FuncJob ) (err e for _, item := range(specs) { err = cronTask.tasks[name].AddFunc(item, cmd) } + cronTask.tasks[name].Start() return err } @@ -71,13 +72,6 @@ func(cronTask *CronTask) IsExist(name string) bool { return ok } -// 启动任务 -func(cronTask *CronTask) Start(name string) { - if cronTask.IsExist(name) { - cronTask.tasks[name].Start() - } -} - // 停止任务 func(cronTask *CronTask) Stop(name string) { if cronTask.IsExist(name) { @@ -91,12 +85,4 @@ func(cronTask *CronTask) Delete(name string) { cronTask.Lock() defer cronTask.Unlock() delete(cronTask.tasks, name) -} - -// 运行所有任务 -func(cronTask *CronTask) Run() { - for _, cron := range cronTask.tasks { - // cron内部有开启goroutine,此处不用新建goroutine - cron.Start() - } } \ No newline at end of file diff --git a/routers/install/install.go b/routers/install/install.go index e0f0bf4..51fe00f 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -46,22 +46,16 @@ func Install(ctx *macaron.Context, form InstallForm) string { utils.RecordLog(err) return json.Failure(utils.ResponseFailure, "数据库配置写入文件失败") } - // 创建安装锁 - err = app.CreateInstallLock() - if err != nil { - utils.RecordLog(err) - return json.Failure(utils.ResponseFailure, "创建文件安装锁失败") - } + // 初始化Db app.InitDb() - // 初始化配置, DB, 定时任务, 创建数据库表 + // 创建数据库表 migration := new(models.Migration) - err = migration.Exec() + err = migration.Exec(form.DbName) if err != nil { utils.RecordLog(err) return json.Failure(utils.ResponseFailure, "创建数据库表失败") } - app.InitResource() // 创建管理员账号 err = createAdminUser(form) @@ -70,6 +64,16 @@ func Install(ctx *macaron.Context, form InstallForm) string { 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) } diff --git a/service/task.go b/service/task.go index fd0f44d..8396bd8 100644 --- a/service/task.go +++ b/service/task.go @@ -30,7 +30,6 @@ func(task *Task) Initialize() { for _, item := range(taskList) { 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 } -// SSH任务 -type SSHHandler struct {} +// SSH-command任务 +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) { // -B 异步执行超时时间, -P 轮询时间 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) { @@ -142,8 +155,10 @@ func createHandlerJob(taskModel models.Task) cron.FuncJob { switch taskModel.Protocol { case models.HTTP: handler = new(HTTPHandler) - case models.SSH: - handler = new(SSHHandler) + case models.SSHCommand: + handler = new(SSHCommandHandler) + case models.SSHScript: + handler = new(SSHScriptHandler) } taskFunc := func() { taskLogId, err := createTaskLog(taskModel.Id)