cloudapi: Return the compose status of all root compose jobs

This returns the status using the same structure as it does for
requesting individual statuses for the jobs.

Related: RHEL-60120
This commit is contained in:
Brian C. Lane 2024-04-05 16:55:35 -07:00 committed by Brian C. Lane
parent 24b939d4c7
commit 325a018c75
4 changed files with 72 additions and 0 deletions

View file

@ -75,6 +75,7 @@ const (
ErrorGettingAWSEC2JobStatus ServiceErrorCode = 1018
ErrorGettingJobType ServiceErrorCode = 1019
ErrorTenantNotInContext ServiceErrorCode = 1020
ErrorGettingComposeList ServiceErrorCode = 1021
// Errors contained within this file
ErrorUnspecified ServiceErrorCode = 10000
@ -157,6 +158,7 @@ func getServiceErrors() serviceErrors {
serviceError{ErrorGettingAWSEC2JobStatus, http.StatusInternalServerError, "Unable to get ec2 job status"},
serviceError{ErrorGettingJobType, http.StatusInternalServerError, "Unable to get job type of existing job"},
serviceError{ErrorTenantNotInContext, http.StatusInternalServerError, "Unable to retrieve tenant from request context"},
serviceError{ErrorGettingComposeList, http.StatusInternalServerError, "Unable to get list of composes"},
serviceError{ErrorUnspecified, http.StatusInternalServerError, "Unspecified internal error "},
serviceError{ErrorNotHTTPError, http.StatusInternalServerError, "Error is not an instance of HTTPError"},

View file

@ -2,6 +2,7 @@
package v2
import (
"cmp"
"encoding/json"
"fmt"
"net/http"
@ -295,6 +296,30 @@ func (h *apiHandlers) targetResultToUploadStatus(jobId uuid.UUID, t *target.Targ
return us, nil
}
// GetComposeList returns a list of the root job UUIDs
func (h *apiHandlers) GetComposeList(ctx echo.Context) error {
jobs, err := h.server.workers.AllRootJobIDs()
if err != nil {
return HTTPErrorWithInternal(ErrorGettingComposeList, err)
}
// Gather up the details of each job
var stats []ComposeStatus
for _, jid := range jobs {
s, err := h.getJobIDComposeStatus(jid)
if err != nil {
// TODO log this error?
continue
}
stats = append(stats, s)
}
slices.SortFunc(stats, func(a, b ComposeStatus) int {
return cmp.Compare(a.Id, b.Id)
})
return ctx.JSON(http.StatusOK, stats)
}
func (h *apiHandlers) GetComposeStatus(ctx echo.Context, id string) error {
return h.server.EnsureJobChannel(h.getComposeStatusImpl)(ctx, id)
}

View file

@ -1834,3 +1834,43 @@ func TestSearchArchErrors(t *testing.T) {
"reason": "Request could not be validated"
}`, "operation_id", "details")
}
func TestComposesRoute(t *testing.T) {
srv, _, _, cancel := newV2Server(t, t.TempDir(), false, false)
defer cancel()
// Make a compose so it has something to list
reply := test.TestRouteWithReply(t, srv.Handler("/api/image-builder-composer/v2"), false, "POST", "/api/image-builder-composer/v2/compose", fmt.Sprintf(`
{
"distribution": "%s",
"image_request":{
"architecture": "%s",
"image_type": "%s",
"repositories": [{
"baseurl": "somerepo.org",
"rhsm": false
}],
"upload_options": {
"region": "eu-central-1",
"snapshot_name": "name",
"share_with_accounts": ["123456789012","234567890123"]
}
}
}`, test_distro.TestDistro1Name, test_distro.TestArch3Name, string(v2.ImageTypesAws)), http.StatusCreated, `
{
"href": "/api/image-builder-composer/v2/compose",
"kind": "ComposeId"
}`, "id")
// Extract the compose ID to use to test the list response
var composeReply v2.ComposeId
err := json.Unmarshal(reply, &composeReply)
require.NoError(t, err)
jobID, err := uuid.Parse(composeReply.Id)
require.NoError(t, err)
// List root composes
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", "/api/image-builder-composer/v2/composes/", ``,
http.StatusOK, fmt.Sprintf(`[{"href":"/api/image-builder-composer/v2/composes/%[1]s", "id":"%[1]s", "image_status":{"status":"pending"}, "kind":"ComposeStatus", "status":"pending"}]`,
jobID.String()))
}

View file

@ -348,6 +348,11 @@ func (s *Server) JobDependencyChainErrors(id uuid.UUID) (*clienterrors.Error, er
return nil, nil
}
// AllRootJobIDs returns a list of top level job UUIDs that the worker knows about
func (s *Server) AllRootJobIDs() ([]uuid.UUID, error) {
return s.jobs.AllRootJobIDs()
}
func (s *Server) OSBuildJobInfo(id uuid.UUID, result *OSBuildJobResult) (*JobInfo, error) {
jobInfo, err := s.jobInfo(id, result)
if err != nil {