diff --git a/cmd/osbuild-worker/jobimpl-osbuild.go b/cmd/osbuild-worker/jobimpl-osbuild.go index 3aea6e0cd..6db4b4f18 100644 --- a/cmd/osbuild-worker/jobimpl-osbuild.go +++ b/cmd/osbuild-worker/jobimpl-osbuild.go @@ -315,7 +315,35 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error { if impl.AWSBucket != "" { bucket = impl.AWSBucket } - _, err = a.Upload(path.Join(outputDirectory, exportPath, options.Filename), bucket, key) + + imagePath := path.Join(outputDirectory, exportPath, options.Filename) + + // *** SPECIAL VMDK HANDLING START *** + // Upload the VMDK image as stream-optimized. + // The VMDK conversion is applied only when the job was submitted by Weldr API, + // therefore we need to do the conversion here explicitly if it was not done. + if args.StreamOptimized { + // If the streamOptimizedPath is empty, the conversion was not done + if streamOptimizedPath == "" { + var f *os.File + f, err = vmware.OpenAsStreamOptimizedVmdk(imagePath) + if err != nil { + osbuildJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, err.Error()) + return nil + } + streamOptimizedPath = f.Name() + f.Close() + } + // Replace the original file by the stream-optimized one + err = os.Rename(streamOptimizedPath, imagePath) + if err != nil { + osbuildJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorInvalidConfig, err.Error()) + return nil + } + } + // *** SPECIAL VMDK HANDLING END *** + + _, err = a.Upload(imagePath, bucket, key) if err != nil { osbuildJobResult.JobError = clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, err.Error()) return nil diff --git a/internal/cloudapi/v2/v2.go b/internal/cloudapi/v2/v2.go index 70ab6da5a..fa5913a21 100644 --- a/internal/cloudapi/v2/v2.go +++ b/internal/cloudapi/v2/v2.go @@ -532,8 +532,9 @@ func enqueueCompose(workers *worker.Server, distribution distro.Distro, bp bluep } id, err = workers.EnqueueOSBuildAsDependency(ir.arch.Name(), &worker.OSBuildJob{ - Targets: []*target.Target{ir.target}, - Exports: ir.imageType.Exports(), + Targets: []*target.Target{ir.target}, + Exports: ir.imageType.Exports(), + StreamOptimized: ir.imageType.Name() == "vmdk", // https://github.com/osbuild/osbuild/issues/528, PipelineNames: &worker.PipelineNames{ Build: ir.imageType.BuildPipelines(), Payload: ir.imageType.PayloadPipelines(), diff --git a/test/cases/api.sh b/test/cases/api.sh index f6c55596a..bf67764e7 100755 --- a/test/cases/api.sh +++ b/test/cases/api.sh @@ -1231,12 +1231,11 @@ function verifyInVSphere() { _ci_iso_path="$(_createCIUserdataISO "${_ci_userdata_path}" "${_ci_metadata_path}")" VSPHERE_IMAGE_NAME="${VSPHERE_VM_NAME}.vmdk" + mv "${_filename}" "${WORKDIR}/${VSPHERE_IMAGE_NAME}" # import the built VMDK image to VSphere # import.vmdk seems to be creating the provided directory and # if one with this name exists, it appends "_" to the name - greenprint "🚧 Converting the downloaded VMDK image to be streamOptimized" - qemu-img convert -O vmdk -o subformat=streamOptimized "${_filename}" "${WORKDIR}/${VSPHERE_IMAGE_NAME}" greenprint "💿 ⬆️ Importing the converted VMDK image to VSphere" $GOVC_CMD import.vmdk \ -u "${GOVMOMI_USERNAME}:${GOVMOMI_PASSWORD}@${GOVMOMI_URL}" \