diff --git a/internal/cloudapi/v2/handler.go b/internal/cloudapi/v2/handler.go index be7fef966..f6060f5a2 100644 --- a/internal/cloudapi/v2/handler.go +++ b/internal/cloudapi/v2/handler.go @@ -434,18 +434,26 @@ func (h *apiHandlers) getComposeStatusImpl(ctx echo.Context, id string) error { return HTTPError(ErrorGettingBuildDependencyStatus) } - var us *UploadStatus + var uploadStatuses *[]UploadStatus + var us0 *UploadStatus if result.TargetResults != nil { - // Only single upload target is allowed, therefore only a single upload target result is allowed as well - if len(result.TargetResults) != 1 { - return HTTPError(ErrorSeveralUploadTargets) + statuses := make([]UploadStatus, len(result.TargetResults)) + for idx := range result.TargetResults { + 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 err != nil { - return HTTPError(ErrorUnknownUploadTarget) + + 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] } - us.Status = uploadStatusFromJobStatus(jobInfo.JobStatus, result.JobError) } 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), ImageStatus: ImageStatus{ - Status: imageStatusFromOSBuildJobStatus(jobInfo.JobStatus, &result), - Error: composeStatusErrorFromJobError(jobError), - UploadStatus: us, + Status: imageStatusFromOSBuildJobStatus(jobInfo.JobStatus, &result), + Error: composeStatusErrorFromJobError(jobError), + UploadStatus: us0, // add the first upload status to the old top-level field + UploadStatuses: uploadStatuses, }, }) } else if jobType == worker.JobTypeKojiFinalize { @@ -488,28 +497,37 @@ func (h *apiHandlers) getComposeStatusImpl(ctx echo.Context, id string) error { return HTTPError(ErrorGettingBuildDependencyStatus) } - var us *UploadStatus - // Only a single upload target in addition to Koji is allowed. - // Koji target is always added to osbuild jobs for Koji compose - // by the enqueueKojiCompose() function. - if len(buildJobResult.TargetResults) > 2 { - return HTTPError(ErrorSeveralUploadTargets) - } - for _, tr := range buildJobResult.TargetResults { - if tr.Name != target.TargetNameKoji { - us, err = targetResultToUploadStatus(tr) - if err != nil { - return HTTPError(ErrorUnknownUploadTarget) + var uploadStatuses *[]UploadStatus + var us0 *UploadStatus + if buildJobResult.TargetResults != nil { + // can't set the array size because koji targets wont be counted + statuses := make([]UploadStatus, 0, len(buildJobResult.TargetResults)) + for idx := range buildJobResult.TargetResults { + tr := buildJobResult.TargetResults[idx] + if tr.Name != target.TargetNameKoji { + us, err := targetResultToUploadStatus(tr) + if err != nil { + 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) buildJobStatuses = append(buildJobStatuses, ImageStatus{ - Status: imageStatusFromKojiJobStatus(buildInfo.JobStatus, &initResult, &buildJobResult), - Error: composeStatusErrorFromJobError(buildJobError), - UploadStatus: us, + Status: imageStatusFromKojiJobStatus(buildInfo.JobStatus, &initResult, &buildJobResult), + Error: composeStatusErrorFromJobError(buildJobError), + UploadStatus: us0, // add the first upload status to the old top-level field + UploadStatuses: uploadStatuses, }) } response := ComposeStatus{ diff --git a/internal/cloudapi/v2/v2_test.go b/internal/cloudapi/v2/v2_test.go index fc5d42496..699922dca 100644 --- a/internal/cloudapi/v2/v2_test.go +++ b/internal/cloudapi/v2/v2_test.go @@ -887,7 +887,15 @@ func TestComposeTargetErrors(t *testing.T) { }, "status": "failure", "type": "aws" - } + }, + "upload_statuses": [{ + "options": { + "ami": "", + "region": "" + }, + "status": "failure", + "type": "aws" + }] }, "status": "failure" }`, jobId, jobId)) @@ -1291,7 +1299,15 @@ func TestImageFromCompose(t *testing.T) { "ami": "ami-abc123", "region": "eu-central-1" } - } + }, + "upload_statuses": [{ + "type": "aws", + "status": "success", + "options": { + "ami": "ami-abc123", + "region": "eu-central-1" + } + }] } }`, jobId, jobId))