diff --git a/.gitignore b/.gitignore index 94fe70bc9..2a9c66bda 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /osbuild-composer +/osbuild-worker diff --git a/cmd/osbuild-worker/main.go b/cmd/osbuild-worker/main.go new file mode 100644 index 000000000..94602ecb8 --- /dev/null +++ b/cmd/osbuild-worker/main.go @@ -0,0 +1,117 @@ +package main + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "net" + "net/http" + "time" + + "github.com/google/uuid" + + "osbuild-composer/internal/pipeline" + "osbuild-composer/internal/target" +) + +type ComposerClient struct { + client *http.Client +} + +type Job struct { + ID uuid.UUID + Pipeline pipeline.Pipeline + Target target.Target +} + +func NewClient() *ComposerClient { + client := &http.Client{ + Transport: &http.Transport{ + DialContext: func(context context.Context, network, addr string) (net.Conn, error) { + return net.Dial("unix", "/run/osbuild-composer/job.socket") + }, + }, + } + return &ComposerClient{client} +} + +func (c *ComposerClient) AddJob() (*Job, error) { + type request struct { + ID string `json:"id"` + } + type reply struct { + Pipeline *pipeline.Pipeline `json:"pipeline"` + Target *target.Target `json:"target"` + } + + job := &Job{ + ID: uuid.New(), + } + + var b bytes.Buffer + json.NewEncoder(&b).Encode(request{job.ID.String()}) + response, err := c.client.Post("http://localhost/job-queue/v1/jobs", "application/json", &b) + if err != nil { + return nil, err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusCreated { + return nil, errors.New("couldn't create job") + } + + err = json.NewDecoder(response.Body).Decode(&reply{ + Pipeline: &job.Pipeline, + Target: &job.Target, + }) + if err != nil { + return nil, err + } + + return job, nil +} + +func (c *ComposerClient) UpdateJob(job *Job, status string) error { + type request struct { + Status string `json:"status"` + } + + var b bytes.Buffer + json.NewEncoder(&b).Encode(&request{status}) + req, err:= http.NewRequest("PATCH", "http://localhost/job-queue/v1/jobs/" + job.ID.String(), &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 main() { + client := NewClient() + + for { + fmt.Println("Waiting for a new job...") + job, err := client.AddJob() + if err != nil { + panic(err) + } + + fmt.Printf("Running job %s\n", job.ID.String()) + time.Sleep(15 * time.Second) + + client.UpdateJob(job, "finished") + } +} diff --git a/go.mod b/go.mod index 219899158..00277647c 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,7 @@ module osbuild-composer go 1.12 -require github.com/julienschmidt/httprouter v1.2.0 +require ( + github.com/google/uuid v1.1.1 + github.com/julienschmidt/httprouter v1.2.0 +) diff --git a/go.sum b/go.sum index 0ead70e8c..eb3fbd95f 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,4 @@ +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= diff --git a/internal/jobqueue/api.go b/internal/jobqueue/api.go index 026f0a66a..1dfec6062 100644 --- a/internal/jobqueue/api.go +++ b/internal/jobqueue/api.go @@ -108,8 +108,8 @@ func (api *API) addJobHandler(writer http.ResponseWriter, request *http.Request, nextJob := <-api.pendingJobs api.jobStore.UpdateJob(id, nextJob) + writer.WriteHeader(http.StatusCreated) json.NewEncoder(writer).Encode(replyBody{nextJob.Pipeline, nextJob.Targets}) - } func (api *API) updateJobHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {