Skip to content

Commit

Permalink
Merge pull request openshift#2645 from Fedosin/uncompress_image
Browse files Browse the repository at this point in the history
Bug 1770441: OpenStack: unpack compressed image data
  • Loading branch information
openshift-merge-robot authored Nov 11, 2019
2 parents 0b98b56 + afc248f commit c85edfd
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 4 deletions.
14 changes: 11 additions & 3 deletions pkg/rhcos/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package rhcos
import (
"context"
"net/url"
"strings"

"github.com/pkg/errors"
)
Expand All @@ -25,9 +26,16 @@ func OpenStack(ctx context.Context) (string, error) {
return "", err
}

// Attach uncompressed sha256 checksum to the URL
checkSuffix := "?sha256=" + meta.Images.OpenStack.UncompressedSHA256
baseURL := base.ResolveReference(relOpenStack).String() + checkSuffix
baseURL := base.ResolveReference(relOpenStack).String()

// Attach sha256 checksum to the URL. If the file has the ".gz" extension, then the
// data is compressed and we use SHA256 value; otherwise we work with uncompressed
// data and therefore need UncompressedSHA256.
if strings.HasSuffix(baseURL, ".gz") {
baseURL += "?sha256=" + meta.Images.OpenStack.SHA256
} else {
baseURL += "?sha256=" + meta.Images.OpenStack.UncompressedSHA256
}

// Check that we have generated a valid URL
_, err = url.ParseRequestURI(baseURL)
Expand Down
59 changes: 58 additions & 1 deletion pkg/tfvars/openstack/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@
package openstack

import (
"compress/gzip"
"encoding/json"
"fmt"
"io"
"net/url"
"os"
"strings"

"github.com/gophercloud/gophercloud/openstack/identity/v3/tokens"
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
"github.com/gophercloud/utils/openstack/clientconfig"
"github.com/openshift/installer/pkg/rhcos"
"github.com/openshift/installer/pkg/tfvars/internal/cache"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"

"sigs.k8s.io/cluster-api-provider-openstack/pkg/apis/openstackproviderconfig/v1alpha1"
)
Expand Down Expand Up @@ -63,7 +69,32 @@ func TFVars(masterConfig *v1alpha1.OpenstackProviderSpec, cloud string, external
return nil, err
}

cfg.BaseImageLocalFilePath = localFilePath
// Compressed image support was added to OpenStack Glance only in Train release. Unfortunately previous
// versions do not have this feature, so we have to check whether or not we need to decompress the file.
// For more information: https://docs.openstack.org/glance/latest/user/formats.html
// TODO(mfedosin): Allow to skip this step if Glance supports compressed images.
baseImageURL, err := url.ParseRequestURI(baseImage)
// If the file has ".gz" extension, then its data is compressed
if strings.HasSuffix(baseImageURL.Path, ".gz") {
localFilePathUncompressed := localFilePath + ".uncompressed"

// Do nothing if we already have the uncompressed file in cache, otherwise decompress the data
_, err = os.Stat(localFilePathUncompressed)
if err != nil {
if os.IsNotExist(err) {
logrus.Infof("Decompress image data from %v to %v", localFilePath, localFilePathUncompressed)
err = decompressFile(localFilePath, localFilePathUncompressed)
if err != nil {
return nil, err
}
} else {
return nil, err
}
}
cfg.BaseImageLocalFilePath = localFilePathUncompressed
} else {
cfg.BaseImageLocalFilePath = localFilePath
}
} else {
// Not a URL -> use baseImage value as an overridden Glance image name.
// Need to check if this image exists and there are no other images with this name.
Expand Down Expand Up @@ -99,6 +130,32 @@ func TFVars(masterConfig *v1alpha1.OpenstackProviderSpec, cloud string, external
return json.MarshalIndent(cfg, "", " ")
}

// decompressFile decompresses data in the cache
func decompressFile(src, dest string) error {
gzipfile, err := os.Open(src)
if err != nil {
return err
}

reader, err := gzip.NewReader(gzipfile)
defer reader.Close()
if err != nil {
return err
}

writer, err := os.Create(dest)
defer writer.Close()
if err != nil {
return err
}

if _, err = io.Copy(writer, reader); err != nil {
return err
}

return nil
}

func validateOverriddenImageName(imageName, cloud string) error {
opts := &clientconfig.ClientOpts{
Cloud: cloud,
Expand Down

0 comments on commit c85edfd

Please sign in to comment.