152 lines
3.9 KiB
Go
Raw Normal View History

2026-03-08 18:05:17 +08:00
package taskdebug
import (
"context"
2026-03-15 17:03:15 +08:00
"devops/agent/script"
"devops/agent/tasks"
2026-03-08 18:05:17 +08:00
"devops/server/apps/task"
2026-03-15 17:03:15 +08:00
"fmt"
"strings"
"time"
2026-03-08 18:05:17 +08:00
)
2026-03-15 17:03:15 +08:00
const (
TASK_NAME = "task_debug"
)
2026-03-08 18:05:17 +08:00
2026-03-15 17:03:15 +08:00
func init() {
tasks.RegisterTaskRunner(TASK_NAME, &TaskDebugRunner{})
}
// 实现一个 task_debug 任务
2026-03-08 18:05:17 +08:00
type TaskDebugRunner struct{}
2026-03-29 11:41:32 +08:00
func (t *TaskDebugRunner) Run(ctx context.Context, spec *tasks.RunTaskRequest) (*script.ExecutionResult, error) {
2026-03-15 17:03:15 +08:00
// 直接使用单元测试的上下文, 方便取消
req := script.NewExecuteScriptRequest("task_debug.sh", []string{})
2026-03-29 11:41:32 +08:00
req.SetWorkDir(spec.WorkDir)
2026-03-15 17:03:15 +08:00
req.SetTimeout(spec.GetTimeout())
req.SetDebugScript(true)
req.SetLogFile("stdout.txt")
2026-03-15 17:57:35 +08:00
// Task的日志后面会通过Websocket 实时上报给Api Server 右API Server进行日志的实时展示
2026-03-29 11:41:32 +08:00
// req.SetLogCallback(func(s string) {
// fmt.Print(s)
// })
2026-03-15 17:57:35 +08:00
2026-03-15 17:03:15 +08:00
// 添加输入参数
for k, v := range spec.InputParams {
req.SetEnv(k, v)
}
2026-03-29 11:41:32 +08:00
return script.ExecuteScript(ctx, req)
2026-03-15 17:03:15 +08:00
}
// 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()
2026-03-08 18:05:17 +08:00
}