package models import ( "fmt" "strconv" "strings" "time" "github.com/acarl005/stripansi" ) type ArgoWatch struct { Name string Namespace string Status string Conditions Created string Started string Duration string Progress string Logs []string } type Conditions struct { PodRunning bool Completed bool } func (a *ArgoWatch) Equals(arg *ArgoWatch) bool { if arg == nil { return false } return a.Status == arg.Status && a.Progress == arg.Progress && a.Conditions.PodRunning == arg.Conditions.PodRunning && a.Conditions.Completed == arg.Conditions.Completed } func NewArgoLogs(name string, namespace string, stepMax int) *ArgoLogs { return &ArgoLogs{ Name: "oc-monitor-" + name, Namespace: namespace, CreatedDate: time.Now().Format("2006-01-02 15:04:05"), StepCount: 0, StepMax: stepMax, stop: false, } } type ArgoLogs struct { Name string Namespace string CreatedDate string StepCount int StepMax int stop bool Started time.Time } func (a *ArgoLogs) StartStepRecording() { a.StepCount += 1 a.Started = time.Now() } func (a *ArgoLogs) StopStepRecording(inputs []string) *ArgoWatch { fn := strings.Split(a.Name, "_") logs := []string{} err := false end := "" for _, input := range inputs { line := strings.TrimSpace(input) if line == "" || !strings.Contains(line, fn[0]) || !strings.Contains(line, ":") { continue } step := strings.Split(line, ":") if strings.Contains(line, "sub-process exited") { b := strings.Split(line, "time=\"") if len(b) > 1 { end = b[1][:19] } } if len(step) < 2 || strings.Contains(line, "time=") || strings.TrimSpace(strings.Join(step[1:], " : ")) == "" || strings.TrimSpace(strings.Join(step[1:], " : ")) == a.Name { continue } log := stripansi.Strip(strings.TrimSpace(strings.Join(step[1:], " : "))) t, e := strconv.Unquote(log) if e == nil { logs = append(logs, t) } else { logs = append(logs, strings.ReplaceAll(log, "\"", "`")) } if strings.Contains(logs[len(logs)-1], "Error") { err = true } } status := "Pending" if a.StepCount > 0 { status = "Running" } if a.StepCount == a.StepMax { if err { status = "Failed" } else { status = "Succeeded" } } duration := float64(0) if end != "" { timeE, _ := time.Parse("2006-01-02T15:04:05", end) duration = timeE.Sub(a.Started).Seconds() } argo := &ArgoWatch{ Name: a.Name, Namespace: a.Namespace, Status: status, Created: a.CreatedDate, Started: a.Started.Format("2006-01-02 15:04:05"), Conditions: Conditions{ PodRunning: a.StepCount > 0 && a.StepCount < a.StepMax, Completed: a.StepCount == a.StepMax, }, Progress: fmt.Sprintf("%v/%v", a.StepCount, a.StepMax), Duration: fmt.Sprintf("%v", fmt.Sprintf("%.2f", duration)+"s"), Logs: logs, } if !argo.Completed { a.StartStepRecording() } return argo }