packer-cn/common/iso_config.go
Adrien Delorme 0fa60c68fb
Drop the iso_checksum_type & iso_checksum_url fields (#8437)
* Drop the iso_checksum_type & iso_checksum_url fields

In favor of simply using iso_checksum that will know what to do.

* fix after master merge

* Update builder_test.go

* Update builder_test.go

* Update builder_test.go

* Update builder_test.go

* Update builder_test.go

* remove checksum lowercasing tests

* Update builder_test.go

* Update builder_test.go

* better docs

* Update builder_test.go

* even better docs

* Update config.go

* Update builder_test.go

* Update step_create_vmx_test.go

* make generate

* better docs

* fix imports

* up tests

* Update _ISOConfig-required.html.md

* Update builder_test.go

* don't use sha1.Sum("none") as a caching path

* Update builder_test.go

* better docs

* Update iso_config_test.go

remove ISOChecksumType/ISOChecksumURL references

* Update step_download_test.go

* add iso_checksum_url and iso_checksum_type fixers + tests

* add concrete examples of checksum values

* add examples of checksumming from local file

* update go-getter dep

* up deps

* use new go-getter version

* up ESX5Driver.VerifyChecksum: use go-getter's checksumming

* ISOConfig.Prepare: get checksum there in case we need it as a string in ESX5Driver.VerifyChecksum

* Update iso_config.go

* get go-getter from v2 branch

* Update driver_esx5.go

add more comments

* Update driver_esx5.go

* show better error message when the checksum is invalid

* Update builder_test.go

put in a valid checksum to fix tests, checksum is md5("packer")

* Update builder_test.go

test invalid and valid checksum

* more test updating

* fix default md5 string to be a valid md5

* TestChecksumFileNameMixedCaseBug: use 'file:' prefix for file checksumming

* Update iso_config_test.go

* Update iso_config_test.go

* Update builder_test.go

* Update builder_test.go

* Update builder_test.go

* Update CHANGELOG.md

* Update CHANGELOG.md

* Update go.mod

* Update go.mod

* Update CHANGELOG.md
2020-05-28 11:02:09 +02:00

177 lines
5.7 KiB
Go

//go:generate struct-markdown
package common
import (
"context"
"errors"
"fmt"
"log"
"os"
"strings"
getter "github.com/hashicorp/go-getter/v2"
urlhelper "github.com/hashicorp/go-getter/v2/helper/url"
"github.com/hashicorp/packer/template/interpolate"
)
// By default, Packer will symlink, download or copy image files to the Packer
// cache into a "`hash($iso_url+$iso_checksum).$iso_target_extension`" file.
// Packer uses [hashicorp/go-getter](https://github.com/hashicorp/go-getter) in
// file mode in order to perform a download.
//
// go-getter supports the following protocols:
//
// * Local files
// * Git
// * Mercurial
// * HTTP
// * Amazon S3
//
// Examples:
// go-getter can guess the checksum type based on `iso_checksum` len.
//
// ```json
// {
// "iso_checksum": "946a6077af6f5f95a51f82fdc44051c7aa19f9cfc5f737954845a6050543d7c2",
// "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso"
// }
// ```
//
// ```json
// {
// "iso_checksum": "file:ubuntu.org/..../ubuntu-14.04.1-server-amd64.iso.sum",
// "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso"
// }
// ```
//
// ```json
// {
// "iso_checksum": "file://./shasums.txt",
// "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso"
// }
// ```
//
// ```json
// {
// "iso_checksum": "file:./shasums.txt",
// "iso_url": "ubuntu.org/.../ubuntu-14.04.1-server-amd64.iso"
// }
// ```
//
type ISOConfig struct {
// The checksum for the ISO file or virtual hard drive file. The type of
// the checksum is specified within the checksum field as a prefix, ex:
// "md5:{$checksum}". The type of the checksum can also be omitted and
// Packer will try to infer it based on string length. Valid values are
// "none", "{$checksum}", "md5:{$checksum}", "sha1:{$checksum}",
// "sha256:{$checksum}", "sha512:{$checksum}" or "file:{$path}". Here is a
// list of valid checksum values:
// * md5:090992ba9fd140077b0661cb75f7ce13
// * 090992ba9fd140077b0661cb75f7ce13
// * sha1:ebfb681885ddf1234c18094a45bbeafd91467911
// * ebfb681885ddf1234c18094a45bbeafd91467911
// * sha256:ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93
// * ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93
// * file:http://releases.ubuntu.com/20.04/MD5SUMS
// * file:file://./local/path/file.sum
// * file:./local/path/file.sum
// * none
// Although the checksum will not be verified when it is set to "none",
// this is not recommended since these files can be very large and
// corruption does happen from time to time.
ISOChecksum string `mapstructure:"iso_checksum" required:"true"`
// A URL to the ISO containing the installation image or virtual hard drive
// (VHD or VHDX) file to clone.
RawSingleISOUrl string `mapstructure:"iso_url" required:"true"`
// Multiple URLs for the ISO to download. Packer will try these in order.
// If anything goes wrong attempting to download or while downloading a
// single URL, it will move on to the next. All URLs must point to the same
// file (same checksum). By default this is empty and `iso_url` is used.
// Only one of `iso_url` or `iso_urls` can be specified.
ISOUrls []string `mapstructure:"iso_urls"`
// The path where the iso should be saved after download. By default will
// go in the packer cache, with a hash of the original filename and
// checksum as its name.
TargetPath string `mapstructure:"iso_target_path"`
// The extension of the iso file after download. This defaults to `iso`.
TargetExtension string `mapstructure:"iso_target_extension"`
}
func (c *ISOConfig) Prepare(*interpolate.Context) (warnings []string, errs []error) {
if len(c.ISOUrls) != 0 && c.RawSingleISOUrl != "" {
errs = append(
errs, errors.New("Only one of iso_url or iso_urls must be specified"))
return
}
if c.RawSingleISOUrl != "" {
// make sure only array is set
c.ISOUrls = append([]string{c.RawSingleISOUrl}, c.ISOUrls...)
c.RawSingleISOUrl = ""
}
if len(c.ISOUrls) == 0 {
errs = append(
errs, errors.New("One of iso_url or iso_urls must be specified"))
return
}
if c.TargetExtension == "" {
c.TargetExtension = "iso"
}
c.TargetExtension = strings.ToLower(c.TargetExtension)
// Warnings
if c.ISOChecksum == "none" {
warnings = append(warnings,
"A checksum of 'none' was specified. Since ISO files are so big,\n"+
"a checksum is highly recommended.")
return warnings, errs
} else if c.ISOChecksum == "" {
errs = append(errs, fmt.Errorf("A checksum must be specified"))
} else {
// ESX5Driver.VerifyChecksum is ran remotely but should not download a
// checksum file, therefore in case it is a file, we need to download
// it now and compute the checksum now, we transform it back to a
// checksum string so that it can be simply read in the VerifyChecksum.
//
// Doing this also has the added benefit of failing early if a checksum
// is incorrect or if getting it should fail.
u, err := urlhelper.Parse(c.ISOUrls[0])
if err != nil {
return warnings, append(errs, fmt.Errorf("url parse: %s", err))
}
q := u.Query()
if c.ISOChecksum != "" {
q.Set("checksum", c.ISOChecksum)
}
u.RawQuery = q.Encode()
wd, err := os.Getwd()
if err != nil {
log.Printf("Getwd: %v", err)
// here we ignore the error in case the
// working directory is not needed.
}
req := &getter.Request{
Src: u.String(),
Pwd: wd,
}
cksum, err := defaultGetterClient.GetChecksum(context.TODO(), req)
if err != nil {
errs = append(errs, fmt.Errorf("%v in %q", err, req.URL().Query().Get("checksum")))
} else {
c.ISOChecksum = cksum.String()
}
}
if strings.HasSuffix(strings.ToLower(c.ISOChecksum), ".iso") {
errs = append(errs, fmt.Errorf("Error parsing checksum:"+
" .iso is not a valid checksum ending"))
}
return warnings, errs
}