mirror of https://github.com/ouqiang/gocron
代码重构
parent
0f41bc6a65
commit
e8351141c0
|
@ -43,7 +43,6 @@ func run(ctx *cli.Context) {
|
|||
|
||||
// 定时任务调度
|
||||
func runScheduler() {
|
||||
|
||||
}
|
||||
|
||||
// 路由注册
|
||||
|
|
|
@ -3,4 +3,6 @@
|
|||
; 默认不收集远程主机信息
|
||||
gathering = explicit
|
||||
; 默认模块
|
||||
module_name = shell
|
||||
module_name = shell
|
||||
|
||||
host_key_checking = false
|
|
@ -5,13 +5,23 @@ package models
|
|||
type Host struct {
|
||||
Id int16 `xorm:"smallint pk autoincr"`
|
||||
Name string `xorm:"varchar(128) notnull"` // 主机名称
|
||||
Alias string `xorm:"varchar(32) notnull default '' "` // 主机别名,仅用于后台显示
|
||||
Port int `xorm:"notnull"` // 主机端口
|
||||
Alias string `xorm:"varchar(32) notnull default '' "` // 主机别名
|
||||
Username string `xorm:"varchar(32) notnull default '' "` // ssh 用户名
|
||||
Password string `xorm:"varchar(64) notnull default ''"` // ssh 密码
|
||||
Port int `xorm:"notnull default 22"` // 主机端口
|
||||
LoginType LoginType `xorm:"tinyint notnull default 1"` // ssh登录方式 1:公钥认证 2:账号密码
|
||||
Remark string `xorm:"varchar(512) notnull default '' "` // 备注
|
||||
Page int `xorm:"-"`
|
||||
PageSize int `xorm:"-"`
|
||||
}
|
||||
|
||||
type LoginType int8;
|
||||
|
||||
const (
|
||||
PublicKey = 1
|
||||
UserPassword = 2
|
||||
)
|
||||
|
||||
// 新增
|
||||
func(host *Host) Create() (int64, error) {
|
||||
return Db.Insert(host)
|
||||
|
|
|
@ -11,17 +11,18 @@ const (
|
|||
SSH Protocol = 2
|
||||
)
|
||||
|
||||
// 任务
|
||||
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
|
||||
Spec string `xorm:"varchar(64) notnull"` // crontab 时间格式
|
||||
Protocol Protocol `xorm:"tinyint notnull"` // 协议 1:http 2:ssh
|
||||
Type int8 `xorm:"tinyint notnull default 1"` // 任务类型 1: 定时任务 2: 延时任务
|
||||
Command string `xorm:"varchar(512) notnull"` // URL地址或shell命令
|
||||
Timeout int `xorm:"mediumint notnull default 0"` // 执行超时时间(单位秒),0不限制, 限制不能超过一周
|
||||
SshHostGroup string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名组
|
||||
Timeout int `xorm:"mediumint notnull default 0"` // 定时任务:执行超时时间(单位秒),0不限制 延时任务: 延时timeout秒后执行
|
||||
SshHosts string `xorm:"varchar(512) notnull defalut '' "` // SSH主机名, host id,逗号分隔
|
||||
Remark string `xorm:"varchar(512) notnull default ''"` // 备注
|
||||
Created time.Time `xorm:"datetime notnull created"` // 创建时间
|
||||
Updated time.Time `xorm:"datetime updated"` // 更新时间
|
||||
Deleted time.Time `xorm:"datetime deleted"` // 删除时间
|
||||
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:正常 0:停止
|
||||
Page int `xorm:"-"`
|
||||
|
|
|
@ -4,17 +4,14 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// 任务执行日志
|
||||
type TaskLog struct{
|
||||
Id int `xorm:"pk autoincr"`
|
||||
Name string `xorm:"varchar(64) notnull"` // 任务名称
|
||||
Protocol Protocol `xorm:"tinyint notnull "` // 协议
|
||||
Command string `xorm:"varchar(512) notnull"` // URL或shell命令
|
||||
Remark string `xorm:"varchar(512) notnull default ''"` // 备注
|
||||
SshHosts string `xorm:"varchar(512) notnull default ''"`
|
||||
Id int `xorm:"int pk autoincr"`
|
||||
TaskId int `xorm:"int not null"` // 任务ID
|
||||
StartTime time.Time `xorm:"datetime created"` // 开始执行时间
|
||||
EndTime time.Time `xorm:"datetime updated"` // 执行完成(失败)时间
|
||||
Status Status `xorm:"tinyint notnull default 1"` // 状态 1:执行中 2:执行完毕 0:执行失败
|
||||
Result string `xorm:"varchar(65535) notnull defalut '' "`
|
||||
Result string `xorm:"varchar(65535) notnull defalut '' "` // 执行结果
|
||||
Page int `xorm:"-"`
|
||||
PageSize int `xorm:"-"`
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@ const PasswordSaltLength = 6;
|
|||
// 用户model
|
||||
type User struct {
|
||||
Id int `xorm:"pk autoincr notnull "`
|
||||
Name string `xorm:"varchar(32) notnull unique"`
|
||||
Password string `xorm:"char(32) notnull "`
|
||||
Salt string `xorm:"char(6) notnull "`
|
||||
Email string `xorm:"varchar(50) notnull unique default '' "`
|
||||
Name string `xorm:"varchar(32) notnull unique"` // 用户名
|
||||
Password string `xorm:"char(32) notnull "` // 密码
|
||||
Salt string `xorm:"char(6) notnull "` // 密码盐值
|
||||
Email string `xorm:"varchar(50) notnull unique default '' "` // 邮箱
|
||||
Created time.Time `xorm:"datetime notnull created"`
|
||||
Updated time.Time `xorm:"datetime updated"`
|
||||
Deleted time.Time `xorm:"datetime deleted"`
|
||||
|
|
|
@ -39,18 +39,26 @@ func(playbook *Playbook) AddHandler(handler Handler) {
|
|||
|
||||
/**
|
||||
* 执行ad-hoc
|
||||
* hosts 主机文件路径
|
||||
* hosts 主机名 逗号分隔
|
||||
* module 调用模块
|
||||
* args 传递给模块的参数
|
||||
*/
|
||||
func ExecCommand(hostPath string, module string, args... string) (output string, err error) {
|
||||
if hostPath == "" || module == "" {
|
||||
func ExecCommand(hosts string, module string, args... string) (output string, err error) {
|
||||
if hosts== "" || module == "" {
|
||||
err = errors.New("参数不完整")
|
||||
return
|
||||
}
|
||||
commandArgs := []string{"-i", , hostPath, "-m", module}
|
||||
hostFile, err := DefaultHosts.GetHostFile()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
os.Remove(hostFile)
|
||||
}()
|
||||
commandArgs := []string{hosts, "-i", hostFile, "-m", module}
|
||||
if len(args) != 0 {
|
||||
commandArgs = append(commandArgs, "-a", args...)
|
||||
commandArgs = append(commandArgs, "-a")
|
||||
commandArgs = append(commandArgs, args...)
|
||||
}
|
||||
output, err = utils.ExecShell("ansible", commandArgs...)
|
||||
|
||||
|
@ -58,32 +66,37 @@ func ExecCommand(hostPath string, module string, args... string) (output string,
|
|||
}
|
||||
|
||||
// 执行playbook
|
||||
func ExecPlaybook(hostPath string, playbook Playbook) (result string, err error) {
|
||||
func ExecPlaybook(playbook Playbook) (result string, err error) {
|
||||
data, err := yaml.Marshal([]Playbook{playbook})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
tmpFile, err := ioutil.TempFile(getTmpDir(), "playbook")
|
||||
playbookFile, err := ioutil.TempFile(GetTmpDir(), "playbook")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hostFile, err := DefaultHosts.GetHostFile()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer func() {
|
||||
tmpFile.Close()
|
||||
os.Remove(tmpFile.Name())
|
||||
playbookFile.Close()
|
||||
os.Remove(playbookFile.Name())
|
||||
os.Remove(hostFile)
|
||||
}()
|
||||
_, err = tmpFile.Write(data)
|
||||
_, err = playbookFile.Write(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
commandArgs := []string{"-i", hostPath, tmpFile.Name()}
|
||||
commandArgs := []string{"-i", hostFile, playbookFile.Name()}
|
||||
result, err = utils.ExecShell("ansible-playbook", commandArgs...)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// 判断 获取临时目录,默认/dev/shm
|
||||
func getTmpDir() string {
|
||||
func GetTmpDir() string {
|
||||
dir := "/dev/shm"
|
||||
_, err := os.Stat(dir)
|
||||
if os.IsPermission(err) {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
package ansible
|
||||
|
||||
import (
|
||||
"scheduler/models"
|
||||
"sync"
|
||||
"io/ioutil"
|
||||
"bytes"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// 主机名
|
||||
var DefaultHosts *Hosts
|
||||
|
||||
type Hosts struct {
|
||||
sync.RWMutex
|
||||
hosts []models.Host
|
||||
}
|
||||
|
||||
func(h *Hosts) Get() []models.Host {
|
||||
h.RLock()
|
||||
defer h.RUnlock()
|
||||
|
||||
return h.hosts
|
||||
}
|
||||
|
||||
func(h *Hosts) Set(hostsModel []models.Host) {
|
||||
h.Lock()
|
||||
defer h.Unlock()
|
||||
|
||||
h.hosts = hostsModel
|
||||
}
|
||||
|
||||
// 获取hosts文件名
|
||||
func(h *Hosts) GetHostFile() (filename string ,err error) {
|
||||
buffer := bytes.Buffer{}
|
||||
for _, hostModel := range(h.hosts) {
|
||||
buffer.WriteString(strconv.Itoa(int(hostModel.Id)))
|
||||
buffer.WriteString(" ansible_ssh_host=")
|
||||
buffer.WriteString(hostModel.Name)
|
||||
buffer.WriteString(" ansible_ssh_port=")
|
||||
buffer.WriteString(strconv.Itoa(hostModel.Port))
|
||||
buffer.WriteString(" ansible_ssh_user=")
|
||||
buffer.WriteString(hostModel.Username)
|
||||
if (hostModel.LoginType != models.PublicKey && hostModel.Password != "") {
|
||||
buffer.WriteString(" ansible_ssh_pass=")
|
||||
buffer.WriteString(hostModel.Password)
|
||||
}
|
||||
buffer.WriteString("\n")
|
||||
}
|
||||
tmpFile, err := ioutil.TempFile(GetTmpDir(), "host")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
defer func() {
|
||||
tmpFile.Close()
|
||||
}()
|
||||
|
||||
_, err = tmpFile.WriteString(buffer.String())
|
||||
if err == nil {
|
||||
filename = tmpFile.Name()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -6,6 +6,7 @@ import (
|
|||
"scheduler/models"
|
||||
"runtime"
|
||||
"scheduler/modules/utils"
|
||||
"scheduler/modules/ansible"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -14,8 +15,8 @@ var (
|
|||
LogDir string // 日志目录
|
||||
DataDir string // 数据目录,存放session文件等
|
||||
AppConfig string // 应用配置文件
|
||||
AnsibleHosts string // ansible hosts文件
|
||||
Installed bool // 应用是否安装过
|
||||
CronTask crontask.CronTask // 定时任务
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -27,7 +28,8 @@ func init() {
|
|||
ConfDir = AppDir + "/conf"
|
||||
LogDir = AppDir + "/log"
|
||||
DataDir = AppDir + "/data"
|
||||
AppConfig = AppDir + "/app.ini"
|
||||
AppConfig = ConfDir + "/app.ini"
|
||||
AnsibleHosts = ConfDir + "/ansible_hosts.ini"
|
||||
checkDirExists(ConfDir, LogDir, DataDir)
|
||||
// ansible配置文件目录
|
||||
os.Setenv("ANSIBLE_CONFIG", ConfDir)
|
||||
|
@ -59,7 +61,7 @@ func CheckEnv() {
|
|||
}
|
||||
_, err = utils.ExecShell("ansible-playbook", "--version")
|
||||
if err != nil {
|
||||
panic("ansible-playbook not found")
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,9 +78,16 @@ func CreateInstallLock() error {
|
|||
|
||||
// 初始化资源
|
||||
func initResource() {
|
||||
crontask.DefaultCronTask = crontask.CreateCronTask()
|
||||
|
||||
crontask.DefaultCronTask = crontask.NewCronTask()
|
||||
models.Db = models.CreateDb(AppConfig)
|
||||
ansible.DefaultHosts = &ansible.Hosts{}
|
||||
hostModel := new(models.Host)
|
||||
hosts, err := hostModel.List()
|
||||
if err != nil {
|
||||
utils.RecordLog(err)
|
||||
} else {
|
||||
ansible.DefaultHosts.Set(hosts)
|
||||
}
|
||||
}
|
||||
|
||||
// 检测目录是否存在
|
||||
|
|
|
@ -13,7 +13,7 @@ type CronTask struct {
|
|||
tasks map[string]*cron.Cron
|
||||
}
|
||||
|
||||
func CreateCronTask() *CronTask {
|
||||
func NewCronTask() *CronTask {
|
||||
return &CronTask {
|
||||
sync.RWMutex{},
|
||||
make(map[string]*cron.Cron),
|
||||
|
|
|
@ -53,9 +53,9 @@ type Handler interface {
|
|||
Run(taskModel models.Task)
|
||||
}
|
||||
|
||||
// HTTP任务
|
||||
type HTTPHandler struct {}
|
||||
|
||||
// 执行HTTP任务
|
||||
func(h *HTTPHandler) Run(taskModel models.Task) {
|
||||
client := &http.Client{}
|
||||
if (taskModel.Timeout > 0) {
|
||||
|
@ -91,9 +91,18 @@ func(h *HTTPHandler) Run(taskModel models.Task) {
|
|||
}
|
||||
}
|
||||
|
||||
// SSH任务
|
||||
type SSHHandler struct {}
|
||||
|
||||
// 执行SSH任务
|
||||
func(ssh *SSHHandler) Run(taskModel models.Task) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 延时任务
|
||||
type DelayHandler struct {}
|
||||
|
||||
func (handler *DelayHandler) Run(taskModel models.Task) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue