Skip to content

Commit

Permalink
Add CheckConsoleText, allowing discussion
Browse files Browse the repository at this point in the history
Ref: #3788
  • Loading branch information
c4rt0 committed Sep 2, 2024
1 parent 77118ab commit d8e6c82
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
16 changes: 16 additions & 0 deletions mantle/cmd/kola/testiso.go
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,22 @@ func awaitCompletion(ctx context.Context, inst *platform.QemuInstance, outdir st
errchan <- err
}
}()
// check for console badness
errBuf, err := inst.CheckConsoleForBadness(ctx)
if err == nil {
if errBuf != "" {
plog.Info("entered emergency.target in initramfs")
path := filepath.Join(outdir, "ignition-virtio-dump.txt")
if err := os.WriteFile(path, []byte(errBuf), 0644); err != nil {
plog.Errorf("Failed to write journal: %v", err)
}
err = platform.ErrInitramfsEmergency
}
}
if err != nil {
errchan <- err
}
}()
}
go func() {
err := inst.Wait()
Expand Down
31 changes: 31 additions & 0 deletions mantle/kola/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -1917,6 +1917,34 @@ func ScpKolet(machines []platform.Machine) error {
return fmt.Errorf("Unable to locate kolet binary for %s", mArch)
}


// CheckConsoleText checks console output for badness
func CheckConsoleText(consoleOutput []byte) (bool, []string) {
var badlines []string
warnOnly, allowRerunSuccess := true, true
for _, check := range consoleChecks {
if check.skipFlag != nil {
continue
}
match := check.match.FindSubmatch(consoleOutput)
if match != nil {
badline := check.desc
if len(match) > 1 {
// include first subexpression
badline += fmt.Sprintf(" (%s)", match[1])
}
badlines = append(badlines, badline)
if !check.warnOnly {
warnOnly = false
}
if !check.allowRerunSuccess {
allowRerunSuccess = false
}
}
}
return warnOnly, badlines
}

// CheckConsole checks some console output for badness and returns short
// descriptions of any bad lines it finds along with a boolean
// indicating if the configuration has the bad lines marked as
Expand Down Expand Up @@ -1944,6 +1972,9 @@ func CheckConsole(output []byte, t *register.Test) (bool, []string) {
if !check.allowRerunSuccess {
allowRerunSuccess = false
}
cc := CheckConsoleText([]byte(output))
fmt.Printf("Test failed: %v", cc)
fmt.Printf("// Leftovers \n\n")
}
}
if len(badlines) > 0 && allowRerunSuccess && t != nil {
Expand Down
60 changes: 60 additions & 0 deletions mantle/platform/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import (
"syscall"
"time"

"github.com/coreos/coreos-assembler/mantle/kola"

Check failure on line 46 in mantle/platform/qemu.go

View workflow job for this annotation

GitHub Actions / golangci-lint

could not import github.com/coreos/coreos-assembler/mantle/kola (-: import cycle not allowed: import stack: [github.com/coreos/coreos-assembler/mantle/cli github.com/coreos/coreos-assembler/mantle/kola github.com/coreos/coreos-assembler/mantle/kola/cluster github.com/coreos/coreos-assembler/mantle/platform github.com/coreos/coreos-assembler/mantle/kola]) (typecheck)
"github.com/coreos/coreos-assembler/mantle/platform/conf"
"github.com/coreos/coreos-assembler/mantle/util"
coreosarch "github.com/coreos/stream-metadata-go/arch"
Expand Down Expand Up @@ -255,6 +256,51 @@ func (inst *QemuInstance) WaitIgnitionError(ctx context.Context) (string, error)
return r.String(), nil
}

// Copy of WaitIgnitionError -> CheckConsoleForBadness
// CheckConsoleForBadness will only return if the instance
// failed inside the initramfs. The resulting string will
// be a newline-delimited stream of JSON strings, as returned
// by `journalctl -o json`.
func (inst *QemuInstance) CheckConsoleForBadness(ctx context.Context) (string, error) {
b := bufio.NewReaderSize(inst.journalPipe, 64768)
var r strings.Builder
iscorrupted := false
_, err := b.Peek(1)
if err != nil {
// It's normal to get EOF if we didn't catch an error and qemu
// is shutting down. We also need to handle when the Destroy()
// function closes the journal FD on us.
if e, ok := err.(*os.PathError); ok && e.Err == os.ErrClosed {
return "", nil
} else if err == io.EOF {
return "", nil
}
return "", errors.Wrapf(err, "Reading from journal")
}
for {
if err := ctx.Err(); err != nil {
return "", err
}

line, prefix, err := b.ReadLine()
if err != nil {
return r.String(), errors.Wrapf(err, "Reading from journal channel")
}
if prefix {
iscorrupted = true
}
if len(line) == 0 || string(line) == "{}" {
break
}
r.Write(line)
r.Write([]byte("\n"))
}
if iscorrupted {
return r.String(), fmt.Errorf("journal was truncated due to overly long line")
}
return r.String(), nil
}

// WaitAll wraps the process exit as well as WaitIgnitionError,
// returning an error if either fail.
func (inst *QemuInstance) WaitAll(ctx context.Context) error {
Expand All @@ -277,6 +323,20 @@ func (inst *QemuInstance) WaitAll(ctx context.Context) error {
}
}()

// Early stop due to failure in initramfs.
go func() {
buf, err := inst.CheckConsoleForBadness(waitCtx)
if err != nil {
c <- err
return
}

// TODO: parse buf and try to nicely render something.
if buf != "" {
c <- ErrInitramfsEmergency
return
}
}()
// Machine terminated.
go func() {
select {
Expand Down

0 comments on commit d8e6c82

Please sign in to comment.