cloudapi: save and return compose request details
The original compose request contains useful details that are not preserved when it is converted to a manifest. Things like the distribution, arch, image type, blueprint or customizations are useful when examining builds later. This saves the original request json using the job id and a new directory (ComposeRequest) under the artifacts directory. The original request, if present, is then added to the compose/<id>/metadata response alongside the package list. Related: RHEL-60120
This commit is contained in:
parent
199a3d31f8
commit
d8e9a86921
2 changed files with 58 additions and 0 deletions
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
"slices"
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
@ -22,6 +24,7 @@ import (
|
||||||
"github.com/osbuild/images/pkg/sbom"
|
"github.com/osbuild/images/pkg/sbom"
|
||||||
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
"github.com/osbuild/osbuild-composer/internal/blueprint"
|
||||||
"github.com/osbuild/osbuild-composer/internal/common"
|
"github.com/osbuild/osbuild-composer/internal/common"
|
||||||
|
"github.com/osbuild/osbuild-composer/internal/jsondb"
|
||||||
"github.com/osbuild/osbuild-composer/internal/target"
|
"github.com/osbuild/osbuild-composer/internal/target"
|
||||||
"github.com/osbuild/osbuild-composer/internal/worker"
|
"github.com/osbuild/osbuild-composer/internal/worker"
|
||||||
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
|
"github.com/osbuild/osbuild-composer/internal/worker/clienterrors"
|
||||||
|
|
@ -150,6 +153,11 @@ func (h *apiHandlers) PostCompose(ctx echo.Context) error {
|
||||||
|
|
||||||
ctx.Logger().Infof("Job ID %s enqueued for operationID %s", id, ctx.Get(common.OperationIDKey))
|
ctx.Logger().Infof("Job ID %s enqueued for operationID %s", id, ctx.Get(common.OperationIDKey))
|
||||||
|
|
||||||
|
// Save the request in the artifacts directory, log errors but continue
|
||||||
|
if err := saveComposeRequest(h.server.workers.ArtifactsDir(), id, request); err != nil {
|
||||||
|
ctx.Logger().Warnf("Failed to save compose request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return ctx.JSON(http.StatusCreated, &ComposeId{
|
return ctx.JSON(http.StatusCreated, &ComposeId{
|
||||||
ObjectReference: ObjectReference{
|
ObjectReference: ObjectReference{
|
||||||
Href: "/api/image-builder-composer/v2/compose",
|
Href: "/api/image-builder-composer/v2/compose",
|
||||||
|
|
@ -622,6 +630,12 @@ func (h *apiHandlers) getComposeMetadataImpl(ctx echo.Context, id string) error
|
||||||
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
|
return HTTPErrorWithInternal(ErrorComposeNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the original compose request, if present
|
||||||
|
request, err := readComposeRequest(h.server.workers.ArtifactsDir(), jobId)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Logger().Warnf("Failed to read compose request: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
if buildInfo.JobStatus.Finished.IsZero() {
|
if buildInfo.JobStatus.Finished.IsZero() {
|
||||||
// job still running: empty response
|
// job still running: empty response
|
||||||
return ctx.JSON(200, ComposeMetadata{
|
return ctx.JSON(200, ComposeMetadata{
|
||||||
|
|
@ -630,6 +644,7 @@ func (h *apiHandlers) getComposeMetadataImpl(ctx echo.Context, id string) error
|
||||||
Id: jobId.String(),
|
Id: jobId.String(),
|
||||||
Kind: "ComposeMetadata",
|
Kind: "ComposeMetadata",
|
||||||
},
|
},
|
||||||
|
Request: request,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -641,6 +656,7 @@ func (h *apiHandlers) getComposeMetadataImpl(ctx echo.Context, id string) error
|
||||||
Id: jobId.String(),
|
Id: jobId.String(),
|
||||||
Kind: "ComposeMetadata",
|
Kind: "ComposeMetadata",
|
||||||
},
|
},
|
||||||
|
Request: request,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -675,6 +691,7 @@ func (h *apiHandlers) getComposeMetadataImpl(ctx echo.Context, id string) error
|
||||||
Kind: "ComposeMetadata",
|
Kind: "ComposeMetadata",
|
||||||
},
|
},
|
||||||
Packages: &packages,
|
Packages: &packages,
|
||||||
|
Request: request,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ostreeCommitMetadata != nil {
|
if ostreeCommitMetadata != nil {
|
||||||
|
|
@ -1571,3 +1588,41 @@ func (h *apiHandlers) getComposeDownloadImpl(ctx echo.Context, id string) error
|
||||||
}
|
}
|
||||||
return ctx.Attachment(file, fmt.Sprintf("%s-%s", jobId, tr.OsbuildArtifact.ExportFilename))
|
return ctx.Attachment(file, fmt.Sprintf("%s-%s", jobId, tr.OsbuildArtifact.ExportFilename))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// saveComposeRequest stores the compose request's json on disk
|
||||||
|
// This is saved in the ComposeRequest directory of the artifacts directory
|
||||||
|
// If no artifacts directory has been configured it saves nothing and silently returns
|
||||||
|
func saveComposeRequest(artifactsDir string, id uuid.UUID, request ComposeRequest) error {
|
||||||
|
if artifactsDir == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
p := path.Join(artifactsDir, "ComposeRequest")
|
||||||
|
err := os.MkdirAll(p, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
db := jsondb.New(p, 0700)
|
||||||
|
return db.Write(id.String(), request)
|
||||||
|
}
|
||||||
|
|
||||||
|
// readComposeRequest reads the compose request's json on disk
|
||||||
|
// This reads the original compose request json from the ComposeRequest directory of
|
||||||
|
// the artifacts directory.
|
||||||
|
// If no artifacts directory had been setup it silently returns nothing
|
||||||
|
func readComposeRequest(artifactsDir string, id uuid.UUID) (*ComposeRequest, error) {
|
||||||
|
if artifactsDir == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
p := path.Join(artifactsDir, "ComposeRequest")
|
||||||
|
err := os.MkdirAll(p, 0700)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
db := jsondb.New(p, 0700)
|
||||||
|
var request ComposeRequest
|
||||||
|
exists, err := db.Read(id.String(), &request)
|
||||||
|
if !exists {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &request, err
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -676,6 +676,9 @@ func (s *Server) DeleteArtifacts(id uuid.UUID) error {
|
||||||
return fmt.Errorf("Cannot delete artifacts before job is finished: %s", id)
|
return fmt.Errorf("Cannot delete artifacts before job is finished: %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove the ComposeRequest but ignore any errors
|
||||||
|
_ = os.Remove(path.Join(s.config.ArtifactsDir, "ComposeRequest", id.String()+".json"))
|
||||||
|
|
||||||
return os.RemoveAll(path.Join(s.config.ArtifactsDir, id.String()))
|
return os.RemoveAll(path.Join(s.config.ArtifactsDir, id.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue