diff options
| -rw-r--r-- | dashboard/app/config.go | 25 | ||||
| -rw-r--r-- | dashboard/app/kcidb.go | 2 | ||||
| -rw-r--r-- | pkg/kcidb/client.go | 62 | ||||
| -rw-r--r-- | tools/syz-kcidb/kcidb.go | 10 |
4 files changed, 56 insertions, 43 deletions
diff --git a/dashboard/app/config.go b/dashboard/app/config.go index 8c9d9fb6e..7f9885fd9 100644 --- a/dashboard/app/config.go +++ b/dashboard/app/config.go @@ -4,11 +4,11 @@ package main import ( - "bytes" "context" "encoding/json" "fmt" "net/mail" + "net/url" "regexp" "strings" "time" @@ -366,12 +366,10 @@ type CCConfig struct { type KcidbConfig struct { // Origin is how this system identified in Kcidb, e.g. "syzbot_foobar". Origin string - // Project is Kcidb GCE project name, e.g. "kernelci-production". - Project string - // Topic is pubsub topic to publish messages to, e.g. "playground_kernelci_new". - Topic string - // Credentials is Google application credentials file contents to use for authorization. - Credentials []byte + // RestURI is the REST API endpoint to which the Kcidb client will send data. + RestURI string + // Token is the authorization token to use for the Kcidb client. + Token string } // ThrottleConfig determines how many requests a single client can make in a period of time. @@ -813,14 +811,15 @@ func checkKcidb(ns string, kcidb *KcidbConfig) { if !regexp.MustCompile("^[a-z0-9_]+$").MatchString(kcidb.Origin) { panic(fmt.Sprintf("%v: bad Kcidb origin %q", ns, kcidb.Origin)) } - if kcidb.Project == "" { - panic(fmt.Sprintf("%v: empty Kcidb project", ns)) + if kcidb.RestURI == "" { + panic(fmt.Sprintf("%v: empty Kcidb RestURI", ns)) } - if kcidb.Topic == "" { - panic(fmt.Sprintf("%v: empty Kcidb topic", ns)) + // Validate RestURI must be a valid URL. + if _, err := url.ParseRequestURI(kcidb.RestURI); err != nil { + panic(fmt.Sprintf("%v: invalid Kcidb RestURI %q: %v", ns, kcidb.RestURI, err)) } - if !bytes.Contains(kcidb.Credentials, []byte("private_key")) { - panic(fmt.Sprintf("%v: empty Kcidb credentials", ns)) + if kcidb.Token == "" || len(kcidb.Token) < 8 { + panic(fmt.Sprintf("%v: bad Kcidb token %q", ns, kcidb.Token)) } } diff --git a/dashboard/app/kcidb.go b/dashboard/app/kcidb.go index f2cfeaacb..25ec23424 100644 --- a/dashboard/app/kcidb.go +++ b/dashboard/app/kcidb.go @@ -32,7 +32,7 @@ func handleKcidbPoll(w http.ResponseWriter, r *http.Request) { } func handleKcidbNamespce(c context.Context, ns string, cfg *KcidbConfig) error { - client, err := kcidb.NewClient(c, cfg.Origin, cfg.Project, cfg.Topic, cfg.Credentials) + client, err := kcidb.NewClient(c, cfg.Origin, cfg.RestURI, cfg.Token) if err != nil { return err } diff --git a/pkg/kcidb/client.go b/pkg/kcidb/client.go index c733aa910..bba811c7e 100644 --- a/pkg/kcidb/client.go +++ b/pkg/kcidb/client.go @@ -8,22 +8,21 @@ import ( "context" "encoding/json" "fmt" + "net/http" "os" "os/exec" "strings" "time" - "cloud.google.com/go/pubsub" "github.com/google/syzkaller/dashboard/dashapi" "github.com/google/syzkaller/sys/targets" - "google.golang.org/api/option" ) type Client struct { - ctx context.Context - origin string - client *pubsub.Client - topic *pubsub.Topic + ctx context.Context + origin string + resturi string + token string } // NewClient creates a new client to send pubsub messages to Kcidb. @@ -31,23 +30,40 @@ type Client struct { // Project is Kcidb GCE project name, e.g. "kernelci-production". // Topic is pubsub topic to publish messages to, e.g. "playground_kernelci_new". // Credentials is Google application credentials file contents to use for authorization. -func NewClient(ctx context.Context, origin, project, topic string, credentials []byte) (*Client, error) { - client, err := pubsub.NewClient(ctx, project, option.WithCredentialsJSON(credentials)) - if err != nil { - return nil, err - } +func NewClient(ctx context.Context, origin, resturi, token string) (*Client, error) { c := &Client{ - ctx: ctx, - origin: origin, - client: client, - topic: client.Topic(topic), + ctx: ctx, + origin: origin, + resturi: resturi, + token: token, } - return c, err + return c, nil } func (c *Client) Close() error { - c.topic.Stop() - return c.client.Close() + return nil +} + +func (c *Client) RESTSubmit(data []byte) error { + if c.resturi == "" { + return fmt.Errorf("resturi is not set") + } + req, err := http.NewRequest("POST", c.resturi, bytes.NewReader(data)) + if err != nil { + return fmt.Errorf("failed to create request: %w", err) + } + req.Header.Set("Content-Type", "application/json") + req.Header.Set("Authorization", "Bearer "+c.token) + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return fmt.Errorf("failed to send request: %w", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected response status: %s", resp.Status) + } + return nil } func (c *Client) Publish(bug *dashapi.BugReport) error { @@ -62,7 +78,9 @@ func (c *Client) Publish(bug *dashapi.BugReport) error { if err := kcidbValidate(data); err != nil { return err } - _, err = c.topic.Publish(c.ctx, &pubsub.Message{Data: data}).Get(c.ctx) + if err := c.RESTSubmit(data); err != nil { + return fmt.Errorf("failed to submit kcidb json: %w", err) + } return err } @@ -100,8 +118,8 @@ func (c *Client) convert(target *targets.Target, bug *dashapi.BugReport) *Kcidb GitRepositoryURL: normalizeRepo(bug.KernelRepo), GitCommitHash: bug.KernelCommit, GitRepositoryBranch: bug.KernelBranch, - Comment: bug.KernelCommitTitle, - StartTime: bug.BuildTime.Format(time.RFC3339), + Comment: bug.KernelCommitTitle, + StartTime: bug.BuildTime.Format(time.RFC3339), Valid: true, }, }, @@ -155,7 +173,7 @@ func (c *Client) convert(target *targets.Target, bug *dashapi.BugReport) *Kcidb Path: "syzkaller", StartTime: bug.CrashTime.Format(time.RFC3339), OutputFiles: outputFiles, - Comment: bug.Title, + Comment: bug.Title, Status: "FAIL", Misc: &TestMisc{ OriginURL: bug.Link, diff --git a/tools/syz-kcidb/kcidb.go b/tools/syz-kcidb/kcidb.go index 81504c654..8d1255cce 100644 --- a/tools/syz-kcidb/kcidb.go +++ b/tools/syz-kcidb/kcidb.go @@ -6,7 +6,6 @@ package main import ( "context" "flag" - "os" "github.com/google/syzkaller/dashboard/dashapi" "github.com/google/syzkaller/pkg/kcidb" @@ -20,7 +19,8 @@ func main() { topicName = "playground_kernelci_new" ) var ( - flagCred = flag.String("cred", "", "application credentials file for KCIDB") + flagRestURI = flag.String("rest", "", "REST API endpoint for KCIDB") + flagToken = flag.String("token", "", "KCIDB API token") flagDashClient = flag.String("client", "", "dashboard client") flagDashAddr = flag.String("addr", "", "dashboard address") flagDashKey = flag.String("key", "", "dashboard API key") @@ -37,12 +37,8 @@ func main() { tool.Fail(err) } - cred, err := os.ReadFile(*flagCred) - if err != nil { - tool.Fail(err) - } kcidb.Validate = true - client, err := kcidb.NewClient(context.Background(), origin, projectID, topicName, cred) + client, err := kcidb.NewClient(context.Background(), origin, *flagRestURI, *flagToken) if err != nil { tool.Fail(err) } |
