diff --git a/cmd/osbuild-worker/jobimpl-koji-finalize.go b/cmd/osbuild-worker/jobimpl-koji-finalize.go index 121cccd62..723d12d6f 100644 --- a/cmd/osbuild-worker/jobimpl-koji-finalize.go +++ b/cmd/osbuild-worker/jobimpl-koji-finalize.go @@ -153,13 +153,15 @@ func (impl *KojiFinalizeJobImpl) Run(job worker.Job) error { // multiple buildRPMs = rpmmd.DeduplicateRPMs(buildRPMs) - // TODO: support multiple upload targets - if len(buildArgs.TargetResults) != 1 { - kojiFinalizeJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorKojiFinalize, "Koji compose OSBuild job result must contain exactly one target result") + kojiTargetResults := buildArgs.TargetResultsByName(target.TargetNameKoji) + // Only a single Koji target is allowed per osbuild job + if len(kojiTargetResults) != 1 { + kojiFinalizeJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorKojiFinalize, "Exactly one Koji target results are expected per osbuild job") return nil } - kojiTarget := buildArgs.TargetResults[0] - kojiTargetOptions := kojiTarget.Options.(*target.KojiTargetResultOptions) + + kojiTargetResult := kojiTargetResults[0] + kojiTargetOptions := kojiTargetResult.Options.(*target.KojiTargetResultOptions) buildRoots = append(buildRoots, koji.BuildRoot{ ID: uint64(i), diff --git a/internal/worker/json.go b/internal/worker/json.go index bcb1a951c..817665e7b 100644 --- a/internal/worker/json.go +++ b/internal/worker/json.go @@ -75,6 +75,20 @@ func (j *OSBuildJobResult) TargetErrors() []*clienterrors.Error { return targetErrors } +// TargetResultsByName iterates over TargetResults attached to the Job result and +// returns a slice of Target results of the provided name (type). If there were no +// TargetResults of the desired type attached to the Job results, the returned +// slice will be empty. +func (j *OSBuildJobResult) TargetResultsByName(name target.TargetName) []*target.TargetResult { + targetResults := []*target.TargetResult{} + for _, targetResult := range j.TargetResults { + if targetResult.Name == name { + targetResults = append(targetResults, targetResult) + } + } + return targetResults +} + type KojiInitJob struct { Server string `json:"server"` Name string `json:"name"` diff --git a/internal/worker/json_test.go b/internal/worker/json_test.go index 6f629e27f..f3565f44f 100644 --- a/internal/worker/json_test.go +++ b/internal/worker/json_test.go @@ -87,6 +87,108 @@ func TestOSBuildJobResultTargetErrors(t *testing.T) { } } +func TestOSBuildJobResultTargetResultsByName(t *testing.T) { + testCases := []struct { + jobResult OSBuildJobResult + targetName target.TargetName + targetResults []*target.TargetResult + }{ + // one target results of a given name + { + jobResult: OSBuildJobResult{ + TargetResults: []*target.TargetResult{ + { + Name: target.TargetNameAWS, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorInvalidTargetConfig, "can't login to AWS"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameAWSS3, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "failed to upload image to AWS S3"), + }, + }, + }, + targetName: target.TargetNameAWS, + targetResults: []*target.TargetResult{ + { + Name: target.TargetNameAWS, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorInvalidTargetConfig, "can't login to AWS"), + }, + }, + }, + // multiple target results of a given name + { + jobResult: OSBuildJobResult{ + TargetResults: []*target.TargetResult{ + { + Name: target.TargetNameAWS, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorInvalidTargetConfig, "can't login to AWS"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameAWSS3, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "failed to upload image to AWS S3"), + }, + }, + }, + targetName: target.TargetNameVMWare, + targetResults: []*target.TargetResult{ + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + }, + }, + // no target result of a given name + { + jobResult: OSBuildJobResult{ + TargetResults: []*target.TargetResult{ + { + Name: target.TargetNameAWS, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorInvalidTargetConfig, "can't login to AWS"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameVMWare, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "can't upload image to VMWare"), + }, + { + Name: target.TargetNameAWSS3, + TargetError: clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, "failed to upload image to AWS S3"), + }, + }, + }, + targetName: target.TargetNameKoji, + targetResults: []*target.TargetResult{}, + }, + } + + for _, testCase := range testCases { + assert.EqualValues(t, testCase.targetResults, testCase.jobResult.TargetResultsByName(testCase.targetName)) + } +} + func TestOSBuildJobExports(t *testing.T) { testCases := []struct { job *OSBuildJob