152 lines
3.9 KiB
Go
152 lines
3.9 KiB
Go
package taskdebug
|
||
|
||
import (
|
||
"context"
|
||
"devops/agent/script"
|
||
"devops/agent/tasks"
|
||
"devops/server/apps/task"
|
||
"fmt"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
TASK_NAME = "task_debug"
|
||
)
|
||
|
||
func init() {
|
||
tasks.RegisterTaskRunner(TASK_NAME, &TaskDebugRunner{})
|
||
}
|
||
|
||
// 实现一个 task_debug 任务
|
||
type TaskDebugRunner struct{}
|
||
|
||
func (t *TaskDebugRunner) Run(ctx context.Context, spec *tasks.RunTaskRequest) (*script.ExecutionResult, error) {
|
||
// 直接使用单元测试的上下文, 方便取消
|
||
req := script.NewExecuteScriptRequest("task_debug.sh", []string{})
|
||
req.SetWorkDir(spec.WorkDir)
|
||
req.SetTimeout(spec.GetTimeout())
|
||
req.SetDebugScript(true)
|
||
req.SetLogFile("stdout.txt")
|
||
|
||
// Task的日志,后面会通过Websocket 实时上报给Api Server 右API Server进行日志的实时展示
|
||
// req.SetLogCallback(func(s string) {
|
||
// fmt.Print(s)
|
||
// })
|
||
|
||
// 添加输入参数
|
||
for k, v := range spec.InputParams {
|
||
req.SetEnv(k, v)
|
||
}
|
||
return script.ExecuteScript(ctx, req)
|
||
}
|
||
|
||
// MapExecutionResultToTask updates a Task with execution results
|
||
func MapExecutionResultToTask(task *task.Task, result *script.ExecutionResult) {
|
||
if task == nil || result == nil {
|
||
return
|
||
}
|
||
|
||
// Update TaskStatus fields from ExecutionResult
|
||
task.TaskStatus = convertExecutionResultToStatus(result)
|
||
|
||
// Optionally update some TaskSpec fields if needed
|
||
// For example, if you want to store output params in the task spec extras
|
||
if len(result.OutputParams) > 0 && task.TaskSpec.Extras == nil {
|
||
task.TaskSpec.Extras = make(map[string]string)
|
||
}
|
||
for k, v := range result.OutputParams {
|
||
task.TaskSpec.Extras["output_"+k] = v
|
||
}
|
||
}
|
||
|
||
// convertExecutionResultToStatus converts ExecutionResult to TaskStatus
|
||
func convertExecutionResultToStatus(result *script.ExecutionResult) *task.TaskStatus {
|
||
status := &task.TaskStatus{
|
||
Status: mapSuccessToStatus(result.Success, result.Skipped),
|
||
Message: getMessage(result),
|
||
Detail: getDetail(result),
|
||
StartAt: &result.StartTime,
|
||
EndAt: getEndTime(result),
|
||
UpdateAt: time.Now(),
|
||
Output: result.OutputParams,
|
||
Extras: make(map[string]string),
|
||
}
|
||
|
||
// Add file contents to extras if present
|
||
if len(result.FileContents) > 0 {
|
||
for k, v := range result.FileContents {
|
||
status.Extras["file_"+k] = v
|
||
}
|
||
}
|
||
|
||
// Add command execution details
|
||
if result.Command != "" {
|
||
status.Extras["executed_command"] = result.Command
|
||
}
|
||
|
||
if result.ExitCode != 0 {
|
||
status.Extras["exit_code"] = fmt.Sprintf("%d", result.ExitCode)
|
||
}
|
||
|
||
if result.Duration > 0 {
|
||
status.Extras["duration"] = result.Duration.String()
|
||
}
|
||
|
||
return status
|
||
}
|
||
|
||
// mapSuccessToStatus maps execution result success/skipped to task status
|
||
func mapSuccessToStatus(success bool, skipped bool) task.STATUS {
|
||
if skipped {
|
||
return task.STATUS_SKIP
|
||
}
|
||
if success {
|
||
return task.STATUS_SUCCESS
|
||
}
|
||
return task.STATUS_FAILED
|
||
}
|
||
|
||
// getMessage combines error and message from execution result
|
||
func getMessage(result *script.ExecutionResult) string {
|
||
if result.Error != "" {
|
||
return result.Error
|
||
}
|
||
return result.Message
|
||
}
|
||
|
||
// getDetail creates a detailed message from execution result
|
||
func getDetail(result *script.ExecutionResult) string {
|
||
var details []string
|
||
|
||
if result.Command != "" {
|
||
details = append(details, fmt.Sprintf("Command: %s", result.Command))
|
||
}
|
||
|
||
if result.ExitCode != 0 {
|
||
details = append(details, fmt.Sprintf("Exit Code: %d", result.ExitCode))
|
||
}
|
||
|
||
if result.Duration > 0 {
|
||
details = append(details, fmt.Sprintf("Duration: %v", result.Duration))
|
||
}
|
||
|
||
if result.Error != "" && result.Error != result.Message {
|
||
details = append(details, fmt.Sprintf("Error: %s", result.Error))
|
||
}
|
||
|
||
if result.Message != "" && result.Message != result.Error {
|
||
details = append(details, fmt.Sprintf("Message: %s", result.Message))
|
||
}
|
||
|
||
return strings.Join(details, "\n")
|
||
}
|
||
|
||
// getEndTime returns the end time or current time if nil
|
||
func getEndTime(result *script.ExecutionResult) time.Time {
|
||
if result.EndTime != nil {
|
||
return *result.EndTime
|
||
}
|
||
return time.Now()
|
||
}
|