func uploadImage(imageLocalStorePath string, bsDriver ObjectStoreDriver, image *Image) error {
	log.Debug("Calculating checksum for raw image")
	rawChecksum, err := util.GetFileChecksum(imageLocalStorePath)
	if err != nil {
		log.Debug("Calculation failed")
		return err
	}
	log.Debug("Calculation done, raw checksum: ", rawChecksum)
	image.RawChecksum = rawChecksum

	log.Debug("Compressing raw image")
	if err := util.CompressFile(imageLocalStorePath); err != nil {
		log.Debug("Compressing failed ")
		return err
	}
	compressedLocalPath := imageLocalStorePath + ".gz"
	log.Debug("Compressed raw image to ", compressedLocalPath)

	log.Debug("Calculating checksum for compressed image")
	if image.Checksum, err = util.GetFileChecksum(compressedLocalPath); err != nil {
		log.Debug("Calculation failed")
		return err
	}
	log.Debug("Calculation done, checksum: ", image.Checksum)

	imageObjectStorePath := getImageObjectStorePath(image.UUID)
	log.Debug("Uploading image to objectstore path: ", imageObjectStorePath)
	if err := bsDriver.Upload(compressedLocalPath, imageObjectStorePath); err != nil {
		log.Debugf("Uploading failed")
		return err
	}
	log.Debugf("Uploading done")
	return nil
}
func loadImageCache(fileName string, compressed bool, image *Image) (bool, error) {
	if st, err := os.Stat(fileName); err == nil && !st.IsDir() {
		log.Debug("Found local image cache at ", fileName)
		log.Debug("Calculating checksum for local image cache")
		checksum, err := util.GetFileChecksum(fileName)
		if err != nil {
			return false, err
		}
		log.Debug("Calculation done, checksum ", checksum)
		if compressed && checksum == image.Checksum {
			log.Debugf("Found image %v in local images directory, and checksum matched, no need to re-download\n", image.UUID)
			return true, nil
		} else if !compressed && checksum == image.RawChecksum {
			log.Debugf("Found image %v in local images directory, and checksum matched, no need to re-download\n", image.UUID)
			return true, nil
		} else {
			log.Debugf("Found image %v in local images directory, but checksum doesn't match record, would re-download\n", image.UUID)
			if err := os.RemoveAll(fileName); err != nil {
				return false, err
			}
			log.Debug("Removed local image cache at ", fileName)
		}
	}
	return false, nil
}
func downloadImage(imagesDir string, driver ObjectStoreDriver, image *Image) error {
	imageLocalStorePath := GetImageLocalStorePath(imagesDir, image.UUID)
	found, err := loadImageCache(imageLocalStorePath, false, image)
	if found || err != nil {
		return err
	}

	compressedLocalPath := imageLocalStorePath + ".gz"
	found, err = loadImageCache(compressedLocalPath, true, image)
	if err != nil {
		return err
	}
	if found {
		return uncompressImage(compressedLocalPath)
	}

	imageObjectStorePath := getImageObjectStorePath(image.UUID)
	log.Debugf("Downloading image from objectstore %v to %v", imageObjectStorePath, compressedLocalPath)
	if err := driver.Download(imageObjectStorePath, compressedLocalPath); err != nil {
		return err
	}
	log.Debug("Download complete")

	if err := uncompressImage(compressedLocalPath); err != nil {
		return err
	}

	log.Debug("Calculating checksum for local image")
	rawChecksum, err := util.GetFileChecksum(imageLocalStorePath)
	if err != nil {
		return err
	}
	log.Debug("Calculation done, raw checksum ", rawChecksum)
	if rawChecksum != image.RawChecksum {
		return fmt.Errorf("Image %v checksum verification failed!", image.UUID)
	}
	return nil
}