diff --git a/README.md b/README.md
index 8f75b60..1c86320 100644
--- a/README.md
+++ b/README.md
@@ -10,3 +10,24 @@ PPGo_Job
3、修改config 配置数据库
4、运行 go build
5、运行 ./run.sh start|stop
+
+前台访问:http://your_host:8080
+用户名:admin 密码:123456
+
+升级日志
+----
+v1.0
+1、初始版本 本地任务的调取和执行
+2、定时任务执行日志
+3、定时任务执行时间
+----
+v1.1
+1、优化界面
+2、优化列表的登录
+3、增加初始化任务
+----
+v1.2
+1、新增服务器资源添加 (新增数据表pp_task_server)
+2、新增远程服务器任务执行
+3、删除邮件通知功能(pp_task删除两个有关字段)
+
diff --git a/conf/app.conf b/conf/app.conf
index 9e626ef..8b650b1 100644
--- a/conf/app.conf
+++ b/conf/app.conf
@@ -3,7 +3,7 @@ httpport = 8080
runmode = dev
# 允许同时运行的任务数
-jobs.pool = 10
+jobs.pool = 1000
# 站点名称
site.name = 定时任务管理器
diff --git a/controllers/group.go b/controllers/group.go
index 10d0bf8..9fd79cb 100644
--- a/controllers/group.go
+++ b/controllers/group.go
@@ -13,6 +13,7 @@ import (
"github.com/george518/PPGo_Job/models"
"strconv"
"strings"
+ "time"
)
type GroupController struct {
@@ -39,6 +40,7 @@ func (this *GroupController) Add() {
group.GroupName = strings.TrimSpace(this.GetString("group_name"))
group.UserId = this.userId
group.Description = strings.TrimSpace(this.GetString("description"))
+ group.CreateTime = time.Now().Unix()
_, err := models.TaskGroupAdd(group)
if err != nil {
diff --git a/controllers/server.go b/controllers/server.go
new file mode 100644
index 0000000..c61bb6e
--- /dev/null
+++ b/controllers/server.go
@@ -0,0 +1,135 @@
+/*
+* @Author: haodaquan
+* @Date: 2017-08-16 10:27:40
+* @Last Modified by: haodaquan
+* @Last Modified time: 2017-08-16 09:17:22
+ */
+
+package controllers
+
+import (
+ "github.com/astaxie/beego"
+ "github.com/george518/PPGo_Job/libs"
+ "github.com/george518/PPGo_Job/models"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type ServerController struct {
+ BaseController
+}
+
+func (this *ServerController) List() {
+ page, _ := this.GetInt("page")
+ if page < 1 {
+ page = 1
+ }
+
+ result, count := models.TaskServerGetList(page, this.pageSize)
+ list := make([]map[string]interface{}, len(result))
+ for k, v := range result {
+ row := make(map[string]interface{})
+ row["id"] = v.Id
+ if(v.Type==0){
+ row["type"] = "密码"
+ }else {
+ row["type"] = "密钥"
+ }
+ row["server_name"] = v.ServerName
+ row["server_ip"] = v.ServerIp
+ row["detail"] = v.Detail
+ row["port"] = v.Port
+ row["create_time"] = beego.Date(time.Unix(v.CreateTime, 0), "Y-m-d H:i:s")
+ list[k] = row
+ }
+ this.Data["pageTitle"] = "服务器列表"
+ this.Data["list"] = list
+ this.Data["pageBar"] = libs.NewPager(page, int(count), this.pageSize, beego.URLFor("ServerController.List"), true).ToString()
+ this.display()
+}
+
+func (this *ServerController) Add() {
+ if this.isPost() {
+ server := new(models.TaskServer)
+ server.ServerName = strings.TrimSpace(this.GetString("server_name"))
+ server.ServerIp = strings.TrimSpace(this.GetString("server_ip"))
+ server.Port,_= strconv.Atoi(this.GetString("port"))
+ server.Type,_ = strconv.Atoi(this.GetString("type"))
+ server.PrivateKeySrc = strings.TrimSpace(this.GetString("private_key_src"))
+ server.PublicKeySrc = strings.TrimSpace(this.GetString("public_key_src"))
+ server.Password = strings.TrimSpace(this.GetString("password"))
+ server.Detail = strings.TrimSpace(this.GetString("detail"))
+ server.CreateTime = time.Now().Unix()
+ server.UpdateTime = time.Now().Unix()
+ server.Status = 0
+ _, err := models.TaskServerAdd(server)
+ if err != nil {
+ this.ajaxMsg(err.Error(), MSG_ERR)
+ }
+ this.ajaxMsg("", MSG_OK)
+ }
+ this.Data["pageTitle"] = "添加服务器"
+ this.display()
+}
+
+func (this *ServerController) Edit() {
+ id, _ := this.GetInt("id")
+ server, err := models.TaskServerGetById(id)
+ if err != nil {
+ this.showMsg(err.Error())
+ }
+
+ if this.isPost() {
+ server.ServerName = strings.TrimSpace(this.GetString("server_name"))
+ server.ServerIp = strings.TrimSpace(this.GetString("server_ip"))
+ server.Port,_ = strconv.Atoi(this.GetString("port"))
+ server.Type,_ = strconv.Atoi(this.GetString("type"))
+ server.Id,_ = strconv.Atoi(this.GetString("id"))
+ server.PrivateKeySrc = strings.TrimSpace(this.GetString("private_key_src"))
+ server.PublicKeySrc = strings.TrimSpace(this.GetString("public_key_src"))
+ server.Password = strings.TrimSpace(this.GetString("password"))
+ server.Detail = strings.TrimSpace(this.GetString("detail"))
+ server.UpdateTime = time.Now().Unix()
+ server.Status = 0
+ err := server.Update()
+ if err != nil {
+ this.ajaxMsg(err.Error(), MSG_ERR)
+ }
+ this.ajaxMsg("", MSG_OK)
+ }
+
+ this.Data["pageTitle"] = "编辑服务器"
+ this.Data["server"] = server
+ this.display()
+}
+
+//TODO删除更新
+func (this *ServerController) Batch() {
+ action := this.GetString("action")
+ ids := this.GetStrings("ids")
+ if len(ids) < 1 {
+ this.ajaxMsg("请选择要操作的项目", MSG_ERR)
+ }
+
+ for _, v := range ids {
+ id, _ := strconv.Atoi(v)
+ if id < 1 {
+ continue
+ }
+ switch action {
+ case "delete":
+ //查询服务器是否被占用
+ filters := make([]interface{}, 0)
+ filters = append(filters, "server_id", id)
+ _, count := models.TaskGetList(1, 1000, filters...)
+ if count > 0 {
+ this.ajaxMsg("请先解除该服务器的任务占用", MSG_ERR)
+ }else{
+ models.TaskServerDelById(id)
+ }
+ }
+ }
+
+ this.ajaxMsg("", MSG_OK)
+}
diff --git a/controllers/task.go b/controllers/task.go
index a3cbe0a..a60d6aa 100644
--- a/controllers/task.go
+++ b/controllers/task.go
@@ -43,12 +43,23 @@ func (this *TaskController) List() {
result, count := models.TaskGetList(page, this.pageSize, filters...)
list := make([]map[string]interface{}, len(result))
+
+
// 分组列表
groups, _ := models.TaskGroupGetList(1, 100)
groups_map := make(map[int]string)
for _, gname := range groups {
groups_map[gname.Id] = gname.GroupName
}
+
+ //服务器列表
+ servers, _ := models.TaskServerGetList(1, 100)
+
+ server_map := make(map[int]string)
+ for _, sname := range servers {
+ server_map[sname.Id] = sname.ServerName
+ }
+ server_map[0] = "本地"
for k, v := range result {
row := make(map[string]interface{})
row["id"] = v.Id
@@ -58,6 +69,7 @@ func (this *TaskController) List() {
row["description"] = v.Description
row["group_id"] = v.GroupId
row["group_name"] = groups_map[v.GroupId]
+ row["server_name"] = server_map[v.ServerId]
row["is_odd"] = k % 2
e := jobs.GetEntryById(v.Id)
@@ -81,6 +93,7 @@ func (this *TaskController) List() {
}
list[k] = row
}
+
this.Data["pageTitle"] = "任务列表"
this.Data["list"] = list
this.Data["groups"] = groups
@@ -99,26 +112,11 @@ func (this *TaskController) Add() {
task.TaskName = strings.TrimSpace(this.GetString("task_name"))
task.Description = strings.TrimSpace(this.GetString("description"))
task.Concurrent, _ = this.GetInt("concurrent")
+ task.ServerId, _ = this.GetInt("server_id")
task.CronSpec = strings.TrimSpace(this.GetString("cron_spec"))
task.Command = strings.TrimSpace(this.GetString("command"))
- task.Notify, _ = this.GetInt("notify")
task.Timeout, _ = this.GetInt("timeout")
- notifyEmail := strings.TrimSpace(this.GetString("notify_email"))
- if notifyEmail != "" {
- emailList := make([]string, 0)
- tmp := strings.Split(notifyEmail, "\n")
- for _, v := range tmp {
- v = strings.TrimSpace(v)
- if !libs.IsEmail([]byte(v)) {
- this.ajaxMsg("无效的Email地址:"+v, MSG_ERR)
- } else {
- emailList = append(emailList, v)
- }
- }
- task.NotifyEmail = strings.Join(emailList, "\n")
- }
-
if task.TaskName == "" || task.CronSpec == "" || task.Command == "" {
this.ajaxMsg("请填写完整信息", MSG_ERR)
}
@@ -135,6 +133,9 @@ func (this *TaskController) Add() {
// 分组列表
groups, _ := models.TaskGroupGetList(1, 100)
this.Data["groups"] = groups
+ //服务器分组
+ servers, _ := models.TaskServerGetList(1, 100)
+ this.Data["servers"] = servers
this.Data["pageTitle"] = "添加任务"
this.display()
}
@@ -153,26 +154,10 @@ func (this *TaskController) Edit() {
task.Description = strings.TrimSpace(this.GetString("description"))
task.GroupId, _ = this.GetInt("group_id")
task.Concurrent, _ = this.GetInt("concurrent")
+ task.ServerId, _ = this.GetInt("server_id")
task.CronSpec = strings.TrimSpace(this.GetString("cron_spec"))
task.Command = strings.TrimSpace(this.GetString("command"))
- task.Notify, _ = this.GetInt("notify")
task.Timeout, _ = this.GetInt("timeout")
-
- notifyEmail := strings.TrimSpace(this.GetString("notify_email"))
- if notifyEmail != "" {
- tmp := strings.Split(notifyEmail, "\n")
- emailList := make([]string, 0, len(tmp))
- for _, v := range tmp {
- v = strings.TrimSpace(v)
- if !libs.IsEmail([]byte(v)) {
- this.ajaxMsg("无效的Email地址:"+v, MSG_ERR)
- } else {
- emailList = append(emailList, v)
- }
- }
- task.NotifyEmail = strings.Join(emailList, "\n")
- }
-
if task.TaskName == "" || task.CronSpec == "" || task.Command == "" {
this.ajaxMsg("请填写完整信息", MSG_ERR)
}
@@ -189,6 +174,10 @@ func (this *TaskController) Edit() {
// 分组列表
groups, _ := models.TaskGroupGetList(1, 100)
this.Data["groups"] = groups
+ //服务器分组
+ servers, _ := models.TaskServerGetList(1, 100)
+ this.Data["servers"] = servers
+
this.Data["task"] = task
this.Data["pageTitle"] = "编辑任务"
this.display()
diff --git a/info.log b/info.log
new file mode 100644
index 0000000..2e2ddb3
--- /dev/null
+++ b/info.log
@@ -0,0 +1,34 @@
+nohup: ./PPGo_Job: No such file or directory
+[ORM]2017/08/16 09:38:35 -[Queries/default] - [ OK / db.QueryRow / 20.4ms] - [SELECT COUNT(*) FROM `pp_task` T0 WHERE T0.`status` = ? ] - `1`
+[ORM]2017/08/16 09:38:35 -[Queries/default] - [ OK / db.Query / 0.8ms] - [SELECT T0.`id`, T0.`user_id`, T0.`group_id`, T0.`task_name`, T0.`task_type`, T0.`description`, T0.`cron_spec`, T0.`concurrent`, T0.`command`, T0.`status`, T0.`notify`, T0.`notify_email`, T0.`timeout`, T0.`execute_times`, T0.`prev_time`, T0.`create_time` FROM `pp_task` T0 WHERE T0.`status` = ? ORDER BY T0.`id` DESC LIMIT 1000000] - `1`
+2017/08/16 09:38:35 [1;34m[I] [asm_amd64.s:2197] http server Running on http://:8080[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 1.098433ms| match|[44m GET [0m /login r:/login[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 405.271µs| match|[44m GET [0m /static/login/style.css[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 4.183452ms| match|[44m GET [0m /static/bootstrap/css/bootstrap.min.css[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 5.848598ms| match|[44m GET [0m /static/js/jquery-1.11.1.min.js[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 7.361263ms| match|[44m GET [0m /static/bootstrap/js/bootstrap.js[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 1.723698ms| match|[44m GET [0m /static/login/background.jpg[0m
+2017/08/16 09:38:40 [1;44m[D] [server.go:2568] | 127.0.0.1|[43m 404 [0m| 329.057µs| nomatch|[44m GET [0m /static/img/favicon.png[0m
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.Query / 9.1ms] - [SELECT T0.`id`, T0.`user_name`, T0.`password`, T0.`salt`, T0.`email`, T0.`last_login`, T0.`last_ip`, T0.`status` FROM `pp_user` T0 WHERE T0.`user_name` = ? LIMIT 1] - `admin`
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.Exec / 4.3ms] - [UPDATE `pp_user` SET `user_name` = ?, `password` = ?, `salt` = ?, `email` = ?, `last_login` = ?, `last_ip` = ?, `status` = ? WHERE `id` = ?] - `admin`, `abfcf6dcedfb4b5b1505d41a8b4c77e8`, `aYk4Q1P83v`, `haodaquan@shoplinq.cn`, `1502847522`, `[`, `0`, `1`
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.Query / 0.5ms] - [SELECT T0.`id`, T0.`user_name`, T0.`password`, T0.`salt`, T0.`email`, T0.`last_login`, T0.`last_ip`, T0.`status` FROM `pp_user` T0 WHERE T0.`id` = ? LIMIT 1] - `1`
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.QueryRow / 0.7ms] - [SELECT COUNT(*) FROM `pp_task` T0 ]
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.Query / 1.0ms] - [SELECT T0.`id`, T0.`user_id`, T0.`group_id`, T0.`task_name`, T0.`task_type`, T0.`description`, T0.`cron_spec`, T0.`concurrent`, T0.`command`, T0.`status`, T0.`notify`, T0.`notify_email`, T0.`timeout`, T0.`execute_times`, T0.`prev_time`, T0.`create_time` FROM `pp_task` T0 ORDER BY T0.`id` DESC LIMIT 20]
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.QueryRow / 3.6ms] - [SELECT COUNT(*) FROM `pp_task_group` T0 ]
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.Query / 1.5ms] - [SELECT T0.`id`, T0.`user_id`, T0.`group_name`, T0.`description`, T0.`create_time` FROM `pp_task_group` T0 ORDER BY T0.`id` DESC LIMIT 100]
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 10.55596ms| match|[44m GET [0m /task/list r:/task/list/*[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 1.173247ms| match|[44m GET [0m /static/css/dermaorange.css[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 628.292µs| match|[44m GET [0m /static/css/dermadefault.css[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 1.808048ms| match|[44m GET [0m /static/css/style.css[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 1.171345ms| match|[44m GET [0m /static/css/templatecss.css[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 2.631179ms| match|[44m GET [0m /static/css/dermagreen.css[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 2.248771ms| match|[44m GET [0m /static/js/jquery.cookie.js[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 809.603µs| match|[44m GET [0m /static/bootstrap/js/bootstrap.min.js[0m
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 367.119µs| match|[44m GET [0m /static/bootstrap/fonts/glyphicons-halflings-regular.woff2[0m
+[ORM]2017/08/16 09:38:42 -[Queries/default] - [ OK / db.Query / 0.4ms] - [SELECT T0.`id`, T0.`user_name`, T0.`password`, T0.`salt`, T0.`email`, T0.`last_login`, T0.`last_ip`, T0.`status` FROM `pp_user` T0 WHERE T0.`id` = ? LIMIT 1] - `1`
+2017/08/16 09:38:42 [1;44m[D] [server.go:2568] | 127.0.0.1|[43m 404 [0m| 278.275µs| nomatch|[44m GET [0m /favicon.ico[0m
+[ORM]2017/08/16 09:38:47 -[Queries/default] - [ OK / db.Query / 1.8ms] - [SELECT T0.`id`, T0.`user_name`, T0.`password`, T0.`salt`, T0.`email`, T0.`last_login`, T0.`last_ip`, T0.`status` FROM `pp_user` T0 WHERE T0.`id` = ? LIMIT 1] - `1`
+[ORM]2017/08/16 09:38:47 -[Queries/default] - [ OK / db.QueryRow / 0.1ms] - [SELECT COUNT(*) FROM `pp_task_group` T0 ]
+[ORM]2017/08/16 09:38:47 -[Queries/default] - [ OK / db.Query / 0.2ms] - [SELECT T0.`id`, T0.`user_id`, T0.`group_name`, T0.`description`, T0.`create_time` FROM `pp_task_group` T0 ORDER BY T0.`id` DESC LIMIT 20]
+2017/08/16 09:38:47 [1;44m[D] [server.go:2568] | 127.0.0.1|[42m 200 [0m| 4.738919ms| match|[44m GET [0m /group/list r:/group/list/*[0m
+[ORM]2017/08/16 09:38:47 -[Queries/default] - [ OK / db.Query / 0.6ms] - [SELECT T0.`id`, T0.`user_name`, T0.`password`, T0.`salt`, T0.`email`, T0.`last_login`, T0.`last_ip`, T0.`status` FROM `pp_user` T0 WHERE T0.`id` = ? LIMIT 1] - `1`
diff --git a/jobs/job.go b/jobs/job.go
index 7cdd5de..f40f4c4 100644
--- a/jobs/job.go
+++ b/jobs/job.go
@@ -11,40 +11,16 @@ import (
"bytes"
"fmt"
"github.com/astaxie/beego"
- "github.com/george518/PPGo_Job/mail"
"github.com/george518/PPGo_Job/models"
- "html/template"
"os/exec"
"runtime/debug"
- "strings"
"time"
+ "io/ioutil"
+ "golang.org/x/crypto/ssh"
+ "net"
)
-var mailTpl *template.Template
-func init() {
- mailTpl, _ = template.New("mail_tpl").Parse(`
- 你好 {{.username}},
-
-
以下是任务执行结果:
-
-
-任务ID:{{.task_id}}
-任务名称:{{.task_name}}
-执行时间:{{.start_time}}
-执行耗时:{{.process_time}}秒
-执行状态:{{.status}}
-
--------------以下是任务执行输出-------------
-{{.output}}
-
---------------------------------------------
-本邮件由系统自动发出,请勿回复
-如果要取消邮件通知,请登录到系统进行设置
-
-`)
-
-}
type Job struct {
id int // 任务ID
@@ -56,14 +32,24 @@ type Job struct {
Concurrent bool // 同一个任务是否允许并行执行
}
+
func NewJobFromTask(task *models.Task) (*Job, error) {
if task.Id < 1 {
return nil, fmt.Errorf("ToJob: 缺少id")
}
- job := NewCommandJob(task.Id, task.TaskName, task.Command)
- job.task = task
- job.Concurrent = task.Concurrent == 1
- return job, nil
+ //本地程序执行
+ if(task.ServerId==0) {
+ job := NewCommandJob(task.Id, task.TaskName, task.Command)
+ job.task = task
+ job.Concurrent = task.Concurrent == 1
+ return job, nil
+ }else{
+ server, _ := models.TaskServerGetById(task.ServerId)
+ job := RemoteCommandJob(task.Id, task.TaskName, task.Command,server)
+ job.task = task
+ job.Concurrent = task.Concurrent == 1
+ return job, nil
+ }
}
func NewCommandJob(id int, name string, command string) *Job {
@@ -85,6 +71,66 @@ func NewCommandJob(id int, name string, command string) *Job {
}
return job
}
+//远程执行任务
+func RemoteCommandJob(id int,name string,command string,servers *models.TaskServer) *Job {
+ job := &Job{
+ id: id,
+ name: name,
+ }
+ job.runFunc = func(timeout time.Duration) (string, string, error, bool) {
+
+ key, err := ioutil.ReadFile(servers.PrivateKeySrc)
+ if err != nil {
+ return "","",err,false
+ }
+ // Create the Signer for this private key.
+ signer, err := ssh.ParsePrivateKey(key)
+ if err != nil {
+ return "","",err,false
+ }
+ addr := fmt.Sprintf("%s:%d", servers.ServerIp, servers.Port)
+ config := &ssh.ClientConfig{
+ User: "root",
+ Auth: []ssh.AuthMethod{
+ // Use the PublicKeys method for remote authentication.
+ ssh.PublicKeys(signer),
+ },
+ //HostKeyCallback: ssh.FixedHostKey(hostKey),
+ HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+ return nil
+ },
+ }
+ // Connect to the remote server and perform the SSH handshake.47.93.220.5
+ client, err := ssh.Dial("tcp", addr, config)
+ if err != nil {
+ return "","",err,false
+ }
+
+ session, err := client.NewSession()
+ if err != nil {
+ return "","",err,false
+ }
+ defer session.Close()
+
+ // Once a Session is created, you can execute a single command on
+ // the remote side using the Run method.
+
+ var b bytes.Buffer
+ var c bytes.Buffer
+ session.Stdout = &b
+ session.Stderr = &c
+
+ //session.Output(command)
+ if err := session.Run(command); err != nil {
+ return "","",err,false
+ }
+ isTimeout := false
+ return b.String(), c.String(), err, isTimeout
+ }
+ return job
+}
+
+
func (j *Job) Status() int {
return j.status
@@ -159,41 +205,41 @@ func (j *Job) Run() {
j.task.Update("PrevTime", "ExecuteTimes")
// 发送邮件通知
- if (j.task.Notify == 1 && err != nil) || j.task.Notify == 2 {
- user, uerr := models.UserGetById(j.task.UserId)
- if uerr != nil {
- return
- }
-
- var title string
-
- data := make(map[string]interface{})
- data["task_id"] = j.task.Id
- data["username"] = user.UserName
- data["task_name"] = j.task.TaskName
- data["start_time"] = beego.Date(t, "Y-m-d H:i:s")
- data["process_time"] = float64(ut) / 1000
- data["output"] = cmdOut
-
- if isTimeout {
- title = fmt.Sprintf("任务执行结果通知 #%d: %s", j.task.Id, "超时")
- data["status"] = fmt.Sprintf("超时(%d秒)", int(timeout/time.Second))
- } else if err != nil {
- title = fmt.Sprintf("任务执行结果通知 #%d: %s", j.task.Id, "失败")
- data["status"] = "失败(" + err.Error() + ")"
- } else {
- title = fmt.Sprintf("任务执行结果通知 #%d: %s", j.task.Id, "成功")
- data["status"] = "成功"
- }
-
- content := new(bytes.Buffer)
- mailTpl.Execute(content, data)
- ccList := make([]string, 0)
- if j.task.NotifyEmail != "" {
- ccList = strings.Split(j.task.NotifyEmail, "\n")
- }
- if !mail.SendMail(user.Email, user.UserName, title, content.String(), ccList) {
- beego.Error("发送邮件超时:", user.Email)
- }
- }
+ //if (j.task.Notify == 1 && err != nil) || j.task.Notify == 2 {
+ // user, uerr := models.UserGetById(j.task.UserId)
+ // if uerr != nil {
+ // return
+ // }
+ //
+ // var title string
+ //
+ // data := make(map[string]interface{})
+ // data["task_id"] = j.task.Id
+ // data["username"] = user.UserName
+ // data["task_name"] = j.task.TaskName
+ // data["start_time"] = beego.Date(t, "Y-m-d H:i:s")
+ // data["process_time"] = float64(ut) / 1000
+ // data["output"] = cmdOut
+ //
+ // if isTimeout {
+ // title = fmt.Sprintf("任务执行结果通知 #%d: %s", j.task.Id, "超时")
+ // data["status"] = fmt.Sprintf("超时(%d秒)", int(timeout/time.Second))
+ // } else if err != nil {
+ // title = fmt.Sprintf("任务执行结果通知 #%d: %s", j.task.Id, "失败")
+ // data["status"] = "失败(" + err.Error() + ")"
+ // } else {
+ // title = fmt.Sprintf("任务执行结果通知 #%d: %s", j.task.Id, "成功")
+ // data["status"] = "成功"
+ // }
+ //
+ // content := new(bytes.Buffer)
+ // mailTpl.Execute(content, data)
+ // ccList := make([]string, 0)
+ // if j.task.NotifyEmail != "" {
+ // ccList = strings.Split(j.task.NotifyEmail, "\n")
+ // }
+ // if !mail.SendMail(user.Email, user.UserName, title, content.String(), ccList) {
+ // beego.Error("发送邮件超时:", user.Email)
+ // }
+ //}
}
diff --git a/mail/mail.go b/mail/mail.go
deleted file mode 100644
index 25afe89..0000000
--- a/mail/mail.go
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-* @Author: haodaquan
-* @Date: 2017-06-21 13:06:28
-* @Last Modified by: haodaquan
-* @Last Modified time: 2017-06-21 13:06:33
- */
-
-package mail
-
-import (
- "fmt"
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/utils"
- "time"
-)
-
-var (
- sendCh chan *utils.Email
- config string
-)
-
-func init() {
- queueSize, _ := beego.AppConfig.Int("mail.queue_size")
- host := beego.AppConfig.String("mail.host")
- port, _ := beego.AppConfig.Int("mail.port")
- username := beego.AppConfig.String("mail.user")
- password := beego.AppConfig.String("mail.password")
- from := beego.AppConfig.String("mail.from")
- if port == 0 {
- port = 25
- }
-
- config = fmt.Sprintf(`{"username":"%s","password":"%s","host":"%s","port":%d,"from":"%s"}`, username, password, host, port, from)
-
- sendCh = make(chan *utils.Email, queueSize)
-
- go func() {
- for {
- select {
- case m, ok := <-sendCh:
- if !ok {
- return
- }
- if err := m.Send(); err != nil {
- beego.Error("SendMail:", err.Error())
- }
- }
- }
- }()
-}
-
-func SendMail(address, name, subject, content string, cc []string) bool {
- mail := utils.NewEMail(config)
- mail.To = []string{address}
- mail.Subject = subject
- mail.HTML = content
- if len(cc) > 0 {
- mail.Cc = cc
- }
-
- select {
- case sendCh <- mail:
- return true
- case <-time.After(time.Second * 3):
- return false
- }
-}
diff --git a/main.go b/main.go
index 6097d81..fe71d1c 100644
--- a/main.go
+++ b/main.go
@@ -2,7 +2,6 @@ package main
import (
"github.com/astaxie/beego"
- _ "github.com/george518/PPGo_Job/mail"
"github.com/george518/PPGo_Job/models"
_ "github.com/george518/PPGo_Job/routers"
"github.com/george518/PPGo_Job/jobs"
diff --git a/models/init.go b/models/init.go
index 42eb5ec..5a75d2a 100644
--- a/models/init.go
+++ b/models/init.go
@@ -30,9 +30,7 @@ func Init() {
dsn = dsn + "&loc=" + url.QueryEscape(timezone)
}
orm.RegisterDataBase("default", "mysql", dsn)
-
- // orm.RegisterModel(new(User), new(Task), new(TaskGroup), new(TaskLog))
- orm.RegisterModel(new(User), new(Task), new(TaskGroup), new(TaskLog))
+ orm.RegisterModel(new(User), new(Task), new(TaskGroup), new(TaskLog),new(TaskServer))
if beego.AppConfig.String("runmode") == "dev" {
orm.Debug = true
diff --git a/models/task.go b/models/task.go
index a585be5..c893c1c 100644
--- a/models/task.go
+++ b/models/task.go
@@ -22,6 +22,7 @@ const (
type Task struct {
Id int
UserId int
+ ServerId int
GroupId int
TaskName string
TaskType int
@@ -30,8 +31,6 @@ type Task struct {
Concurrent int
Command string
Status int
- Notify int
- NotifyEmail string
Timeout int
ExecuteTimes int
PrevTime int64
diff --git a/models/task_group.go b/models/task_group.go
index 9b47ed3..a5570df 100644
--- a/models/task_group.go
+++ b/models/task_group.go
@@ -60,9 +60,7 @@ func TaskGroupDelById(id int) error {
func TaskGroupGetList(page, pageSize int) ([]*TaskGroup, int64) {
offset := (page - 1) * pageSize
-
list := make([]*TaskGroup, 0)
-
query := orm.NewOrm().QueryTable(TableName("task_group"))
total, _ := query.Count()
query.OrderBy("-id").Limit(pageSize, offset).All(&list)
diff --git a/models/task_server.go b/models/task_server.go
new file mode 100644
index 0000000..2f2ed79
--- /dev/null
+++ b/models/task_server.go
@@ -0,0 +1,87 @@
+/*
+* @Author: haodaquan
+* @Date: 2017-08-16 12:22:37
+* @Last Modified by: haodaquan
+* @Last Modified time: 2017-08-16 12:22:55
+ */
+
+package models
+
+import (
+ "fmt"
+ "github.com/astaxie/beego/orm"
+)
+
+type TaskServer struct {
+ Id int
+ ServerName string
+ ServerIp string
+ Port int
+ Password string
+ PrivateKeySrc string
+ PublicKeySrc string
+ Type int
+ Detail string
+ CreateTime int64
+ UpdateTime int64
+ Status int
+}
+
+func (t *TaskServer) TableName() string {
+ return TableName("task_server")
+}
+
+func (t *TaskServer) Update(fields ...string) error {
+ if t.ServerName == "" {
+ return fmt.Errorf("服务器名不能为空")
+ }
+ if t.ServerIp == "" {
+ return fmt.Errorf("服务器IP不能为空")
+ }
+
+ if t.Type == 0 && t.Password == "" {
+ return fmt.Errorf("服务器密码不能为空")
+ }
+
+ if t.Type == 1 && t.PrivateKeySrc == "" {
+ return fmt.Errorf("私钥不能为空")
+ }
+
+ if _, err := orm.NewOrm().Update(t, fields...); err != nil {
+ return err
+ }
+ return nil
+}
+
+func TaskServerAdd(obj *TaskServer) (int64, error) {
+ if obj.ServerName == "" {
+ return 0, fmt.Errorf("服务器名不能为空")
+ }
+ return orm.NewOrm().Insert(obj)
+}
+
+func TaskServerGetById(id int) (*TaskServer, error) {
+ obj := &TaskServer{
+ Id: id,
+ }
+ err := orm.NewOrm().Read(obj)
+ if err != nil {
+ return nil, err
+ }
+ return obj, nil
+}
+
+func TaskServerDelById(id int) error {
+ _, err := orm.NewOrm().QueryTable(TableName("task_server")).Filter("id", id).Delete()
+ return err
+}
+
+func TaskServerGetList(page, pageSize int) ([]*TaskServer, int64) {
+ offset := (page - 1) * pageSize
+ list := make([]*TaskServer, 0)
+ query := orm.NewOrm().QueryTable(TableName("task_server"))
+ total, _ := query.Count()
+ query.OrderBy("-id").Limit(pageSize, offset).All(&list)
+
+ return list, total
+}
diff --git a/ppgo_job.sql b/ppgo_job.sql
index 9f6f823..3da4dde 100644
--- a/ppgo_job.sql
+++ b/ppgo_job.sql
@@ -9,7 +9,7 @@
Target Server Version : 50712
File Encoding : utf-8
- Date: 07/03/2017 17:02:41 PM
+ Date: 08/17/2017 11:29:01 AM
*/
SET NAMES utf8;
@@ -46,6 +46,7 @@ DROP TABLE IF EXISTS `pp_task`;
CREATE TABLE `pp_task` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL DEFAULT '0' COMMENT '用户ID',
+ `server_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '服务器资源ID',
`group_id` int(11) NOT NULL DEFAULT '0' COMMENT '分组ID',
`task_name` varchar(50) NOT NULL DEFAULT '' COMMENT '任务名称',
`task_type` tinyint(4) unsigned NOT NULL DEFAULT '0' COMMENT '任务类型:1-常驻类型,0-定时类型',
@@ -54,8 +55,6 @@ CREATE TABLE `pp_task` (
`concurrent` tinyint(4) NOT NULL DEFAULT '0' COMMENT '是否只允许一个实例',
`command` text NOT NULL COMMENT '命令详情',
`status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0停用 1启用',
- `notify` tinyint(4) NOT NULL DEFAULT '0' COMMENT '通知设置',
- `notify_email` text NOT NULL COMMENT '通知人列表',
`timeout` smallint(6) NOT NULL DEFAULT '0' COMMENT '超时设置',
`execute_times` int(11) NOT NULL DEFAULT '0' COMMENT '累计执行次数',
`prev_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '上次执行时间',
@@ -63,13 +62,13 @@ CREATE TABLE `pp_task` (
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_group_id` (`group_id`)
-) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of `pp_task`
-- ----------------------------
BEGIN;
-INSERT INTO `pp_task` VALUES ('1', '1', '1', '测试任务', '0', '测试任务说明', '0 0/1 11 * *', '0', 'echo \"hello\\n\" >> /tmp/test_cron1.log', '0', '0', '', '0', '46', '1498187640', '1497855526'), ('2', '1', '1', '测试任务23', '0', '这是测试任务3', '*/5 * * * *', '0', 'echo \"hello22\" >> /tmp/test.log', '0', '1', 'sdf@11.com', '2', '14', '1498554870', '1498034382'), ('3', '1', '2', '测试php', '1', '五秒中一次', '*/5 * * * *', '0', '/usr/local/php/bin/php /Users/haodaquan/Sites/WorkList/xiyou_channel/index.php /tmall_abroad/task test_cron', '0', '0', '', '0', '143', '1498808295', '1498541334'), ('4', '1', '1', '定时获取订单2', '1', '每五秒执行一次22', '*/5 * * * *', '0', 'echo \"test\" >> /tmp/test.log', '0', '0', '', '0', '15', '1498728615', '1498723369'), ('5', '1', '2', 'ceshi', '0', '每天一次1', '0 */5 * * *', '0', 'echo \"test\" >> /tmp/test.log', '0', '0', '', '0', '1', '1499072538', '1499072512');
+INSERT INTO `pp_task` VALUES ('1', '1', '0', '2', '测试任务名称', '0', '测试任务说明', '0 0/1 11 * *', '0', 'echo \"hello\\n\" >> /tmp/test_cron1.log', '0', '0', '46', '1498187640', '1497855526'), ('2', '1', '1', '2', '外部服务器', '0', '一分钟一次', '0 */1 * * * *', '0', '/webroot/server/php/bin/php /webroot/www/default/test.php', '0', '0', '83', '1502940180', '1502876155'), ('3', '1', '1', '1', '重要测试任务222', '0', '1分钟执行一次', '0 */1 * * *', '0', '/webroot/server/php/bin/php /webroot/www/default/test2.php', '0', '0', '22', '1502940060', '1502936077');
COMMIT;
-- ----------------------------
@@ -84,13 +83,13 @@ CREATE TABLE `pp_task_group` (
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of `pp_task_group`
-- ----------------------------
BEGIN;
-INSERT INTO `pp_task_group` VALUES ('1', '1', '测试分组的', '这是测试的分组内容', '0'), ('2', '1', '小红书', '小红书的任务', '0');
+INSERT INTO `pp_task_group` VALUES ('1', '1', '抓取任务', '定时抓取网页', '0'), ('2', '1', '测试任务', '任务分组测试', '0');
COMMIT;
-- ----------------------------
@@ -107,13 +106,40 @@ CREATE TABLE `pp_task_log` (
`create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_task_id` (`task_id`,`create_time`)
-) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8;
+) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of `pp_task_log`
-- ----------------------------
BEGIN;
-INSERT INTO `pp_task_log` VALUES ('1', '3', '2017-06-30 10:45:31开始写入日志\n2017-06-30 10:45:32开始写入日志\n2017-06-30 10:45:33开始写入日志\n2017-06-30 10:45:34开始写入日志\n2017-06-30 10:45:35开始写入日志\n2017-06-30 10:45:36开始写入日志\n2017-06-30 10:45:37开始写入日志\n2017-06-30 10:45:38开始写入日志\n2017-06-30 10:45:39开始写入日志\n2017-06-30 10:45:40开始写入日志\n2017-06-30 10:45:41开始写入日志\n2017-06-30 10:45:42开始写入日志\n2017-06-30 10:45:43开始写入日志\n2017-06-30 10:45:44开始写入日志\n2017-06-30 10:45:45开始写入日志\n2017-06-30 10:45:46开始写入日志\n2017-06-30 10:45:47开始写入日志\n2017-06-30 10:45:48开始写入日志\n2017-06-30 10:45:49开始写入日志\n2017-06-30 10:45:50开始写入日志\n2017-06-30 10:45:51开始写入日志\n2017-06-30 10:45:52开始写入日志\n2017-06-30 10:45:53开始写入日志\n2017-06-30 10:45:54开始写入日志\n2017-06-30 10:45:55开始写入日志\n2017-06-30 10:45:56开始写入日志\n2017-06-30 10:45:57开始写入日志\n2017-06-30 10:45:58开始写入日志\n2017-06-30 10:45:59开始写入日志\n2017-06-30 10:46:00开始写入日志\n2017-06-30 10:46:01开始写入日志\n2017-06-30 10:46:02开始写入日志\n2017-06-30 10:46:03开始写入日志\n2017-06-30 10:46:04开始写入日志\n2017-06-30 10:46:05开始写入日志\n2017-06-30 10:46:06开始写入日志\n2017-06-30 10:46:07开始写入日志\n2017-06-30 10:46:08开始写入日志\n2017-06-30 10:46:09开始写入日志\n2017-06-30 10:46:10开始写入日志\n2017-06-30 10:46:11开始写入日志\n2017-06-30 10:46:12开始写入日志\n2017-06-30 10:46:13开始写入日志\n2017-06-30 10:46:14开始写入日志\n2017-06-30 10:46:15开始写入日志\n2017-06-30 10:46:16开始写入日志\n2017-06-30 10:46:17开始写入日志\n2017-06-30 10:46:18开始写入日志\n2017-06-30 10:46:19开始写入日志\n2017-06-30 10:46:20开始写入日志\n2017-06-30 10:46:21开始写入日志\n2017-06-30 10:46:22开始写入日志\n2017-06-30 10:46:23开始写入日志\n2017-06-30 10:46:24开始写入日志\n2017-06-30 10:46:25开始写入日志\n2017-06-30 10:46:26开始写入日志\n2017-06-30 10:46:27开始写入日志\n2017-06-30 10:46:28开始写入日志\n2017-06-30 10:46:29开始写入日志\n2017-06-30 10:46:30开始写入日志\n2017-06-30 10:46:31开始写入日志\n2017-06-30 10:46:32开始写入日志\n2017-06-30 10:46:33开始写入日志\n2017-06-30 10:46:34开始写入日志\n2017-06-30 10:46:35开始写入日志\n2017-06-30 10:46:36开始写入日志\n2017-06-30 10:46:37开始写入日志\n2017-06-30 10:46:38开始写入日志\n2017-06-30 10:46:39开始写入日志\n2017-06-30 10:46:40开始写入日志\n2017-06-30 10:46:41开始写入日志\n2017-06-30 10:46:42开始写入日志\n2017-06-30 10:46:43开始写入日志\n2017-06-30 10:46:44开始写入日志\n2017-06-30 10:46:45开始写入日志\n2017-06-30 10:46:46开始写入日志\n2017-06-30 10:46:47开始写入日志\n2017-06-30 10:46:48开始写入日志\n2017-06-30 10:46:49开始写入日志\n2017-06-30 10:46:50开始写入日志\n2017-06-30 10:46:51开始写入日志\n2017-06-30 10:46:52开始写入日志\n2017-06-30 10:46:53开始写入日志\n2017-06-30 10:46:54开始写入日志\n2017-06-30 10:46:55开始写入日志\n2017-06-30 10:46:56开始写入日志\n2017-06-30 10:46:57开始写入日志\n2017-06-30 10:46:58开始写入日志\n2017-06-30 10:46:59开始写入日志\n2017-06-30 10:47:00开始写入日志\n2017-06-30 10:47:01开始写入日志\n2017-06-30 10:47:02开始写入日志\n2017-06-30 10:47:03开始写入日志\n2017-06-30 10:47:04开始写入日志\n2017-06-30 10:47:05开始写入日志\n2017-06-30 10:47:06开始写入日志\n2017-06-30 10:47:07开始写入日志\n2017-06-30 10:47:08开始写入日志\n2017-06-30 10:47:09开始写入日志\n2017-06-30 10:47:10开始写入日志\n2017-06-30 10:47:11开始写入日志\n2017-06-30 10:47:12开始写入日志\n2017-06-30 10:47:13开始写入日志\n2017-06-30 10:47:14开始写入日志\n2017-06-30 10:47:15开始写入日志\n2017-06-30 10:47:16开始写入日志\n2017-06-30 10:47:17开始写入日志\n2017-06-30 10:47:18开始写入日志\n2017-06-30 10:47:19开始写入日志\n2017-06-30 10:47:20开始写入日志\n2017-06-30 10:47:21开始写入日志\n2017-06-30 10:47:22开始写入日志\n2017-06-30 10:47:23开始写入日志\n2017-06-30 10:47:24开始写入日志\n2017-06-30 10:47:25开始写入日志\n2017-06-30 10:47:26开始写入日志\n2017-06-30 10:47:27开始写入日志\n2017-06-30 10:47:28开始写入日志\n2017-06-30 10:47:29开始写入日志\n2017-06-30 10:47:30开始写入日志\n2017-06-30 10:47:31开始写入日志\n2017-06-30 10:47:32开始写入日志\n2017-06-30 10:47:33开始写入日志\n2017-06-30 10:47:34开始写入日志\n2017-06-30 10:47:35开始写入日志\n2017-06-30 10:47:36开始写入日志\n2017-06-30 10:47:37开始写入日志\n2017-06-30 10:47:38开始写入日志\n2017-06-30 10:47:39开始写入日志\n2017-06-30 10:47:40开始写入日志\n2017-06-30 10:47:41开始写入日志\n2017-06-30 10:47:42开始写入日志\n2017-06-30 10:47:43开始写入日志\n2017-06-30 10:47:44开始写入日志\n2017-06-30 10:47:45开始写入日志\n2017-06-30 10:47:46开始写入日志\n2017-06-30 10:47:47开始写入日志\n2017-06-30 10:47:48开始写入日志\n2017-06-30 10:47:49开始写入日志\n2017-06-30 10:47:50开始写入日志\n2017-06-30 10:47:51开始写入日志\n2017-06-30 10:47:52开始写入日志\n2017-06-30 10:47:53开始写入日志\n2017-06-30 10:47:54开始写入日志\n2017-06-30 10:47:55开始写入日志\n2017-06-30 10:47:56开始写入日志\n2017-06-30 10:47:57开始写入日志\n2017-06-30 10:47:58开始写入日志\n2017-06-30 10:47:59开始写入日志\n2017-06-30 10:48:00开始写入日志\n2017-06-30 10:48:01开始写入日志\n2017-06-30 10:48:02开始写入日志\n2017-06-30 10:48:03开始写入日志\n2017-06-30 10:48:04开始写入日志\n2017-06-30 10:48:05开始写入日志\n2017-06-30 10:48:06开始写入日志\n2017-06-30 10:48:07开始写入日志\n2017-06-30 10:48:08开始写入日志\n2017-06-30 10:48:09开始写入日志\n2017-06-30 10:48:10开始写入日志\n2017-06-30 10:48:11开始写入日志\n2017-06-30 10:48:12开始写入日志\n2017-06-30 10:48:13开始写入日志\n2017-06-30 10:48:14开始写入日志\n2017-06-30 10:48:15开始写入日志\n2017-06-30 10:48:16开始写入日志\n2017-06-30 10:48:17开始写入日志\n2017-06-30 10:48:18开始写入日志\n2017-06-30 10:48:19开始写入日志\n2017-06-30 10:48:20开始写入日志\n2017-06-30 10:48:21开始写入日志\n2017-06-30 10:48:22开始写入日志\n2017-06-30 10:48:23开始写入日志\n2017-06-30 10:48:24开始写入日志\n2017-06-30 10:48:25开始写入日志\n2017-06-30 10:48:26开始写入日志\n2017-06-30 10:48:27开始写入日志\n2017-06-30 10:48:28开始写入日志\n2017-06-30 10:48:29开始写入日志\n2017-06-30 10:48:30开始写入日志\n2017-06-30 10:48:31开始写入日志\n2017-06-30 10:48:32开始写入日志\n2017-06-30 10:48:33开始写入日志\n2017-06-30 10:48:34开始写入日志\n2017-06-30 10:48:35开始写入日志\n2017-06-30 10:48:36开始写入日志\n2017-06-30 10:48:37开始写入日志\n2017-06-30 10:48:38开始写入日志\n2017-06-30 10:48:39开始写入日志\n2017-06-30 10:48:40开始写入日志\n2017-06-30 10:48:41开始写入日志\n2017-06-30 10:48:42开始写入日志\n2017-06-30 10:48:43开始写入日志\n2017-06-30 10:48:44开始写入日志\n2017-06-30 10:48:45开始写入日志\n2017-06-30 10:48:46开始写入日志\n2017-06-30 10:48:47开始写入日志\n2017-06-30 10:48:48开始写入日志\n2017-06-30 10:48:49开始写入日志\n2017-06-30 10:48:50开始写入日志\n2017-06-30 10:48:51开始写入日志\n2017-06-30 10:48:52开始写入日志\n2017-06-30 10:48:53开始写入日志\n2017-06-30 10:48:54开始写入日志\n2017-06-30 10:48:55开始写入日志\n2017-06-30 10:48:56开始写入日志\n2017-06-30 10:48:57开始写入日志\n2017-06-30 10:48:58开始写入日志\n2017-06-30 10:48:59开始写入日志\n2017-06-30 10:49:00开始写入日志\n2017-06-30 10:49:01开始写入日志\n2017-06-30 10:49:02开始写入日志\n2017-06-30 10:49:03开始写入日志\n2017-06-30 10:49:04开始写入日志\n2017-06-30 10:49:05开始写入日志\n2017-06-30 10:49:06开始写入日志\n2017-06-30 10:49:07开始写入日志\n2017-06-30 10:49:08开始写入日志\n2017-06-30 10:49:09开始写入日志\n2017-06-30 10:49:10开始写入日志\n2017-06-30 10:49:11开始写入日志\n2017-06-30 10:49:12开始写入日志\n2017-06-30 10:49:13开始写入日志\n2017-06-30 10:49:14开始写入日志\n2017-06-30 10:49:15开始写入日志\n2017-06-30 10:49:16开始写入日志\n2017-06-30 10:49:17开始写入日志\n2017-06-30 10:49:18开始写入日志\n2017-06-30 10:49:19开始写入日志\n2017-06-30 10:49:20开始写入日志\n2017-06-30 10:49:21开始写入日志\n2017-06-30 10:49:22开始写入日志\n2017-06-30 10:49:23开始写入日志\n2017-06-30 10:49:24开始写入日志\n2017-06-30 10:49:25开始写入日志\n2017-06-30 10:49:26开始写入日志\n2017-06-30 10:49:27开始写入日志\n2017-06-30 10:49:28开始写入日志\n2017-06-30 10:49:29开始写入日志\n2017-06-30 10:49:30开始写入日志\n2017-06-30 10:49:31开始写入日志\n2017-06-30 10:49:32开始写入日志\n2017-06-30 10:49:33开始写入日志\n2017-06-30 10:49:34开始写入日志\n2017-06-30 10:49:35开始写入日志\n2017-06-30 10:49:36开始写入日志\n2017-06-30 10:49:37开始写入日志\n2017-06-30 10:49:38开始写入日志\n2017-06-30 10:49:39开始写入日志\n', 'signal: killed:', '-1', '250268', '1498790730'), ('2', '3', '2017-06-30 11:00:21开始写入日志\n2017-06-30 11:00:22开始写入日志\n2017-06-30 11:00:23开始写入日志\n2017-06-30 11:00:24开始写入日志\n2017-06-30 11:00:25开始写入日志\n2017-06-30 11:00:26开始写入日志\n2017-06-30 11:00:27开始写入日志\n2017-06-30 11:00:28开始写入日志\n2017-06-30 11:00:29开始写入日志\n2017-06-30 11:00:30开始写入日志\n', 'signal: killed:', '-1', '10292', '1498791620'), ('3', '3', '2017-06-30 11:21:56开始写入日志\n2017-06-30 11:21:57开始写入日志\n2017-06-30 11:21:58开始写入日志\n2017-06-30 11:21:59开始写入日志\n2017-06-30 11:22:00开始写入日志\n2017-06-30 11:22:01开始写入日志\n2017-06-30 11:22:02开始写入日志\n2017-06-30 11:22:03开始写入日志\n2017-06-30 11:22:04开始写入日志\n2017-06-30 11:22:05开始写入日志\n2017-06-30 11:22:06开始写入日志\n2017-06-30 11:22:07开始写入日志\n', 'signal: killed:', '-1', '12625', '1498792915'), ('4', '3', '2017-06-30 11:28:51开始写入日志\n2017-06-30 11:28:52开始写入日志\n', 'signal: killed:', '-1', '3123', '1498793330'), ('5', '3', '2017-06-30 12:05:01开始写入日志\n2017-06-30 12:05:02开始写入日志\n2017-06-30 12:05:03开始写入日志\n2017-06-30 12:05:04开始写入日志\n2017-06-30 12:05:05开始写入日志\n', 'signal: killed:', '-1', '6057', '1498795500'), ('6', '3', '2017-06-30 12:06:31开始写入日志\n2017-06-30 12:06:32开始写入日志\n2017-06-30 12:06:33开始写入日志\n2017-06-30 12:06:34开始写入日志\n2017-06-30 12:06:35开始写入日志\n2017-06-30 12:06:36开始写入日志\n2017-06-30 12:06:37开始写入日志\n2017-06-30 12:06:38开始写入日志\n2017-06-30 12:06:39开始写入日志\n', 'signal: killed:', '-1', '9896', '1498795590'), ('7', '3', '2017-06-30 12:17:21开始写入日志\n2017-06-30 12:17:22开始写入日志\n2017-06-30 12:17:23开始写入日志\n2017-06-30 12:17:24开始写入日志\n2017-06-30 12:17:25开始写入日志\n2017-06-30 12:17:26开始写入日志\n2017-06-30 12:17:27开始写入日志\n2017-06-30 12:17:28开始写入日志\n', 'signal: killed:', '-1', '8298', '1498796240'), ('8', '3', '2017-06-30 12:20:01开始写入日志\n2017-06-30 12:20:02开始写入日志\n2017-06-30 12:20:03开始写入日志\n2017-06-30 12:20:04开始写入日志\n2017-06-30 12:20:05开始写入日志\n2017-06-30 12:20:06开始写入日志\n2017-06-30 12:20:07开始写入日志\n2017-06-30 12:20:08开始写入日志\n2017-06-30 12:20:09开始写入日志\n2017-06-30 12:20:10开始写入日志\n', 'signal: killed:', '-1', '10617', '1498796400'), ('9', '3', '2017-06-30 12:56:16开始写入日志\n2017-06-30 12:56:17开始写入日志\n2017-06-30 12:56:18开始写入日志\n2017-06-30 12:56:19开始写入日志\n2017-06-30 12:56:20开始写入日志\n2017-06-30 12:56:21开始写入日志\n2017-06-30 12:56:22开始写入日志\n2017-06-30 12:56:23开始写入日志\n2017-06-30 12:56:24开始写入日志\n2017-06-30 12:56:25开始写入日志\n2017-06-30 12:56:26开始写入日志\n', 'signal: killed:', '-1', '11809', '1498798575'), ('10', '3', '2017-06-30 13:24:41开始写入日志\n2017-06-30 13:24:42开始写入日志\n2017-06-30 13:24:43开始写入日志\n2017-06-30 13:24:44开始写入日志\n2017-06-30 13:24:45开始写入日志\n2017-06-30 13:24:46开始写入日志\n2017-06-30 13:24:47开始写入日志\n2017-06-30 13:24:48开始写入日志\n2017-06-30 13:24:49开始写入日志\n2017-06-30 13:24:50开始写入日志\n2017-06-30 13:24:51开始写入日志\n2017-06-30 13:24:52开始写入日志\n2017-06-30 13:24:53开始写入日志\n2017-06-30 13:24:54开始写入日志\n2017-06-30 13:24:55开始写入日志\n2017-06-30 13:24:56开始写入日志\n2017-06-30 13:24:57开始写入日志\n2017-06-30 13:24:58开始写入日志\n2017-06-30 13:24:59开始写入日志\n2017-06-30 13:25:00开始写入日志\n2017-06-30 13:25:01开始写入日志\n2017-06-30 13:25:02开始写入日志\n2017-06-30 13:25:03开始写入日志\n2017-06-30 13:25:04开始写入日志\n2017-06-30 13:25:05开始写入日志\n2017-06-30 13:25:06开始写入日志\n', 'signal: killed:', '-1', '27203', '1498800280'), ('11', '3', '2017-06-30 13:56:41开始写入日志\n2017-06-30 13:56:42开始写入日志\n2017-06-30 13:56:43开始写入日志\n2017-06-30 13:56:44开始写入日志\n2017-06-30 13:56:45开始写入日志\n2017-06-30 13:56:46开始写入日志\n2017-06-30 13:56:47开始写入日志\n2017-06-30 13:56:48开始写入日志\n2017-06-30 13:56:49开始写入日志\n2017-06-30 13:56:50开始写入日志\n2017-06-30 13:56:51开始写入日志\n2017-06-30 13:56:52开始写入日志\n2017-06-30 13:56:53开始写入日志\n2017-06-30 13:56:54开始写入日志\n', 'signal: killed:', '-1', '14527', '1498802200'), ('12', '3', '2017-06-30 13:59:56开始写入日志\n2017-06-30 13:59:57开始写入日志\n2017-06-30 13:59:58开始写入日志\n2017-06-30 13:59:59开始写入日志\n2017-06-30 14:00:00开始写入日志\n2017-06-30 14:00:01开始写入日志\n2017-06-30 14:00:02开始写入日志\n2017-06-30 14:00:03开始写入日志\n', 'signal: killed:', '-1', '8550', '1498802395'), ('13', '3', '2017-06-30 14:02:41开始写入日志\n2017-06-30 14:02:42开始写入日志\n2017-06-30 14:02:43开始写入日志\n2017-06-30 14:02:44开始写入日志\n2017-06-30 14:02:45开始写入日志\n2017-06-30 14:02:46开始写入日志\n2017-06-30 14:02:47开始写入日志\nsignal: killed', '', '0', '7457', '1498802560'), ('14', '3', '2017-06-30 14:04:28开始写入日志\n2017-06-30 14:04:29开始写入日志\n2017-06-30 14:04:30开始写入日志\n2017-06-30 14:04:31开始写入日志\n2017-06-30 14:04:32开始写入日志\n2017-06-30 14:04:33开始写入日志\n2017-06-30 14:04:34开始写入日志\n2017-06-30 14:04:35开始写入日志\n2017-06-30 14:04:36开始写入日志\n2017-06-30 14:04:37开始写入日志\n2017-06-30 14:04:38开始写入日志\n2017-06-30 14:04:39开始写入日志\n2017-06-30 14:04:40开始写入日志\n2017-06-30 14:04:41开始写入日志\n2017-06-30 14:04:42开始写入日志\n2017-06-30 14:04:43开始写入日志\n2017-06-30 14:04:44开始写入日志\n2017-06-30 14:04:45开始写入日志\n2017-06-30 14:04:46开始写入日志\n2017-06-30 14:04:47开始写入日志\n2017-06-30 14:04:48开始写入日志\n2017-06-30 14:04:49开始写入日志\n2017-06-30 14:04:50开始写入日志\n2017-06-30 14:04:51开始写入日志\n2017-06-30 14:04:52开始写入日志\n2017-06-30 14:04:53开始写入日志\n2017-06-30 14:04:54开始写入日志\n2017-06-30 14:04:55开始写入日志\n2017-06-30 14:04:56开始写入日志\n2017-06-30 14:04:57开始写入日志\n2017-06-30 14:04:58开始写入日志\n2017-06-30 14:04:59开始写入日志\nsignal: killed', '', '0', '32806', '1498802667'), ('15', '3', '2017-06-30 15:20:26开始写入日志\n2017-06-30 15:20:27开始写入日志\n2017-06-30 15:20:28开始写入日志\n2017-06-30 15:20:29开始写入日志\n2017-06-30 15:20:30开始写入日志\n2017-06-30 15:20:31开始写入日志\n2017-06-30 15:20:32开始写入日志\n2017-06-30 15:20:33开始写入日志\n2017-06-30 15:20:34开始写入日志\n2017-06-30 15:20:35开始写入日志\n2017-06-30 15:20:36开始写入日志\n2017-06-30 15:20:37开始写入日志\n2017-06-30 15:20:38开始写入日志\n2017-06-30 15:20:39开始写入日志\n2017-06-30 15:20:40开始写入日志\n2017-06-30 15:20:41开始写入日志\n2017-06-30 15:20:42开始写入日志\n2017-06-30 15:20:43开始写入日志\n2017-06-30 15:20:44开始写入日志\n2017-06-30 15:20:45开始写入日志\n2017-06-30 15:20:46开始写入日志\n2017-06-30 15:20:47开始写入日志\n2017-06-30 15:20:48开始写入日志\n2017-06-30 15:20:49开始写入日志\n2017-06-30 15:20:50开始写入日志\n2017-06-30 15:20:51开始写入日志\n2017-06-30 15:20:52开始写入日志\n2017-06-30 15:20:53开始写入日志\n2017-06-30 15:20:54开始写入日志\n2017-06-30 15:20:55开始写入日志\nsignal: killed', '', '0', '31220', '1498807225'), ('16', '3', '2017-06-30 15:20:56开始写入日志\nsignal: killed', '', '0', '1228', '1498807255'), ('17', '3', '2017-06-30 15:38:16开始写入日志\n2017-06-30 15:38:17开始写入日志\n2017-06-30 15:38:18开始写入日志\n2017-06-30 15:38:19开始写入日志\n2017-06-30 15:38:20开始写入日志\n2017-06-30 15:38:21开始写入日志\n2017-06-30 15:38:22开始写入日志\n2017-06-30 15:38:23开始写入日志\n2017-06-30 15:38:24开始写入日志\n2017-06-30 15:38:25开始写入日志\n2017-06-30 15:38:26开始写入日志\nsignal: killed', '', '0', '12042', '1498808295'), ('18', '5', '', '', '0', '27', '1499072538');
+INSERT INTO `pp_task_log` VALUES ('1', '7', '等待10秒\nphp执行完毕', '', '0', '20484', '1502940420'), ('2', '7', '等待10秒\nphp执行完毕', '', '0', '20367', '1502940480');
+COMMIT;
+
+-- ----------------------------
+-- Table structure for `pp_task_server`
+-- ----------------------------
+DROP TABLE IF EXISTS `pp_task_server`;
+CREATE TABLE `pp_task_server` (
+ `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
+ `server_name` varchar(64) NOT NULL DEFAULT '0' COMMENT '服务器名称',
+ `server_ip` varchar(20) NOT NULL DEFAULT '0' COMMENT '服务器IP',
+ `port` int(4) unsigned NOT NULL DEFAULT '22' COMMENT '服务器端口',
+ `password` varchar(64) NOT NULL DEFAULT '0' COMMENT '服务器密码',
+ `private_key_src` varchar(128) NOT NULL DEFAULT '0' COMMENT '私钥文件地址',
+ `public_key_src` varchar(128) NOT NULL DEFAULT '0' COMMENT '公钥地址',
+ `type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '登录类型:0-密码登录,1-私钥登录',
+ `detail` varchar(255) NOT NULL DEFAULT '0' COMMENT '备注',
+ `create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
+ `update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
+ `status` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '状态:0-正常,1-删除',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='服务器列表';
+
+-- ----------------------------
+-- Records of `pp_task_server`
+-- ----------------------------
+BEGIN;
+INSERT INTO `pp_task_server` VALUES ('1', '远程服务器-php', '172.16.210.157', '22', '', '/Users/haodaquan/.ssh/pp_rsa', '/Users/haodaquan/.ssh/pp_rsa.pub', '1', '远程服务器示例', '1502862723', '1502939962', '0');
COMMIT;
-- ----------------------------
@@ -137,7 +163,7 @@ CREATE TABLE `pp_user` (
-- Records of `pp_user`
-- ----------------------------
BEGIN;
-INSERT INTO `pp_user` VALUES ('1', 'admin', 'haodaquan@shoplinq.cn', '7fef6171469e80d32c0559f88b377245', '', '1498491432', '[', '0');
+INSERT INTO `pp_user` VALUES ('1', 'admin', 'haodaquan@shoplinq.cn', 'abfcf6dcedfb4b5b1505d41a8b4c77e8', 'aYk4Q1P83v', '1502870914', '[', '0');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
diff --git a/routers/router.go b/routers/router.go
index 5ed7803..0b5f892 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -14,4 +14,5 @@ func init() {
beego.Router("/help", &controllers.HelpController{}, "*:Index")
beego.AutoRouter(&controllers.TaskController{})
beego.AutoRouter(&controllers.GroupController{})
+ beego.AutoRouter(&controllers.ServerController{})
}
diff --git a/views/group/add.html b/views/group/add.html
index cda45c5..1899873 100644
--- a/views/group/add.html
+++ b/views/group/add.html
@@ -21,7 +21,7 @@