worker/osbuild: workaround cloud upload for compressed images

The AWS and Azure RHUI images are produced as compressed archives, which
can be uploaded to Koji, but they can't be uploaded to the cloud
provider in this format. To support cloud upload for these types of
images, we need to decompress them before the upload.

Add a workaround for AWS and AzureImage targets to check if the image
has `.xz` suffix and if yes, decompress it before uploading to cloud.

This workaround is needed until image definitions will support and use
multiple exports per image to allow using different export per upload
target.
This commit is contained in:
Tomas Hozza 2022-07-20 22:48:00 +02:00 committed by Tom Gundersen
parent abc3d31222
commit 2ff34767cc

View file

@ -9,6 +9,7 @@ import (
"math/big"
"net/url"
"os"
"os/exec"
"path"
"strings"
@ -418,7 +419,22 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
if impl.AWSBucket != "" {
bucket = impl.AWSBucket
}
_, err = a.Upload(path.Join(outputDirectory, jobTarget.OsbuildArtifact.ExportName, jobTarget.OsbuildArtifact.ExportFilename), bucket, key)
// TODO: Remove this once multiple exports will be supported and used by image definitions
// RHUI images tend to be produced as archives in Brew to save disk space,
// however they can't be imported to the cloud provider as an archive.
// Workaround this situation for Koji composes by checking if the image file
// is an archive and if it is, extract it before uploading to the cloud.
imagePath := path.Join(outputDirectory, jobTarget.OsbuildArtifact.ExportName, jobTarget.OsbuildArtifact.ExportFilename)
if strings.HasSuffix(imagePath, ".xz") {
imagePath, err = extractXzArchive(imagePath)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorTargetError, "Failed to extract compressed image", err.Error())
break
}
}
_, err = a.Upload(imagePath, bucket, key)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorUploadingImage, err.Error())
break
@ -614,6 +630,20 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
// Azure cannot create an image from a blob without .vhd extension
blobName := azure.EnsureVHDExtension(jobTarget.ImageName)
// TODO: Remove this once multiple exports will be supported and used by image definitions
// RHUI images tend to be produced as archives in Brew to save disk space,
// however they can't be imported to the cloud provider as an archive.
// Workaround this situation for Koji composes by checking if the image file
// is an archive and if it is, extract it before uploading to the cloud.
imagePath := path.Join(outputDirectory, jobTarget.OsbuildArtifact.ExportName, jobTarget.OsbuildArtifact.ExportFilename)
if strings.HasSuffix(imagePath, ".xz") {
imagePath, err = extractXzArchive(imagePath)
if err != nil {
targetResult.TargetError = clienterrors.WorkerClientError(clienterrors.ErrorTargetError, "Failed to extract compressed image", err.Error())
break
}
}
logWithId.Info("[Azure] ⬆ Uploading the image")
err = azureStorageClient.UploadPageBlob(
azure.BlobMetadata{
@ -621,7 +651,7 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
ContainerName: storageContainer,
BlobName: blobName,
},
path.Join(outputDirectory, jobTarget.OsbuildArtifact.ExportName, jobTarget.OsbuildArtifact.ExportFilename),
imagePath,
azure.DefaultUploadThreads,
)
if err != nil {
@ -790,3 +820,19 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error {
return nil
}
// extractXzArchive extracts the provided XZ archive in the same directory
// and returns the path to decompressed file.
func extractXzArchive(archivePath string) (string, error) {
workingDir, archiveFilename := path.Split(archivePath)
decompressedFilename := strings.TrimSuffix(archiveFilename, ".xz")
cmd := exec.Command("xz", "-d", archivePath)
cmd.Dir = workingDir
err := cmd.Run()
if err != nil {
return "", err
}
return path.Join(workingDir, decompressedFilename), nil
}