osbuild/result: parse the metadata from the rpm stage
osbuild support returning metadata about each of the stages/assembler runs. Parse the results from the rpm stage, which contains the header fields from the installed RPMs, in particular the MD5 sum of the RPMs in question. This information is needed to be passed as metadata to koji when uploading images. Signed-off-by: Tom Gundersen <teg@jklm.no>
This commit is contained in:
parent
ac5f69e757
commit
5803abfeee
3 changed files with 154 additions and 24 deletions
|
|
@ -6,33 +6,74 @@ import (
|
|||
"io"
|
||||
)
|
||||
|
||||
type assembler struct {
|
||||
type rawAssemblerResult struct {
|
||||
Name string `json:"name"`
|
||||
Options json.RawMessage `json:"options"`
|
||||
Success bool `json:"success"`
|
||||
Output string `json:"output"`
|
||||
}
|
||||
|
||||
type stage struct {
|
||||
Name string `json:"name"`
|
||||
Options json.RawMessage `json:"options"`
|
||||
Success bool `json:"success"`
|
||||
Output string `json:"output"`
|
||||
type StageResult struct {
|
||||
Name string `json:"name"`
|
||||
Options json.RawMessage `json:"options"`
|
||||
Success bool `json:"success"`
|
||||
Output string `json:"output"`
|
||||
Metadata StageMetadata `json:"metadata"`
|
||||
}
|
||||
|
||||
type build struct {
|
||||
Stages []stage `json:"stages"`
|
||||
TreeID string `json:"tree_id"`
|
||||
Success bool `json:"success"`
|
||||
// StageMetadata specify the metadata of a given stage-type.
|
||||
type StageMetadata interface {
|
||||
isStageMetadata()
|
||||
}
|
||||
|
||||
type rawStageResult struct {
|
||||
Name string `json:"name"`
|
||||
Options json.RawMessage `json:"options"`
|
||||
Success bool `json:"success"`
|
||||
Output string `json:"output"`
|
||||
Metadata json.RawMessage `json:"metadata"`
|
||||
}
|
||||
|
||||
type buildResult struct {
|
||||
Stages []StageResult `json:"stages"`
|
||||
TreeID string `json:"tree_id"`
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
TreeID string `json:"tree_id"`
|
||||
OutputID string `json:"output_id"`
|
||||
Build *build `json:"build"`
|
||||
Stages []stage `json:"stages"`
|
||||
Assembler *assembler `json:"assembler"`
|
||||
Success bool `json:"success"`
|
||||
TreeID string `json:"tree_id"`
|
||||
OutputID string `json:"output_id"`
|
||||
Build *buildResult `json:"build"`
|
||||
Stages []StageResult `json:"stages"`
|
||||
Assembler *rawAssemblerResult `json:"assembler"`
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
func (result *StageResult) UnmarshalJSON(data []byte) error {
|
||||
var rawStageResult rawStageResult
|
||||
err := json.Unmarshal(data, &rawStageResult)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var metadata StageMetadata
|
||||
switch rawStageResult.Name {
|
||||
case "org.osbuild.rpm":
|
||||
metadata = new(RPMStageMetadata)
|
||||
err = json.Unmarshal(rawStageResult.Metadata, metadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
metadata = nil
|
||||
}
|
||||
|
||||
result.Name = rawStageResult.Name
|
||||
result.Options = rawStageResult.Options
|
||||
result.Success = rawStageResult.Success
|
||||
result.Output = rawStageResult.Output
|
||||
result.Metadata = metadata
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cr *Result) Write(writer io.Writer) error {
|
||||
|
|
|
|||
|
|
@ -2,29 +2,101 @@ package osbuild
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUnmarshall(t *testing.T) {
|
||||
resultRaw := `{
|
||||
"success": true,
|
||||
"build": {
|
||||
"success": true,
|
||||
"stages": [
|
||||
{
|
||||
"name": "org.osbuild.rpm",
|
||||
"id": "9eb0a6f6fd6e2995e107f5bcc6aa3b19643b02ec133bdc8a8ac614860b1bbf2d",
|
||||
"success": true,
|
||||
"output": "Building...",
|
||||
"metadata": {
|
||||
"packages": [
|
||||
{
|
||||
"name": "libgcc",
|
||||
"version": "10.0.1",
|
||||
"release": "0.11.fc32",
|
||||
"epoch": null,
|
||||
"arch": "x86_64",
|
||||
"sigmd5": "84fc907a5047aeebaf8da1642925a417"
|
||||
},
|
||||
{
|
||||
"name": "whois-nls",
|
||||
"version": "5.5.6",
|
||||
"release": "1.fc32",
|
||||
"epoch": null,
|
||||
"arch": "noarch",
|
||||
"sigmd5": "f868cd02046630c8ce3a9c48820e2437"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var result Result
|
||||
err := json.Unmarshal([]byte(resultRaw), &result)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, result.Build.Stages[0].Name, "org.osbuild.rpm")
|
||||
metadata, ok := result.Build.Stages[0].Metadata.(*RPMStageMetadata)
|
||||
assert.True(t, ok)
|
||||
package1 := metadata.Packages[0]
|
||||
assert.Equal(t, package1.Name, "libgcc")
|
||||
assert.Nil(t, package1.Epoch)
|
||||
assert.Equal(t, package1.Version, "10.0.1")
|
||||
assert.Equal(t, package1.Release, "0.11.fc32")
|
||||
assert.Equal(t, package1.Arch, "x86_64")
|
||||
assert.Equal(t, package1.SigMD5, "84fc907a5047aeebaf8da1642925a417")
|
||||
}
|
||||
|
||||
func TestWriteFull(t *testing.T) {
|
||||
|
||||
const testOptions = `{"msg": "test"}`
|
||||
|
||||
testStage := stage{
|
||||
Name: "testStage",
|
||||
dnfStage := StageResult{
|
||||
Name: "org.osbuild.rpm",
|
||||
Options: []byte(testOptions),
|
||||
Success: true,
|
||||
Output: "Finished",
|
||||
Metadata: RPMStageMetadata{
|
||||
Packages: []RPMPackageMetadata{
|
||||
{
|
||||
Name: "foobar",
|
||||
Epoch: nil,
|
||||
Version: "1",
|
||||
Release: "1",
|
||||
Arch: "noarch",
|
||||
SigMD5: "deadbeef",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
testStage := StageResult{
|
||||
Name: "org.osbuild.test",
|
||||
Options: []byte(testOptions),
|
||||
Success: true,
|
||||
Output: "Finished",
|
||||
}
|
||||
|
||||
testBuild := build{
|
||||
Stages: []stage{testStage},
|
||||
testBuild := buildResult{
|
||||
Stages: []StageResult{testStage},
|
||||
TreeID: "treeID",
|
||||
Success: true,
|
||||
}
|
||||
|
||||
testAssembler := assembler{
|
||||
testAssembler := rawAssemblerResult{
|
||||
Name: "testAssembler",
|
||||
Options: []byte(testOptions),
|
||||
Success: true,
|
||||
|
|
@ -35,7 +107,7 @@ func TestWriteFull(t *testing.T) {
|
|||
TreeID: "TreeID",
|
||||
OutputID: "OutputID",
|
||||
Build: &testBuild,
|
||||
Stages: []stage{testStage},
|
||||
Stages: []StageResult{dnfStage},
|
||||
Assembler: &testAssembler,
|
||||
Success: true,
|
||||
}
|
||||
|
|
@ -44,7 +116,7 @@ func TestWriteFull(t *testing.T) {
|
|||
assert.NoError(t, testComposeResult.Write(&b))
|
||||
expectedMessage :=
|
||||
`Build pipeline:
|
||||
Stage testStage
|
||||
Stage org.osbuild.test
|
||||
{
|
||||
"msg": "test"
|
||||
}
|
||||
|
|
@ -52,7 +124,7 @@ Stage testStage
|
|||
Output:
|
||||
Finished
|
||||
Stages:
|
||||
Stage: testStage
|
||||
Stage: org.osbuild.rpm
|
||||
{
|
||||
"msg": "test"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,3 +28,20 @@ func NewRPMStage(options *RPMStageOptions) *Stage {
|
|||
Options: options,
|
||||
}
|
||||
}
|
||||
|
||||
// RPMStageMetadata gives the set of packages installed by the RPM stage
|
||||
type RPMStageMetadata struct {
|
||||
Packages []RPMPackageMetadata `json:"packages"`
|
||||
}
|
||||
|
||||
// RPMPackageMetadata contains the metadata extracted from one RPM header
|
||||
type RPMPackageMetadata struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Release string `json:"release"`
|
||||
Epoch *string `json:"epoch"`
|
||||
Arch string `json:"arch"`
|
||||
SigMD5 string `json:"sigmd5"`
|
||||
}
|
||||
|
||||
func (RPMStageMetadata) isStageMetadata() {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue