修复在Unix-like系统上, exec.command启动的子孙进程, 调用cmd.Process.Kill()不能结束

pull/21/merge
ouqiang 8 years ago
parent 4c07b02706
commit 14295049d2

@ -86,10 +86,11 @@ func Exec(sshConfig SSHConfig, cmd string) (output string, err error) {
return "", err
}
defer session.Close()
// 后台运行
if sshConfig.ExecTimeout < 0 {
go session.CombinedOutput(cmd)
time.Sleep(3 * time.Second)
time.Sleep(10 * time.Second)
return "", nil
}
// 不限制超时

@ -10,22 +10,33 @@ import (
"github.com/Tang-RoseChild/mahonia"
"strings"
"os"
"syscall"
)
// 执行shell命令可设置执行超时时间
// todo Windows不能KILL掉子进程, 需特殊处理
func ExecShellWithTimeout(timeout int, command string, args... string) (string, error) {
cmd := exec.Command(command, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
// 不限制超时时间
if timeout <= 0 {
// 后台运行
if timeout == -1 {
go cmd.CombinedOutput()
return "", nil
}
// 不限制超时
if timeout == 0 {
output ,err := cmd.CombinedOutput()
return string(output), err
}
d := time.Duration(timeout) * time.Second
timer := time.AfterFunc(d, func() {
// 超时kill进程
cmd.Process.Kill()
syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
})
output ,err := cmd.CombinedOutput()
timer.Stop()
@ -33,6 +44,8 @@ func ExecShellWithTimeout(timeout int, command string, args... string) (string,
return string(output), err
}
// 生成长度为length的随机字符串
func RandString(length int64) string {
sources := []byte("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")

@ -138,6 +138,9 @@ func Store(ctx *macaron.Context, form TaskForm) string {
if taskModel.NotifyStatus > 0 && taskModel.NotifyReceiverId == "" {
return json.CommonFailure("请至少选择一个接收者", err)
}
if taskModel.Protocol == models.TaskHTTP && taskModel.Timeout == -1 {
return json.CommonFailure("HTTP任务不支持后台运行", err)
}
if id == 0 {
id, err = taskModel.Create()
} else {

@ -233,7 +233,7 @@ func createTaskLog(taskModel models.TaskHost, status models.Status) (int64, stri
taskLogModel.Status = status
// SSH执行远程命令后台运行
var notifyId string = ""
if taskModel.Timeout == -1 && taskModel.Protocol == models.TaskSSH {
if taskModel.Timeout == -1 {
notifyId = utils.RandString(32);
taskLogModel.NotifyId = notifyId;
}
@ -320,7 +320,7 @@ func afterExecJob(taskModel models.TaskHost, taskResult TaskResult, taskLogId in
if taskResult.Err != nil {
taskResult.Result = taskResult.Err.Error() + "\n" + taskResult.Result
}
if taskModel.Protocol == models.TaskSSH && taskModel.Timeout == -1 {
if taskModel.Timeout == -1 {
taskResult.IsAsync = true
}
_, err := updateTaskLog(taskLogId, taskResult)

Loading…
Cancel
Save