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  }