mirror of https://github.com/ouqiang/gocron
解决循环依赖
parent
f39d0ac508
commit
b0909706ec
|
@ -25,4 +25,5 @@ _testmain.go
|
|||
|
||||
.idea
|
||||
data/*
|
||||
log/*
|
||||
log/*
|
||||
conf/install.lock
|
||||
|
|
10
cmd/web.go
10
cmd/web.go
|
@ -6,9 +6,7 @@ import (
|
|||
"github.com/go-macaron/gzip"
|
||||
"github.com/go-macaron/session"
|
||||
"github.com/go-macaron/csrf"
|
||||
"scheduler/utils"
|
||||
"fmt"
|
||||
"scheduler/utils/app"
|
||||
"scheduler/modules/app"
|
||||
)
|
||||
|
||||
// web服务器默认端口
|
||||
|
@ -31,7 +29,7 @@ var CmdWeb = cli.Command{
|
|||
|
||||
func run(ctx *cli.Context) {
|
||||
// 检测环境
|
||||
utils.CheckEnv()
|
||||
app.CheckEnv()
|
||||
// 启动定时任务
|
||||
runScheduler()
|
||||
m := macaron.Classic()
|
||||
|
@ -44,7 +42,9 @@ func run(ctx *cli.Context) {
|
|||
}
|
||||
|
||||
// 定时任务调度
|
||||
func runScheduler() {}
|
||||
func runScheduler() {
|
||||
|
||||
}
|
||||
|
||||
// 路由注册
|
||||
func registerRouter(m *macaron.Macaron) {
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
[db]
|
||||
password = wozaixiamen
|
||||
charset = utf8
|
||||
database = cron
|
||||
host = 127.0.0.1
|
||||
port = 3306
|
||||
user = root
|
||||
prefix =
|
|
@ -1,5 +1,6 @@
|
|||
package models
|
||||
|
||||
|
||||
// 主机
|
||||
type Host struct {
|
||||
Id int16 `xorm:"smallint pk autoincr"`
|
||||
|
|
|
@ -3,24 +3,17 @@ package models
|
|||
import (
|
||||
"github.com/go-xorm/xorm"
|
||||
"fmt"
|
||||
"scheduler/utils/setting"
|
||||
"scheduler/modules/setting"
|
||||
"github.com/go-xorm/core"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"gopkg.in/macaron.v1"
|
||||
"scheduler/utils/app"
|
||||
)
|
||||
|
||||
var Db *xorm.Engine
|
||||
|
||||
func init() {
|
||||
if app.Installed {
|
||||
Db = createDb()
|
||||
}
|
||||
}
|
||||
|
||||
type Status int8
|
||||
type CommonMap map[string]interface{}
|
||||
|
||||
var Db *xorm.Engine
|
||||
|
||||
const (
|
||||
Disabled Status = 0 // 禁用
|
||||
Failure Status = 0 // 失败
|
||||
|
@ -36,8 +29,8 @@ const (
|
|||
)
|
||||
|
||||
// 创建Db
|
||||
func createDb() *xorm.Engine{
|
||||
config,err := setting.Read()
|
||||
func CreateDb(configFile string) *xorm.Engine{
|
||||
config,err := setting.Read(configFile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package models
|
||||
|
||||
import "time"
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type TaskLog struct{
|
||||
Id int `xorm:"pk autoincr"`
|
||||
|
|
|
@ -2,7 +2,7 @@ package models
|
|||
|
||||
import (
|
||||
"time"
|
||||
"scheduler/utils"
|
||||
"scheduler/modules/utils"
|
||||
)
|
||||
|
||||
const PasswordSaltLength = 6;
|
||||
|
|
|
@ -4,18 +4,12 @@ package ansible
|
|||
|
||||
import (
|
||||
"os"
|
||||
"scheduler/utils"
|
||||
"scheduler/modules/utils"
|
||||
"errors"
|
||||
"gopkg.in/yaml.v2"
|
||||
"io/ioutil"
|
||||
"scheduler/utils/app"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// ansible配置文件目录
|
||||
os.Setenv("ANSIBLE_CONFIG", app.ConfDir)
|
||||
}
|
||||
|
||||
type Handler map[string]interface{}
|
||||
|
||||
type Playbook struct {
|
|
@ -0,0 +1,95 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
"scheduler/modules/crontask"
|
||||
"scheduler/models"
|
||||
"runtime"
|
||||
"scheduler/modules/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
AppDir string // 应用根目录
|
||||
ConfDir string // 配置目录
|
||||
LogDir string // 日志目录
|
||||
DataDir string // 数据目录,存放session文件等
|
||||
AppConfig string // 应用配置文件
|
||||
Installed bool // 应用是否安装过
|
||||
CronTask crontask.CronTask // 定时任务
|
||||
)
|
||||
|
||||
func init() {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
AppDir = wd
|
||||
ConfDir = AppDir + "/conf"
|
||||
LogDir = AppDir + "/log"
|
||||
DataDir = AppDir + "/data"
|
||||
AppConfig = AppDir + "/app.ini"
|
||||
checkDirExists(ConfDir, LogDir, DataDir)
|
||||
// ansible配置文件目录
|
||||
os.Setenv("ANSIBLE_CONFIG", ConfDir)
|
||||
Installed = IsInstalled()
|
||||
if Installed {
|
||||
initResource()
|
||||
}
|
||||
}
|
||||
|
||||
// 判断应用是否安装过
|
||||
func IsInstalled() bool {
|
||||
_, err := os.Stat(ConfDir + "/install.lock")
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// 检测环境
|
||||
func CheckEnv() {
|
||||
// ansible不支持安装在windows上, windows只能作为被控机
|
||||
if runtime.GOOS == "windows" {
|
||||
panic("不支持在windows上运行")
|
||||
}
|
||||
_, err := utils.ExecShell("ansible", "--version")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = utils.ExecShell("ansible-playbook", "--version")
|
||||
if err != nil {
|
||||
panic("ansible-playbook not found")
|
||||
}
|
||||
}
|
||||
|
||||
// 创建安装锁文件
|
||||
func CreateInstallLock() error {
|
||||
_, err := os.Create(ConfDir + "/install.lock")
|
||||
if err != nil {
|
||||
utils.RecordLog("创建安装锁文件失败")
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// 初始化资源
|
||||
func initResource() {
|
||||
crontask.DefaultCronTask = crontask.CreateCronTask()
|
||||
|
||||
models.Db = models.CreateDb(AppConfig)
|
||||
}
|
||||
|
||||
// 检测目录是否存在
|
||||
func checkDirExists(path... string) {
|
||||
for _, value := range(path) {
|
||||
_, err := os.Stat(value)
|
||||
if os.IsNotExist(err) {
|
||||
panic(value + "目录不存在")
|
||||
}
|
||||
if os.IsPermission(err) {
|
||||
panic(value + "目录无权限操作")
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +1,22 @@
|
|||
package utils
|
||||
package crontask
|
||||
|
||||
import (
|
||||
"github.com/robfig/cron"
|
||||
"errors"
|
||||
"scheduler/utils/app"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var DefaultCronTask CronTask;
|
||||
var DefaultCronTask *CronTask
|
||||
|
||||
type CronTask struct {
|
||||
sync.RWMutex
|
||||
tasks map[string]*cron.Cron
|
||||
}
|
||||
|
||||
func init() {
|
||||
if app.Installed {
|
||||
DefaultCronTask = CronTask{
|
||||
sync.RWMutex{},
|
||||
make(map[string]*cron.Cron),
|
||||
}
|
||||
func CreateCronTask() *CronTask {
|
||||
return &CronTask {
|
||||
sync.RWMutex{},
|
||||
make(map[string]*cron.Cron),
|
||||
}
|
||||
}
|
||||
|
|
@ -3,12 +3,11 @@ package setting
|
|||
import (
|
||||
"gopkg.in/ini.v1"
|
||||
"errors"
|
||||
"scheduler/utils/app"
|
||||
)
|
||||
|
||||
// 读取配置
|
||||
func Read() (config *ini.File, err error) {
|
||||
config, err = ini.Load(app.AppConfig)
|
||||
func Read(filename string) (config *ini.File, err error) {
|
||||
config, err = ini.Load(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -18,7 +17,7 @@ func Read() (config *ini.File, err error) {
|
|||
|
||||
|
||||
// 写入配置
|
||||
func Write(config map[string]map[string]string) (error) {
|
||||
func Write(config map[string]map[string]string, filename string) (error) {
|
||||
if len(config) == 0 {
|
||||
return errors.New("参数不能为空")
|
||||
}
|
||||
|
@ -39,7 +38,7 @@ func Write(config map[string]map[string]string) (error) {
|
|||
}
|
||||
}
|
||||
}
|
||||
err := file.SaveTo(app.AppConfig)
|
||||
err := file.SaveTo(filename)
|
||||
|
||||
return err
|
||||
}
|
|
@ -7,34 +7,8 @@ import (
|
|||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"log"
|
||||
"os"
|
||||
"runtime"
|
||||
"scheduler/utils/app"
|
||||
)
|
||||
|
||||
// 检测环境
|
||||
func CheckEnv() {
|
||||
// ansible不支持安装在windows上, windows只能作为被控机
|
||||
if runtime.GOOS == "windows" {
|
||||
panic("不支持在windows上运行")
|
||||
}
|
||||
_, err := ExecShell("ansible", "--version")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = ExecShell("ansible-playbook", "--version")
|
||||
if err != nil {
|
||||
panic("ansible-playbook not found")
|
||||
}
|
||||
}
|
||||
|
||||
// 创建安装锁文件
|
||||
func CreateInstallLock() {
|
||||
_, err := os.Create(app.ConfDir + "/install.lock")
|
||||
if err != nil {
|
||||
RecordLog("创建安装锁文件失败")
|
||||
}
|
||||
}
|
||||
|
||||
// 执行shell命令
|
||||
func ExecShell(command string, args... string) (string, error) {
|
|
@ -1,9 +1,9 @@
|
|||
package main
|
||||
|
||||
/*--------------------------------------------------------
|
||||
| 定时任务调度 |
|
||||
| 兼容Linux crontab时间格式语法,最小粒度可精确到每秒 |
|
||||
| 支持通过HTTP、SSH协议触发任务执行 |
|
||||
定时任务调度
|
||||
兼容Linux crontab时间格式语法,最小粒度可精确到每秒
|
||||
支持通过HTTP、SSH协议触发任务执行
|
||||
--------------------------------------------------------*/
|
||||
|
||||
import (
|
||||
|
|
|
@ -2,29 +2,14 @@ package service
|
|||
|
||||
import (
|
||||
"scheduler/models"
|
||||
"scheduler/utils"
|
||||
"scheduler/modules/utils"
|
||||
"net/http"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"time"
|
||||
"scheduler/modules/crontask"
|
||||
)
|
||||
|
||||
func initHosts() []models.Host {
|
||||
// 获取所有主机
|
||||
hostModel := new(models.Host)
|
||||
list, err := hostModel.List()
|
||||
if err != nil {
|
||||
utils.RecordLog("获取主机列表失败-", err.Error())
|
||||
return nil
|
||||
}
|
||||
if len(list) == 0 {
|
||||
utils.RecordLog("主机列表为空")
|
||||
return nil
|
||||
}
|
||||
|
||||
return list
|
||||
}
|
||||
|
||||
type Task struct {}
|
||||
|
||||
// 初始化任务,从数据库取出所有任务添加到定时任务
|
||||
|
@ -60,7 +45,7 @@ func(task *Task) Add(taskModel models.Task) {
|
|||
utils.RecordLog("任务协议不存在-协议编号: ", taskModel.Protocol)
|
||||
}
|
||||
if (taskFunc != nil) {
|
||||
utils.DefaultCronTask.Add(strconv.Itoa(taskModel.Id), taskModel.Spec, taskFunc)
|
||||
crontask.DefaultCronTask.Add(strconv.Itoa(taskModel.Id), taskModel.Spec, taskFunc)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,4 +94,6 @@ func(h *HTTPHandler) Run(taskModel models.Task) {
|
|||
type SSHHandler struct {}
|
||||
|
||||
// 执行SSH任务
|
||||
func(ssh *SSHHandler) Run(taskModel models.Task) {}
|
||||
func(ssh *SSHHandler) Run(taskModel models.Task) {
|
||||
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
package app
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
AppDir string // 应用根目录
|
||||
ConfDir string // 配置目录
|
||||
LogDir string // 日志目录
|
||||
DataDir string // 数据目录,存放session文件等
|
||||
AppConfig string // 应用配置文件
|
||||
Installed bool // 应用是否安装过
|
||||
)
|
||||
|
||||
func init() {
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
AppDir = wd
|
||||
ConfDir = AppDir + "/conf"
|
||||
LogDir = AppDir + "/log"
|
||||
DataDir = AppDir + "/data"
|
||||
AppConfig = AppDir + "/app.ini"
|
||||
checkDirExists(ConfDir, LogDir, DataDir)
|
||||
Installed = isInstalled()
|
||||
}
|
||||
|
||||
// 判断应用是否安装过
|
||||
func isInstalled() bool {
|
||||
_, err := os.Stat(ConfDir + "/install.lock")
|
||||
if os.IsExist(err) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// 检测目录是否存在
|
||||
func checkDirExists(path... string) {
|
||||
for _, value := range(path) {
|
||||
_, err := os.Stat(value)
|
||||
if os.IsNotExist(err) {
|
||||
panic(value + "目录不存在")
|
||||
}
|
||||
if os.IsPermission(err) {
|
||||
panic(value + "目录无权限操作")
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue