debian-forge-composer/internal/jobqueue/client.go
Lars Karlitski ada058f2c3 jobqueue: move Job struct to client.go
`Job` is now a simple data struct, which is only used to return
multiple arguments from `AddJob()`. Move it to that file.
2020-04-06 12:11:54 +02:00

136 lines
2.9 KiB
Go

package jobqueue
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"github.com/google/uuid"
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/osbuild"
"github.com/osbuild/osbuild-composer/internal/target"
)
type Client struct {
client *http.Client
scheme string
hostname string
}
type Job struct {
ComposeID uuid.UUID
ImageBuildID int
Manifest *osbuild.Manifest
Targets []*target.Target
}
func NewClient(address string, conf *tls.Config) *Client {
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: conf,
},
}
var scheme string
if conf != nil {
scheme = "http"
} else {
scheme = "https"
}
return &Client{client, scheme, address}
}
func NewClientUnix(path string) *Client {
client := &http.Client{
Transport: &http.Transport{
DialContext: func(context context.Context, network, addr string) (net.Conn, error) {
return net.Dial("unix", path)
},
},
}
return &Client{client, "http", "localhost"}
}
func (c *Client) AddJob() (*Job, error) {
type request struct {
}
var b bytes.Buffer
err := json.NewEncoder(&b).Encode(request{})
if err != nil {
panic(err)
}
response, err := c.client.Post(c.createURL("/job-queue/v1/jobs"), "application/json", &b)
if err != nil {
return nil, err
}
defer response.Body.Close()
if response.StatusCode != http.StatusCreated {
rawR, _ := ioutil.ReadAll(response.Body)
r := string(rawR)
return nil, fmt.Errorf("couldn't create job, got %d: %s", response.StatusCode, r)
}
var jr addJobResponse
err = json.NewDecoder(response.Body).Decode(&jr)
if err != nil {
return nil, err
}
return &Job{
jr.ComposeID,
jr.ImageBuildID,
jr.Manifest,
jr.Targets,
}, nil
}
func (c *Client) UpdateJob(job *Job, status common.ImageBuildState, result *common.ComposeResult) error {
var b bytes.Buffer
err := json.NewEncoder(&b).Encode(&updateJobRequest{status, result})
if err != nil {
panic(err)
}
urlPath := fmt.Sprintf("/job-queue/v1/jobs/%s/builds/%d", job.ComposeID.String(), job.ImageBuildID)
url := c.createURL(urlPath)
req, err := http.NewRequest("PATCH", url, &b)
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
response, err := c.client.Do(req)
if err != nil {
return err
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return errors.New("error setting job status")
}
return nil
}
func (c *Client) UploadImage(job *Job, reader io.Reader) error {
// content type doesn't really matter
url := c.createURL(fmt.Sprintf("/job-queue/v1/jobs/%s/builds/%d/image", job.ComposeID.String(), job.ImageBuildID))
_, err := c.client.Post(url, "application/octet-stream", reader)
return err
}
func (c *Client) createURL(path string) string {
return c.scheme + "://" + c.hostname + path
}