aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-10-11 13:18:10 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-10-15 08:34:09 +0000
commit14943bb8b0b96031f1ac7110e2bfa628c0ce9e30 (patch)
treee29baecafb7398297a8d19c9892af16307dea35a
parentb9fb2ea80e9852ae6465fcb3b822ca9ffa3306bd (diff)
tools/syz-reprolist: switch to dashboard/api.Client
-rw-r--r--tools/syz-reprolist/external_api.go51
-rw-r--r--tools/syz-reprolist/reprolist.go108
2 files changed, 31 insertions, 128 deletions
diff --git a/tools/syz-reprolist/external_api.go b/tools/syz-reprolist/external_api.go
deleted file mode 100644
index d611691cc..000000000
--- a/tools/syz-reprolist/external_api.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2024 syzkaller project authors. All rights reserved.
-// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
-
-package main
-
-import (
- "encoding/json"
- "fmt"
- "log"
- "strings"
-
- "github.com/google/syzkaller/dashboard/api"
-)
-
-func reproIDFromURL(url string) string {
- parts := strings.Split(url, "&")
- if len(parts) != 2 {
- log.Panicf("can't split %s in two parts by ?", url)
- }
- parts = strings.Split(parts[1], "=")
- if len(parts) != 2 {
- log.Panicf("can't split %s in two parts by =", url)
- }
- return parts[1]
-}
-
-func getBugList(jsonBugs []byte) ([]string, error) {
- var bl api.BugGroup
- if err := json.Unmarshal(jsonBugs, &bl); err != nil {
- return nil, fmt.Errorf("json.Unmarshal: %w", err)
- }
- if bl.Version != 1 {
- return nil, fmt.Errorf("unsupported export version %d", bl.Version)
- }
- res := []string{}
- for _, b := range bl.Bugs {
- res = append(res, b.Link)
- }
- return res, nil
-}
-
-func makeBugDetails(jsonDetails []byte) (*api.Bug, error) {
- var bd api.Bug
- if err := json.Unmarshal(jsonDetails, &bd); err != nil {
- return nil, fmt.Errorf("json.Unmarshal: %w", err)
- }
- if bd.Version != 1 {
- return nil, fmt.Errorf("unsupported export version %d", bd.Version)
- }
- return &bd, nil
-}
diff --git a/tools/syz-reprolist/reprolist.go b/tools/syz-reprolist/reprolist.go
index 34a3cefb9..d3cf6289c 100644
--- a/tools/syz-reprolist/reprolist.go
+++ b/tools/syz-reprolist/reprolist.go
@@ -8,9 +8,7 @@ import (
"flag"
"fmt"
"html"
- "io"
"log"
- "net/http"
"os"
"path"
"path/filepath"
@@ -19,6 +17,7 @@ import (
"sync"
"time"
+ "github.com/google/syzkaller/dashboard/api"
"github.com/google/syzkaller/dashboard/dashapi"
"github.com/google/syzkaller/pkg/csource"
"github.com/google/syzkaller/pkg/osutil"
@@ -290,11 +289,12 @@ func containsCommit(hash string) bool {
}
func exportNamespace() error {
- bugURLs, err := getFullBugList()
+ cli := api.NewClient(*flagDashboard, *flagToken)
+ bugs, err := cli.BugGroups(*flagNamespace, api.BugGroupOpen|api.BugGroupFixed)
if err != nil {
return err
}
- fmt.Printf("total %d bugs available\n", len(bugURLs))
+ fmt.Printf("total %d bugs available\n", len(bugs))
iBugChan := make(chan int)
g, _ := errgroup.WithContext(context.Background())
@@ -302,28 +302,24 @@ func exportNamespace() error {
i := i
g.Go(func() error {
for iBug := range iBugChan {
- bugURL := *flagDashboard + bugURLs[iBug]
- bugBody, err := getJSONBody(bugURL)
+ bug, err := cli.Bug(bugs[iBug].Link)
if err != nil {
- return fmt.Errorf("getJSONBody(%s): %w", bugURL, err)
+ return err
}
- bugDetails, err := makeBugDetails(bugBody)
+ cReproURL := bug.Crashes[0].CReproducerLink // export max 1 CRepro per bug
+ if cReproURL == "" {
+ continue
+ }
+ reproID := reproIDFromURL(cReproURL)
+ fmt.Printf("[%v](%v/%v)saving c-repro %v for bug %v\n",
+ i, iBug, len(bugs), reproID, bug.ID)
+ fullReproURL := *flagDashboard + html.UnescapeString(cReproURL)
+ cReproBody, err := cli.Text(fullReproURL)
if err != nil {
- return fmt.Errorf("makeBugDetails: %w", err)
+ return err
}
- // Export max 1 CRepro per bug.
- if cReproURL := bugDetails.Crashes[0].CReproducerLink; cReproURL != "" {
- reproID := reproIDFromURL(cReproURL)
- fmt.Printf("[%d](%d/%d)saving c-repro %s for bug %s\n",
- i, iBug, len(bugURLs), reproID, bugDetails.ID)
- fullReproURL := *flagDashboard + html.UnescapeString(cReproURL)
- cReproBody, err := getJSONBody(fullReproURL)
- if err != nil {
- return fmt.Errorf("getJSONBody(%s): %w", fullReproURL, err)
- }
- if err := saveCRepro(reproID, cReproBody); err != nil {
- return fmt.Errorf("saveRepro(bugID=%s, reproID=%s): %w", bugDetails.ID, reproID, err)
- }
+ if err := saveCRepro(reproID, cReproBody); err != nil {
+ return fmt.Errorf("saveRepro(bugID=%s, reproID=%s): %w", bug.ID, reproID, err)
}
}
return nil
@@ -333,7 +329,7 @@ func exportNamespace() error {
go func() {
errChan <- g.Wait()
}()
- for iBug := range bugURLs {
+ for iBug := range bugs {
select {
case iBugChan <- iBug:
case err := <-errChan:
@@ -344,60 +340,6 @@ func exportNamespace() error {
return g.Wait()
}
-func getFullBugList() ([]string, error) {
- bugLists := []string{
- *flagDashboard + "/" + *flagNamespace,
- *flagDashboard + "/" + *flagNamespace + "/fixed",
- }
- fullBugList := []string{}
- for _, url := range bugLists {
- fmt.Printf("loading bug list from %s\n", url)
- body, err := getJSONBody(url)
- if err != nil {
- return nil, fmt.Errorf("getBody(%s): %w", url, err)
- }
- bugs, err := getBugList(body)
- if err != nil {
- return nil, fmt.Errorf("bugList: %w", err)
- }
- fullBugList = append(fullBugList, bugs...)
- }
- return fullBugList, nil
-}
-
-var throttler = time.NewTicker(time.Second).C
-
-func getJSONBody(url string) ([]byte, error) {
- if strings.Contains(url, "?") {
- url = url + "&json=1"
- } else {
- url = url + "?json=1"
- }
- req, err := http.NewRequest("GET", url, nil)
- if err != nil {
- return nil, fmt.Errorf("http.NewRequest: %w", err)
- }
- if *flagToken != "" {
- req.Header.Add("Authorization", "Bearer "+*flagToken)
- } else {
- <-throttler // tolerate throttling
- }
- client := &http.Client{}
- res, err := client.Do(req)
- if err != nil {
- return nil, fmt.Errorf("http.Get(%s): %w", url, err)
- }
- defer res.Body.Close()
- body, err := io.ReadAll(res.Body)
- if res.StatusCode > 299 {
- return nil, fmt.Errorf("io.ReadAll failed with status code: %d and\nbody: %s", res.StatusCode, body)
- }
- if err != nil {
- return nil, fmt.Errorf("io.ReadAll(body): %w", err)
- }
- return body, nil
-}
-
func saveCRepro(reproID string, reproData []byte) error {
reproPath := path.Join(*flagOutputDir, reproID+".c")
if err := os.WriteFile(reproPath, reproData, 0666); err != nil {
@@ -405,3 +347,15 @@ func saveCRepro(reproID string, reproData []byte) error {
}
return nil
}
+
+func reproIDFromURL(url string) string {
+ parts := strings.Split(url, "&")
+ if len(parts) != 2 {
+ log.Panicf("can't split %s in two parts by ?", url)
+ }
+ parts = strings.Split(parts[1], "=")
+ if len(parts) != 2 {
+ log.Panicf("can't split %s in two parts by =", url)
+ }
+ return parts[1]
+}