From a852e2d9e9a4d6774baf8c31e3eac55ad7261f7a Mon Sep 17 00:00:00 2001 From: Mikhail Klementev Date: Mon, 7 Oct 2024 20:40:58 +0000 Subject: [PATCH] feat: show relevant qemu output --- artifact/artifact.go | 19 +++++++++++++++++-- container/container.go | 1 - qemu/qemu-kernel.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/artifact/artifact.go b/artifact/artifact.go index 61d149d..16eecfb 100644 --- a/artifact/artifact.go +++ b/artifact/artifact.go @@ -337,10 +337,10 @@ func (ka Artifact) Process(slog zerolog.Logger, ki distro.KernelInfo, slog.Debug().Str("duration", time.Since(start).String()). Msg("build done") if err != nil { - slog.Error().Err(err).Msg("build") + slog.Error().Err(err).Msgf("build failure\n%v\n", result.Build.Output) return } else { - slog.Info().Err(err).Msg("build success") + slog.Info().Msgf("build success\n%v\n", result.Build.Output) } result.Build.Ok = true } else { @@ -398,11 +398,26 @@ func (ka Artifact) Process(slog zerolog.Logger, ki distro.KernelInfo, return } + var qemuTestOutput string + q.SetOutputHandler(func(s string) { + qemuTestOutput += s + "\n" + }) + start := time.Now() copyArtifactAndTest(slog, q, ka, &result, remoteTest) slog.Debug().Str("duration", time.Since(start).String()). Msgf("test completed (success: %v)", result.Test.Ok) + if result.Build.Ok { + if !result.Run.Ok || !result.Test.Ok { + slog.Error().Msgf("qemu output\n%v\n", qemuTestOutput) + } else { + slog.Info().Msgf("qemu output\n%v\n", qemuTestOutput) + } + } + + q.CloseOutputHandler() + if !endless { return } diff --git a/container/container.go b/container/container.go index af45bc9..9e9d119 100644 --- a/container/container.go +++ b/container/container.go @@ -488,7 +488,6 @@ func (c Container) Run(workdir string, cmds []string) (out string, err error) { err = cmd.Wait() if err != nil { - flog.Error().Msg(out) return } diff --git a/qemu/qemu-kernel.go b/qemu/qemu-kernel.go index 59218b9..cd65b4c 100644 --- a/qemu/qemu-kernel.go +++ b/qemu/qemu-kernel.go @@ -101,6 +101,11 @@ type System struct { Stdout, Stderr string + output struct { + listener chan string + mu sync.Mutex + } + // accessible after qemu is closed exitErr error @@ -138,6 +143,41 @@ func NewSystem(arch arch, kernel Kernel, drivePath string) (q *System, err error return } +// q.SetOutputHandler(func(s string) { fmt.Println(s) }) +// defer q.CloseOutputHandler() +func (q *System) SetOutputHandler(handler func(s string)) { + q.output.mu.Lock() + defer q.output.mu.Unlock() + + q.output.listener = make(chan string) + + go func(l chan string) { + for m := range l { + handler(m) + } + }(q.output.listener) +} + +func (q *System) CloseOutputHandler() { + q.output.mu.Lock() + defer q.output.mu.Unlock() + + close(q.output.listener) + q.output.listener = nil +} + +func (q *System) handleOutput(m string) { + if q.output.listener == nil { + return + } + q.output.mu.Lock() + defer q.output.mu.Unlock() + + if q.output.listener != nil { + q.output.listener <- m + } +} + func (q *System) SetSSHAddrPort(addr string, port int) (err error) { // TODO validate q.SSH.AddrPort = fmt.Sprintf("%s:%d", addr, port) @@ -313,6 +353,7 @@ func (q *System) Start() (err error) { scanner := bufio.NewScanner(q.pipe.stdout) for scanner.Scan() { m := scanner.Text() + q.handleOutput(m) q.Stdout += m + "\n" q.Log.Trace().Str("stdout", m).Msg("qemu") go q.checkOopsPanic(m) @@ -323,6 +364,7 @@ func (q *System) Start() (err error) { scanner := bufio.NewScanner(q.pipe.stderr) for scanner.Scan() { m := scanner.Text() + q.handleOutput(m) q.Stderr += m + "\n" q.Log.Trace().Str("stderr", m).Msg("qemu") }