github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/dashboard/app/reporting_external.go (about) 1 // Copyright 2017 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 package main 5 6 import ( 7 "context" 8 "encoding/json" 9 "errors" 10 "fmt" 11 "net/http" 12 13 "github.com/google/syzkaller/dashboard/dashapi" 14 "google.golang.org/appengine/v2/log" 15 ) 16 17 // Interface with external reporting systems. 18 // The external system is meant to poll for new bugs with apiReportingPoll, 19 // and report back bug status updates with apiReportingUpdate. 20 21 func apiReportingPollBugs(c context.Context, r *http.Request, payload []byte) (interface{}, error) { 22 if stop, err := emergentlyStopped(c); err != nil || stop { 23 return &dashapi.PollBugsResponse{}, err 24 } 25 req := new(dashapi.PollBugsRequest) 26 if err := json.Unmarshal(payload, req); err != nil { 27 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 28 } 29 reports := reportingPollBugs(c, req.Type) 30 resp := &dashapi.PollBugsResponse{ 31 Reports: reports, 32 } 33 jobs, err := pollCompletedJobs(c, req.Type) 34 if err != nil { 35 log.Errorf(c, "failed to poll jobs(bugs): %v", err) 36 } 37 resp.Reports = append(resp.Reports, jobs...) 38 return resp, nil 39 } 40 41 func apiReportingPollNotifications(c context.Context, r *http.Request, payload []byte) (interface{}, error) { 42 if stop, err := emergentlyStopped(c); err != nil || stop { 43 return &dashapi.PollNotificationsResponse{}, err 44 } 45 req := new(dashapi.PollNotificationsRequest) 46 if err := json.Unmarshal(payload, req); err != nil { 47 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 48 } 49 notifs := reportingPollNotifications(c, req.Type) 50 resp := &dashapi.PollNotificationsResponse{ 51 Notifications: notifs, 52 } 53 return resp, nil 54 } 55 56 func apiReportingPollClosed(c context.Context, r *http.Request, payload []byte) (interface{}, error) { 57 if stop, err := emergentlyStopped(c); err != nil || stop { 58 return &dashapi.PollClosedResponse{}, err 59 } 60 req := new(dashapi.PollClosedRequest) 61 if err := json.Unmarshal(payload, req); err != nil { 62 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 63 } 64 ids, err := reportingPollClosed(c, req.IDs) 65 if err != nil { 66 return nil, err 67 } 68 resp := &dashapi.PollClosedResponse{ 69 IDs: ids, 70 } 71 return resp, nil 72 } 73 74 func apiReportingUpdate(c context.Context, r *http.Request, payload []byte) (interface{}, error) { 75 req := new(dashapi.BugUpdate) 76 if err := json.Unmarshal(payload, req); err != nil { 77 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 78 } 79 if req.JobID != "" { 80 resp := &dashapi.BugUpdateReply{ 81 OK: true, 82 Error: false, 83 } 84 if err := jobReported(c, req.JobID); err != nil { 85 log.Errorf(c, "failed to mark job reported: %v", err) 86 resp.Text = err.Error() 87 resp.Error = true 88 } 89 return resp, nil 90 } 91 ok, reason, err := incomingCommand(c, req) 92 return &dashapi.BugUpdateReply{ 93 OK: ok, 94 Error: err != nil, 95 Text: reason, 96 }, nil 97 } 98 99 func apiNewTestJob(c context.Context, r *http.Request, payload []byte) (interface{}, error) { 100 req := new(dashapi.TestPatchRequest) 101 if err := json.Unmarshal(payload, req); err != nil { 102 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 103 } 104 resp := &dashapi.TestPatchReply{} 105 err := handleExternalTestRequest(c, req) 106 if err != nil { 107 resp.ErrorText = err.Error() 108 var badTest *BadTestRequestError 109 if !errors.As(err, &badTest) { 110 // Log errors that are not related to the invalid input. 111 log.Errorf(c, "external patch posting error: %v", err) 112 } 113 } 114 return resp, nil 115 }