github.com/google/syzkaller@v0.0.0-20251211124644-a066d2bc4b02/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 "io" 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, payload io.Reader) (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.NewDecoder(payload).Decode(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, payload io.Reader, 42 ) (interface{}, error) { 43 if stop, err := emergentlyStopped(c); err != nil || stop { 44 return &dashapi.PollNotificationsResponse{}, err 45 } 46 req := new(dashapi.PollNotificationsRequest) 47 if err := json.NewDecoder(payload).Decode(req); err != nil { 48 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 49 } 50 notifs := reportingPollNotifications(c, req.Type) 51 resp := &dashapi.PollNotificationsResponse{ 52 Notifications: notifs, 53 } 54 return resp, nil 55 } 56 57 func apiReportingPollClosed(c context.Context, payload io.Reader) (interface{}, error) { 58 if stop, err := emergentlyStopped(c); err != nil || stop { 59 return &dashapi.PollClosedResponse{}, err 60 } 61 req := new(dashapi.PollClosedRequest) 62 if err := json.NewDecoder(payload).Decode(req); err != nil { 63 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 64 } 65 ids, err := reportingPollClosed(c, req.IDs) 66 if err != nil { 67 return nil, err 68 } 69 resp := &dashapi.PollClosedResponse{ 70 IDs: ids, 71 } 72 return resp, nil 73 } 74 75 func apiReportingUpdate(c context.Context, payload io.Reader) (interface{}, error) { 76 req := new(dashapi.BugUpdate) 77 if err := json.NewDecoder(payload).Decode(req); err != nil { 78 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 79 } 80 if req.JobID != "" { 81 resp := &dashapi.BugUpdateReply{ 82 OK: true, 83 Error: false, 84 } 85 if err := jobReported(c, req.JobID); err != nil { 86 log.Errorf(c, "failed to mark job reported: %v", err) 87 resp.Text = err.Error() 88 resp.Error = true 89 } 90 return resp, nil 91 } 92 ok, reason, err := incomingCommand(c, req) 93 return &dashapi.BugUpdateReply{ 94 OK: ok, 95 Error: err != nil, 96 Text: reason, 97 }, nil 98 } 99 100 func apiNewTestJob(c context.Context, payload io.Reader) (interface{}, error) { 101 req := new(dashapi.TestPatchRequest) 102 if err := json.NewDecoder(payload).Decode(req); err != nil { 103 return nil, fmt.Errorf("failed to unmarshal request: %w", err) 104 } 105 resp := &dashapi.TestPatchReply{} 106 err := handleExternalTestRequest(c, req) 107 if err != nil { 108 resp.ErrorText = err.Error() 109 var badTest *BadTestRequestError 110 if !errors.As(err, &badTest) { 111 // Log errors that are not related to the invalid input. 112 log.Errorf(c, "external patch posting error: %v", err) 113 } 114 } 115 return resp, nil 116 }