cloudapi: support multiple upload statuses in ComposeStatus

Add the new upload_statuses under the image_status in the result of the
ComposeStatus object.  The first status is also included in the old
top-level 'upload_status' property for backwards compatibility.

Tests are updated to match the new results.
This commit is contained in:
Achilleas Koutsou 2023-10-30 16:28:16 +01:00 committed by Sanne Raymaekers
parent ba2240b578
commit 5a93166f6b
2 changed files with 64 additions and 30 deletions

View file

@ -434,18 +434,26 @@ func (h *apiHandlers) getComposeStatusImpl(ctx echo.Context, id string) error {
return HTTPError(ErrorGettingBuildDependencyStatus) return HTTPError(ErrorGettingBuildDependencyStatus)
} }
var us *UploadStatus var uploadStatuses *[]UploadStatus
var us0 *UploadStatus
if result.TargetResults != nil { if result.TargetResults != nil {
// Only single upload target is allowed, therefore only a single upload target result is allowed as well statuses := make([]UploadStatus, len(result.TargetResults))
if len(result.TargetResults) != 1 { for idx := range result.TargetResults {
return HTTPError(ErrorSeveralUploadTargets) tr := result.TargetResults[idx]
us, err := targetResultToUploadStatus(tr)
if err != nil {
return HTTPError(ErrorUnknownUploadTarget)
}
us.Status = uploadStatusFromJobStatus(jobInfo.JobStatus, result.JobError)
statuses[idx] = *us
} }
tr := result.TargetResults[0]
us, err = targetResultToUploadStatus(tr) if len(statuses) > 0 {
if err != nil { // make sure uploadStatuses remains nil if the array is empty but not nill
return HTTPError(ErrorUnknownUploadTarget) uploadStatuses = &statuses
// get first upload status if there's at least one
us0 = &statuses[0]
} }
us.Status = uploadStatusFromJobStatus(jobInfo.JobStatus, result.JobError)
} }
return ctx.JSON(http.StatusOK, ComposeStatus{ return ctx.JSON(http.StatusOK, ComposeStatus{
@ -456,9 +464,10 @@ func (h *apiHandlers) getComposeStatusImpl(ctx echo.Context, id string) error {
}, },
Status: composeStatusFromOSBuildJobStatus(jobInfo.JobStatus, &result), Status: composeStatusFromOSBuildJobStatus(jobInfo.JobStatus, &result),
ImageStatus: ImageStatus{ ImageStatus: ImageStatus{
Status: imageStatusFromOSBuildJobStatus(jobInfo.JobStatus, &result), Status: imageStatusFromOSBuildJobStatus(jobInfo.JobStatus, &result),
Error: composeStatusErrorFromJobError(jobError), Error: composeStatusErrorFromJobError(jobError),
UploadStatus: us, UploadStatus: us0, // add the first upload status to the old top-level field
UploadStatuses: uploadStatuses,
}, },
}) })
} else if jobType == worker.JobTypeKojiFinalize { } else if jobType == worker.JobTypeKojiFinalize {
@ -488,28 +497,37 @@ func (h *apiHandlers) getComposeStatusImpl(ctx echo.Context, id string) error {
return HTTPError(ErrorGettingBuildDependencyStatus) return HTTPError(ErrorGettingBuildDependencyStatus)
} }
var us *UploadStatus var uploadStatuses *[]UploadStatus
// Only a single upload target in addition to Koji is allowed. var us0 *UploadStatus
// Koji target is always added to osbuild jobs for Koji compose if buildJobResult.TargetResults != nil {
// by the enqueueKojiCompose() function. // can't set the array size because koji targets wont be counted
if len(buildJobResult.TargetResults) > 2 { statuses := make([]UploadStatus, 0, len(buildJobResult.TargetResults))
return HTTPError(ErrorSeveralUploadTargets) for idx := range buildJobResult.TargetResults {
} tr := buildJobResult.TargetResults[idx]
for _, tr := range buildJobResult.TargetResults { if tr.Name != target.TargetNameKoji {
if tr.Name != target.TargetNameKoji { us, err := targetResultToUploadStatus(tr)
us, err = targetResultToUploadStatus(tr) if err != nil {
if err != nil { return HTTPError(ErrorUnknownUploadTarget)
return HTTPError(ErrorUnknownUploadTarget) }
us.Status = uploadStatusFromJobStatus(buildInfo.JobStatus, result.JobError)
statuses = append(statuses, *us)
} }
us.Status = uploadStatusFromJobStatus(buildInfo.JobStatus, result.JobError) }
if len(statuses) > 0 {
// make sure uploadStatuses remains nil if the array is empty but not nill
uploadStatuses = &statuses
// get first upload status if there's at least one
us0 = &statuses[0]
} }
} }
buildJobResults = append(buildJobResults, buildJobResult) buildJobResults = append(buildJobResults, buildJobResult)
buildJobStatuses = append(buildJobStatuses, ImageStatus{ buildJobStatuses = append(buildJobStatuses, ImageStatus{
Status: imageStatusFromKojiJobStatus(buildInfo.JobStatus, &initResult, &buildJobResult), Status: imageStatusFromKojiJobStatus(buildInfo.JobStatus, &initResult, &buildJobResult),
Error: composeStatusErrorFromJobError(buildJobError), Error: composeStatusErrorFromJobError(buildJobError),
UploadStatus: us, UploadStatus: us0, // add the first upload status to the old top-level field
UploadStatuses: uploadStatuses,
}) })
} }
response := ComposeStatus{ response := ComposeStatus{

View file

@ -887,7 +887,15 @@ func TestComposeTargetErrors(t *testing.T) {
}, },
"status": "failure", "status": "failure",
"type": "aws" "type": "aws"
} },
"upload_statuses": [{
"options": {
"ami": "",
"region": ""
},
"status": "failure",
"type": "aws"
}]
}, },
"status": "failure" "status": "failure"
}`, jobId, jobId)) }`, jobId, jobId))
@ -1291,7 +1299,15 @@ func TestImageFromCompose(t *testing.T) {
"ami": "ami-abc123", "ami": "ami-abc123",
"region": "eu-central-1" "region": "eu-central-1"
} }
} },
"upload_statuses": [{
"type": "aws",
"status": "success",
"options": {
"ami": "ami-abc123",
"region": "eu-central-1"
}
}]
} }
}`, jobId, jobId)) }`, jobId, jobId))