Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package openqa-mon for openSUSE:Factory checked in at 2021-12-07 00:00:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openqa-mon (Old) and /work/SRC/openSUSE:Factory/.openqa-mon.new.31177 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openqa-mon" Tue Dec 7 00:00:32 2021 rev:4 rq:936125 version:0.25 Changes: -------- --- /work/SRC/openSUSE:Factory/openqa-mon/openqa-mon.changes 2021-08-16 10:17:44.562646527 +0200 +++ /work/SRC/openSUSE:Factory/.openqa-mon.new.31177/openqa-mon.changes 2021-12-07 00:02:22.299930056 +0100 @@ -1,0 +2,7 @@ +Fri Dec 3 09:51:07 UTC 2021 - Felix Niederwanger <felix.niederwan...@suse.com> + +- Update to upstream version 0.25 + - New interaction options for openqa-mon + - openqa-revtui received the "reviewed" keyword + +------------------------------------------------------------------- Old: ---- openqa-mon-0.24.tar.gz New: ---- openqa-mon-0.25.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openqa-mon.spec ++++++ --- /var/tmp/diff_new_pack.sqr0YC/_old 2021-12-07 00:02:22.875928019 +0100 +++ /var/tmp/diff_new_pack.sqr0YC/_new 2021-12-07 00:02:22.879928004 +0100 @@ -17,7 +17,7 @@ Name: openqa-mon -Version: 0.24 +Version: 0.25 Release: 0 Summary: CLI monitoring utility for openQA License: GPL-3.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.sqr0YC/_old 2021-12-07 00:02:22.911927891 +0100 +++ /var/tmp/diff_new_pack.sqr0YC/_new 2021-12-07 00:02:22.915927877 +0100 @@ -3,7 +3,7 @@ <param name="url">git://github.com/grisu48/openqa-mon.git</param> <param name="scm">git</param> <param name="revision">master</param> - <param name="version">v0.24</param> + <param name="version">v0.25</param> <param name="versionrewrite-pattern">v(.*)</param> </service> <service name="tar" mode="localonly"/> ++++++ openqa-mon-0.24.tar.gz -> openqa-mon-0.25.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/README.md new/openqa-mon-0.25/README.md --- old/openqa-mon-0.24/README.md 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/README.md 2021-12-03 10:41:12.000000000 +0100 @@ -1,13 +1,11 @@ -# openqa-mon - [](https://travis-ci.com/grisu48/openqa-mon) Simple CLI monitoring utilities for [openQA](https://open.qa). This project now consists of three programs: -* `openqa-mon` - live monitoring of openQA jobs -* `openqa-mq` - Query [RabbitMQ instance](https://rabbit.opensuse.org/) for updates -* `openqa-revtui` - (Experimental) openQA review dashboard +* [openqa-mon](#openqa-mon) - live monitoring of openQA jobs +* [openqa-mq](#openqa-mq) - Query [RabbitMQ instance](https://rabbit.opensuse.org/) for updates +* [openqa-revtui](#openqa-revtui) - (Experimental) openQA review dashboard Those utilities are intended as live monitor tool for your jobs. In contrast to the Browser interface they are smaller, more efficient on the resources and should make your life easier :-) @@ -126,3 +124,16 @@ openqa-mq osd # Monitor the SUSE internal openQA instance `openqa-mq` connects to the given RabbitMQ server and prints all received messages. It might be useful to grep for status updates of certain jobs or whatever else you want to monitor. + +# `openqa-revtui` + +## Usage + + openqa-revtui [OPTIONS] [FLAVORS] + openqa-revtui -c config.toml + +`openqa-revtui` is a terminal user interface for helping the user to review the jobs of whole job groups. The typical usage is to run `openqa-revtui` with a predefined configuration toml file. The configuration file defines the remote openQA instance to monitor, job groups and additional query parameters, as well as settings to hide jobs that are not interesting for you (e.g. passing jobs). + + + +You find a set of example configurations in the [review](_review) subfolder. \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/_review/README.md new/openqa-mon-0.25/_review/README.md --- old/openqa-mon-0.24/_review/README.md 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/_review/README.md 2021-12-03 10:41:12.000000000 +0100 @@ -2,4 +2,44 @@ This directory contains example configuration files for `openqa-revtui` -* [publiccloud.toml](publiccloud.toml) - PublicCloud test runs \ No newline at end of file +* [opensuse-microos.toml](opensuse-microos.toml) - Review template for openSUSE MicroOS test runs +* [opensuse-tumbleweed.toml](opensuse-tumbleweed.toml) - Review template for openSUSE Tumbleweed test runs + +## SLES templates + +* [publiccloud.toml](publiccloud.toml) - Review template for SLES PublicCloud test runs +* [containers.yoml](containers.toml) - Review template for SLES container test runs +* [sle-base-images.toml](sle-base-images.toml) - Review template for SLE Base image test runs + +## Create a TODO template + +A `TODO` configuration is a `toml` configuration file, which shows only test run that require an action from a reviewer. +In practice this means it shows only failed and incomplete jobs and hides all currently running, scheduled or passing and softfailing jobs. + +To create such a `TODO` configuration, the following template might be useful. + +```toml +Instance = "https://openqa.opensuse.org" +RabbitMQ = "amqps://opensuse:opens...@rabbit.opensuse.org" +RabbitMQTopic = "opensuse.openqa.job.done" +HideStatus = [ "scheduled", "assigned", "passed", "softfailed", "cancelled", "skipped", "running", "reviewed" ] +RefreshInterval = 60 +MaxJobs = 20 +GroupBy = "groups" +DefaultParams = { distri="opensuse", version = "Tumbleweed" } +``` + +The important parameter is the `HideStatus` one. Here we hide all job states, except failures. + +The `reviewed` status in HideStatus is a special status, which indicates all failures which have a bugref (bugzilla or progress.opensuse.org issue) in at least one of the comments. Those are considered as "reviewed" jobs. + +### Template for SLES + +For usage on OSD, replace the `Instance` and `RabbitMQ` variables accordingly. Also update the required query parameters (`DefaultParams`) to match your distri/flavors. + +```toml +Instance = "https://openqa.suse.de" +RabbitMQ = "amqps://suse:s...@rabbit.suse.de" +RabbitMQTopic = "suse.openqa.job.done" +DefaultParams = { distri = "sle" } +``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/_review/containers.toml new/openqa-mon-0.25/_review/containers.toml --- old/openqa-mon-0.24/_review/containers.toml 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/_review/containers.toml 2021-12-03 10:41:12.000000000 +0100 @@ -38,41 +38,3 @@ Name = "Containers 12 SP3 Updates" Params = { groupid = "358" } -[[Groups]] -Name = "Containers Latest" -Params = { groupid = "313" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 15-SP3" -Params = { groupid = "378" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 15-SP2" -Params = { groupid = "379" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 15-SP1" -Params = { groupid = "380" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 15 GA" -Params = { groupid = "381" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 12-SP5" -Params = { groupid = "382" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 12-SP4" -Params = { groupid = "383" } - -[[Groups]] -Name = "Containers SLE Base Image Updates 12-SP3" -Params = { groupid = "384" } - -[[Groups]] -Name = "Containers Create_hdd_stable_hosts" -Params = { groupid = "377" } - - - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/_review/run_screen_qac new/openqa-mon-0.25/_review/run_screen_qac --- old/openqa-mon-0.24/_review/run_screen_qac 1970-01-01 01:00:00.000000000 +0100 +++ new/openqa-mon-0.25/_review/run_screen_qac 2021-12-03 10:41:12.000000000 +0100 @@ -0,0 +1,23 @@ +#/bin/bash +FILE=$(readlink -nf "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}") +DIR=$(dirname $FILE) +DATE=$(date '+%G_%V') + +if [[ "$TERM" =~ ^screen ]]; then + + pushd $DIR + screen -t notes $EDITOR ${DATE}_review_notes.txt + + files="containers.toml opensuse-microos.toml publiccloud.toml" + for f in $files; do + screen -t $f openqa-revtui $_review_dir$f + done + popd + + screen -t bash + sleep 1; # avoid reusage of window 0 + +else + screen -S "$(basename $FILE)_${DATE}" $@ $FILE +fi + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/_review/sle-base-images.toml new/openqa-mon-0.25/_review/sle-base-images.toml --- old/openqa-mon-0.24/_review/sle-base-images.toml 1970-01-01 01:00:00.000000000 +0100 +++ new/openqa-mon-0.25/_review/sle-base-images.toml 2021-12-03 10:41:12.000000000 +0100 @@ -0,0 +1,40 @@ +## Review template file for PublicCloud test runs on OSD + +Instance = "https://openqa.suse.de" # openQA instance to query +RabbitMQ = "amqps://suse:s...@rabbit.suse.de" # RabbitMQ instance to query +RabbitMQTopic = "suse.openqa.job.done" # RabbitMQ topic to query +HideStatus = [ "scheduled","passed","running","softfailed","assigned" ] # Hide scheduled and passed jobs +RefreshInterval = 60 # Refresh from API once every minute +MaxJobs = 20 # Max. job per group to display +GroupBy = "groups" # Group by defined groups ("none" or "groups") + + +## Define container groups by their group ID +[[Groups]] +Name = "Containers SLE Base Image Updates 15-SP3" +Params = { groupid = "378" } + +[[Groups]] +Name = "Containers SLE Base Image Updates 15-SP2" +Params = { groupid = "379" } + +[[Groups]] +Name = "Containers SLE Base Image Updates 15-SP1" +Params = { groupid = "380" } + +[[Groups]] +Name = "Containers SLE Base Image Updates 15 GA" +Params = { groupid = "381" } + +[[Groups]] +Name = "Containers SLE Base Image Updates 12-SP5" +Params = { groupid = "382" } + +[[Groups]] +Name = "Containers SLE Base Image Updates 12-SP4" +Params = { groupid = "383" } + +[[Groups]] +Name = "Containers SLE Base Image Updates 12-SP3" +Params = { groupid = "384" } + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/cmd/openqa-mon/config.go new/openqa-mon-0.25/cmd/openqa-mon/config.go --- old/openqa-mon-0.24/cmd/openqa-mon/config.go 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/cmd/openqa-mon/config.go 2021-12-03 10:41:12.000000000 +0100 @@ -17,6 +17,7 @@ Hierarchy bool // show hierarchy HideStates []string // hide the following job states Quit bool // quit program, once all jobs are completed + Paused bool // Continuous monitoring pased } func strBool(text string) (bool, error) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/cmd/openqa-mon/openqa-mon.go new/openqa-mon-0.25/cmd/openqa-mon/openqa-mon.go --- old/openqa-mon-0.24/cmd/openqa-mon/openqa-mon.go 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/cmd/openqa-mon/openqa-mon.go 2021-12-03 10:41:12.000000000 +0100 @@ -15,7 +15,7 @@ "github.com/grisu48/gopenqa" ) -const VERSION = "0.5.1" +const VERSION = "0.6.0" // Remote instance type Remote struct { @@ -218,6 +218,29 @@ var config Config var tui TUI +func SetStatus() { + if config.Paused { + tui.SetStatus("Paused") + return + } + if config.Continuous > 0 { + status := fmt.Sprintf("(continuous monitoring) | %d seconds |", config.Continuous) + if config.Bell || config.Notify { + status += " (" + if config.Bell { + status += "b" + } + if config.Notify { + status += "n" + } + status += ")" + } + tui.SetStatus(status) + } else { + tui.SetStatus("") + } +} + func main() { var err error args := expandArguments(os.Args[1:]) @@ -406,7 +429,7 @@ if len(remotes) == 1 { remotesString = remotes[0].URI } - tui.SetHeader(fmt.Sprintf("openqa-mon - Monitoring %s | Refreshing every %d seconds", remotesString, config.Continuous)) + tui.SetHeader(fmt.Sprintf("openqa-mon - Monitoring %s", remotesString)) tui.Model.HideStates = config.HideStates tui.Update() defer tui.LeaveAltScreen() @@ -684,14 +707,43 @@ } else if b == 'r' { // Refresh refreshSignal <- 1 + return } else if b == '?' { tui.SetShowHelp(!tui.DoShowHelp()) } else if b == 'h' { tui.SetHideStates(!tui.DoHideStates()) - } else { - // Ignore keypress and update tui - tui.Update() + } else if b == 'p' { + config.Paused = !config.Paused + if config.Paused { + SetStatus() + } else { + refreshSignal <- 1 + } + return + } else if b == 'd' || b == 'n' { + config.Notify = !config.Notify + SetStatus() + } else if b == 'b' { + config.Bell = !config.Bell + SetStatus() + } else if b == 'm' { + config.Notify = false + config.Bell = false + SetStatus() + } else if b == 'l' { + config.Notify = true + config.Bell = true + SetStatus() + } else if b == '+' { + config.Continuous++ + SetStatus() + } else if b == '-' { + if config.Continuous > 1 { + config.Continuous-- + } + SetStatus() } + tui.Update() } // Start TUI handlers (keypress, ecc) @@ -702,66 +754,70 @@ tui.SetStatus("Initial job fetching ... ") for { - exists := make(map[int]bool, 0) // Keep track of existing jobs - notifyJobs := make([]gopenqa.Job, 0) // jobs which fire a notification - // Fetch new jobs. Update remotes (job id's) when necessary - remotes, err = FetchJobs(remotes, func(id int, job gopenqa.Job) { - exists[job.ID] = true - // Job received. Update existing job or add job if not yet present - for i, j := range jobs { - if j.ID == id { // Compare to given id as this is the original id (not the ID of a possible cloned job) - jobs[i] = job - // Ignore if job status remains the same - if j.JobState() == job.JobState() { - return - } - // Ignore trivial changes (uploading, assigned) and skipped jobs - state := job.JobState() - if state == "uploading" || state == "assigned" || state == "skipped" || state == "cancelled" { + if config.Paused { + SetStatus() + } else { + exists := make(map[int]bool, 0) // Keep track of existing jobs + notifyJobs := make([]gopenqa.Job, 0) // jobs which fire a notification + // Fetch new jobs. Update remotes (job id's) when necessary + remotes, err = FetchJobs(remotes, func(id int, job gopenqa.Job) { + exists[job.ID] = true + // Job received. Update existing job or add job if not yet present + for i, j := range jobs { + if j.ID == id { // Compare to given id as this is the original id (not the ID of a possible cloned job) + jobs[i] = job + // Ignore if job status remains the same + if j.JobState() == job.JobState() { + return + } + // Ignore trivial changes (uploading, assigned) and skipped jobs + state := job.JobState() + if state == "uploading" || state == "assigned" || state == "skipped" || state == "cancelled" { + return + } + // Notify about job update + notifyJobs = append(notifyJobs, job) + // Refresh tui after each job update + tui.Model.SetJobs(jobs) + tui.Update() return } - // Notify about job update - notifyJobs = append(notifyJobs, job) - // Refresh tui after each job update - tui.Model.SetJobs(jobs) - tui.Update() - return } + + // Append new job + jobs = append(jobs, job) + tui.Model.SetJobs(jobs) + tui.Update() + }) + if len(notifyJobs) > 0 { + NotifyJobsChanged(notifyJobs) } - // Append new job - jobs = append(jobs, job) + // Remove items which are not present anymore - (e.g. old children) + jobs = uniqueJobs(filterJobs(jobs, func(job gopenqa.Job) bool { + _, ok := exists[job.ID] + return ok + })) tui.Model.SetJobs(jobs) + if err != nil { + tui.SetStatus(fmt.Sprintf("Error fetching jobs: %s", err)) + } else { + SetStatus() + } tui.Update() - }) - if len(notifyJobs) > 0 { - NotifyJobsChanged(notifyJobs) - } - - // Remove items which are not present anymore - (e.g. old children) - jobs = uniqueJobs(filterJobs(jobs, func(job gopenqa.Job) bool { - _, ok := exists[job.ID] - return ok - })) - tui.Model.SetJobs(jobs) - if err != nil { - tui.SetStatus(fmt.Sprintf("Error fetching jobs: %s", err)) - } else { - tui.SetStatus("") - } - tui.Update() - // Terminate if all jobs are done - if config.Quit && jobsDone(jobs) { - tui.LeaveAltScreen() - failed := getFailedJobs(jobs) - if len(failed) > 0 { - fmt.Fprintf(os.Stderr, "%d job(s) completed with errors\n", len(failed)) - for _, job := range failed { - fmt.Fprintf(os.Stderr, "%s\n", job.String()) + // Terminate if all jobs are done + if config.Quit && jobsDone(jobs) { + tui.LeaveAltScreen() + failed := getFailedJobs(jobs) + if len(failed) > 0 { + fmt.Fprintf(os.Stderr, "%d job(s) completed with errors\n", len(failed)) + for _, job := range failed { + fmt.Fprintf(os.Stderr, "%s\n", job.String()) + } + os.Exit(1) + } else { + os.Exit(0) } - os.Exit(1) - } else { - os.Exit(0) } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/cmd/openqa-mon/tui.go new/openqa-mon-0.25/cmd/openqa-mon/tui.go --- old/openqa-mon-0.24/cmd/openqa-mon/tui.go 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/cmd/openqa-mon/tui.go 2021-12-03 10:41:12.000000000 +0100 @@ -89,6 +89,13 @@ return ret } +func PrintLine(line string, maxWidth int) { + if maxWidth > 0 && len(line) > maxWidth { + line = line[:maxWidth] + } + fmt.Println(line) +} + func CreateTUI() TUI { var tui TUI tui.done = make(chan bool, 1) @@ -297,16 +304,16 @@ tui.Clear() lines := 0 if tui.header != "" { - fmt.Println(tui.header) + PrintLine(tui.header, width) lines++ } if tui.showHelp { - - fmt.Print("?:Toggle help r: Refresh") + help := "?:Toggle help r: Refresh d:Toggle notifications b:Toggle bell +/-:Increase/Decrease refresh time" if len(tui.Model.HideStates) > 0 { - fmt.Print(" h:Toggle hide") + help += " h:Toggle hide" } - fmt.Println(" q:Quit") + help += " q:Quit" + PrintLine(help, width) lines++ } fmt.Println() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/cmd/openqa-revtui/openqa-revtui.go new/openqa-mon-0.25/cmd/openqa-revtui/openqa-revtui.go --- old/openqa-mon-0.24/cmd/openqa-revtui/openqa-revtui.go 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/cmd/openqa-revtui/openqa-revtui.go 2021-12-03 10:41:12.000000000 +0100 @@ -11,7 +11,7 @@ "github.com/grisu48/gopenqa" ) -const VERSION = "0.3" +const VERSION = "0.3.1" /* Group is a single configurable monitoring unit. A group contains all parameters that will be queried from openQA */ type Group struct { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.24/cmd/openqa-revtui/tui.go new/openqa-mon-0.25/cmd/openqa-revtui/tui.go --- old/openqa-mon-0.24/cmd/openqa-revtui/tui.go 2021-08-13 11:44:45.000000000 +0200 +++ new/openqa-mon-0.25/cmd/openqa-revtui/tui.go 2021-12-03 10:41:12.000000000 +0100 @@ -276,6 +276,12 @@ if state == s { return true } + // Special reviewed keyword + if s == "reviewed" && state == "failed" { + if reviewed, found := tui.Model.reviewed[job.ID]; found && reviewed { + return true + } + } } return false } Binary files old/openqa-mon-0.24/doc/openqa-revtui.png and new/openqa-mon-0.25/doc/openqa-revtui.png differ ++++++ openqa-mon.obsinfo ++++++ --- /var/tmp/diff_new_pack.sqr0YC/_old 2021-12-07 00:02:23.035927453 +0100 +++ /var/tmp/diff_new_pack.sqr0YC/_new 2021-12-07 00:02:23.039927439 +0100 @@ -1,5 +1,5 @@ name: openqa-mon -version: 0.24 -mtime: 1628847885 -commit: d1ee31bf06c8ac0b661c4dbcb7fa5198ea95f16c +version: 0.25 +mtime: 1638524472 +commit: 0401b41cdac39aeb46400bb8bc3008944ef461a2 ++++++ vendor.tar.gz ++++++