cloudapi: Hook up the /composes/{id}/download handler

Resolves: RHEL-60142
This commit is contained in:
Brian C. Lane 2025-01-30 14:09:43 -08:00 committed by Sanne Raymaekers
parent 1d0d198e67
commit d0be06278c
2 changed files with 53 additions and 0 deletions

View file

@ -76,6 +76,7 @@ const (
ErrorGettingJobType ServiceErrorCode = 1019
ErrorTenantNotInContext ServiceErrorCode = 1020
ErrorGettingComposeList ServiceErrorCode = 1021
ErrorArtifactNotFound ServiceErrorCode = 1022
// Errors contained within this file
ErrorUnspecified ServiceErrorCode = 10000
@ -123,6 +124,7 @@ func getServiceErrors() serviceErrors {
serviceError{ErrorInvalidNumberOfImageBuilds, http.StatusBadRequest, "Compose request has unsupported number of image builds"},
serviceError{ErrorInvalidOSTreeParams, http.StatusBadRequest, "Invalid OSTree parameters or parameter combination"},
serviceError{ErrorTenantNotFound, http.StatusBadRequest, "Tenant not found in JWT claims"},
serviceError{ErrorArtifactNotFound, http.StatusBadRequest, "Artifact not found"},
serviceError{ErrorNoGPGKey, http.StatusBadRequest, "Invalid repository, when check_gpg is set, gpgkey must be specified"},
serviceError{ErrorValidationFailed, http.StatusBadRequest, "Request could not be validated"},
serviceError{ErrorComposeBadState, http.StatusBadRequest, "Compose is running or has failed"},

View file

@ -1514,3 +1514,54 @@ func (h *apiHandlers) GetDistributionList(ctx echo.Context) error {
return ctx.JSON(http.StatusOK, distros)
}
// GetComposeDownload downloads a compose artifact
func (h *apiHandlers) GetComposeDownload(ctx echo.Context, id string) error {
return h.server.EnsureJobChannel(h.getComposeDownloadImpl)(ctx, id)
}
func (h *apiHandlers) getComposeDownloadImpl(ctx echo.Context, id string) error {
jobId, err := uuid.Parse(id)
if err != nil {
return HTTPError(ErrorInvalidComposeId)
}
jobType, err := h.server.workers.JobType(jobId)
if err != nil {
return HTTPError(ErrorComposeNotFound)
}
if jobType != worker.JobTypeOSBuild {
return HTTPError(ErrorInvalidJobType)
}
var osbuildResult worker.OSBuildJobResult
jobInfo, err := h.server.workers.OSBuildJobInfo(jobId, &osbuildResult)
if err != nil {
return HTTPErrorWithInternal(ErrorGettingOSBuildJobStatus, err)
}
// Is it finished?
if jobInfo.JobStatus.Finished.IsZero() {
err := fmt.Errorf("Cannot access artifacts before job is finished: %s", jobId)
return HTTPErrorWithInternal(ErrorArtifactNotFound, err)
}
// Building only supports one target, but that may change, so make sure to check.
// NOTE: TargetResults isn't populated until it is finished
if len(osbuildResult.TargetResults) != 1 {
msg := fmt.Errorf("%#v", osbuildResult.TargetResults)
//return HTTPError(ErrorSeveralUploadTargets)
return HTTPErrorWithInternal(ErrorSeveralUploadTargets, msg)
}
tr := osbuildResult.TargetResults[0]
if tr.OsbuildArtifact == nil {
return HTTPError(ErrorArtifactNotFound)
}
// NOTE: This also returns an error if the job isn't finished or it cannot find the file
file, err := h.server.workers.JobArtifactLocation(jobId, tr.OsbuildArtifact.ExportFilename)
if err != nil {
return HTTPErrorWithInternal(ErrorArtifactNotFound, err)
}
return ctx.Attachment(file, fmt.Sprintf("%s-%s", jobId, tr.OsbuildArtifact.ExportFilename))
}