diff --git a/internal/osbuild1/result.go b/internal/osbuild1/result.go index b7d51303f..e8e8eda53 100644 --- a/internal/osbuild1/result.go +++ b/internal/osbuild1/result.go @@ -1,9 +1,12 @@ package osbuild1 import ( + "bytes" "encoding/json" "fmt" "io" + + "github.com/osbuild/osbuild-composer/internal/osbuild2" ) type rawAssemblerResult struct { @@ -123,3 +126,54 @@ func (cr *Result) Write(writer io.Writer) error { return nil } + +func (cr *Result) UnmarshalJSON(data []byte) error { + // NOTE(akoutsou) 1to2t: result format depends on the osbuild version; this + // unmarshaller tries to read both old and new versions + type resultAlias Result + crv1 := new(resultAlias) + + dec := json.NewDecoder(bytes.NewReader(data)) + dec.DisallowUnknownFields() + if err := dec.Decode(&crv1); err == nil { + *cr = Result(*crv1) + return nil + } + + // try osbuild2 result object + crv2 := new(osbuild2.Result) + + // NOTE: Using plain (non-strict) Unmarshal here. The format of the new + // osbuild output schema is not yet fixed and is likely to change, so + // disallowing unknown fields will likely cause failures in the near future. + if err := json.Unmarshal(data, &crv2); err != nil { + return err + } + cr.fromV2(crv2) + return nil +} + +// Convert new OSBuild v2 format result into a v1 by copying the most useful +// values: +// - Compose success status +// - Output of Stages (Log) as flattened list of v1 StageResults +func (cr *Result) fromV2(crv2 *osbuild2.Result) { + cr.Success = crv2.Success + // Empty build and assembler results for new types of jobs + cr.Build = new(buildResult) + cr.Assembler = new(rawAssemblerResult) + + // convert all stages logs from all pipelines into v1 StageResult objects + for pname, stages := range crv2.Log { + for idx, stage := range stages { + stageResult := StageResult{ + // Create uniquely identifiable name for the stage: + // :- + Name: fmt.Sprintf("%s:%d-%s", pname, idx, stage.Type), + Success: stage.Success, + Output: stage.Output, + } + cr.Stages = append(cr.Stages, stageResult) + } + } +}