mirror of https://github.com/ouqiang/gocron
style: 代码格式化
parent
21028ec6f0
commit
f0ff9a88a7
16
cmd/web.go
16
cmd/web.go
|
@ -1,25 +1,24 @@
|
||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/app"
|
"github.com/ouqiang/gocron/modules/app"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/rpc/grpcpool"
|
||||||
|
"github.com/ouqiang/gocron/modules/setting"
|
||||||
"github.com/ouqiang/gocron/routers"
|
"github.com/ouqiang/gocron/routers"
|
||||||
|
"github.com/ouqiang/gocron/service"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"github.com/ouqiang/gocron/service"
|
|
||||||
"github.com/ouqiang/gocron/models"
|
|
||||||
"github.com/ouqiang/gocron/modules/setting"
|
|
||||||
"time"
|
"time"
|
||||||
"github.com/ouqiang/gocron/modules/rpc/grpcpool"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// web服务器默认端口
|
// web服务器默认端口
|
||||||
const DefaultPort = 5920
|
const DefaultPort = 5920
|
||||||
|
|
||||||
|
|
||||||
var CmdWeb = cli.Command{
|
var CmdWeb = cli.Command{
|
||||||
Name: "web",
|
Name: "web",
|
||||||
Usage: "run web server",
|
Usage: "run web server",
|
||||||
|
@ -128,7 +127,7 @@ func catchSignal() {
|
||||||
// todo 配置热更新, windows 不支持 syscall.SIGUSR1, syscall.SIGUSR2
|
// todo 配置热更新, windows 不支持 syscall.SIGUSR1, syscall.SIGUSR2
|
||||||
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(c, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM)
|
||||||
for {
|
for {
|
||||||
s := <- c
|
s := <-c
|
||||||
logger.Info("收到信号 -- ", s)
|
logger.Info("收到信号 -- ", s)
|
||||||
switch s {
|
switch s {
|
||||||
case syscall.SIGHUP:
|
case syscall.SIGHUP:
|
||||||
|
@ -139,7 +138,6 @@ func catchSignal() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 应用退出
|
// 应用退出
|
||||||
func shutdown() {
|
func shutdown() {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -178,7 +176,7 @@ func upgradeIfNeed() {
|
||||||
currentVersionId := app.GetCurrentVersionId()
|
currentVersionId := app.GetCurrentVersionId()
|
||||||
// 没有版本号文件
|
// 没有版本号文件
|
||||||
if currentVersionId == 0 {
|
if currentVersionId == 0 {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if currentVersionId >= app.VersionId {
|
if currentVersionId >= app.VersionId {
|
||||||
return
|
return
|
||||||
|
|
|
@ -4,14 +4,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ouqiang/gocron/modules/rpc/server"
|
|
||||||
"flag"
|
"flag"
|
||||||
"runtime"
|
|
||||||
"os"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
|
||||||
"github.com/ouqiang/gocron/modules/rpc/auth"
|
"github.com/ouqiang/gocron/modules/rpc/auth"
|
||||||
|
"github.com/ouqiang/gocron/modules/rpc/server"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const AppVersion = "1.2.2"
|
const AppVersion = "1.2.2"
|
||||||
|
@ -38,7 +38,7 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enableTLS) {
|
if enableTLS {
|
||||||
if !utils.FileExist(CAFile) {
|
if !utils.FileExist(CAFile) {
|
||||||
fmt.Printf("failed to read ca cert file: %s", CAFile)
|
fmt.Printf("failed to read ca cert file: %s", CAFile)
|
||||||
return
|
return
|
||||||
|
@ -59,12 +59,10 @@ func main() {
|
||||||
KeyFile: strings.TrimSpace(keyFile),
|
KeyFile: strings.TrimSpace(keyFile),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if runtime.GOOS != "windows" && os.Getuid() == 0 && !allowRoot {
|
if runtime.GOOS != "windows" && os.Getuid() == 0 && !allowRoot {
|
||||||
fmt.Println("Do not run gocron-node as root user")
|
fmt.Println("Do not run gocron-node as root user")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
server.Start(serverAddr, enableTLS, certificate)
|
server.Start(serverAddr, enableTLS, certificate)
|
||||||
}
|
}
|
|
@ -29,7 +29,6 @@ func (host *Host) UpdateBean(id int16) (int64, error) {
|
||||||
return Db.ID(id).Cols("name,alias,port,remark").Update(host)
|
return Db.ID(id).Cols("name,alias,port,remark").Update(host)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
func (host *Host) Update(id int, data CommonMap) (int64, error) {
|
func (host *Host) Update(id int, data CommonMap) (int64, error) {
|
||||||
return Db.Table(host).ID(id).Update(data)
|
return Db.Table(host).ID(id).Update(data)
|
||||||
|
@ -48,11 +47,11 @@ func (host *Host) Find(id int) error {
|
||||||
|
|
||||||
func (host *Host) NameExists(name string, id int16) (bool, error) {
|
func (host *Host) NameExists(name string, id int16) (bool, error) {
|
||||||
if id == 0 {
|
if id == 0 {
|
||||||
count, err := Db.Where("name = ?", name).Count(host);
|
count, err := Db.Where("name = ?", name).Count(host)
|
||||||
return count > 0, err
|
return count > 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := Db.Where("name = ? AND id != ?", name, id).Count(host);
|
count, err := Db.Where("name = ? AND id != ?", name, id).Count(host)
|
||||||
return count > 0, err
|
return count > 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,11 @@ package models
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Migration struct{}
|
type Migration struct{}
|
||||||
|
|
||||||
// 首次安装, 创建数据库表
|
// 首次安装, 创建数据库表
|
||||||
|
@ -19,10 +18,10 @@ func (migration *Migration) Install(dbName string) error {
|
||||||
setting := new(Setting)
|
setting := new(Setting)
|
||||||
task := new(Task)
|
task := new(Task)
|
||||||
tables := []interface{}{
|
tables := []interface{}{
|
||||||
&User{}, task, &TaskLog{}, &Host{}, setting,&LoginLog{},&TaskHost{},
|
&User{}, task, &TaskLog{}, &Host{}, setting, &LoginLog{}, &TaskHost{},
|
||||||
}
|
}
|
||||||
for _, table := range tables {
|
for _, table := range tables {
|
||||||
exist, err:= Db.IsTableExist(table)
|
exist, err := Db.IsTableExist(table)
|
||||||
if exist {
|
if exist {
|
||||||
return errors.New("数据表已存在")
|
return errors.New("数据表已存在")
|
||||||
}
|
}
|
||||||
|
@ -55,7 +54,7 @@ func (migration *Migration) Upgrade(oldVersionId int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
versionIds := []int{110, 122}
|
versionIds := []int{110, 122}
|
||||||
upgradeFuncs := []func(*xorm.Session) error {
|
upgradeFuncs := []func(*xorm.Session) error{
|
||||||
migration.upgradeFor110,
|
migration.upgradeFor110,
|
||||||
migration.upgradeFor122,
|
migration.upgradeFor122,
|
||||||
}
|
}
|
||||||
|
@ -65,7 +64,7 @@ func (migration *Migration) Upgrade(oldVersionId int) {
|
||||||
for i, value := range versionIds {
|
for i, value := range versionIds {
|
||||||
if value > oldVersionId {
|
if value > oldVersionId {
|
||||||
startIndex = i
|
startIndex = i
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +90,7 @@ func (migration *Migration) Upgrade(oldVersionId int) {
|
||||||
}
|
}
|
||||||
dbErr := session.Rollback()
|
dbErr := session.Rollback()
|
||||||
if dbErr != nil {
|
if dbErr != nil {
|
||||||
logger.Fatalf("事务回滚失败-%s",dbErr.Error())
|
logger.Fatalf("事务回滚失败-%s", dbErr.Error())
|
||||||
}
|
}
|
||||||
logger.Fatal(err)
|
logger.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -136,7 +135,6 @@ func (migration *Migration) upgradeFor110(session *xorm.Session) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 删除task表host_id字段
|
// 删除task表host_id字段
|
||||||
_, err = session.Exec(fmt.Sprintf("ALTER TABLE %s DROP COLUMN host_id", tableName))
|
_, err = session.Exec(fmt.Sprintf("ALTER TABLE %s DROP COLUMN host_id", tableName))
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,12 @@ import (
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
"github.com/ouqiang/gocron/modules/app"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/setting"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
"strings"
|
"strings"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"github.com/ouqiang/gocron/modules/app"
|
|
||||||
"time"
|
"time"
|
||||||
"github.com/ouqiang/gocron/modules/setting"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Status int8
|
type Status int8
|
||||||
|
@ -107,7 +107,7 @@ func getDbEngineDSN(setting *setting.Setting) string {
|
||||||
setting.Db.User,
|
setting.Db.User,
|
||||||
setting.Db.Password,
|
setting.Db.Password,
|
||||||
setting.Db.Host,
|
setting.Db.Host,
|
||||||
setting.Db.Port ,
|
setting.Db.Port,
|
||||||
setting.Db.Database,
|
setting.Db.Database,
|
||||||
setting.Db.Charset)
|
setting.Db.Charset)
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ func getDbEngineDSN(setting *setting.Setting) string {
|
||||||
func keepDbAlived(engine *xorm.Engine) {
|
func keepDbAlived(engine *xorm.Engine) {
|
||||||
t := time.Tick(180 * time.Second)
|
t := time.Tick(180 * time.Second)
|
||||||
for {
|
for {
|
||||||
<- t
|
<-t
|
||||||
engine.Ping()
|
engine.Ping()
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -21,7 +21,7 @@ const MailUserKey = "user"
|
||||||
|
|
||||||
// 初始化基本字段 邮件、slack等
|
// 初始化基本字段 邮件、slack等
|
||||||
func (setting *Setting) InitBasicField() {
|
func (setting *Setting) InitBasicField() {
|
||||||
setting.Code = SlackCode;
|
setting.Code = SlackCode
|
||||||
setting.Key = SlackUrlKey
|
setting.Key = SlackUrlKey
|
||||||
Db.Insert(setting)
|
Db.Insert(setting)
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ type Channel struct {
|
||||||
func (setting *Setting) Slack() (Slack, error) {
|
func (setting *Setting) Slack() (Slack, error) {
|
||||||
list := make([]Setting, 0)
|
list := make([]Setting, 0)
|
||||||
err := Db.Where("code = ?", SlackCode).Find(&list)
|
err := Db.Where("code = ?", SlackCode).Find(&list)
|
||||||
slack := Slack{Url:"", Channels:make([]Channel, 0)}
|
slack := Slack{Url: "", Channels: make([]Channel, 0)}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return slack, err
|
return slack, err
|
||||||
}
|
}
|
||||||
|
@ -73,10 +73,9 @@ func (setting *Setting) formatSlack(list []Setting, slack *Slack) {
|
||||||
func (setting *Setting) UpdateSlackUrl(url string) (int64, error) {
|
func (setting *Setting) UpdateSlackUrl(url string) (int64, error) {
|
||||||
setting.Value = url
|
setting.Value = url
|
||||||
|
|
||||||
return Db.Cols("value").Update(setting, Setting{Code:SlackCode, Key:SlackUrlKey})
|
return Db.Cols("value").Update(setting, Setting{Code: SlackCode, Key: SlackUrlKey})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 创建slack渠道
|
// 创建slack渠道
|
||||||
func (setting *Setting) CreateChannel(channel string) (int64, error) {
|
func (setting *Setting) CreateChannel(channel string) (int64, error) {
|
||||||
setting.Code = SlackCode
|
setting.Code = SlackCode
|
||||||
|
@ -86,7 +85,7 @@ func (setting *Setting) CreateChannel(channel string) (int64, error) {
|
||||||
return Db.Insert(setting)
|
return Db.Insert(setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (setting *Setting) IsChannelExist(channel string) (bool) {
|
func (setting *Setting) IsChannelExist(channel string) bool {
|
||||||
setting.Code = SlackCode
|
setting.Code = SlackCode
|
||||||
setting.Key = SlackChannelKey
|
setting.Key = SlackChannelKey
|
||||||
setting.Value = channel
|
setting.Value = channel
|
||||||
|
@ -124,7 +123,7 @@ type MailUser struct {
|
||||||
func (setting *Setting) Mail() (Mail, error) {
|
func (setting *Setting) Mail() (Mail, error) {
|
||||||
list := make([]Setting, 0)
|
list := make([]Setting, 0)
|
||||||
err := Db.Where("code = ?", MailCode).Find(&list)
|
err := Db.Where("code = ?", MailCode).Find(&list)
|
||||||
mail := Mail{MailUsers:make([]MailUser, 0)}
|
mail := Mail{MailUsers: make([]MailUser, 0)}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return mail, err
|
return mail, err
|
||||||
}
|
}
|
||||||
|
@ -149,7 +148,7 @@ func (setting *Setting) formatMail(list []Setting, mail *Mail) {
|
||||||
|
|
||||||
func (setting *Setting) UpdateMailServer(config string) (int64, error) {
|
func (setting *Setting) UpdateMailServer(config string) (int64, error) {
|
||||||
setting.Value = config
|
setting.Value = config
|
||||||
return Db.Cols("value").Update(setting, Setting{Code:MailCode, Key:MailServerKey})
|
return Db.Cols("value").Update(setting, Setting{Code: MailCode, Key: MailServerKey})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (setting *Setting) CreateMailUser(username, email string) (int64, error) {
|
func (setting *Setting) CreateMailUser(username, email string) (int64, error) {
|
||||||
|
@ -171,4 +170,5 @@ func (setting *Setting) RemoveMailUser(id int) (int64, error) {
|
||||||
setting.Id = id
|
setting.Id = id
|
||||||
return Db.Delete(setting)
|
return Db.Delete(setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
|
@ -1,10 +1,10 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"github.com/go-xorm/xorm"
|
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/go-xorm/xorm"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TaskProtocol int8
|
type TaskProtocol int8
|
||||||
|
@ -155,10 +155,10 @@ func (task *Task) setHostsForTasks(tasks []Task) ([]Task, error) {
|
||||||
// 判断任务名称是否存在
|
// 判断任务名称是否存在
|
||||||
func (task *Task) NameExist(name string, id int) (bool, error) {
|
func (task *Task) NameExist(name string, id int) (bool, error) {
|
||||||
if id > 0 {
|
if id > 0 {
|
||||||
count, err := Db.Where("name = ? AND status = ? AND id != ?", name, Enabled, id).Count(task);
|
count, err := Db.Where("name = ? AND status = ? AND id != ?", name, Enabled, id).Count(task)
|
||||||
return count > 0, err
|
return count > 0, err
|
||||||
}
|
}
|
||||||
count, err := Db.Where("name = ? AND status = ?", name, Enabled).Count(task);
|
count, err := Db.Where("name = ? AND status = ?", name, Enabled).Count(task)
|
||||||
|
|
||||||
return count > 0, err
|
return count > 0, err
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ func (task *Task) GetStatus(id int) (Status, error) {
|
||||||
return task.Status, nil
|
return task.Status, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func(task *Task) Detail(id int) (Task, error) {
|
func (task *Task) Detail(id int) (Task, error) {
|
||||||
t := Task{}
|
t := Task{}
|
||||||
_, err := Db.Where("id=?", id).Get(&t)
|
_, err := Db.Where("id=?", id).Get(&t)
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ func (task *Task) parseWhere(session *xorm.Session, params CommonMap) {
|
||||||
}
|
}
|
||||||
name, ok := params["Name"]
|
name, ok := params["Name"]
|
||||||
if ok && name.(string) != "" {
|
if ok && name.(string) != "" {
|
||||||
session.And("t.name LIKE ?", "%" + name.(string) + "%")
|
session.And("t.name LIKE ?", "%"+name.(string)+"%")
|
||||||
}
|
}
|
||||||
protocol, ok := params["Protocol"]
|
protocol, ok := params["Protocol"]
|
||||||
if ok && protocol.(int) > 0 {
|
if ok && protocol.(int) > 0 {
|
||||||
|
@ -269,4 +269,3 @@ func (task *Task) parseWhere(session *xorm.Session, params CommonMap) {
|
||||||
session.And("tag = ? ", tag)
|
session.And("tag = ? ", tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
|
|
||||||
type TaskHost struct {
|
type TaskHost struct {
|
||||||
Id int `xorm:"int pk autoincr"`
|
Id int `xorm:"int pk autoincr"`
|
||||||
TaskId int `xorm:"int not null index"`
|
TaskId int `xorm:"int not null index"`
|
||||||
|
@ -75,7 +74,7 @@ func (th *TaskHost) GetTaskIdsByHostId(hostId int16) ([]interface{}, error) {
|
||||||
|
|
||||||
// 判断主机id是否有引用
|
// 判断主机id是否有引用
|
||||||
func (th *TaskHost) HostIdExist(hostId int16) (bool, error) {
|
func (th *TaskHost) HostIdExist(hostId int16) (bool, error) {
|
||||||
count, err := Db.Where("host_id = ?", hostId).Count(th);
|
count, err := Db.Where("host_id = ?", hostId).Count(th)
|
||||||
|
|
||||||
return count > 0, err
|
return count > 0, err
|
||||||
}
|
}
|
|
@ -1,13 +1,12 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TaskType int8
|
type TaskType int8
|
||||||
|
|
||||||
|
|
||||||
// 任务执行日志
|
// 任务执行日志
|
||||||
type TaskLog struct {
|
type TaskLog struct {
|
||||||
Id int64 `xorm:"bigint pk autoincr"`
|
Id int64 `xorm:"bigint pk autoincr"`
|
||||||
|
@ -63,7 +62,7 @@ func (taskLog *TaskLog) List(params CommonMap) ([]TaskLog, error) {
|
||||||
|
|
||||||
// 清空表
|
// 清空表
|
||||||
func (taskLog *TaskLog) Clear() (int64, error) {
|
func (taskLog *TaskLog) Clear() (int64, error) {
|
||||||
return Db.Where("1=1").Delete(taskLog);
|
return Db.Where("1=1").Delete(taskLog)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除N个月前的日志
|
// 删除N个月前的日志
|
||||||
|
|
|
@ -4,11 +4,11 @@ import (
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/setting"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"github.com/ouqiang/gocron/modules/setting"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -23,7 +23,6 @@ var (
|
||||||
VersionFile string // 版本号文件
|
VersionFile string // 版本号文件
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func InitEnv(versionString string) {
|
func InitEnv(versionString string) {
|
||||||
logger.InitLogger()
|
logger.InitLogger()
|
||||||
wd, err := os.Getwd()
|
wd, err := os.Getwd()
|
||||||
|
@ -76,7 +75,7 @@ func UpdateVersionFile() {
|
||||||
// 获取应用当前版本号, 从版本号文件中读取
|
// 获取应用当前版本号, 从版本号文件中读取
|
||||||
func GetCurrentVersionId() int {
|
func GetCurrentVersionId() int {
|
||||||
if !utils.FileExist(VersionFile) {
|
if !utils.FileExist(VersionFile) {
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes, err := ioutil.ReadFile(VersionFile)
|
bytes, err := ioutil.ReadFile(VersionFile)
|
||||||
|
|
|
@ -3,11 +3,11 @@ package httpclient
|
||||||
// http-client
|
// http-client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
"fmt"
|
|
||||||
"bytes"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResponseWrapper struct {
|
type ResponseWrapper struct {
|
||||||
|
@ -25,7 +25,7 @@ func Get(url string, timeout int) ResponseWrapper {
|
||||||
return request(req, timeout)
|
return request(req, timeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
func PostParams(url string,params string, timeout int) ResponseWrapper {
|
func PostParams(url string, params string, timeout int) ResponseWrapper {
|
||||||
buf := bytes.NewBufferString(params)
|
buf := bytes.NewBufferString(params)
|
||||||
req, err := http.NewRequest("POST", url, buf)
|
req, err := http.NewRequest("POST", url, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package logger
|
package logger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/cihub/seelog"
|
"github.com/cihub/seelog"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
package notify
|
package notify
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/go-gomail/gomail"
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
|
||||||
"time"
|
"time"
|
||||||
"github.com/go-gomail/gomail"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// @author qiang.ou<qingqianludao@gmail.com>
|
// @author qiang.ou<qingqianludao@gmail.com>
|
||||||
// @date 2017/5/1-00:19
|
// @date 2017/5/1-00:19
|
||||||
|
|
||||||
|
|
||||||
type Mail struct {
|
type Mail struct {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mail *Mail) Send(msg Message) {
|
func (mail *Mail) Send(msg Message) {
|
||||||
|
@ -61,7 +59,7 @@ func (mail *Mail) send(mailSetting models.Mail, toUsers []string, msg Message)
|
||||||
for i < maxTimes {
|
for i < maxTimes {
|
||||||
err := mailer.DialAndSend(gomailMessage)
|
err := mailer.DialAndSend(gomailMessage)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
i += 1
|
i += 1
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
@ -74,7 +72,7 @@ func (mail *Mail) send(mailSetting models.Mail, toUsers []string, msg Message)
|
||||||
func (mail *Mail) getActiveMailUsers(mailSetting models.Mail, msg Message) []string {
|
func (mail *Mail) getActiveMailUsers(mailSetting models.Mail, msg Message) []string {
|
||||||
taskReceiverIds := strings.Split(msg["task_receiver_id"].(string), ",")
|
taskReceiverIds := strings.Split(msg["task_receiver_id"].(string), ",")
|
||||||
users := []string{}
|
users := []string{}
|
||||||
for _, v := range(mailSetting.MailUsers) {
|
for _, v := range mailSetting.MailUsers {
|
||||||
if utils.InStringSlice(taskReceiverIds, strconv.Itoa(v.Id)) {
|
if utils.InStringSlice(taskReceiverIds, strconv.Itoa(v.Id)) {
|
||||||
users = append(users, v.Email)
|
users = append(users, v.Email)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package notify
|
package notify
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Message map[string]interface{}
|
type Message map[string]interface{}
|
||||||
|
@ -37,7 +37,7 @@ func run() {
|
||||||
}
|
}
|
||||||
msg["content"] = fmt.Sprintf("============\n============\n============\n任务名称: %s\n状态: %s\n输出:\n %s\n", msg["name"], msg["status"], msg["output"])
|
msg["content"] = fmt.Sprintf("============\n============\n============\n任务名称: %s\n状态: %s\n输出:\n %s\n", msg["name"], msg["status"], msg["output"])
|
||||||
logger.Debugf("%+v", msg)
|
logger.Debugf("%+v", msg)
|
||||||
switch(taskType.(int8)) {
|
switch taskType.(int8) {
|
||||||
case 1:
|
case 1:
|
||||||
// 邮件
|
// 邮件
|
||||||
mail := Mail{}
|
mail := Mail{}
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
package notify
|
package notify
|
||||||
|
|
||||||
// 发送消息到slack
|
// 发送消息到slack
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/httpclient"
|
"github.com/ouqiang/gocron/modules/httpclient"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
"strings"
|
|
||||||
"github.com/ouqiang/gocron/models"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Slack struct {}
|
type Slack struct{}
|
||||||
|
|
||||||
func (slack *Slack) Send(msg Message) {
|
func (slack *Slack) Send(msg Message) {
|
||||||
model := new(models.Setting)
|
model := new(models.Setting)
|
||||||
|
@ -32,7 +33,7 @@ func (slack *Slack) Send(msg Message) {
|
||||||
logger.Debugf("%+v", slackSetting)
|
logger.Debugf("%+v", slackSetting)
|
||||||
channels := slack.getActiveSlackChannels(slackSetting, msg)
|
channels := slack.getActiveSlackChannels(slackSetting, msg)
|
||||||
logger.Debugf("%+v", channels)
|
logger.Debugf("%+v", channels)
|
||||||
for _, channel := range(channels) {
|
for _, channel := range channels {
|
||||||
slack.send(msg, slackSetting.Url, channel)
|
slack.send(msg, slackSetting.Url, channel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +46,7 @@ func (slack *Slack) send(msg Message, slackUrl string, channel string) {
|
||||||
for i < maxTimes {
|
for i < maxTimes {
|
||||||
resp := httpclient.PostJson(slackUrl, formatBody, timeout)
|
resp := httpclient.PostJson(slackUrl, formatBody, timeout)
|
||||||
if resp.StatusCode == 200 {
|
if resp.StatusCode == 200 {
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
i += 1
|
i += 1
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
|
@ -58,7 +59,7 @@ func (slack *Slack) send(msg Message, slackUrl string, channel string) {
|
||||||
func (slack *Slack) getActiveSlackChannels(slackSetting models.Slack, msg Message) []string {
|
func (slack *Slack) getActiveSlackChannels(slackSetting models.Slack, msg Message) []string {
|
||||||
taskReceiverIds := strings.Split(msg["task_receiver_id"].(string), ",")
|
taskReceiverIds := strings.Split(msg["task_receiver_id"].(string), ",")
|
||||||
channels := []string{}
|
channels := []string{}
|
||||||
for _, v := range(slackSetting.Channels) {
|
for _, v := range slackSetting.Channels {
|
||||||
if utils.InStringSlice(taskReceiverIds, strconv.Itoa(v.Id)) {
|
if utils.InStringSlice(taskReceiverIds, strconv.Itoa(v.Id)) {
|
||||||
channels = append(channels, v.Name)
|
channels = append(channels, v.Name)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ package auth
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"io/ioutil"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
"io/ioutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Certificate struct {
|
type Certificate struct {
|
||||||
|
@ -33,14 +33,12 @@ func (c Certificate) GetTLSConfigForServer() (*tls.Config, error) {
|
||||||
return nil, errors.New("failed to append client certs")
|
return nil, errors.New("failed to append client certs")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
tlsConfig := &tls.Config{
|
tlsConfig := &tls.Config{
|
||||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||||
Certificates: []tls.Certificate{certificate},
|
Certificates: []tls.Certificate{certificate},
|
||||||
ClientCAs: certPool,
|
ClientCAs: certPool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return tlsConfig, nil
|
return tlsConfig, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,42 +1,27 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/rpc/grpcpool"
|
||||||
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"errors"
|
|
||||||
"github.com/ouqiang/gocron/modules/rpc/grpcpool"
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"google.golang.org/grpc/codes"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errUnavailable = errors.New("无法连接远程服务器")
|
errUnavailable = errors.New("无法连接远程服务器")
|
||||||
)
|
)
|
||||||
|
|
||||||
func ExecWithRetry(ip string, port int, taskReq *pb.TaskRequest) (string, error) {
|
|
||||||
tryTimes := 60
|
|
||||||
i := 0
|
|
||||||
for i < tryTimes {
|
|
||||||
output, err := Exec(ip, port, taskReq)
|
|
||||||
if err != errUnavailable {
|
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
i++
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", errUnavailable
|
|
||||||
}
|
|
||||||
|
|
||||||
func Exec(ip string, port int, taskReq *pb.TaskRequest) (string, error) {
|
func Exec(ip string, port int, taskReq *pb.TaskRequest) (string, error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
logger.Error("panic#rpc/client.go:Exec#", err)
|
logger.Error("panic#rpc/client.go:Exec#", err)
|
||||||
}
|
}
|
||||||
} ()
|
}()
|
||||||
addr := fmt.Sprintf("%s:%d", ip, port)
|
addr := fmt.Sprintf("%s:%d", ip, port)
|
||||||
conn, err := grpcpool.Pool.Get(addr)
|
conn, err := grpcpool.Pool.Get(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
package grpcpool
|
package grpcpool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/ouqiang/gocron/modules/app"
|
||||||
|
"github.com/ouqiang/gocron/modules/rpc/auth"
|
||||||
"github.com/silenceper/pool"
|
"github.com/silenceper/pool"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"google.golang.org/grpc"
|
|
||||||
"errors"
|
|
||||||
"github.com/ouqiang/gocron/modules/rpc/auth"
|
|
||||||
"github.com/ouqiang/gocron/modules/app"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Pool GRPCPool
|
Pool GRPCPool
|
||||||
)
|
)
|
||||||
|
@ -66,7 +65,6 @@ func (p *GRPCPool) Put(addr string, conn *grpc.ClientConn) error {
|
||||||
return ErrInvalidConn
|
return ErrInvalidConn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 释放连接池
|
// 释放连接池
|
||||||
func (p *GRPCPool) Release(addr string) {
|
func (p *GRPCPool) Release(addr string) {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
|
@ -83,13 +81,13 @@ func (p *GRPCPool) Release(addr string) {
|
||||||
func (p *GRPCPool) ReleaseAll() {
|
func (p *GRPCPool) ReleaseAll() {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
for _, pool := range(p.conns) {
|
for _, pool := range p.conns {
|
||||||
pool.Release()
|
pool.Release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化底层连接池
|
// 初始化底层连接池
|
||||||
func (p *GRPCPool) newCommonPool(addr string) (error) {
|
func (p *GRPCPool) newCommonPool(addr string) error {
|
||||||
p.Lock()
|
p.Lock()
|
||||||
defer p.Unlock()
|
defer p.Unlock()
|
||||||
commonPool, ok := p.conns[addr]
|
commonPool, ok := p.conns[addr]
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/net/context"
|
"github.com/ouqiang/gocron/modules/rpc/auth"
|
||||||
"net"
|
|
||||||
"google.golang.org/grpc/grpclog"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
"github.com/ouqiang/gocron/modules/rpc/auth"
|
"golang.org/x/net/context"
|
||||||
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials"
|
"google.golang.org/grpc/credentials"
|
||||||
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {}
|
type Server struct{}
|
||||||
|
|
||||||
func (s Server) Run(ctx context.Context, req *pb.TaskRequest) (*pb.TaskResponse, error) {
|
func (s Server) Run(ctx context.Context, req *pb.TaskRequest) (*pb.TaskResponse, error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
grpclog.Println(err)
|
grpclog.Println(err)
|
||||||
}
|
}
|
||||||
} ()
|
}()
|
||||||
output, err := utils.ExecShell(ctx, req.Command)
|
output, err := utils.ExecShell(ctx, req.Command)
|
||||||
resp := new(pb.TaskResponse)
|
resp := new(pb.TaskResponse)
|
||||||
resp.Output = output
|
resp.Output = output
|
||||||
|
@ -36,7 +36,7 @@ func Start(addr string, enableTLS bool, certificate auth.Certificate) {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
grpclog.Println("panic", err)
|
grpclog.Println("panic", err)
|
||||||
}
|
}
|
||||||
} ()
|
}()
|
||||||
|
|
||||||
l, err := net.Listen("tcp", addr)
|
l, err := net.Listen("tcp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,4 +62,3 @@ func Start(addr string, enableTLS bool, certificate auth.Certificate) {
|
||||||
err = s.Serve(l)
|
err = s.Serve(l)
|
||||||
grpclog.Fatal(err)
|
grpclog.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,15 @@ package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"gopkg.in/ini.v1"
|
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"gopkg.in/ini.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const DefaultSection = "default"
|
const DefaultSection = "default"
|
||||||
|
|
||||||
type Setting struct {
|
type Setting struct {
|
||||||
Db struct{
|
Db struct {
|
||||||
Engine string
|
Engine string
|
||||||
Host string
|
Host string
|
||||||
Port int
|
Port int
|
||||||
|
@ -35,7 +35,7 @@ type Setting struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取配置
|
// 读取配置
|
||||||
func Read(filename string) (*Setting,error) {
|
func Read(filename string) (*Setting, error) {
|
||||||
config, err := ini.Load(filename)
|
config, err := ini.Load(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -88,7 +88,7 @@ func Write(config []string, filename string) error {
|
||||||
if len(config) == 0 {
|
if len(config) == 0 {
|
||||||
return errors.New("参数不能为空")
|
return errors.New("参数不能为空")
|
||||||
}
|
}
|
||||||
if len(config) % 2 != 0 {
|
if len(config)%2 != 0 {
|
||||||
return errors.New("参数不匹配")
|
return errors.New("参数不匹配")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ func Write(config []string, filename string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for i := 0 ;i < len(config); {
|
for i := 0; i < len(config); {
|
||||||
_, err = section.NewKey(config[i], config[i+1])
|
_, err = section.NewKey(config[i], config[i+1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package ssh
|
package ssh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/ssh"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
"errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type HostAuthType int8 // 认证方式
|
type HostAuthType int8 // 认证方式
|
||||||
|
@ -17,7 +17,6 @@ const (
|
||||||
|
|
||||||
const SSHConnectTimeout = 10
|
const SSHConnectTimeout = 10
|
||||||
|
|
||||||
|
|
||||||
type SSHConfig struct {
|
type SSHConfig struct {
|
||||||
AuthType HostAuthType
|
AuthType HostAuthType
|
||||||
User string
|
User string
|
||||||
|
@ -25,7 +24,7 @@ type SSHConfig struct {
|
||||||
PrivateKey string
|
PrivateKey string
|
||||||
Host string
|
Host string
|
||||||
Port int
|
Port int
|
||||||
ExecTimeout int// 执行超时时间
|
ExecTimeout int // 执行超时时间
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
|
@ -43,7 +42,7 @@ func parseSSHConfig(sshConfig SSHConfig) (config *ssh.ClientConfig, err error) {
|
||||||
ssh.Password(sshConfig.Password),
|
ssh.Password(sshConfig.Password),
|
||||||
},
|
},
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
HostKeyCallback:func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -63,7 +62,7 @@ func parseSSHConfig(sshConfig SSHConfig) (config *ssh.ClientConfig, err error) {
|
||||||
ssh.PublicKeys(signer),
|
ssh.PublicKeys(signer),
|
||||||
},
|
},
|
||||||
Timeout: timeout,
|
Timeout: timeout,
|
||||||
HostKeyCallback:func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -71,7 +70,6 @@ func parseSSHConfig(sshConfig SSHConfig) (config *ssh.ClientConfig, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 执行shell命令
|
// 执行shell命令
|
||||||
func Exec(sshConfig SSHConfig, cmd string) (output string, err error) {
|
func Exec(sshConfig SSHConfig, cmd string) (output string, err error) {
|
||||||
client, err := getClient(sshConfig)
|
client, err := getClient(sshConfig)
|
||||||
|
@ -110,10 +108,10 @@ func Exec(sshConfig SSHConfig, cmd string) (output string, err error) {
|
||||||
// todo 等待超时后,如何停止远程正在执行的任务, 使用timeout命令,但不具有通用性
|
// todo 等待超时后,如何停止远程正在执行的任务, 使用timeout命令,但不具有通用性
|
||||||
go triggerTimeout(timeoutChan, sshConfig.ExecTimeout)
|
go triggerTimeout(timeoutChan, sshConfig.ExecTimeout)
|
||||||
select {
|
select {
|
||||||
case result := <- resultChan:
|
case result := <-resultChan:
|
||||||
output = result.Output
|
output = result.Output
|
||||||
err = result.Err
|
err = result.Err
|
||||||
case <- timeoutChan:
|
case <-timeoutChan:
|
||||||
output = ""
|
output = ""
|
||||||
err = errors.New("timeout")
|
err = errors.New("timeout")
|
||||||
}
|
}
|
||||||
|
@ -131,8 +129,7 @@ func getClient(sshConfig SSHConfig) (*ssh.Client, error) {
|
||||||
return ssh.Dial("tcp", addr, config)
|
return ssh.Dial("tcp", addr, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func triggerTimeout(ch chan bool, timeout int) {
|
||||||
func triggerTimeout(ch chan bool, timeout int){
|
|
||||||
// 最长执行时间不能超过24小时
|
// 最长执行时间不能超过24小时
|
||||||
if timeout <= 0 || timeout > 86400 {
|
if timeout <= 0 || timeout > 86400 {
|
||||||
timeout = 86400
|
timeout = 86400
|
||||||
|
@ -140,4 +137,3 @@ func triggerTimeout(ch chan bool, timeout int){
|
||||||
time.Sleep(time.Duration(timeout) * time.Second)
|
time.Sleep(time.Duration(timeout) * time.Second)
|
||||||
close(ch)
|
close(ch)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ func (j *JsonResponse) Failure(code int, message string) string {
|
||||||
return j.response(code, message, nil)
|
return j.response(code, message, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j *JsonResponse) CommonFailure(message string, err... error) string {
|
func (j *JsonResponse) CommonFailure(message string, err ...error) string {
|
||||||
if len(err) > 0 {
|
if len(err) > 0 {
|
||||||
logger.Warn(err)
|
logger.Warn(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,13 @@ package utils
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
"runtime"
|
|
||||||
"github.com/Tang-RoseChild/mahonia"
|
|
||||||
"strings"
|
|
||||||
"os"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Tang-RoseChild/mahonia"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 生成长度为length的随机字符串
|
// 生成长度为length的随机字符串
|
||||||
|
@ -72,7 +72,7 @@ func ReplaceStrings(s string, old []string, replace []string) string {
|
||||||
func InStringSlice(slice []string, element string) bool {
|
func InStringSlice(slice []string, element string) bool {
|
||||||
element = strings.TrimSpace(element)
|
element = strings.TrimSpace(element)
|
||||||
for _, v := range slice {
|
for _, v := range slice {
|
||||||
if strings.TrimSpace(v) == element{
|
if strings.TrimSpace(v) == element {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,8 @@ func InStringSlice(slice []string, element string) bool {
|
||||||
|
|
||||||
// 转义json特殊字符
|
// 转义json特殊字符
|
||||||
func EscapeJson(s string) string {
|
func EscapeJson(s string) string {
|
||||||
specialChars := []string{"\\", "\b","\f", "\n", "\r", "\t", "\"",}
|
specialChars := []string{"\\", "\b", "\f", "\n", "\r", "\t", "\""}
|
||||||
replaceChars := []string{ "\\\\", "\\b", "\\f", "\\n", "\\r", "\\t", "\\\"",}
|
replaceChars := []string{"\\\\", "\\b", "\\f", "\\n", "\\r", "\\t", "\\\""}
|
||||||
|
|
||||||
return ReplaceStrings(s, specialChars, replaceChars)
|
return ReplaceStrings(s, specialChars, replaceChars)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"golang.org/x/net/context"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"syscall"
|
"syscall"
|
||||||
"golang.org/x/net/context"
|
|
||||||
"errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
|
@ -22,16 +22,16 @@ func ExecShell(ctx context.Context, command string) (string, error) {
|
||||||
}
|
}
|
||||||
var resultChan chan Result = make(chan Result)
|
var resultChan chan Result = make(chan Result)
|
||||||
go func() {
|
go func() {
|
||||||
output ,err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
resultChan <- Result{string(output), err}
|
resultChan <- Result{string(output), err}
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <- ctx.Done():
|
case <-ctx.Done():
|
||||||
if cmd.Process.Pid > 0 {
|
if cmd.Process.Pid > 0 {
|
||||||
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
|
||||||
}
|
}
|
||||||
return "", errors.New("timeout killed")
|
return "", errors.New("timeout killed")
|
||||||
case result := <- resultChan:
|
case result := <-resultChan:
|
||||||
return result.output, result.err
|
return result.output, result.err
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,11 +3,11 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"errors"
|
||||||
|
"golang.org/x/net/context"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"golang.org/x/net/context"
|
"syscall"
|
||||||
"errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Result struct {
|
type Result struct {
|
||||||
|
@ -24,25 +24,22 @@ func ExecShell(ctx context.Context, command string) (string, error) {
|
||||||
}
|
}
|
||||||
var resultChan chan Result = make(chan Result)
|
var resultChan chan Result = make(chan Result)
|
||||||
go func() {
|
go func() {
|
||||||
output ,err := cmd.CombinedOutput()
|
output, err := cmd.CombinedOutput()
|
||||||
resultChan <- Result{string(output), err}
|
resultChan <- Result{string(output), err}
|
||||||
}()
|
}()
|
||||||
select {
|
select {
|
||||||
case <- ctx.Done():
|
case <-ctx.Done():
|
||||||
if cmd.Process.Pid > 0 {
|
if cmd.Process.Pid > 0 {
|
||||||
exec.Command("taskkill", "/F", "/T", "/PID", strconv.Itoa(cmd.Process.Pid)).Run()
|
exec.Command("taskkill", "/F", "/T", "/PID", strconv.Itoa(cmd.Process.Pid)).Run()
|
||||||
cmd.Process.Kill()
|
cmd.Process.Kill()
|
||||||
}
|
}
|
||||||
return "", errors.New("timeout killed")
|
return "", errors.New("timeout killed")
|
||||||
case result := <- resultChan:
|
case result := <-resultChan:
|
||||||
return ConvertEncoding(result.output), result.err
|
return ConvertEncoding(result.output), result.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return "", nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ConvertEncoding(outputGBK string) (string) {
|
func ConvertEncoding(outputGBK string) string {
|
||||||
// windows平台编码为gbk,需转换为utf8才能入库
|
// windows平台编码为gbk,需转换为utf8才能入库
|
||||||
outputUTF8, ok := GBK2UTF8(outputGBK)
|
outputUTF8, ok := GBK2UTF8(outputGBK)
|
||||||
if ok {
|
if ok {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package base
|
package base
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ParsePageAndPageSize(ctx *macaron.Context, params models.CommonMap) {
|
func ParsePageAndPageSize(ctx *macaron.Context, params models.CommonMap) {
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
package host
|
package host
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
|
||||||
"github.com/ouqiang/gocron/models"
|
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"strconv"
|
|
||||||
"github.com/ouqiang/gocron/service"
|
|
||||||
"github.com/Unknwon/paginater"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"github.com/Unknwon/paginater"
|
||||||
"github.com/ouqiang/gocron/routers/base"
|
|
||||||
"github.com/go-macaron/binding"
|
"github.com/go-macaron/binding"
|
||||||
"github.com/ouqiang/gocron/modules/rpc/grpcpool"
|
"github.com/ouqiang/gocron/models"
|
||||||
"strings"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"github.com/ouqiang/gocron/modules/rpc/client"
|
"github.com/ouqiang/gocron/modules/rpc/client"
|
||||||
|
"github.com/ouqiang/gocron/modules/rpc/grpcpool"
|
||||||
"github.com/ouqiang/gocron/modules/rpc/proto"
|
"github.com/ouqiang/gocron/modules/rpc/proto"
|
||||||
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"github.com/ouqiang/gocron/routers/base"
|
||||||
|
"github.com/ouqiang/gocron/service"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
|
"html/template"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Index(ctx *macaron.Context) {
|
func Index(ctx *macaron.Context) {
|
||||||
|
@ -32,7 +32,7 @@ func Index(ctx *macaron.Context) {
|
||||||
safeNameHTML = template.HTMLEscapeString(name)
|
safeNameHTML = template.HTMLEscapeString(name)
|
||||||
}
|
}
|
||||||
PageParams := fmt.Sprintf("id=%d&name=%s&page_size=%d",
|
PageParams := fmt.Sprintf("id=%d&name=%s&page_size=%d",
|
||||||
queryParams["Id"], safeNameHTML, queryParams["PageSize"]);
|
queryParams["Id"], safeNameHTML, queryParams["PageSize"])
|
||||||
queryParams["PageParams"] = template.URL(PageParams)
|
queryParams["PageParams"] = template.URL(PageParams)
|
||||||
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
||||||
ctx.Data["Pagination"] = p
|
ctx.Data["Pagination"] = p
|
||||||
|
@ -136,7 +136,7 @@ func Remove(ctx *macaron.Context) string {
|
||||||
return json.CommonFailure("参数错误", err)
|
return json.CommonFailure("参数错误", err)
|
||||||
}
|
}
|
||||||
taskHostModel := new(models.TaskHost)
|
taskHostModel := new(models.TaskHost)
|
||||||
exist,err := taskHostModel.HostIdExist(int16(id))
|
exist, err := taskHostModel.HostIdExist(int16(id))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return json.CommonFailure("操作失败", err)
|
return json.CommonFailure("操作失败", err)
|
||||||
}
|
}
|
||||||
|
@ -150,7 +150,7 @@ func Remove(ctx *macaron.Context) string {
|
||||||
return json.CommonFailure("主机不存在")
|
return json.CommonFailure("主机不存在")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err =hostModel.Delete(id)
|
_, err = hostModel.Delete(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return json.CommonFailure("操作失败", err)
|
return json.CommonFailure("操作失败", err)
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,6 @@ func Remove(ctx *macaron.Context) string {
|
||||||
addr := fmt.Sprintf("%s:%d", hostModel.Name, hostModel.Port)
|
addr := fmt.Sprintf("%s:%d", hostModel.Name, hostModel.Port)
|
||||||
grpcpool.Pool.Release(addr)
|
grpcpool.Pool.Release(addr)
|
||||||
|
|
||||||
|
|
||||||
return json.Success("操作成功", nil)
|
return json.Success("操作成功", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,24 +166,23 @@ func Ping(ctx *macaron.Context) string {
|
||||||
hostModel := new(models.Host)
|
hostModel := new(models.Host)
|
||||||
err := hostModel.Find(id)
|
err := hostModel.Find(id)
|
||||||
json := utils.JsonResponse{}
|
json := utils.JsonResponse{}
|
||||||
if err != nil || hostModel.Id <= 0{
|
if err != nil || hostModel.Id <= 0 {
|
||||||
return json.CommonFailure("主机不存在", err)
|
return json.CommonFailure("主机不存在", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
taskReq := &rpc.TaskRequest{}
|
taskReq := &rpc.TaskRequest{}
|
||||||
taskReq.Command = "echo hello"
|
taskReq.Command = "echo hello"
|
||||||
taskReq.Timeout = 10
|
taskReq.Timeout = 10
|
||||||
output, err := client.Exec(hostModel.Name, hostModel.Port, taskReq)
|
output, err := client.Exec(hostModel.Name, hostModel.Port, taskReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return json.CommonFailure("连接失败-" + err.Error() + " " + output, err)
|
return json.CommonFailure("连接失败-"+err.Error()+" "+output, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Success("连接成功", nil)
|
return json.Success("连接成功", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析查询参数
|
// 解析查询参数
|
||||||
func parseQueryParams(ctx *macaron.Context) (models.CommonMap) {
|
func parseQueryParams(ctx *macaron.Context) models.CommonMap {
|
||||||
var params models.CommonMap = models.CommonMap{}
|
var params models.CommonMap = models.CommonMap{}
|
||||||
params["Id"] = ctx.QueryInt("id")
|
params["Id"] = ctx.QueryInt("id")
|
||||||
params["Name"] = ctx.QueryTrim("name")
|
params["Name"] = ctx.QueryTrim("name")
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package install
|
package install
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/go-macaron/binding"
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/app"
|
"github.com/ouqiang/gocron/modules/app"
|
||||||
"github.com/ouqiang/gocron/modules/setting"
|
"github.com/ouqiang/gocron/modules/setting"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"github.com/ouqiang/gocron/service"
|
||||||
"gopkg.in/macaron.v1"
|
"gopkg.in/macaron.v1"
|
||||||
"strconv"
|
"strconv"
|
||||||
"fmt"
|
|
||||||
"github.com/ouqiang/gocron/service"
|
|
||||||
"github.com/go-macaron/binding"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 系统安装
|
// 系统安装
|
||||||
|
@ -110,7 +110,7 @@ func writeConfig(form InstallForm) error {
|
||||||
"db.host", form.DbHost,
|
"db.host", form.DbHost,
|
||||||
"db.port", strconv.Itoa(form.DbPort),
|
"db.port", strconv.Itoa(form.DbPort),
|
||||||
"db.user", form.DbUsername,
|
"db.user", form.DbUsername,
|
||||||
"db.password",form.DbPassword,
|
"db.password", form.DbPassword,
|
||||||
"db.database", form.DbName,
|
"db.database", form.DbName,
|
||||||
"db.prefix", form.DbTablePrefix,
|
"db.prefix", form.DbTablePrefix,
|
||||||
"db.charset", "utf8",
|
"db.charset", "utf8",
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package loginlog
|
package loginlog
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
|
||||||
"github.com/Unknwon/paginater"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/Unknwon/paginater"
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"github.com/ouqiang/gocron/routers/base"
|
"github.com/ouqiang/gocron/routers/base"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
"html/template"
|
"html/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ func Index(ctx *macaron.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
}
|
}
|
||||||
PageParams := fmt.Sprintf("page_size=%d", params["PageSize"]);
|
PageParams := fmt.Sprintf("page_size=%d", params["PageSize"])
|
||||||
params["PageParams"] = template.URL(PageParams)
|
params["PageParams"] = template.URL(PageParams)
|
||||||
p := paginater.New(int(total), params["PageSize"].(int), params["Page"].(int), 5)
|
p := paginater.New(int(total), params["PageSize"].(int), params["Page"].(int), 5)
|
||||||
ctx.Data["Pagination"] = p
|
ctx.Data["Pagination"] = p
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
package manage
|
package manage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
"encoding/json"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"encoding/json"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
// region slack
|
// region slack
|
||||||
|
|
||||||
func EditSlack(ctx *macaron.Context) {
|
func EditSlack(ctx *macaron.Context) {
|
||||||
|
@ -89,7 +88,6 @@ func Mail(ctx *macaron.Context) string {
|
||||||
return json.Success("", mail)
|
return json.Success("", mail)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type MailServerForm struct {
|
type MailServerForm struct {
|
||||||
Host string `binding:"Required;MaxSize(100)"`
|
Host string `binding:"Required;MaxSize(100)"`
|
||||||
Port int `binding:"Required;Range(1-65535)"`
|
Port int `binding:"Required;Range(1-65535)"`
|
||||||
|
|
|
@ -2,26 +2,26 @@ package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/go-macaron/binding"
|
"github.com/go-macaron/binding"
|
||||||
"github.com/ouqiang/gocron/routers/install"
|
|
||||||
"gopkg.in/macaron.v1"
|
|
||||||
"github.com/ouqiang/gocron/routers/task"
|
|
||||||
"github.com/ouqiang/gocron/routers/host"
|
|
||||||
"github.com/ouqiang/gocron/routers/tasklog"
|
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
|
||||||
"github.com/go-macaron/session"
|
|
||||||
"github.com/go-macaron/toolbox"
|
|
||||||
"strings"
|
|
||||||
"github.com/ouqiang/gocron/modules/app"
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"github.com/ouqiang/gocron/routers/user"
|
|
||||||
"github.com/go-macaron/gzip"
|
|
||||||
"github.com/ouqiang/gocron/routers/manage"
|
|
||||||
"github.com/ouqiang/gocron/routers/loginlog"
|
|
||||||
"time"
|
|
||||||
"strconv"
|
|
||||||
"html/template"
|
|
||||||
"github.com/go-macaron/cache"
|
"github.com/go-macaron/cache"
|
||||||
"github.com/go-macaron/captcha"
|
"github.com/go-macaron/captcha"
|
||||||
|
"github.com/go-macaron/gzip"
|
||||||
|
"github.com/go-macaron/session"
|
||||||
|
"github.com/go-macaron/toolbox"
|
||||||
|
"github.com/ouqiang/gocron/modules/app"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"github.com/ouqiang/gocron/routers/host"
|
||||||
|
"github.com/ouqiang/gocron/routers/install"
|
||||||
|
"github.com/ouqiang/gocron/routers/loginlog"
|
||||||
|
"github.com/ouqiang/gocron/routers/manage"
|
||||||
|
"github.com/ouqiang/gocron/routers/task"
|
||||||
|
"github.com/ouqiang/gocron/routers/tasklog"
|
||||||
|
"github.com/ouqiang/gocron/routers/user"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
|
"html/template"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 静态文件目录
|
// 静态文件目录
|
||||||
|
@ -97,7 +97,7 @@ func Register(m *macaron.Macaron) {
|
||||||
m.Post("/tasklog/remove/:id", tasklog.Remove)
|
m.Post("/tasklog/remove/:id", tasklog.Remove)
|
||||||
m.Post("/task/enable/:id", task.Enable)
|
m.Post("/task/enable/:id", task.Enable)
|
||||||
m.Post("/task/disable/:id", task.Disable)
|
m.Post("/task/disable/:id", task.Disable)
|
||||||
}, apiAuth);
|
}, apiAuth)
|
||||||
|
|
||||||
// 404错误
|
// 404错误
|
||||||
m.NotFound(func(ctx *macaron.Context) {
|
m.NotFound(func(ctx *macaron.Context) {
|
||||||
|
@ -141,9 +141,9 @@ func RegisterMiddleware(m *macaron.Macaron) {
|
||||||
IndentJSON: true,
|
IndentJSON: true,
|
||||||
// 渲染具有缩进格式的 XML,默认为不缩进
|
// 渲染具有缩进格式的 XML,默认为不缩进
|
||||||
IndentXML: true,
|
IndentXML: true,
|
||||||
Funcs: []template.FuncMap{map[string]interface{} {
|
Funcs: []template.FuncMap{map[string]interface{}{
|
||||||
"HostFormat": func(index int) bool {
|
"HostFormat": func(index int) bool {
|
||||||
return (index + 1) % 3 == 0
|
return (index+1)%3 == 0
|
||||||
},
|
},
|
||||||
"unescape": func(str string) template.HTML {
|
"unescape": func(str string) template.HTML {
|
||||||
return template.HTML(str)
|
return template.HTML(str)
|
||||||
|
@ -158,7 +158,7 @@ func RegisterMiddleware(m *macaron.Macaron) {
|
||||||
}))
|
}))
|
||||||
m.Use(toolbox.Toolboxer(m))
|
m.Use(toolbox.Toolboxer(m))
|
||||||
checkAppInstall(m)
|
checkAppInstall(m)
|
||||||
m.Use(func(ctx *macaron.Context, sess session.Store){
|
m.Use(func(ctx *macaron.Context, sess session.Store) {
|
||||||
if app.Installed {
|
if app.Installed {
|
||||||
ipAuth(ctx)
|
ipAuth(ctx)
|
||||||
userAuth(ctx, sess)
|
userAuth(ctx, sess)
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
package task
|
package task
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
"fmt"
|
||||||
|
"github.com/Unknwon/paginater"
|
||||||
|
"github.com/go-macaron/binding"
|
||||||
|
"github.com/jakecoffman/cron"
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
"github.com/ouqiang/gocron/service"
|
|
||||||
"strconv"
|
|
||||||
"github.com/jakecoffman/cron"
|
|
||||||
"github.com/Unknwon/paginater"
|
|
||||||
"fmt"
|
|
||||||
"html/template"
|
|
||||||
"github.com/ouqiang/gocron/routers/base"
|
"github.com/ouqiang/gocron/routers/base"
|
||||||
"github.com/go-macaron/binding"
|
"github.com/ouqiang/gocron/service"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
|
"html/template"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ type TaskForm struct {
|
||||||
NotifyReceiverId string
|
NotifyReceiverId string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func (f TaskForm) Error(ctx *macaron.Context, errs binding.Errors) {
|
func (f TaskForm) Error(ctx *macaron.Context, errs binding.Errors) {
|
||||||
if len(errs) == 0 {
|
if len(errs) == 0 {
|
||||||
return
|
return
|
||||||
|
@ -65,7 +64,7 @@ func Index(ctx *macaron.Context) {
|
||||||
safeNameHTML = template.HTMLEscapeString(name)
|
safeNameHTML = template.HTMLEscapeString(name)
|
||||||
}
|
}
|
||||||
PageParams := fmt.Sprintf("id=%d&host_id=%d&name=%s&protocol=%d&tag=%s&status=%d&page_size=%d",
|
PageParams := fmt.Sprintf("id=%d&host_id=%d&name=%s&protocol=%d&tag=%s&status=%d&page_size=%d",
|
||||||
queryParams["Id"], queryParams["HostId"], safeNameHTML, queryParams["Protocol"], queryParams["Tag"], queryParams["Status"], queryParams["PageSize"]);
|
queryParams["Id"], queryParams["HostId"], safeNameHTML, queryParams["Protocol"], queryParams["Tag"], queryParams["Status"], queryParams["PageSize"])
|
||||||
queryParams["PageParams"] = template.URL(PageParams)
|
queryParams["PageParams"] = template.URL(PageParams)
|
||||||
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
||||||
ctx.Data["Pagination"] = p
|
ctx.Data["Pagination"] = p
|
||||||
|
@ -98,7 +97,7 @@ func Edit(ctx *macaron.Context) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
} else {
|
} else {
|
||||||
for i, host := range(hosts) {
|
for i, host := range hosts {
|
||||||
if inHosts(task.Hosts, host.Id) {
|
if inHosts(task.Hosts, host.Id) {
|
||||||
hosts[i].Selected = true
|
hosts[i].Selected = true
|
||||||
}
|
}
|
||||||
|
@ -163,8 +162,8 @@ func Store(ctx *macaron.Context, form TaskForm) string {
|
||||||
return json.CommonFailure("任务重试次数取值0-10")
|
return json.CommonFailure("任务重试次数取值0-10")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taskModel.DependencyStatus != models.TaskDependencyStatusStrong &&
|
if taskModel.DependencyStatus != models.TaskDependencyStatusStrong &&
|
||||||
taskModel.DependencyStatus != models.TaskDependencyStatusWeak) {
|
taskModel.DependencyStatus != models.TaskDependencyStatusWeak {
|
||||||
return json.CommonFailure("请选择依赖关系")
|
return json.CommonFailure("请选择依赖关系")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +249,7 @@ func Run(ctx *macaron.Context) string {
|
||||||
id := ctx.ParamsInt(":id")
|
id := ctx.ParamsInt(":id")
|
||||||
json := utils.JsonResponse{}
|
json := utils.JsonResponse{}
|
||||||
taskModel := new(models.Task)
|
taskModel := new(models.Task)
|
||||||
task , err := taskModel.Detail(id)
|
task, err := taskModel.Detail(id)
|
||||||
if err != nil || task.Id <= 0 {
|
if err != nil || task.Id <= 0 {
|
||||||
return json.CommonFailure("获取任务详情失败", err)
|
return json.CommonFailure("获取任务详情失败", err)
|
||||||
}
|
}
|
||||||
|
@ -259,7 +258,7 @@ func Run(ctx *macaron.Context) string {
|
||||||
serviceTask := new(service.Task)
|
serviceTask := new(service.Task)
|
||||||
serviceTask.Run(task)
|
serviceTask.Run(task)
|
||||||
|
|
||||||
return json.Success("任务已开始运行, 请到任务日志中查看结果", nil);
|
return json.Success("任务已开始运行, 请到任务日志中查看结果", nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 改变任务状态
|
// 改变任务状态
|
||||||
|
@ -297,7 +296,7 @@ func addTaskToTimer(id int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析查询参数
|
// 解析查询参数
|
||||||
func parseQueryParams(ctx *macaron.Context) (models.CommonMap) {
|
func parseQueryParams(ctx *macaron.Context) models.CommonMap {
|
||||||
var params models.CommonMap = models.CommonMap{}
|
var params models.CommonMap = models.CommonMap{}
|
||||||
params["Id"] = ctx.QueryInt("id")
|
params["Id"] = ctx.QueryInt("id")
|
||||||
params["HostId"] = ctx.QueryInt("host_id")
|
params["HostId"] = ctx.QueryInt("host_id")
|
||||||
|
@ -305,7 +304,7 @@ func parseQueryParams(ctx *macaron.Context) (models.CommonMap) {
|
||||||
params["Protocol"] = ctx.QueryInt("protocol")
|
params["Protocol"] = ctx.QueryInt("protocol")
|
||||||
params["Tag"] = ctx.QueryTrim("tag")
|
params["Tag"] = ctx.QueryTrim("tag")
|
||||||
status := ctx.QueryInt("status")
|
status := ctx.QueryInt("status")
|
||||||
if status >=0 {
|
if status >= 0 {
|
||||||
status -= 1
|
status -= 1
|
||||||
}
|
}
|
||||||
params["Status"] = status
|
params["Status"] = status
|
||||||
|
|
|
@ -3,14 +3,14 @@ package tasklog
|
||||||
// 任务日志
|
// 任务日志
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
"fmt"
|
||||||
|
"github.com/Unknwon/paginater"
|
||||||
"github.com/ouqiang/gocron/models"
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
"github.com/Unknwon/paginater"
|
|
||||||
"fmt"
|
|
||||||
"html/template"
|
|
||||||
"github.com/ouqiang/gocron/routers/base"
|
"github.com/ouqiang/gocron/routers/base"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
|
"html/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Index(ctx *macaron.Context) {
|
func Index(ctx *macaron.Context) {
|
||||||
|
@ -26,7 +26,7 @@ func Index(ctx *macaron.Context) {
|
||||||
}
|
}
|
||||||
PageParams := fmt.Sprintf("task_id=%d&protocol=%d&status=%d&page_size=%d",
|
PageParams := fmt.Sprintf("task_id=%d&protocol=%d&status=%d&page_size=%d",
|
||||||
queryParams["TaskId"], queryParams["Protocol"], queryParams["Status"],
|
queryParams["TaskId"], queryParams["Protocol"], queryParams["Status"],
|
||||||
queryParams["PageSize"]);
|
queryParams["PageSize"])
|
||||||
queryParams["PageParams"] = template.URL(PageParams)
|
queryParams["PageParams"] = template.URL(PageParams)
|
||||||
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
p := paginater.New(int(total), queryParams["PageSize"].(int), queryParams["Page"].(int), 5)
|
||||||
ctx.Data["Pagination"] = p
|
ctx.Data["Pagination"] = p
|
||||||
|
@ -65,12 +65,12 @@ func Remove(ctx *macaron.Context) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析查询参数
|
// 解析查询参数
|
||||||
func parseQueryParams(ctx *macaron.Context) (models.CommonMap) {
|
func parseQueryParams(ctx *macaron.Context) models.CommonMap {
|
||||||
var params models.CommonMap = models.CommonMap{}
|
var params models.CommonMap = models.CommonMap{}
|
||||||
params["TaskId"] = ctx.QueryInt("task_id")
|
params["TaskId"] = ctx.QueryInt("task_id")
|
||||||
params["Protocol"] = ctx.QueryInt("protocol")
|
params["Protocol"] = ctx.QueryInt("protocol")
|
||||||
status := ctx.QueryInt("status")
|
status := ctx.QueryInt("status")
|
||||||
if status >=0 {
|
if status >= 0 {
|
||||||
status -= 1
|
status -= 1
|
||||||
}
|
}
|
||||||
params["Status"] = status
|
params["Status"] = status
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gopkg.in/macaron.v1"
|
|
||||||
"github.com/ouqiang/gocron/modules/utils"
|
|
||||||
"github.com/ouqiang/gocron/models"
|
|
||||||
"github.com/go-macaron/session"
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"github.com/go-macaron/captcha"
|
"github.com/go-macaron/captcha"
|
||||||
|
"github.com/go-macaron/session"
|
||||||
|
"github.com/ouqiang/gocron/models"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
|
"github.com/ouqiang/gocron/modules/utils"
|
||||||
|
"gopkg.in/macaron.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// @author qiang.ou<qingqianludao@gmail.com>
|
// @author qiang.ou<qingqianludao@gmail.com>
|
||||||
|
@ -55,7 +55,7 @@ func ValidateLogin(ctx *macaron.Context, sess session.Store, cpt *captcha.Captch
|
||||||
if username == "" || password == "" {
|
if username == "" || password == "" {
|
||||||
return json.CommonFailure("用户名、密码不能为空")
|
return json.CommonFailure("用户名、密码不能为空")
|
||||||
}
|
}
|
||||||
userModel := new (models.User)
|
userModel := new(models.User)
|
||||||
if !userModel.Match(username, password) {
|
if !userModel.Match(username, password) {
|
||||||
return json.CommonFailure("用户名或密码错误")
|
return json.CommonFailure("用户名或密码错误")
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,6 @@ func ValidateLogin(ctx *macaron.Context, sess session.Store, cpt *captcha.Captch
|
||||||
logger.Error("记录用户登录日志失败", err)
|
logger.Error("记录用户登录日志失败", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sess.Set("username", userModel.Name)
|
sess.Set("username", userModel.Name)
|
||||||
sess.Set("uid", userModel.Id)
|
sess.Set("uid", userModel.Id)
|
||||||
sess.Set("isAdmin", userModel.IsAdmin)
|
sess.Set("isAdmin", userModel.IsAdmin)
|
||||||
|
@ -91,7 +90,7 @@ func Logout(ctx *macaron.Context, sess session.Store) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Username(sess session.Store) string {
|
func Username(sess session.Store) string {
|
||||||
username,ok := sess.Get("username").(string)
|
username, ok := sess.Get("username").(string)
|
||||||
if ok {
|
if ok {
|
||||||
return username
|
return username
|
||||||
}
|
}
|
||||||
|
@ -100,7 +99,7 @@ func Username(sess session.Store) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Uid(sess session.Store) int {
|
func Uid(sess session.Store) int {
|
||||||
uid,ok := sess.Get("uid").(int)
|
uid, ok := sess.Get("uid").(int)
|
||||||
if ok {
|
if ok {
|
||||||
return uid
|
return uid
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ouqiang/gocron/models"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
"github.com/ouqiang/gocron/modules/logger"
|
|
||||||
"github.com/jakecoffman/cron"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/jakecoffman/cron"
|
||||||
|
"github.com/ouqiang/gocron/models"
|
||||||
"github.com/ouqiang/gocron/modules/httpclient"
|
"github.com/ouqiang/gocron/modules/httpclient"
|
||||||
|
"github.com/ouqiang/gocron/modules/logger"
|
||||||
"github.com/ouqiang/gocron/modules/notify"
|
"github.com/ouqiang/gocron/modules/notify"
|
||||||
"sync"
|
|
||||||
rpcClient "github.com/ouqiang/gocron/modules/rpc/client"
|
rpcClient "github.com/ouqiang/gocron/modules/rpc/client"
|
||||||
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
pb "github.com/ouqiang/gocron/modules/rpc/proto"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// 定时任务调度管理器
|
// 定时任务调度管理器
|
||||||
var Cron *cron.Cron
|
var Cron *cron.Cron
|
||||||
|
|
||||||
// 同一任务是否有实例处于运行中
|
// 同一任务是否有实例处于运行中
|
||||||
var runInstance Instance
|
var runInstance Instance
|
||||||
|
|
||||||
// 任务计数-正在运行中的任务
|
// 任务计数-正在运行中的任务
|
||||||
var TaskNum TaskCount
|
var TaskNum TaskCount
|
||||||
|
|
||||||
|
@ -116,7 +118,7 @@ func (task *Task) BatchAdd(tasks []models.Task) {
|
||||||
// 添加任务
|
// 添加任务
|
||||||
func (task *Task) Add(taskModel models.Task) {
|
func (task *Task) Add(taskModel models.Task) {
|
||||||
if taskModel.Level == models.TaskLevelChild {
|
if taskModel.Level == models.TaskLevelChild {
|
||||||
logger.Errorf("添加任务失败#不允许添加子任务到调度器#任务Id-%d", taskModel.Id);
|
logger.Errorf("添加任务失败#不允许添加子任务到调度器#任务Id-%d", taskModel.Id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
taskFunc := createJob(taskModel)
|
taskFunc := createJob(taskModel)
|
||||||
|
@ -148,7 +150,6 @@ type Handler interface {
|
||||||
Run(taskModel models.Task) (string, error)
|
Run(taskModel models.Task) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// HTTP任务
|
// HTTP任务
|
||||||
type HTTPHandler struct{}
|
type HTTPHandler struct{}
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ func (h *HTTPHandler) Run(taskModel models.Task) (result string, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// RPC调用执行任务
|
// RPC调用执行任务
|
||||||
type RPCHandler struct {}
|
type RPCHandler struct{}
|
||||||
|
|
||||||
func (h *RPCHandler) Run(taskModel models.Task) (result string, err error) {
|
func (h *RPCHandler) Run(taskModel models.Task) (result string, err error) {
|
||||||
taskRequest := new(pb.TaskRequest)
|
taskRequest := new(pb.TaskRequest)
|
||||||
|
@ -178,7 +179,7 @@ func (h *RPCHandler) Run(taskModel models.Task) (result string, err error) {
|
||||||
var resultChan chan TaskResult = make(chan TaskResult, len(taskModel.Hosts))
|
var resultChan chan TaskResult = make(chan TaskResult, len(taskModel.Hosts))
|
||||||
for _, taskHost := range taskModel.Hosts {
|
for _, taskHost := range taskModel.Hosts {
|
||||||
go func(th models.TaskHostDetail) {
|
go func(th models.TaskHostDetail) {
|
||||||
output, err := rpcClient.ExecWithRetry(th.Name, th.Port, taskRequest)
|
output, err := rpcClient.Exec(th.Name, th.Port, taskRequest)
|
||||||
var errorMessage string = ""
|
var errorMessage string = ""
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorMessage = err.Error()
|
errorMessage = err.Error()
|
||||||
|
@ -186,14 +187,14 @@ func (h *RPCHandler) Run(taskModel models.Task) (result string, err error) {
|
||||||
outputMessage := fmt.Sprintf("主机: [%s-%s]\n%s\n%s\n\n",
|
outputMessage := fmt.Sprintf("主机: [%s-%s]\n%s\n%s\n\n",
|
||||||
th.Alias, th.Name, errorMessage, output,
|
th.Alias, th.Name, errorMessage, output,
|
||||||
)
|
)
|
||||||
resultChan <- TaskResult{Err:err, Result: outputMessage}
|
resultChan <- TaskResult{Err: err, Result: outputMessage}
|
||||||
}(taskHost)
|
}(taskHost)
|
||||||
}
|
}
|
||||||
|
|
||||||
var aggregationErr error = nil
|
var aggregationErr error = nil
|
||||||
var aggregationResult string = ""
|
var aggregationResult string = ""
|
||||||
for i := 0; i < len(taskModel.Hosts); i++ {
|
for i := 0; i < len(taskModel.Hosts); i++ {
|
||||||
taskResult := <- resultChan
|
taskResult := <-resultChan
|
||||||
aggregationResult += taskResult.Result
|
aggregationResult += taskResult.Result
|
||||||
if taskResult.Err != nil {
|
if taskResult.Err != nil {
|
||||||
aggregationErr = taskResult.Err
|
aggregationErr = taskResult.Err
|
||||||
|
@ -203,7 +204,6 @@ func (h *RPCHandler) Run(taskModel models.Task) (result string, err error) {
|
||||||
return aggregationResult, aggregationErr
|
return aggregationResult, aggregationErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 创建任务日志
|
// 创建任务日志
|
||||||
func createTaskLog(taskModel models.Task, status models.Status) (int64, error) {
|
func createTaskLog(taskModel models.Task, status models.Status) (int64, error) {
|
||||||
taskLogModel := new(models.TaskLog)
|
taskLogModel := new(models.TaskLog)
|
||||||
|
@ -275,8 +275,7 @@ func createHandler(taskModel models.Task) Handler {
|
||||||
handler = new(RPCHandler)
|
handler = new(RPCHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return handler
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 任务前置操作
|
// 任务前置操作
|
||||||
|
@ -333,7 +332,7 @@ func execDependencyTask(taskModel models.Task, taskResult TaskResult) {
|
||||||
|
|
||||||
// 获取子任务
|
// 获取子任务
|
||||||
model := new(models.Task)
|
model := new(models.Task)
|
||||||
tasks , err := model.GetDependencyTaskList(dependencyTaskId)
|
tasks, err := model.GetDependencyTaskList(dependencyTaskId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("获取依赖任务失败#主任务ID-%d#%s", taskModel.Id, err.Error())
|
logger.Errorf("获取依赖任务失败#主任务ID-%d#%s", taskModel.Id, err.Error())
|
||||||
return
|
return
|
||||||
|
@ -375,7 +374,7 @@ func SendNotification(taskModel models.Task, taskResult TaskResult) {
|
||||||
"output": taskResult.Result,
|
"output": taskResult.Result,
|
||||||
"status": statusName,
|
"status": statusName,
|
||||||
"taskId": taskModel.Id,
|
"taskId": taskModel.Id,
|
||||||
};
|
}
|
||||||
notify.Push(msg)
|
notify.Push(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,13 +384,13 @@ func execJob(handler Handler, taskModel models.Task) TaskResult {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
logger.Error("panic#service/task.go:execJob#", err)
|
logger.Error("panic#service/task.go:execJob#", err)
|
||||||
}
|
}
|
||||||
} ()
|
}()
|
||||||
if taskModel.Multi == 0 {
|
if taskModel.Multi == 0 {
|
||||||
defer runInstance.done(taskModel.Id)
|
defer runInstance.done(taskModel.Id)
|
||||||
}
|
}
|
||||||
// 默认只运行任务一次
|
// 默认只运行任务一次
|
||||||
var execTimes int8 = 1
|
var execTimes int8 = 1
|
||||||
if (taskModel.RetryTimes > 0) {
|
if taskModel.RetryTimes > 0 {
|
||||||
execTimes += taskModel.RetryTimes
|
execTimes += taskModel.RetryTimes
|
||||||
}
|
}
|
||||||
var i int8 = 0
|
var i int8 = 0
|
||||||
|
@ -406,7 +405,7 @@ func execJob(handler Handler, taskModel models.Task) TaskResult {
|
||||||
if i < execTimes {
|
if i < execTimes {
|
||||||
logger.Warnf("任务执行失败#任务id-%d#重试第%d次#输出-%s#错误-%s", taskModel.Id, i, output, err.Error())
|
logger.Warnf("任务执行失败#任务id-%d#重试第%d次#输出-%s#错误-%s", taskModel.Id, i, output, err.Error())
|
||||||
// 重试间隔时间,每次递增1分钟
|
// 重试间隔时间,每次递增1分钟
|
||||||
time.Sleep( time.Duration(i) * time.Minute)
|
time.Sleep(time.Duration(i) * time.Minute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ func PowInt(x int, y int) int {
|
||||||
if y <= 0 {
|
if y <= 0 {
|
||||||
return 1
|
return 1
|
||||||
} else {
|
} else {
|
||||||
if y % 2 == 0 {
|
if y%2 == 0 {
|
||||||
sqrt := PowInt(x, y/2)
|
sqrt := PowInt(x, y/2)
|
||||||
return sqrt * sqrt
|
return sqrt * sqrt
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/gob"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
"bytes"
|
|
||||||
"encoding/gob"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -55,7 +55,6 @@ func encodeIds(ids []PK) (string, error) {
|
||||||
return buf.String(), err
|
return buf.String(), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func decodeIds(s string) ([]PK, error) {
|
func decodeIds(s string) ([]PK, error) {
|
||||||
pks := make([]PK, 0)
|
pks := make([]PK, 0)
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
package cron
|
package cron
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"fmt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Parse returns a new crontab schedule representing the given spec.
|
// Parse returns a new crontab schedule representing the given spec.
|
||||||
|
@ -160,7 +160,7 @@ func all(r bounds) uint64 {
|
||||||
|
|
||||||
// parseDescriptor returns a pre-defined schedule for the expression, or panics
|
// parseDescriptor returns a pre-defined schedule for the expression, or panics
|
||||||
// if none matches.
|
// if none matches.
|
||||||
func parseDescriptor(spec string) (Schedule,error) {
|
func parseDescriptor(spec string) (Schedule, error) {
|
||||||
switch spec {
|
switch spec {
|
||||||
case "@yearly", "@annually":
|
case "@yearly", "@annually":
|
||||||
return &SpecSchedule{
|
return &SpecSchedule{
|
||||||
|
@ -219,7 +219,7 @@ func parseDescriptor(spec string) (Schedule,error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("Failed to parse duration %s: %s", spec, err)
|
return nil, fmt.Errorf("Failed to parse duration %s: %s", spec, err)
|
||||||
}
|
}
|
||||||
return Every(duration),nil
|
return Every(duration), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("Unrecognized descriptor: %s", spec)
|
return nil, fmt.Errorf("Unrecognized descriptor: %s", spec)
|
||||||
|
|
Loading…
Reference in New Issue