Cloud API: support composes/<id>/logs endpoint for non-koji builds

Support the composes/<id>/logs API endpoint for non-koji builds. The
endpoint will have to anyway handle `osbuild` job results once Koji
composes will start using `osbuild` job type for builds.

Extend the unit test testing a successful compose to test the logs
endpoint.
This commit is contained in:
Tomas Hozza 2022-05-18 14:50:53 +02:00 committed by Tom Gundersen
parent 97da1e7ad6
commit 205dcd4147
2 changed files with 75 additions and 35 deletions

View file

@ -861,49 +861,59 @@ func (h *apiHandlers) GetComposeLogs(ctx echo.Context, id string) error {
return HTTPError(ErrorComposeNotFound)
}
// TODO: support non-koji builds
if jobType != worker.JobTypeKojiFinalize {
return HTTPError(ErrorInvalidJobType)
}
var finalizeResult worker.KojiFinalizeJobResult
_, deps, err := h.server.workers.KojiFinalizeJobStatus(jobId, &finalizeResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
var initResult worker.KojiInitJobResult
_, _, err = h.server.workers.KojiInitJobStatus(deps[0], &initResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
var buildResultBlobs []interface{}
for i := 1; i < len(deps); i++ {
var buildResult worker.OSBuildKojiJobResult
_, _, err = h.server.workers.OSBuildKojiJobStatus(deps[i], &buildResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
buildResultBlobs = append(buildResultBlobs, buildResult)
}
// Return the OSBuildJobResults as-is for now. The contents of ImageLogs
// is not part of the API. It's meant for a human to be able to access
// the logs, which just happen to be in JSON.
resp := &ComposeLogs{
ObjectReference: ObjectReference{
Href: fmt.Sprintf("/api/image-builder-composer/v2/composes/%v/logs", jobId),
Id: jobId.String(),
Kind: "ComposeLogs",
},
Koji: &KojiLogs{
Init: initResult,
Import: finalizeResult,
},
ImageBuilds: buildResultBlobs,
}
switch jobType {
case worker.JobTypeKojiFinalize:
var finalizeResult worker.KojiFinalizeJobResult
_, deps, err := h.server.workers.KojiFinalizeJobStatus(jobId, &finalizeResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
var initResult worker.KojiInitJobResult
_, _, err = h.server.workers.KojiInitJobStatus(deps[0], &initResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
for i := 1; i < len(deps); i++ {
var buildResult worker.OSBuildKojiJobResult
_, _, err = h.server.workers.OSBuildKojiJobStatus(deps[i], &buildResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
buildResultBlobs = append(buildResultBlobs, buildResult)
}
resp.Koji = &KojiLogs{
Init: initResult,
Import: finalizeResult,
}
case worker.JobTypeOSBuild:
var buildResult worker.OSBuildJobResult
_, _, err = h.server.workers.OSBuildJobStatus(jobId, &buildResult)
if err != nil {
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
}
buildResultBlobs = append(buildResultBlobs, buildResult)
default:
return HTTPError(ErrorInvalidJobType)
}
// Return the OSBuildJobResults as-is for now. The contents of ImageBuilds
// is not part of the API. It's meant for a human to be able to access
// the logs, which just happen to be in JSON.
resp.ImageBuilds = buildResultBlobs
return ctx.JSON(http.StatusOK, resp)
}

View file

@ -593,7 +593,7 @@ func TestComposeStatusSuccess(t *testing.T) {
res, err := json.Marshal(&worker.OSBuildJobResult{
Success: true,
OSBuildOutput: &osbuild2.Result{},
OSBuildOutput: &osbuild2.Result{Success: true},
})
require.NoError(t, err)
@ -616,6 +616,36 @@ func TestComposeStatusSuccess(t *testing.T) {
"code": "IMAGE-BUILDER-COMPOSER-1012",
"reason": "OSBuildJobResult does not have expected fields set"
}`, "operation_id")
test.TestRoute(t, srv.Handler("/api/image-builder-composer/v2"), false, "GET", fmt.Sprintf("/api/image-builder-composer/v2/composes/%v/logs", jobId), ``, http.StatusOK, fmt.Sprintf(`
{
"href": "/api/image-builder-composer/v2/composes/%v/logs",
"id": "%v",
"kind": "ComposeLogs",
"image_builds": [
{
"arch": "",
"host_os": "",
"osbuild_output": {
"log": null,
"metadata": null,
"success": true,
"type": ""
},
"pipeline_names": {
"build": [
"build"
],
"payload": [
"os",
"assembler"
]
},
"success": true,
"upload_status": ""
}
]
}`, jobId, jobId))
}
func TestComposeStatusFailure(t *testing.T) {