data, conf, log目录不存在自动创建

pull/21/merge
ouqiang 2018-01-26 21:08:52 +08:00
parent 750fb49a37
commit 0950fc69f9
6 changed files with 36 additions and 146 deletions

6
.gitignore vendored
View File

@ -25,9 +25,9 @@ _testmain.go
.DS_Store .DS_Store
.idea .idea
log/* log
data/* data
conf/* conf
profile/* profile/*
public/resource/javascript/vue.js public/resource/javascript/vue.js
gocron gocron

View File

View File

View File

@ -1,139 +0,0 @@
package ssh
import (
"errors"
"fmt"
"golang.org/x/crypto/ssh"
"net"
"time"
)
type HostAuthType int8 // 认证方式
const (
HostPassword = 1 // 密码认证
HostPublicKey = 2 // 公钥认证
)
const SSHConnectTimeout = 10
type SSHConfig struct {
AuthType HostAuthType
User string
Password string
PrivateKey string
Host string
Port int
ExecTimeout int // 执行超时时间
}
type Result struct {
Output string
Err error
}
func parseSSHConfig(sshConfig SSHConfig) (config *ssh.ClientConfig, err error) {
timeout := time.Duration(SSHConnectTimeout) * time.Second
// 密码认证
if sshConfig.AuthType == HostPassword {
config = &ssh.ClientConfig{
User: sshConfig.User,
Auth: []ssh.AuthMethod{
ssh.Password(sshConfig.Password),
},
Timeout: timeout,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
return
}
signer, err := ssh.ParsePrivateKey([]byte(sshConfig.PrivateKey))
if err != nil {
return
}
// 公钥认证
config = &ssh.ClientConfig{
User: sshConfig.User,
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
Timeout: timeout,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
return
}
// 执行shell命令
func Exec(sshConfig SSHConfig, cmd string) (output string, err error) {
client, err := getClient(sshConfig)
if err != nil {
return "", err
}
defer client.Close()
session, err := client.NewSession()
if err != nil {
return "", err
}
defer session.Close()
// 后台运行
if sshConfig.ExecTimeout < 0 {
go session.CombinedOutput(cmd)
time.Sleep(10 * time.Second)
return "", nil
}
// 不限制超时
if sshConfig.ExecTimeout == 0 {
outputByte, execErr := session.CombinedOutput(cmd)
output = string(outputByte)
err = execErr
return
}
var resultChan chan Result = make(chan Result)
var timeoutChan chan bool = make(chan bool)
go func() {
output, err := session.CombinedOutput(cmd)
resultChan <- Result{string(output), err}
}()
// todo 等待超时后,如何停止远程正在执行的任务, 使用timeout命令但不具有通用性
go triggerTimeout(timeoutChan, sshConfig.ExecTimeout)
select {
case result := <-resultChan:
output = result.Output
err = result.Err
case <-timeoutChan:
output = ""
err = errors.New("timeout")
}
return
}
func getClient(sshConfig SSHConfig) (*ssh.Client, error) {
config, err := parseSSHConfig(sshConfig)
if err != nil {
return nil, err
}
addr := fmt.Sprintf("%s:%d", sshConfig.Host, sshConfig.Port)
return ssh.Dial("tcp", addr, config)
}
func triggerTimeout(ch chan bool, timeout int) {
// 最长执行时间不能超过24小时
if timeout <= 0 || timeout > 86400 {
timeout = 86400
}
time.Sleep(time.Duration(timeout) * time.Second)
close(ch)
}

28
package.json Normal file
View File

@ -0,0 +1,28 @@
{
"name": "gocron",
"version": "1.0.0",
"description": "[![Build Status](https://travis-ci.org/ouqiang/gocron.png)](https://travis-ci.org/ouqiang/gocron) # gocron - 定时任务管理系统",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ouqiang/gocron.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/ouqiang/gocron/issues"
},
"homepage": "https://github.com/ouqiang/gocron#readme",
"devDependencies": {
"cz-conventional-changelog": "^2.0.0"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
}

View File

@ -22,6 +22,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"time" "time"
"net/http"
) )
// 静态文件目录 // 静态文件目录
@ -112,7 +113,7 @@ func Register(m *macaron.Macaron) {
m.NotFound(func(ctx *macaron.Context) { m.NotFound(func(ctx *macaron.Context) {
if isGetRequest(ctx) && !isAjaxRequest(ctx) { if isGetRequest(ctx) && !isAjaxRequest(ctx) {
ctx.Data["Title"] = "404 - NOT FOUND" ctx.Data["Title"] = "404 - NOT FOUND"
ctx.HTML(404, "error/404") ctx.HTML(http.StatusNotFound, "error/404")
} else { } else {
json := utils.JsonResponse{} json := utils.JsonResponse{}
ctx.Resp.Write([]byte(json.Failure(utils.NotFound, "您访问的地址不存在"))) ctx.Resp.Write([]byte(json.Failure(utils.NotFound, "您访问的地址不存在")))
@ -123,7 +124,7 @@ func Register(m *macaron.Macaron) {
logger.Debug("500错误") logger.Debug("500错误")
if isGetRequest(ctx) && !isAjaxRequest(ctx) { if isGetRequest(ctx) && !isAjaxRequest(ctx) {
ctx.Data["Title"] = "500 - INTERNAL SERVER ERROR" ctx.Data["Title"] = "500 - INTERNAL SERVER ERROR"
ctx.HTML(500, "error/500") ctx.HTML(http.StatusInternalServerError, "error/500")
} else { } else {
json := utils.JsonResponse{} json := utils.JsonResponse{}
ctx.Resp.Write([]byte(json.Failure(utils.ServerError, "网站暂时无法访问,请稍后再试"))) ctx.Resp.Write([]byte(json.Failure(utils.ServerError, "网站暂时无法访问,请稍后再试")))
@ -202,7 +203,7 @@ func ipAuth(ctx *macaron.Context) {
allowIps := strings.Split(allowIpsStr, ",") allowIps := strings.Split(allowIpsStr, ",")
if !utils.InStringSlice(allowIps, clientIp) { if !utils.InStringSlice(allowIps, clientIp) {
logger.Warnf("非法IP访问-%s", clientIp) logger.Warnf("非法IP访问-%s", clientIp)
ctx.Status(403) ctx.Status(http.StatusForbidden)
} }
} }
@ -251,7 +252,7 @@ func urlAuth(ctx *macaron.Context, sess session.Store) {
} }
} }
ctx.Status(403) ctx.Status(http.StatusUnauthorized)
} }