diff --git a/cmd/osbuild-upload-azure/main.go b/cmd/osbuild-upload-azure/main.go index 7a260241f..330e1d802 100644 --- a/cmd/osbuild-upload-azure/main.go +++ b/cmd/osbuild-upload-azure/main.go @@ -43,10 +43,12 @@ func main() { os.Exit(1) } + blobName := azure.EnsureVHDExtension(path.Base(fileName)) + err = c.UploadPageBlob( azure.BlobMetadata{ StorageAccount: storageAccount, - BlobName: path.Base(fileName), + BlobName: blobName, ContainerName: containerName, }, fileName, diff --git a/cmd/osbuild-worker/jobimpl-osbuild.go b/cmd/osbuild-worker/jobimpl-osbuild.go index 00d5529e3..101165fc6 100644 --- a/cmd/osbuild-worker/jobimpl-osbuild.go +++ b/cmd/osbuild-worker/jobimpl-osbuild.go @@ -527,10 +527,12 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error { return err } + // Azure cannot create an image from a blob without .vhd extension + blobName := azure.EnsureVHDExtension(args.Targets[0].ImageName) metadata := azure.BlobMetadata{ StorageAccount: options.StorageAccount, ContainerName: options.Container, - BlobName: args.Targets[0].ImageName, + BlobName: blobName, } const azureMaxUploadGoroutines = 4 @@ -677,10 +679,8 @@ func (impl *OSBuildJobImpl) Run(job worker.Job) error { return nil } - blobName := args.Targets[0].ImageName - if !strings.HasSuffix(blobName, ".vhd") { - blobName += ".vhd" - } + // Azure cannot create an image from a blob without .vhd extension + blobName := azure.EnsureVHDExtension(args.Targets[0].ImageName) logWithId.Info("[Azure] ⬆ Uploading the image") err = azureStorageClient.UploadPageBlob( diff --git a/internal/upload/azure/azurestorage.go b/internal/upload/azure/azurestorage.go index d9821aef5..99553c70d 100644 --- a/internal/upload/azure/azurestorage.go +++ b/internal/upload/azure/azurestorage.go @@ -56,12 +56,10 @@ const DefaultUploadThreads = 16 // UploadPageBlob takes the metadata and credentials required to upload the image specified by `fileName` // It can speed up the upload by using goroutines. The number of parallel goroutines is bounded by // the `threads` argument. +// +// Note that if you want to create an image out of the page blob, make sure that metadata.BlobName +// has a .vhd extension, see EnsureVHDExtension. func (c StorageClient) UploadPageBlob(metadata BlobMetadata, fileName string, threads int) error { - // Azure cannot create an image from a storage blob without .vhd extension - if !strings.HasSuffix(metadata.BlobName, ".vhd") { - metadata.BlobName = metadata.BlobName + ".vhd" - } - // get storage account blob service URL endpoint. URL, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s", metadata.StorageAccount, metadata.ContainerName)) @@ -205,3 +203,13 @@ func RandomStorageAccountName(prefix string) string { return (prefix + id)[:24] } + +// EnsureVHDExtension returns the given string with .vhd suffix if it already +// doesn't have one. +func EnsureVHDExtension(s string) string { + if strings.HasSuffix(s, ".vhd") { + return s + } + + return s + ".vhd" +} diff --git a/internal/upload/azure/azurestorage_test.go b/internal/upload/azure/azurestorage_test.go index aada263dd..249b4f4a4 100644 --- a/internal/upload/azure/azurestorage_test.go +++ b/internal/upload/azure/azurestorage_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestRandomStorageAccountName(t *testing.T) { @@ -15,3 +16,18 @@ func TestRandomStorageAccountName(t *testing.T) { r := regexp.MustCompile(`^[\d\w]{24}$`) assert.True(t, r.MatchString(randomName), "the returned name should be 24 characters long and contain only alphanumerical characters") } + +func TestEnsureVHDExtension(t *testing.T) { + tests := []struct { + s string + want string + }{ + {s: "toucan.zip", want: "toucan.zip.vhd"}, + {s: "kingfisher.vhd", want: "kingfisher.vhd"}, + } + for _, tt := range tests { + t.Run(tt.s, func(t *testing.T) { + require.Equal(t, tt.want, EnsureVHDExtension(tt.s)) + }) + } +}