jobqueue: include image build id

The compose will soon move to a concept of including multiple image
builds per one compose, we need to accommodate extra identifier to
handle this scenario.
This commit is contained in:
Martin Sehnoutka 2020-02-10 09:36:09 +01:00 committed by Ondřej Budai
parent 73994eb06d
commit 80e01bb397
3 changed files with 44 additions and 33 deletions

View file

@ -89,15 +89,17 @@ func (api *API) addJobHandler(writer http.ResponseWriter, request *http.Request,
return
}
nextJob := api.store.PopCompose()
nextJob := api.store.PopJob()
writer.WriteHeader(http.StatusCreated)
json.NewEncoder(writer).Encode(Job{
ID: nextJob.ComposeID,
Distro: nextJob.Distro,
Pipeline: nextJob.Pipeline,
Targets: nextJob.Targets,
OutputType: nextJob.OutputType,
// FIXME: handle or comment this possible error
_ = json.NewEncoder(writer).Encode(Job{
ID: nextJob.ComposeID,
ImageBuildID: nextJob.ImageBuildID,
Distro: nextJob.Distro,
Pipeline: nextJob.Pipeline,
Targets: nextJob.Targets,
OutputType: nextJob.ImageType,
})
}
@ -121,7 +123,7 @@ func (api *API) updateJobHandler(writer http.ResponseWriter, request *http.Reque
return
}
err = api.store.UpdateCompose(id, body.Status, body.Image, body.Result)
err = api.store.UpdateImageBuildInCompose(id, body.ImageBuildID, body.Status, body.Image, body.Result)
if err != nil {
switch err.(type) {
case *store.NotFoundError:

View file

@ -5,7 +5,8 @@ import (
"testing"
"github.com/osbuild/osbuild-composer/internal/blueprint"
test_distro "github.com/osbuild/osbuild-composer/internal/distro/test"
"github.com/osbuild/osbuild-composer/internal/distro"
test_distro "github.com/osbuild/osbuild-composer/internal/distro/fedoratest"
"github.com/osbuild/osbuild-composer/internal/jobqueue"
"github.com/osbuild/osbuild-composer/internal/store"
"github.com/osbuild/osbuild-composer/internal/test"
@ -28,12 +29,13 @@ func TestBasic(t *testing.T) {
// Update job that does not exist, with invalid body
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", ``, http.StatusBadRequest, ``},
// Update job that does not exist
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", `{"status":"RUNNING"}`, http.StatusNotFound, ``},
{"PATCH", "/job-queue/v1/jobs/aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", `{"image_build_id": 0, "status":"RUNNING"}`, http.StatusNotFound, ``},
}
for _, c := range cases {
distro := test_distro.New()
api := jobqueue.New(nil, store.New(nil, distro))
distroStruct := test_distro.New()
registry := distro.NewRegistry([]string{"."})
api := jobqueue.New(nil, store.New(nil, distroStruct, *registry))
test.TestRoute(t, api, false, c.Method, c.Path, c.Body, c.ExpectedStatus, c.ExpectedJSON)
}
@ -41,27 +43,29 @@ func TestBasic(t *testing.T) {
func TestCreate(t *testing.T) {
id, _ := uuid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff")
distro := test_distro.New()
store := store.New(nil, distro)
distroStruct := test_distro.New()
registry := distro.NewRegistry([]string{"."})
store := store.New(nil, distroStruct, *registry)
api := jobqueue.New(nil, store)
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"test-repo": "test:foo"}, "test_arch", "test_output", 0, nil)
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"test-repo": "test:foo"}, "x86_64", "qcow2", 0, nil)
if err != nil {
t.Fatalf("error pushing compose: %v", err)
}
test.TestRoute(t, api, false, "POST", "/job-queue/v1/jobs", `{}`, http.StatusCreated,
`{"distro":"test-distro","id":"ffffffff-ffff-ffff-ffff-ffffffffffff","output_type":"test_output","pipeline":{},"targets":[]}`, "created", "uuid")
`{"distro":"fedora-30","id":"ffffffff-ffff-ffff-ffff-ffffffffffff","image_build_id":0,"output_type":"qcow2","pipeline":{},"targets":[]}`, "created", "uuid")
}
func testUpdateTransition(t *testing.T, from, to string, expectedStatus int) {
id, _ := uuid.Parse("ffffffff-ffff-ffff-ffff-ffffffffffff")
distro := test_distro.New()
store := store.New(nil, distro)
distroStruct := test_distro.New()
registry := distro.NewRegistry([]string{"."})
store := store.New(nil, distroStruct, *registry)
api := jobqueue.New(nil, store)
if from != "VOID" {
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"test": "test:foo"}, "test_arch", "test_output", 0, nil)
err := store.PushCompose(id, &blueprint.Blueprint{}, map[string]string{"test": "test:foo"}, "x86_64", "qcow2", 0, nil)
if err != nil {
t.Fatalf("error pushing compose: %v", err)
}

View file

@ -3,6 +3,7 @@ package jobqueue
import (
"encoding/json"
"fmt"
"github.com/osbuild/osbuild-composer/internal/compose"
"io/ioutil"
"os"
"os/exec"
@ -12,23 +13,24 @@ import (
"github.com/osbuild/osbuild-composer/internal/common"
"github.com/osbuild/osbuild-composer/internal/distro"
"github.com/osbuild/osbuild-composer/internal/pipeline"
"github.com/osbuild/osbuild-composer/internal/store"
"github.com/osbuild/osbuild-composer/internal/target"
"github.com/osbuild/osbuild-composer/internal/upload/awsupload"
)
type Job struct {
ID uuid.UUID `json:"id"`
Distro string `json:"distro"`
Pipeline *pipeline.Pipeline `json:"pipeline"`
Targets []*target.Target `json:"targets"`
OutputType string `json:"output_type"`
ID uuid.UUID `json:"id"`
ImageBuildID int `json:"image_build_id"`
Distro string `json:"distro"`
Pipeline *pipeline.Pipeline `json:"pipeline"`
Targets []*target.Target `json:"targets"`
OutputType string `json:"output_type"`
}
type JobStatus struct {
Status string `json:"status"`
Image *store.Image `json:"image"`
Result *common.ComposeResult `json:"result"`
Status common.ImageBuildState `json:"status"`
ImageBuildID int `json:"image_build_id"`
Image *compose.Image `json:"image"`
Result *common.ComposeResult `json:"result"`
}
type TargetsError struct {
@ -45,7 +47,7 @@ func (e *TargetsError) Error() string {
return errString
}
func (job *Job) Run() (*store.Image, *common.ComposeResult, error) {
func (job *Job) Run() (*compose.Image, *common.ComposeResult, error) {
distros := distro.NewRegistry([]string{"/etc/osbuild-composer", "/usr/share/osbuild-composer"})
d := distros.GetDistro(job.Distro)
if d == nil {
@ -60,6 +62,7 @@ func (job *Job) Run() (*store.Image, *common.ComposeResult, error) {
if err != nil {
return nil, nil, err
}
// FIXME: how to handle errors in defer?
defer os.Remove(buildFile.Name())
err = json.NewEncoder(buildFile).Encode(build)
@ -71,6 +74,7 @@ func (job *Job) Run() (*store.Image, *common.ComposeResult, error) {
if err != nil {
return nil, nil, fmt.Errorf("error setting up osbuild store: %v", err)
}
// FIXME: how to handle errors in defer?
defer os.RemoveAll(tmpStore)
cmd := exec.Command(
@ -100,7 +104,8 @@ func (job *Job) Run() (*store.Image, *common.ComposeResult, error) {
if err != nil {
return nil, nil, fmt.Errorf("error encoding osbuild pipeline: %v", err)
}
stdin.Close()
// FIXME: handle or comment this possible error
_ = stdin.Close()
var result common.ComposeResult
err = json.NewDecoder(stdout).Decode(&result)
@ -118,7 +123,7 @@ func (job *Job) Run() (*store.Image, *common.ComposeResult, error) {
return nil, &result, fmt.Errorf("cannot fetch information about output type %s: %v", job.OutputType, err)
}
var image store.Image
var image compose.Image
var r []error
@ -150,10 +155,10 @@ func (job *Job) Run() (*store.Image, *common.ComposeResult, error) {
return nil, &result, err
}
image = store.Image{
image = compose.Image{
Path: imagePath,
Mime: mimeType,
Size: fileStat.Size(),
Size: uint64(fileStat.Size()),
}
case *target.AWSTargetOptions: