2024-04-12 12:21:05 +02:00
|
|
|
package runners
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
|
|
|
"os/exec"
|
|
|
|
"time"
|
|
|
|
|
2024-04-12 12:32:54 +02:00
|
|
|
"github.com/ansible-semaphore/semaphore/pkg/task_logger"
|
2024-04-12 12:21:05 +02:00
|
|
|
"github.com/ansible-semaphore/semaphore/services/tasks"
|
|
|
|
"github.com/ansible-semaphore/semaphore/util"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
type runningJob struct {
|
2024-04-12 12:32:54 +02:00
|
|
|
status task_logger.TaskStatus
|
2024-04-12 12:21:05 +02:00
|
|
|
logRecords []LogRecord
|
|
|
|
job *tasks.LocalJob
|
2024-06-17 20:37:45 +02:00
|
|
|
|
|
|
|
statusListeners []task_logger.StatusListener
|
|
|
|
logListeners []task_logger.LogListener
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) AddStatusListener(l task_logger.StatusListener) {
|
|
|
|
p.statusListeners = append(p.statusListeners, l)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) AddLogListener(l task_logger.LogListener) {
|
|
|
|
p.logListeners = append(p.logListeners, l)
|
2024-04-12 12:21:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) Log(msg string) {
|
|
|
|
p.LogWithTime(time.Now(), msg)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) Logf(format string, a ...any) {
|
|
|
|
p.LogfWithTime(time.Now(), format, a...)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) LogWithTime(now time.Time, msg string) {
|
|
|
|
p.logRecords = append(
|
|
|
|
p.logRecords,
|
|
|
|
LogRecord{
|
|
|
|
Time: now,
|
|
|
|
Message: msg,
|
|
|
|
},
|
|
|
|
)
|
2024-06-17 20:37:45 +02:00
|
|
|
for _, l := range p.logListeners {
|
|
|
|
l(now, msg)
|
|
|
|
}
|
2024-04-12 12:21:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) LogfWithTime(now time.Time, format string, a ...any) {
|
|
|
|
p.LogWithTime(now, fmt.Sprintf(format, a...))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) LogCmd(cmd *exec.Cmd) {
|
|
|
|
stderr, _ := cmd.StderrPipe()
|
|
|
|
stdout, _ := cmd.StdoutPipe()
|
|
|
|
|
|
|
|
go p.logPipe(bufio.NewReader(stderr))
|
|
|
|
go p.logPipe(bufio.NewReader(stdout))
|
|
|
|
}
|
|
|
|
|
2024-04-12 12:32:54 +02:00
|
|
|
func (p *runningJob) SetStatus(status task_logger.TaskStatus) {
|
2024-04-12 12:21:05 +02:00
|
|
|
if p.status == status {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
p.status = status
|
|
|
|
p.job.SetStatus(status)
|
2024-06-17 20:37:45 +02:00
|
|
|
|
|
|
|
for _, l := range p.statusListeners {
|
|
|
|
l(status)
|
|
|
|
}
|
2024-04-12 12:21:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p *runningJob) logPipe(reader *bufio.Reader) {
|
|
|
|
line, err := tasks.Readln(reader)
|
|
|
|
for err == nil {
|
|
|
|
p.Log(line)
|
|
|
|
line, err = tasks.Readln(reader)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err != nil && err.Error() != "EOF" {
|
|
|
|
//don't panic on these errors, sometimes it throws not dangerous "read |0: file already closed" error
|
|
|
|
util.LogWarningWithFields(err, log.Fields{"error": "Failed to read TaskRunner output"})
|
|
|
|
}
|
|
|
|
}
|