From 5b414a4516d1c5156a4e42855c0e26065f838f7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hozza?= Date: Thu, 21 Sep 2023 09:36:16 +0200 Subject: [PATCH] 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. --- cmd/osbuild-worker/jobimpl-osbuild.go | 22 +++++++++++----------- internal/cloudapi/v2/v2_koji_test.go | 21 +++++++++++++++++++++ internal/cloudapi/v2/v2_test.go | 3 +++ internal/target/aws_target.go | 8 ++++---- internal/target/azure_image_target.go | 4 ++-- internal/target/azure_target.go | 4 ++-- internal/target/container_target.go | 4 ++-- internal/target/gcp_target.go | 4 ++-- internal/target/koji_target.go | 4 ++-- internal/target/oci_target.go | 8 ++++---- internal/target/targetresult.go | 23 ++++++++++++++--------- internal/target/vmware_target.go | 4 ++-- internal/target/worker_server_target.go | 4 ++-- 13 files changed, 71 insertions(+), 42 deletions(-) diff --git a/cmd/osbuild-worker/jobimpl-osbuild.go b/cmd/osbuild-worker/jobimpl-osbuild.go index b9067ee6e..d9fc6f76a 100644 --- a/cmd/osbuild-worker/jobimpl-osbuild.go +++ b/cmd/osbuild-worker/jobimpl-osbuild.go @@ -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) diff --git a/internal/cloudapi/v2/v2_koji_test.go b/internal/cloudapi/v2/v2_koji_test.go index c4463457b..9d1611277 100644 --- a/internal/cloudapi/v2/v2_koji_test.go +++ b/internal/cloudapi/v2/v2_koji_test.go @@ -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, diff --git a/internal/cloudapi/v2/v2_test.go b/internal/cloudapi/v2/v2_test.go index 149232f4d..fc5d42496 100644 --- a/internal/cloudapi/v2/v2_test.go +++ b/internal/cloudapi/v2/v2_test.go @@ -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, diff --git a/internal/target/aws_target.go b/internal/target/aws_target.go index 1f82bbf00..b6921a1a4 100644 --- a/internal/target/aws_target.go +++ b/internal/target/aws_target.go @@ -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) } diff --git a/internal/target/azure_image_target.go b/internal/target/azure_image_target.go index c5b5c713d..19e70cf4b 100644 --- a/internal/target/azure_image_target.go +++ b/internal/target/azure_image_target.go @@ -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) } diff --git a/internal/target/azure_target.go b/internal/target/azure_target.go index 1cb9dd65e..931d5adc0 100644 --- a/internal/target/azure_target.go +++ b/internal/target/azure_target.go @@ -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) } diff --git a/internal/target/container_target.go b/internal/target/container_target.go index 237718a7a..a0c2956c3 100644 --- a/internal/target/container_target.go +++ b/internal/target/container_target.go @@ -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) } diff --git a/internal/target/gcp_target.go b/internal/target/gcp_target.go index 3979f00e8..5d43e7030 100644 --- a/internal/target/gcp_target.go +++ b/internal/target/gcp_target.go @@ -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) } diff --git a/internal/target/koji_target.go b/internal/target/koji_target.go index 6145e29b3..ef0755afb 100644 --- a/internal/target/koji_target.go +++ b/internal/target/koji_target.go @@ -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) } diff --git a/internal/target/oci_target.go b/internal/target/oci_target.go index 5759332de..08c891e20 100644 --- a/internal/target/oci_target.go +++ b/internal/target/oci_target.go @@ -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) } diff --git a/internal/target/targetresult.go b/internal/target/targetresult.go index 0fd1922d8..59bccbfb7 100644 --- a/internal/target/targetresult.go +++ b/internal/target/targetresult.go @@ -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 } diff --git a/internal/target/vmware_target.go b/internal/target/vmware_target.go index 594ab1cf0..f7d415dd9 100644 --- a/internal/target/vmware_target.go +++ b/internal/target/vmware_target.go @@ -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) } diff --git a/internal/target/worker_server_target.go b/internal/target/worker_server_target.go index 880aea414..e25c5c48e 100644 --- a/internal/target/worker_server_target.go +++ b/internal/target/worker_server_target.go @@ -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) }