111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
|
|
"gitlab.com/slon/shad-go/distbuild/pkg/build"
|
|
)
|
|
|
|
type Client struct {
|
|
Endpoint string
|
|
}
|
|
|
|
type statusReader struct {
|
|
r io.ReadCloser
|
|
dec *json.Decoder
|
|
}
|
|
|
|
func (r *statusReader) Close() error {
|
|
return r.r.Close()
|
|
}
|
|
|
|
func (r *statusReader) Next() (*StatusUpdate, error) {
|
|
var u StatusUpdate
|
|
if err := r.dec.Decode(&u); err != nil {
|
|
return nil, err
|
|
}
|
|
return &u, nil
|
|
}
|
|
|
|
func (c *Client) StartBuild(ctx context.Context, request *BuildRequest) (*BuildStarted, StatusReader, error) {
|
|
reqJSON, err := json.Marshal(request)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", c.Endpoint+"/build", bytes.NewBuffer(reqJSON))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
req.Header.Set("content-type", "application/json")
|
|
|
|
rsp, err := http.DefaultClient.Do(req.WithContext(ctx))
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
defer func() {
|
|
if rsp.Body != nil {
|
|
_ = rsp.Body.Close()
|
|
}
|
|
}()
|
|
|
|
if rsp.StatusCode != 200 {
|
|
bodyStr, err := ioutil.ReadAll(rsp.Body)
|
|
if err != nil {
|
|
return nil, nil, fmt.Errorf("build request failed: %v", err)
|
|
}
|
|
|
|
return nil, nil, fmt.Errorf("build failed: %s", bodyStr)
|
|
}
|
|
|
|
dec := json.NewDecoder(rsp.Body)
|
|
var started BuildStarted
|
|
if err := dec.Decode(&started); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
r := &statusReader{r: rsp.Body, dec: dec}
|
|
rsp.Body = nil
|
|
return &started, r, nil
|
|
}
|
|
|
|
func (c *Client) SignalBuild(ctx context.Context, buildID build.ID, signal *SignalRequest) (*SignalResponse, error) {
|
|
signalJSON, err := json.Marshal(signal)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", c.Endpoint+"/signal?build_id="+buildID.String(), bytes.NewBuffer(signalJSON))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.Header.Set("content-type", "application/json")
|
|
|
|
rsp, err := http.DefaultClient.Do(req.WithContext(ctx))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rsp.Body.Close()
|
|
|
|
rspBody, err := ioutil.ReadAll(rsp.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("signal request failed: %v", err)
|
|
}
|
|
|
|
if rsp.StatusCode != 200 {
|
|
return nil, fmt.Errorf("signal failed: %s", rspBody)
|
|
}
|
|
|
|
var signalRsp SignalResponse
|
|
if err = json.Unmarshal(rspBody, &rsp); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &signalRsp, err
|
|
}
|