Target: expose osbuild artifact information in target result

Add the information about osbuid artifact to the target result.
Specifically the name of the osbuild pipeline which was exported for the
specific target, and the filename of the exported file.

This will later enable embedding this information in Koji build metadata
to make it easy to reproduce the image build using the attached
manifest.
This commit is contained in:
Tomáš Hozza 2023-09-21 09:36:16 +02:00 committed by Tomáš Hozza
parent 4f51d44762
commit 5b414a4516
13 changed files with 71 additions and 42 deletions

View file

@ -458,7 +458,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
var targetResult *target.TargetResult
switch targetOptions := jobTarget.Options.(type) {
case *target.WorkerServerTargetOptions:
targetResult = target.NewWorkerServerTargetResult()
targetResult = target.NewWorkerServerTargetResult(&jobTarget.OsbuildArtifact)
var f *os.File
imagePath := path.Join(outputDirectory, jobTarget.OsbuildArtifact.ExportName, jobTarget.OsbuildArtifact.ExportFilename)
f, err = os.Open(imagePath)
@ -474,7 +474,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.VMWareTargetOptions:
targetResult = target.NewVMWareTargetResult()
targetResult = target.NewVMWareTargetResult(&jobTarget.OsbuildArtifact)
credentials := vmware.Credentials{
Username: targetOptions.Username,
Password: targetOptions.Password,
@ -528,7 +528,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.AWSTargetOptions:
targetResult = target.NewAWSTargetResult(nil)
targetResult = target.NewAWSTargetResult(nil, &jobTarget.OsbuildArtifact)
a, err := impl.getAWS(targetOptions.Region, targetOptions.AccessKeyID, targetOptions.SecretAccessKey, targetOptions.SessionToken)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, err.Error(), nil)
@ -585,7 +585,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.AWSS3TargetOptions:
targetResult = target.NewAWSS3TargetResult(nil)
targetResult = target.NewAWSS3TargetResult(nil, &jobTarget.OsbuildArtifact)
a, bucket, err := impl.getAWSForS3Target(targetOptions)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, err.Error(), nil)
@ -605,7 +605,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
targetResult.Options = &target.AWSS3TargetResultOptions{URL: url}
case *target.AzureTargetOptions:
targetResult = target.NewAzureTargetResult()
targetResult = target.NewAzureTargetResult(&jobTarget.OsbuildArtifact)
azureStorageClient, err := azure.NewStorageClient(targetOptions.StorageAccount, targetOptions.StorageAccessKey)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, err.Error(), nil)
@ -633,7 +633,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.GCPTargetOptions:
targetResult = target.NewGCPTargetResult(nil)
targetResult = target.NewGCPTargetResult(nil, &jobTarget.OsbuildArtifact)
ctx := context.Background()
g, err := impl.getGCP(targetOptions.Credentials)
@ -698,7 +698,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.AzureImageTargetOptions:
targetResult = target.NewAzureImageTargetResult(nil)
targetResult = target.NewAzureImageTargetResult(nil, &jobTarget.OsbuildArtifact)
ctx := context.Background()
if impl.AzureConfig.Creds == nil {
@ -828,7 +828,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.KojiTargetOptions:
targetResult = target.NewKojiTargetResult(nil)
targetResult = target.NewKojiTargetResult(nil, &jobTarget.OsbuildArtifact)
kojiServerURL, err := url.Parse(targetOptions.Server)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidTargetConfig, fmt.Sprintf("failed to parse Koji server URL: %v", err), nil)
@ -923,7 +923,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
}
case *target.OCITargetOptions:
targetResult = target.NewOCITargetResult(nil)
targetResult = target.NewOCITargetResult(nil, &jobTarget.OsbuildArtifact)
// create an ociClient uploader with a valid storage client
var ociClient oci.Client
ociClient, err = impl.getOCI(oci.ClientParams{
@ -984,7 +984,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
logWithId.Info("[OCI] 🎉 Image uploaded and registered!")
targetResult.Options = &target.OCITargetResultOptions{ImageID: imageID}
case *target.OCIObjectStorageTargetOptions:
targetResult = target.NewOCIObjectStorageTargetResult(nil)
targetResult = target.NewOCIObjectStorageTargetResult(nil, &jobTarget.OsbuildArtifact)
// create an ociClient uploader with a valid storage client
ociClient, err := impl.getOCI(oci.ClientParams{
User: targetOptions.User,
@ -1033,7 +1033,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
logWithId.Info("[OCI] 🎉 Image uploaded and pre-authenticated request generated!")
targetResult.Options = &target.OCIObjectStorageTargetResultOptions{URL: uri}
case *target.ContainerTargetOptions:
targetResult = target.NewContainerTargetResult(nil)
targetResult = target.NewContainerTargetResult(nil, &jobTarget.OsbuildArtifact)
destination := jobTarget.ImageName
logWithId.Printf("[container] 📦 Preparing upload to '%s'", destination)

View file

@ -56,6 +56,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: true,
@ -97,6 +100,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: true,
@ -138,6 +144,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: true,
@ -178,6 +187,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: false,
@ -220,6 +232,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: true,
@ -273,6 +288,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: true,
@ -318,6 +336,9 @@ func TestKojiCompose(t *testing.T) {
Checksum: "browns",
Size: 42,
},
}, &target.OsbuildArtifact{
ExportFilename: "disk.img",
ExportName: "image",
})},
OSBuildOutput: &osbuild.Result{
Success: true,

View file

@ -1261,6 +1261,9 @@ func TestImageFromCompose(t *testing.T) {
tr := target.NewAWSTargetResult(&target.AWSTargetResultOptions{
Ami: "ami-abc123",
Region: "eu-central-1",
}, &target.OsbuildArtifact{
ExportFilename: "image.raw",
ExportName: "image",
})
res, err := json.Marshal(&worker.OSBuildJobResult{
Success: true,

View file

@ -37,8 +37,8 @@ type AWSTargetResultOptions struct {
func (AWSTargetResultOptions) isTargetResultOptions() {}
func NewAWSTargetResult(options *AWSTargetResultOptions) *TargetResult {
return newTargetResult(TargetNameAWS, options)
func NewAWSTargetResult(options *AWSTargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameAWS, options, artifact)
}
type AWSS3TargetOptions struct {
@ -66,6 +66,6 @@ type AWSS3TargetResultOptions struct {
func (AWSS3TargetResultOptions) isTargetResultOptions() {}
func NewAWSS3TargetResult(options *AWSS3TargetResultOptions) *TargetResult {
return newTargetResult(TargetNameAWSS3, options)
func NewAWSS3TargetResult(options *AWSS3TargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameAWSS3, options, artifact)
}

View file

@ -39,6 +39,6 @@ type AzureImageTargetResultOptions struct {
func (AzureImageTargetResultOptions) isTargetResultOptions() {}
func NewAzureImageTargetResult(options *AzureImageTargetResultOptions) *TargetResult {
return newTargetResult(TargetNameAzureImage, options)
func NewAzureImageTargetResult(options *AzureImageTargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameAzureImage, options, artifact)
}

View file

@ -24,6 +24,6 @@ func NewAzureTarget(options *AzureTargetOptions) *Target {
return newTarget(TargetNameAzure, options)
}
func NewAzureTargetResult() *TargetResult {
return newTargetResult(TargetNameAzure, nil)
func NewAzureTargetResult(artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameAzure, nil, artifact)
}

View file

@ -24,6 +24,6 @@ type ContainerTargetResultOptions struct {
func (ContainerTargetResultOptions) isTargetResultOptions() {}
func NewContainerTargetResult(options *ContainerTargetResultOptions) *TargetResult {
return newTargetResult(TargetNameContainer, options)
func NewContainerTargetResult(options *ContainerTargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameContainer, options, artifact)
}

View file

@ -28,6 +28,6 @@ type GCPTargetResultOptions struct {
func (GCPTargetResultOptions) isTargetResultOptions() {}
func NewGCPTargetResult(options *GCPTargetResultOptions) *TargetResult {
return newTargetResult(TargetNameGCP, options)
func NewGCPTargetResult(options *GCPTargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameGCP, options, artifact)
}

View file

@ -117,6 +117,6 @@ func (o KojiTargetResultOptions) MarshalJSON() ([]byte, error) {
func (KojiTargetResultOptions) isTargetResultOptions() {}
func NewKojiTargetResult(options *KojiTargetResultOptions) *TargetResult {
return newTargetResult(TargetNameKoji, options)
func NewKojiTargetResult(options *KojiTargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameKoji, options, artifact)
}

View file

@ -26,8 +26,8 @@ type OCITargetResultOptions struct {
func (OCITargetResultOptions) isTargetResultOptions() {}
func NewOCITargetResult(options *OCITargetResultOptions) *TargetResult {
return newTargetResult(TargetNameOCI, options)
func NewOCITargetResult(options *OCITargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameOCI, options, artifact)
}
const TargetNameOCIObjectStorage TargetName = "org.osbuild.oci.objectstorage"
@ -55,6 +55,6 @@ type OCIObjectStorageTargetResultOptions struct {
func (OCIObjectStorageTargetResultOptions) isTargetResultOptions() {}
func NewOCIObjectStorageTargetResult(options *OCIObjectStorageTargetResultOptions) *TargetResult {
return newTargetResult(TargetNameOCIObjectStorage, options)
func NewOCIObjectStorageTargetResult(options *OCIObjectStorageTargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameOCIObjectStorage, options, artifact)
}

View file

@ -8,15 +8,18 @@ import (
)
type TargetResult struct {
Name TargetName `json:"name"`
Options TargetResultOptions `json:"options,omitempty"`
TargetError *clienterrors.Error `json:"target_error,omitempty"`
Name TargetName `json:"name"`
Options TargetResultOptions `json:"options,omitempty"`
// Configuration used to produce osbuild artifact specific to this target
OsbuildArtifact *OsbuildArtifact `json:"osbuild_artifact,omitempty"`
TargetError *clienterrors.Error `json:"target_error,omitempty"`
}
func newTargetResult(name TargetName, options TargetResultOptions) *TargetResult {
func newTargetResult(name TargetName, options TargetResultOptions, artifact *OsbuildArtifact) *TargetResult {
return &TargetResult{
Name: name,
Options: options,
Name: name,
Options: options,
OsbuildArtifact: artifact,
}
}
@ -25,9 +28,10 @@ type TargetResultOptions interface {
}
type rawTargetResult struct {
Name TargetName `json:"name"`
Options json.RawMessage `json:"options,omitempty"`
TargetError *clienterrors.Error `json:"target_error,omitempty"`
Name TargetName `json:"name"`
Options json.RawMessage `json:"options,omitempty"`
OsbuildArtifact *OsbuildArtifact `json:"osbuild_artifact,omitempty"`
TargetError *clienterrors.Error `json:"target_error,omitempty"`
}
func (targetResult *TargetResult) UnmarshalJSON(data []byte) error {
@ -48,6 +52,7 @@ func (targetResult *TargetResult) UnmarshalJSON(data []byte) error {
targetResult.Name = rawTR.Name
targetResult.Options = options
targetResult.OsbuildArtifact = rawTR.OsbuildArtifact
targetResult.TargetError = rawTR.TargetError
return nil
}

View file

@ -18,6 +18,6 @@ func NewVMWareTarget(options *VMWareTargetOptions) *Target {
return newTarget(TargetNameVMWare, options)
}
func NewVMWareTargetResult() *TargetResult {
return newTargetResult(TargetNameVMWare, nil)
func NewVMWareTargetResult(artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameVMWare, nil, artifact)
}

View file

@ -10,6 +10,6 @@ func NewWorkerServerTarget() *Target {
return newTarget(TargetNameWorkerServer, &WorkerServerTargetOptions{})
}
func NewWorkerServerTargetResult() *TargetResult {
return newTargetResult(TargetNameWorkerServer, nil)
func NewWorkerServerTargetResult(artifact *OsbuildArtifact) *TargetResult {
return newTargetResult(TargetNameWorkerServer, nil, artifact)
}