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-08-16 10:11:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/openqa-mon (Old) and /work/SRC/openSUSE:Factory/.openqa-mon.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "openqa-mon" Mon Aug 16 10:11:37 2021 rev:3 rq:912013 version:0.24 Changes: -------- --- /work/SRC/openSUSE:Factory/openqa-mon/openqa-mon.changes 2021-06-26 21:25:46.751368350 +0200 +++ /work/SRC/openSUSE:Factory/.openqa-mon.new.1899/openqa-mon.changes 2021-08-16 10:17:44.562646527 +0200 @@ -1,0 +2,5 @@ +Fri Aug 13 09:58:50 UTC 2021 - Felix Niederwanger <[email protected]> + +- Add useragent + +------------------------------------------------------------------- Old: ---- openqa-mon-0.23.tar.gz New: ---- openqa-mon-0.24.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ openqa-mon.spec ++++++ --- /var/tmp/diff_new_pack.vtPkxp/_old 2021-08-16 10:17:45.918644352 +0200 +++ /var/tmp/diff_new_pack.vtPkxp/_new 2021-08-16 10:17:45.922644347 +0200 @@ -17,7 +17,7 @@ Name: openqa-mon -Version: 0.23 +Version: 0.24 Release: 0 Summary: CLI monitoring utility for openQA License: GPL-3.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.vtPkxp/_old 2021-08-16 10:17:45.970644269 +0200 +++ /var/tmp/diff_new_pack.vtPkxp/_new 2021-08-16 10:17:45.970644269 +0200 @@ -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.23</param> + <param name="version">v0.24</param> <param name="versionrewrite-pattern">v(.*)</param> </service> <service name="tar" mode="localonly"/> @@ -14,4 +14,3 @@ <service name="go_modules" mode="disabled"/> <service name="set_version" mode="buildtime"/> </services> - ++++++ openqa-mon-0.23.tar.gz -> openqa-mon-0.24.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/.gitignore new/openqa-mon-0.24/.gitignore --- old/openqa-mon-0.23/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/openqa-mon-0.24/.gitignore 2021-08-13 11:44:45.000000000 +0200 @@ -0,0 +1,6 @@ +# Binaries +/openqa-mon +/openqa-revtui +/openqa-mq +# Temporary files +/*.json diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/_review/containers.toml new/openqa-mon-0.24/_review/containers.toml --- old/openqa-mon-0.23/_review/containers.toml 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/_review/containers.toml 2021-08-13 11:44:45.000000000 +0200 @@ -1,16 +1,20 @@ ## Review template file for PublicCloud test runs on OSD -Instance = "https://openqa.suse.de" # openQA instance to query -RabbitMQ = "amqps://suse:[email protected]" # RabbitMQ instance to query -RabbitMQTopic = "suse.openqa.job.done" # RabbitMQ topic to query -HideStatus = [ "scheduled", "passed" ] # 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") +Instance = "https://openqa.suse.de" # openQA instance to query +RabbitMQ = "amqps://suse:[email protected]" # 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 15 SP3 Updates" +Params = { groupid = "369" } + +[[Groups]] Name = "Containers 15 SP2 Updates" Params = { groupid = "352" } @@ -39,7 +43,36 @@ Params = { groupid = "313" } [[Groups]] -Name = "Containers SLE Base Image Updates" -Params = { groupid = "315" } +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.23/_review/opensuse-tumbleweed.toml new/openqa-mon-0.24/_review/opensuse-tumbleweed.toml --- old/openqa-mon-0.23/_review/opensuse-tumbleweed.toml 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/_review/opensuse-tumbleweed.toml 2021-08-13 11:44:45.000000000 +0200 @@ -1,13 +1,13 @@ ## Review template file for PublicCloud test runs on OSD -Instance = "https://openqa.opensuse.org" # openQA instance to query -RabbitMQ = "amqps://opensuse:[email protected]" # RabbitMQ instance to query -RabbitMQTopic = "opensuse.openqa.job.done" # RabbitMQ topic to query -HideStatus = [ "scheduled","passed","assigned" ] # Hide scheduled, passed and assigned 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") -DefaultParams = { distri="opensuse", version = "Tumbleweed" } # Set of default parameters +Instance = "https://openqa.opensuse.org" # openQA instance to query +RabbitMQ = "amqps://opensuse:[email protected]" # RabbitMQ instance to query +RabbitMQTopic = "opensuse.openqa.job.done" # RabbitMQ topic to query +HideStatus = [ "scheduled","passed","assigned","running","softfailed" ] # Hide scheduled, passed and assigned 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") +DefaultParams = { distri="opensuse", version = "Tumbleweed" } # Set of default parameters ## Define container groups by their group ID [[Groups]] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/_review/publiccloud.toml new/openqa-mon-0.24/_review/publiccloud.toml --- old/openqa-mon-0.23/_review/publiccloud.toml 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/_review/publiccloud.toml 2021-08-13 11:44:45.000000000 +0200 @@ -1,14 +1,14 @@ ## Review template file for PublicCloud test runs on OSD -Instance = "https://openqa.suse.de" # openQA instance to query -RabbitMQ = "amqps://suse:[email protected]" # RabbitMQ instance to query -RabbitMQTopic = "suse.openqa.job.done" # RabbitMQ topic to query -HideStatus = [ "scheduled", "passed" ] # Hide scheduled and passed jobs -Notify = false # No notifications by default -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") -DefaultParams = { distri = "sle" } # Set of default parameters +Instance = "https://openqa.suse.de" # openQA instance to query +RabbitMQ = "amqps://suse:[email protected]" # RabbitMQ instance to query +RabbitMQTopic = "suse.openqa.job.done" # RabbitMQ topic to query +HideStatus = [ "scheduled","passed","running","softfailed","assigned" ] # Hide scheduled and passed jobs +Notify = false # No notifications by default +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") +DefaultParams = { distri = "sle" } # Set of default parameters # Define publiccloud groups based on their flavor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/cmd/openqa-mon/openqa-mon.go new/openqa-mon-0.24/cmd/openqa-mon/openqa-mon.go --- old/openqa-mon-0.23/cmd/openqa-mon/openqa-mon.go 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/cmd/openqa-mon/openqa-mon.go 2021-08-13 11:44:45.000000000 +0200 @@ -15,7 +15,7 @@ "github.com/grisu48/gopenqa" ) -const VERSION = "0.5" +const VERSION = "0.5.1" // Remote instance type Remote struct { @@ -546,6 +546,7 @@ func FetchJobs(remotes []Remote, callback func(int, gopenqa.Job)) ([]Remote, error) { for i, remote := range remotes { instance := gopenqa.CreateInstance(ensureHTTP(remote.URI)) + instance.SetUserAgent("openqa-mon") instance.SetMaxRecursionDepth(100) // Certain jobs (e.g. verification runs) can have a lot of clones // If no jobs are defined, fetch overview if len(remote.Jobs) == 0 { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/cmd/openqa-revtui/openqa-revtui.go new/openqa-mon-0.24/cmd/openqa-revtui/openqa-revtui.go --- old/openqa-mon-0.23/cmd/openqa-revtui/openqa-revtui.go 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/cmd/openqa-revtui/openqa-revtui.go 2021-08-13 11:44:45.000000000 +0200 @@ -11,7 +11,7 @@ "github.com/grisu48/gopenqa" ) -const VERSION = "0.2b" +const VERSION = "0.3" /* Group is a single configurable monitoring unit. A group contains all parameters that will be queried from openQA */ type Group struct { @@ -145,7 +145,7 @@ /* Get job or restarted current job of the given job ID */ func FetchJob(id int, instance gopenqa.Instance) (gopenqa.Job, error) { var job gopenqa.Job - for i := 0; i < 10; i++ { // Max recursion depth is 10 + for i := 0; i < 25; i++ { // Max recursion depth is 25 var err error job, err = instance.GetJob(id) if err != nil { @@ -153,10 +153,10 @@ } if job.CloneID != 0 && job.CloneID != job.ID { id = job.CloneID + time.Sleep(100 * time.Millisecond) // Don't spam the instance continue - } else { - return job, nil } + return job, nil } return job, fmt.Errorf("max recursion depth reached") } @@ -401,6 +401,7 @@ } instance := gopenqa.CreateInstance(cf.Instance) + instance.SetUserAgent("openqa-mon/revtui") // Run TUI and use the return code tui := CreateTUI() @@ -414,9 +415,12 @@ os.Exit(1) } tui.SetHideStatus(cf.HideStatus) - rc := tui_main(&tui, instance) + err := tui_main(&tui, instance) tui.LeaveAltScreen() // Ensure we leave alt screen - os.Exit(rc) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(1) + } } func refreshJobs(tui *TUI, instance gopenqa.Instance) error { @@ -443,7 +447,8 @@ } } // Failed jobs will be also scanned for comments - if job.JobState() == "failed" { + state := job.JobState() + if state == "failed" || state == "incomplete" { reviewed, err := isReviewed(job, instance) if err != nil { return err @@ -459,7 +464,7 @@ } // main routine for the TUI instance -func tui_main(tui *TUI, instance gopenqa.Instance) int { +func tui_main(tui *TUI, instance gopenqa.Instance) error { title := "openqa Review TUI Dashboard v" + VERSION var rabbitmq gopenqa.RabbitMQ var err error @@ -510,8 +515,7 @@ fmt.Println("\tGet job groups ... ") jobgroups, err := FetchJobGroups(instance) if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching job groups: %s\n", err) - return 1 + return fmt.Errorf("Error fetching job groups: %s", err) } if len(jobgroups) == 0 { fmt.Fprintf(os.Stderr, "Warn: No job groups\n") @@ -520,16 +524,15 @@ fmt.Printf("\tGet jobs for %d groups ... \n", len(cf.Groups)) jobs, err := FetchJobs(instance) if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching jobs: %s\n", err) - os.Exit(1) + return fmt.Errorf("Error fetching jobs: %s", err) } // Failed jobs will be also scanned for comments for _, job := range jobs { - if job.JobState() == "failed" { + state := job.JobState() + if state == "failed" || state == "incomplete" { reviewed, err := isReviewed(job, instance) if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching job comment: %s\n", err) - os.Exit(1) + return fmt.Errorf("Error fetching job comment: %s", err) } tui.Model.SetReviewed(job.ID, reviewed) } @@ -565,5 +568,5 @@ if cf.RabbitMQ != "" { rabbitmq.Close() } - return 0 + return nil } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/cmd/openqa-revtui/tui.go new/openqa-mon-0.24/cmd/openqa-revtui/tui.go --- old/openqa-mon-0.23/cmd/openqa-revtui/tui.go 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/cmd/openqa-revtui/tui.go 2021-08-13 11:44:45.000000000 +0200 @@ -504,12 +504,9 @@ tStr = timestamp.Format("2006-01-02-15:04:05") } // For failed jobs check if they are reviewed - if state == "failed" || state == "incomplete" { - if reviewed, found := tui.Model.reviewed[job.ID]; found { - if reviewed { - state = "reviewed" - c2 = ANSI_MAGENTA - } + if job.Result == "failed" || job.Result == "incomplete" { + if reviewed, found := tui.Model.reviewed[job.ID]; found && reviewed { + c2 = ANSI_MAGENTA } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/go.mod new/openqa-mon-0.24/go.mod --- old/openqa-mon-0.23/go.mod 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/go.mod 2021-08-13 11:44:45.000000000 +0200 @@ -4,6 +4,6 @@ require ( github.com/BurntSushi/toml v0.3.1 - github.com/grisu48/gopenqa v0.3.3 + github.com/grisu48/gopenqa v0.4.2 github.com/streadway/amqp v1.0.0 ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/openqa-mon-0.23/go.sum new/openqa-mon-0.24/go.sum --- old/openqa-mon-0.23/go.sum 2021-06-04 09:58:59.000000000 +0200 +++ new/openqa-mon-0.24/go.sum 2021-08-13 11:44:45.000000000 +0200 @@ -1,21 +1,14 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/grisu48/gopenqa v0.0.0-20210224104953-f86136cfe826/go.mod h1:ZVDyBqnwiOAv+vm7FFB8/S94Rt+0da4lQD5TaZWl8oE= -github.com/grisu48/gopenqa v0.0.0-20210301125648-f72f716c6bfb h1:Xvj1gHwROF2xIPETjhUW7TFXBeq29qoqYRLxu7E4J5w= -github.com/grisu48/gopenqa v0.0.0-20210301125648-f72f716c6bfb/go.mod h1:ZVDyBqnwiOAv+vm7FFB8/S94Rt+0da4lQD5TaZWl8oE= -github.com/grisu48/gopenqa v0.0.0-20210301131952-e781e21a6e9c h1:g8/Zih9pi182bkyGoa3Y/AFXS/qLhv5nTpoQjilwgHo= -github.com/grisu48/gopenqa v0.0.0-20210301131952-e781e21a6e9c/go.mod h1:ZVDyBqnwiOAv+vm7FFB8/S94Rt+0da4lQD5TaZWl8oE= -github.com/grisu48/gopenqa v0.0.0-20210420081537-0d0d61f743e6 h1:b+OqOOGaLU9eWIEZVEeh6KCb4DYaMLDM36gSutC+hTg= -github.com/grisu48/gopenqa v0.0.0-20210420081537-0d0d61f743e6/go.mod h1:D7EFTPhtzNvnHnDol9UoPCFmnzOiLBVa1tOOYqJDgGo= -github.com/grisu48/gopenqa v0.3.0 h1:LSstlioho4vFqxSf3jNVJSU9BeCYqLW6mlSwy0Qzw9k= -github.com/grisu48/gopenqa v0.3.0/go.mod h1:D7EFTPhtzNvnHnDol9UoPCFmnzOiLBVa1tOOYqJDgGo= -github.com/grisu48/gopenqa v0.3.2 h1:v8h5iYqZqGHph69OlPvrd3+E4AqnOAph51+NbAihzUk= -github.com/grisu48/gopenqa v0.3.2/go.mod h1:D7EFTPhtzNvnHnDol9UoPCFmnzOiLBVa1tOOYqJDgGo= -github.com/grisu48/gopenqa v0.3.3 h1:WTwTBcIc06uFW4NgMkbhq6bkH+3TGF1H3p5u2/9wYoI= -github.com/grisu48/gopenqa v0.3.3/go.mod h1:D7EFTPhtzNvnHnDol9UoPCFmnzOiLBVa1tOOYqJDgGo= +github.com/grisu48/gopenqa v0.4.2 h1:iStMnys0A+kHkvH/ImoGydyDSvXDUUYYVP0SOwZdAn0= +github.com/grisu48/gopenqa v0.4.2/go.mod h1:D7EFTPhtzNvnHnDol9UoPCFmnzOiLBVa1tOOYqJDgGo= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/streadway/amqp v1.0.0 h1:kuuDrUJFZL1QYL9hUNuCxNObNzB0bV/ZG5jV3RWAQgo= github.com/streadway/amqp v1.0.0/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= ++++++ openqa-mon.obsinfo ++++++ --- /var/tmp/diff_new_pack.vtPkxp/_old 2021-08-16 10:17:46.098644064 +0200 +++ /var/tmp/diff_new_pack.vtPkxp/_new 2021-08-16 10:17:46.098644064 +0200 @@ -1,5 +1,5 @@ name: openqa-mon -version: 0.23 -mtime: 1622793539 -commit: 2b90079f91f8cfc39e0a587caa3f5c9683550363 +version: 0.24 +mtime: 1628847885 +commit: d1ee31bf06c8ac0b661c4dbcb7fa5198ea95f16c ++++++ vendor.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/grisu48/gopenqa/.gitignore new/vendor/github.com/grisu48/gopenqa/.gitignore --- old/vendor/github.com/grisu48/gopenqa/.gitignore 2021-06-04 10:15:05.510018000 +0200 +++ new/vendor/github.com/grisu48/gopenqa/.gitignore 2021-08-13 11:55:41.712317700 +0200 @@ -4,6 +4,7 @@ *.dll *.so *.dylib +/gopenqa # Test binary, built with `go test -c` *.test diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/grisu48/gopenqa/comment.go new/vendor/github.com/grisu48/gopenqa/comment.go --- old/vendor/github.com/grisu48/gopenqa/comment.go 2021-06-04 10:15:05.514018300 +0200 +++ new/vendor/github.com/grisu48/gopenqa/comment.go 2021-08-13 11:55:41.712317700 +0200 @@ -3,7 +3,7 @@ type Comment struct { ID int `json:"id"` Text string `json:"text"` // Comment text - Rendered string `json:"renderedMarkdown"` // HTML of the rendered markdown + Markdown string `json:"renderedMarkdown"` // HTML of the rendered markdown BugRefs []string `json:"bugrefs"` // Referenced bugs Created string `json:"created"` // bug creation date Updated string `json:"updated"` // timestamp for update diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/grisu48/gopenqa/gopenqa.go new/vendor/github.com/grisu48/gopenqa/gopenqa.go --- old/vendor/github.com/grisu48/gopenqa/gopenqa.go 2021-06-04 10:15:05.514018300 +0200 +++ new/vendor/github.com/grisu48/gopenqa/gopenqa.go 2021-08-13 11:55:41.712317700 +0200 @@ -20,21 +20,22 @@ apikey string apisecret string verbose bool - maxRecursions int // Maximum number of recursions + maxRecursions int // Maximum number of recursions + userAgent string // Useragent sent with the request } -// the settings are given as a bit of a weird dict: +// the settings are given as dict: // e.g. "settings":[{"key":"WORKER_CLASS","value":"\"plebs\""}]}] // We create an internal struct to account for that -type weirdMachine struct { +type machine2 struct { ID int `json:"id"` Backend string `json:"backend"` Name string `json:"name"` Settings []map[string]string `json:"settings"` } -// same as weirdMachine for Product -type weirdProduct struct { +// same as machine2 for Product +type product2 struct { Arch string `json:"arch"` Distri string `json:"distri"` Flavor string `json:"flavor"` @@ -71,21 +72,21 @@ return ret } -func (mach *weirdMachine) CopySettingsFrom(src Machine) { +func (mach *machine2) CopySettingsFrom(src Machine) { mach.Settings = convertSettingsFrom(src.Settings) } -func (mach *weirdMachine) CopySettingsTo(dst *Machine) { +func (mach *machine2) CopySettingsTo(dst *Machine) { dst.Settings = convertSettingsTo(mach.Settings) } -func (p *weirdProduct) CopySettingsFrom(src Product) { +func (p *product2) CopySettingsFrom(src Product) { p.Settings = convertSettingsFrom(src.Settings) } -func (p *weirdProduct) CopySettingsTo(dst *Product) { +func (p *product2) CopySettingsTo(dst *Product) { dst.Settings = convertSettingsTo(p.Settings) } -func (w *weirdProduct) toProduct() Product { +func (w *product2) toProduct() Product { p := Product{} p.Arch = w.Arch p.Distri = w.Distri @@ -97,8 +98,8 @@ return p } -func createWeirdProduct(p Product) weirdProduct { - w := weirdProduct{} +func createProduct2(p Product) product2 { + w := product2{} w.Arch = p.Arch w.Distri = p.Distri w.Flavor = p.Flavor @@ -110,7 +111,7 @@ } /* Get www-form-urlencoded parameters of this Product */ -func (p *weirdProduct) encodeParams() string { +func (p *product2) encodeParams() string { params := url.Values{} params.Add("arch", p.Arch) params.Add("distri", p.Distri) @@ -137,7 +138,7 @@ /* Create a openQA instance module */ func CreateInstance(url string) Instance { - inst := Instance{URL: url, maxRecursions: 10, verbose: false} + inst := Instance{URL: url, maxRecursions: 10, verbose: false, userAgent: "gopenqa"} return inst } @@ -157,10 +158,16 @@ i.apisecret = secret } +// Enable verbosity func (i *Instance) SetVerbose(verbose bool) { i.verbose = verbose } +// Set the UserAgent for HTTP requests +func (i *Instance) SetUserAgent(userAgent string) { + i.userAgent = userAgent +} + func assignInstance(jobs []Job, instance *Instance) []Job { for i, j := range jobs { j.instance = instance @@ -238,6 +245,9 @@ return make([]byte, 0), err } req.Header.Add("Content-Type", contentType) + if i.userAgent != "" { + req.Header.Set("User-Agent", i.userAgent) + } // Credentials are sent in the headers // "X-API-Key" -> api key // "X-API-Hash" -> sha1 hashed api secret @@ -299,7 +309,7 @@ url += "?" + mergeParams(params) } - jobs, err := fetchJobs(url) + jobs, err := i.fetchJobs(url) assignInstance(jobs, i) return jobs, err } @@ -322,14 +332,11 @@ } url += "?" + mergeParams(params) // Fetch jobs here, as we expect it to be in `jobs` - r, err := http.Get(url) + resp, err := i.request("GET", url, nil) if err != nil { return jobs.Jobs, err } - if r.StatusCode != 200 { - return jobs.Jobs, fmt.Errorf("http status code %d", r.StatusCode) - } - err = json.NewDecoder(r.Body).Decode(&jobs) + err = json.Unmarshal(resp, &jobs) // Now, get only the latest job per group_id mapped := make(map[int]Job) @@ -358,7 +365,7 @@ // GetJob fetches detailled job information func (i *Instance) GetJob(id int) (Job, error) { url := fmt.Sprintf("%s/api/v1/jobs/%d", i.URL, id) - job, err := fetchJob(url) + job, err := i.fetchJob(url) job.Link = fmt.Sprintf("%s/tests/%d", i.URL, id) job.instance = i return job, err @@ -378,7 +385,7 @@ recursions := 0 // keep track of the number of recursions fetch: url := fmt.Sprintf("%s/api/v1/jobs/%d", i.URL, id) - job, err := fetchJob(url) + job, err := i.fetchJob(url) if job.CloneID != 0 && job.CloneID != job.ID { recursions++ if i.maxRecursions != 0 && recursions >= i.maxRecursions { @@ -394,12 +401,12 @@ func (i *Instance) GetJobGroups() ([]JobGroup, error) { url := fmt.Sprintf("%s/api/v1/job_groups", i.URL) - return fetchJobGroups(url) + return i.fetchJobGroups(url) } func (i *Instance) GetJobGroup(id int) (JobGroup, error) { url := fmt.Sprintf("%s/api/v1/job_groups/%d", i.URL, id) - groups, err := fetchJobGroups(url) + groups, err := i.fetchJobGroups(url) if err != nil { return JobGroup{}, err } @@ -424,12 +431,12 @@ func (i *Instance) GetParentJobGroups() ([]JobGroup, error) { url := fmt.Sprintf("%s/api/v1/parent_groups", i.URL) - return fetchJobGroups(url) + return i.fetchJobGroups(url) } func (i *Instance) GetParentJobGroup(id int) (JobGroup, error) { url := fmt.Sprintf("%s/api/v1/parent_groups/%d", i.URL, id) - groups, err := fetchJobGroups(url) + groups, err := i.fetchJobGroups(url) if err != nil { return JobGroup{}, err } @@ -454,87 +461,68 @@ func (i *Instance) GetWorkers() ([]Worker, error) { url := fmt.Sprintf("%s/api/v1/workers", i.URL) - return fetchWorkers(url) + return i.fetchWorkers(url) } -func fetchJobs(url string) ([]Job, error) { +func (i *Instance) fetchJobs(url string) ([]Job, error) { jobs := make([]Job, 0) - r, err := http.Get(url) + + resp, err := i.get(url, nil) if err != nil { return jobs, err } - if r.StatusCode != 200 { - return jobs, fmt.Errorf("http status code %d", r.StatusCode) - } - err = json.NewDecoder(r.Body).Decode(&jobs) + err = json.Unmarshal(resp, &jobs) return jobs, err } -func fetchJobGroups(url string) ([]JobGroup, error) { +func (i *Instance) fetchJobGroups(url string) ([]JobGroup, error) { jobs := make([]JobGroup, 0) - r, err := http.Get(url) - if err != nil { - return jobs, err - } - if r.StatusCode != 200 { - return jobs, fmt.Errorf("http status code %d", r.StatusCode) - } - data, err := ioutil.ReadAll(r.Body) + resp, err := i.get(url, nil) if err != nil { return jobs, err } - // Sometimes SizeLimit is returned as string but it should be an int. Fix this. - err = json.Unmarshal(data, &jobs) + // TODO: Sometimes SizeLimit is returned as string but it should be an int. Fix this. + err = json.Unmarshal(resp, &jobs) return jobs, err } -func fetchWorkers(url string) ([]Worker, error) { - r, err := http.Get(url) +func (i *Instance) fetchWorkers(url string) ([]Worker, error) { + resp, err := i.get(url, nil) if err != nil { return make([]Worker, 0), err } - if r.StatusCode != 200 { - return make([]Worker, 0), fmt.Errorf("http status code %d", r.StatusCode) - } // workers come in a "workers:[...]" dict workers := make(map[string][]Worker, 0) - err = json.NewDecoder(r.Body).Decode(&workers) + err = json.Unmarshal(resp, &workers) if workers, ok := workers["workers"]; ok { return workers, err } return make([]Worker, 0), nil } -func fetchJobTemplates(url string) ([]JobTemplate, error) { - r, err := http.Get(url) +func (i *Instance) fetchJobTemplates(url string) ([]JobTemplate, error) { + resp, err := i.get(url, nil) if err != nil { return make([]JobTemplate, 0), err } - if r.StatusCode != 200 { - return make([]JobTemplate, 0), fmt.Errorf("http status code %d", r.StatusCode) - } // the templates come as a "JobTemplates:[...]" dict templates := make(map[string][]JobTemplate, 0) - err = json.NewDecoder(r.Body).Decode(&templates) + err = json.Unmarshal(resp, &templates) if templates, ok := templates["JobTemplates"]; ok { return templates, err } return make([]JobTemplate, 0), nil } -func fetchMachines(url string) ([]Machine, error) { - r, err := http.Get(url) +func (i *Instance) fetchMachines(url string) ([]Machine, error) { + resp, err := i.get(url, nil) if err != nil { return make([]Machine, 0), err } - if r.StatusCode != 200 { - return make([]Machine, 0), fmt.Errorf("http status code %d", r.StatusCode) - } - // machines come as a "Machines:[...]" dict - machines := make(map[string][]weirdMachine, 0) - err = json.NewDecoder(r.Body).Decode(&machines) + machines := make(map[string][]machine2, 0) + err = json.Unmarshal(resp, &machines) if machines, ok := machines["Machines"]; ok { // Parse those weird machines to actual machine instances ret := make([]Machine, 0) @@ -548,20 +536,17 @@ return make([]Machine, 0), nil } -func fetchJob(url string) (Job, error) { - // Expected result structure - type ResultJob struct { +func (i *Instance) fetchJob(url string) (Job, error) { + type ResultJob struct { // Expected result structure Job Job `json:"job"` } var job ResultJob - r, err := http.Get(url) + resp, err := i.get(url, nil) if err != nil { return job.Job, err } - if r.StatusCode != 200 { - return job.Job, fmt.Errorf("http status code %d", r.StatusCode) - } - err = json.NewDecoder(r.Body).Decode(&job) + // TODO: Sometimes SizeLimit is returned as string but it should be an int. Fix this. + err = json.Unmarshal(resp, &job) return job.Job, err } @@ -607,7 +592,7 @@ func (i *Instance) GetJobTemplates() ([]JobTemplate, error) { url := fmt.Sprintf("%s/api/v1/job_templates", i.URL) - return fetchJobTemplates(url) + return i.fetchJobTemplates(url) } func (instance *Instance) GetJobGroupJobs(id int) ([]int, error) { @@ -663,7 +648,7 @@ func (i *Instance) GetJobTemplate(id int) (JobTemplate, error) { url := fmt.Sprintf("%s/api/v1/job_templates/%d", i.URL, id) - templates, err := fetchJobTemplates(url) + templates, err := i.fetchJobTemplates(url) if err != nil { return JobTemplate{}, err } @@ -687,12 +672,12 @@ func (i *Instance) GetMachines() ([]Machine, error) { url := fmt.Sprintf("%s/api/v1/machines", i.URL) - return fetchMachines(url) + return i.fetchMachines(url) } func (i *Instance) GetMachine(id int) (Machine, error) { url := fmt.Sprintf("%s/api/v1/machines/%d", i.URL, id) - if machines, err := fetchMachines(url); err != nil { + if machines, err := i.fetchMachines(url); err != nil { return Machine{}, err } else { if len(machines) > 0 { @@ -726,7 +711,7 @@ // Setting are encoded in a bit weird way // Note: This is not supported by openQA at the moment, but we keep it here for when it does. - wmach := weirdMachine{Name: machine.Name, ID: machine.ID, Backend: machine.Backend} + wmach := machine2{Name: machine.Name, ID: machine.ID, Backend: machine.Backend} wmach.CopySettingsFrom(machine) // Encode the machine settings as JSON @@ -766,12 +751,12 @@ if err != nil { return products, err } - var obj map[string][]weirdProduct + var obj map[string][]product2 if err := json.Unmarshal(buf, &obj); err != nil { return products, err } if fetched, ok := obj["Products"]; ok { - // Convert from weirdProduct to product + // Convert from product2 to product for _, product := range fetched { products = append(products, product.toProduct()) } @@ -789,7 +774,7 @@ if err != nil { return Product{}, err } - var obj map[string][]weirdProduct + var obj map[string][]product2 if err := json.Unmarshal(buf, &obj); err != nil { return Product{}, err } @@ -815,7 +800,7 @@ } // Product to values - wproduct := createWeirdProduct(product) + wproduct := createProduct2(product) data := []byte(wproduct.encodeParams()) if i.verbose { fmt.Fprintf(os.Stderr, "%s\n", data) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/github.com/grisu48/gopenqa/rabbitmq.go new/vendor/github.com/grisu48/gopenqa/rabbitmq.go --- old/vendor/github.com/grisu48/gopenqa/rabbitmq.go 2021-06-04 10:15:05.514018300 +0200 +++ new/vendor/github.com/grisu48/gopenqa/rabbitmq.go 2021-08-13 11:55:41.712317700 +0200 @@ -11,18 +11,27 @@ // JobStatus is the returns struct for job status updates from RabbitMQ type JobStatus struct { - Arch string `json:"ARCH"` - Build string `json:"BUILD"` - Flavor string `json:"FLAVOR"` - Machine string `json:"MACHINE"` - Test string `json:"TEST"` - BugRef string `json:"bugref"` - GroupID int `json:"group_id"` - ID int `json:"id"` - NewBuild string `json:"newbuild"` - Reason string `json:"reason"` - Remaining int `json:"remaining"` - Result string `json:"result"` + Arch string `json:"ARCH"` + Build string `json:"BUILD"` + Flavor string `json:"FLAVOR"` + Machine string `json:"MACHINE"` + Test string `json:"TEST"` + BugRef string `json:"bugref"` + GroupID int `json:"group_id"` + ID int `json:"id"` + NewBuild string `json:"newbuild"` + Reason string `json:"reason"` + Remaining int `json:"remaining"` + Result string `json:"result"` +} + +// RabbitMQ comment +type CommentMQ struct { + ID int `json:"id"` + Created string `json:"created"` + Updates string `json:"updated"` + Text string `json:"text"` + User string `json:"user"` } // RabbitMQ struct is the object which handles the connection to a RabbitMQ instance @@ -83,6 +92,21 @@ return status, err } +// ReceiveJobStatus receives the next message and try to parse it as Comment. Use this for job status updates +func (sub *RabbitMQSubscription) ReceiveComment() (CommentMQ, error) { + var comment CommentMQ + d, err := sub.Receive() + if err != nil { + return comment, err + } + // Try to unmarshall to json + err = json.Unmarshal(d.Body, &comment) + if err != nil { + return comment, err + } + return comment, err +} + // Close subscription channel func (sub *RabbitMQSubscription) Close() { sub.channel.Close() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/vendor/modules.txt new/vendor/modules.txt --- old/vendor/modules.txt 2021-06-04 10:15:05.514018300 +0200 +++ new/vendor/modules.txt 2021-08-13 11:55:41.716317700 +0200 @@ -1,6 +1,6 @@ # github.com/BurntSushi/toml v0.3.1 github.com/BurntSushi/toml -# github.com/grisu48/gopenqa v0.3.3 +# github.com/grisu48/gopenqa v0.4.2 github.com/grisu48/gopenqa # github.com/streadway/amqp v1.0.0 github.com/streadway/amqp
