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  }