解决循环依赖

pull/21/merge
ouqiang 2017-03-14 14:31:46 +08:00
parent f39d0ac508
commit b0909706ec
15 changed files with 132 additions and 148 deletions

3
.gitignore vendored
View File

@ -25,4 +25,5 @@ _testmain.go
.idea .idea
data/* data/*
log/* log/*
conf/install.lock

View File

@ -6,9 +6,7 @@ import (
"github.com/go-macaron/gzip" "github.com/go-macaron/gzip"
"github.com/go-macaron/session" "github.com/go-macaron/session"
"github.com/go-macaron/csrf" "github.com/go-macaron/csrf"
"scheduler/utils" "scheduler/modules/app"
"fmt"
"scheduler/utils/app"
) )
// web服务器默认端口 // web服务器默认端口
@ -31,7 +29,7 @@ var CmdWeb = cli.Command{
func run(ctx *cli.Context) { func run(ctx *cli.Context) {
// 检测环境 // 检测环境
utils.CheckEnv() app.CheckEnv()
// 启动定时任务 // 启动定时任务
runScheduler() runScheduler()
m := macaron.Classic() m := macaron.Classic()
@ -44,7 +42,9 @@ func run(ctx *cli.Context) {
} }
// 定时任务调度 // 定时任务调度
func runScheduler() {} func runScheduler() {
}
// 路由注册 // 路由注册
func registerRouter(m *macaron.Macaron) { func registerRouter(m *macaron.Macaron) {

View File

@ -1,8 +0,0 @@
[db]
password = wozaixiamen
charset = utf8
database = cron
host = 127.0.0.1
port = 3306
user = root
prefix =

View File

@ -1,5 +1,6 @@
package models package models
// 主机 // 主机
type Host struct { type Host struct {
Id int16 `xorm:"smallint pk autoincr"` Id int16 `xorm:"smallint pk autoincr"`

View File

@ -3,24 +3,17 @@ package models
import ( import (
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
"fmt" "fmt"
"scheduler/utils/setting" "scheduler/modules/setting"
"github.com/go-xorm/core" "github.com/go-xorm/core"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
"gopkg.in/macaron.v1" "gopkg.in/macaron.v1"
"scheduler/utils/app"
) )
var Db *xorm.Engine
func init() {
if app.Installed {
Db = createDb()
}
}
type Status int8 type Status int8
type CommonMap map[string]interface{} type CommonMap map[string]interface{}
var Db *xorm.Engine
const ( const (
Disabled Status = 0 // 禁用 Disabled Status = 0 // 禁用
Failure Status = 0 // 失败 Failure Status = 0 // 失败
@ -36,8 +29,8 @@ const (
) )
// 创建Db // 创建Db
func createDb() *xorm.Engine{ func CreateDb(configFile string) *xorm.Engine{
config,err := setting.Read() config,err := setting.Read(configFile)
if err != nil { if err != nil {
panic(err) panic(err)
} }

View File

@ -1,6 +1,8 @@
package models package models
import "time" import (
"time"
)
type TaskLog struct{ type TaskLog struct{
Id int `xorm:"pk autoincr"` Id int `xorm:"pk autoincr"`

View File

@ -2,7 +2,7 @@ package models
import ( import (
"time" "time"
"scheduler/utils" "scheduler/modules/utils"
) )
const PasswordSaltLength = 6; const PasswordSaltLength = 6;

View File

@ -4,18 +4,12 @@ package ansible
import ( import (
"os" "os"
"scheduler/utils" "scheduler/modules/utils"
"errors" "errors"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
"scheduler/utils/app"
) )
func init() {
// ansible配置文件目录
os.Setenv("ANSIBLE_CONFIG", app.ConfDir)
}
type Handler map[string]interface{} type Handler map[string]interface{}
type Playbook struct { type Playbook struct {

95
modules/app/app.go Normal file
View File

@ -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 + "目录无权限操作")
}
}
}

View File

@ -1,25 +1,22 @@
package utils package crontask
import ( import (
"github.com/robfig/cron" "github.com/robfig/cron"
"errors" "errors"
"scheduler/utils/app"
"sync" "sync"
) )
var DefaultCronTask CronTask; var DefaultCronTask *CronTask
type CronTask struct { type CronTask struct {
sync.RWMutex sync.RWMutex
tasks map[string]*cron.Cron tasks map[string]*cron.Cron
} }
func init() { func CreateCronTask() *CronTask {
if app.Installed { return &CronTask {
DefaultCronTask = CronTask{ sync.RWMutex{},
sync.RWMutex{}, make(map[string]*cron.Cron),
make(map[string]*cron.Cron),
}
} }
} }

View File

@ -3,12 +3,11 @@ package setting
import ( import (
"gopkg.in/ini.v1" "gopkg.in/ini.v1"
"errors" "errors"
"scheduler/utils/app"
) )
// 读取配置 // 读取配置
func Read() (config *ini.File, err error) { func Read(filename string) (config *ini.File, err error) {
config, err = ini.Load(app.AppConfig) config, err = ini.Load(filename)
if err != nil { if err != nil {
return 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 { if len(config) == 0 {
return errors.New("参数不能为空") 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 return err
} }

View File

@ -7,34 +7,8 @@ import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"log" "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命令 // 执行shell命令
func ExecShell(command string, args... string) (string, error) { func ExecShell(command string, args... string) (string, error) {

View File

@ -1,9 +1,9 @@
package main package main
/*-------------------------------------------------------- /*--------------------------------------------------------
| |
| Linux crontab | Linux crontab
| HTTPSSH | HTTPSSH
--------------------------------------------------------*/ --------------------------------------------------------*/
import ( import (

View File

@ -2,29 +2,14 @@ package service
import ( import (
"scheduler/models" "scheduler/models"
"scheduler/utils" "scheduler/modules/utils"
"net/http" "net/http"
"io/ioutil" "io/ioutil"
"strconv" "strconv"
"time" "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 {} type Task struct {}
// 初始化任务,从数据库取出所有任务添加到定时任务 // 初始化任务,从数据库取出所有任务添加到定时任务
@ -60,7 +45,7 @@ func(task *Task) Add(taskModel models.Task) {
utils.RecordLog("任务协议不存在-协议编号: ", taskModel.Protocol) utils.RecordLog("任务协议不存在-协议编号: ", taskModel.Protocol)
} }
if (taskFunc != nil) { 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 {} type SSHHandler struct {}
// 执行SSH任务 // 执行SSH任务
func(ssh *SSHHandler) Run(taskModel models.Task) {} func(ssh *SSHHandler) Run(taskModel models.Task) {
}

View File

@ -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 + "目录无权限操作")
}
}
}