Added "iso_checksum_url" and keep the functionality of "iso_checksum"
Added support for file shema in "iso_checksum_url". Added some unit tests and updated the docs accordingly.
This commit is contained in:
parent
00fcc3dfdc
commit
bbade5d8ae
|
@ -4,8 +4,10 @@ import (
|
|||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -15,6 +17,7 @@ import (
|
|||
// ISOConfig contains configuration for downloading ISO images.
|
||||
type ISOConfig struct {
|
||||
ISOChecksum string `mapstructure:"iso_checksum"`
|
||||
ISOChecksumURL string `mapstructure:"iso_checksum_url"`
|
||||
ISOChecksumType string `mapstructure:"iso_checksum_type"`
|
||||
ISOUrls []string `mapstructure:"iso_urls"`
|
||||
TargetPath string `mapstructure:"iso_target_path"`
|
||||
|
@ -43,7 +46,7 @@ func (c *ISOConfig) Prepare(ctx *interpolate.Context) ([]string, []error) {
|
|||
} else {
|
||||
c.ISOChecksumType = strings.ToLower(c.ISOChecksumType)
|
||||
if c.ISOChecksumType != "none" {
|
||||
if c.ISOChecksum == "" {
|
||||
if c.ISOChecksum == "" && c.ISOChecksumURL == "" {
|
||||
errs = append(
|
||||
errs, errors.New("Due to large file sizes, an iso_checksum is required"))
|
||||
return warnings, errs
|
||||
|
@ -54,59 +57,48 @@ func (c *ISOConfig) Prepare(ctx *interpolate.Context) ([]string, []error) {
|
|||
return warnings, errs
|
||||
}
|
||||
|
||||
u, err := url.Parse(c.ISOChecksum)
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error parsing checksum: %s", err))
|
||||
return warnings, errs
|
||||
}
|
||||
switch u.Scheme {
|
||||
case "http", "https", "ftp", "ftps":
|
||||
res, err := http.Get(c.ISOChecksum)
|
||||
c.ISOChecksum = ""
|
||||
// If iso_checksum has no value use iso_checksum_url instead.
|
||||
if c.ISOChecksum == "" {
|
||||
u, err := url.Parse(c.ISOChecksumURL)
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error getting checksum from url: %s", c.ISOChecksum))
|
||||
fmt.Errorf("Error parsing checksum: %s", err))
|
||||
return warnings, errs
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
rd := bufio.NewReader(res.Body)
|
||||
for {
|
||||
line, err := rd.ReadString('\n')
|
||||
switch u.Scheme {
|
||||
case "http", "https", "ftp", "ftps":
|
||||
res, err := http.Get(c.ISOChecksumURL)
|
||||
c.ISOChecksum = ""
|
||||
if err != nil {
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error getting checksum from url: %s , %s", c.ISOChecksum, err.Error()))
|
||||
fmt.Errorf("Error getting checksum from url: %s", c.ISOChecksumURL))
|
||||
return warnings, errs
|
||||
}
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
defer res.Body.Close()
|
||||
err = c.parseCheckSumFile(bufio.NewReader(res.Body))
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
return warnings, errs
|
||||
}
|
||||
if strings.ToLower(parts[0]) == c.ISOChecksumType {
|
||||
// BSD-style checksum
|
||||
if parts[1] == fmt.Sprintf("(%s)", filepath.Base(c.ISOUrls[0])) {
|
||||
c.ISOChecksum = parts[3]
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// Standard checksum
|
||||
if parts[1][0] == '*' {
|
||||
// Binary mode
|
||||
parts[1] = parts[1][1:]
|
||||
}
|
||||
if parts[1] == filepath.Base(c.ISOUrls[0]) {
|
||||
c.ISOChecksum = parts[0]
|
||||
break
|
||||
}
|
||||
case "file":
|
||||
file, err := os.Open(u.Path)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
return warnings, errs
|
||||
}
|
||||
err = c.parseCheckSumFile(bufio.NewReader(file))
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
return warnings, errs
|
||||
}
|
||||
|
||||
case "":
|
||||
break
|
||||
default:
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error parsing checksum url: %s, scheme not supported: %s", c.ISOChecksumURL, u.Scheme))
|
||||
return warnings, errs
|
||||
}
|
||||
case "":
|
||||
break
|
||||
default:
|
||||
errs = append(errs,
|
||||
fmt.Errorf("Error parsing checksum url, scheme not supported: %s", u.Scheme))
|
||||
return warnings, errs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,3 +123,38 @@ func (c *ISOConfig) Prepare(ctx *interpolate.Context) ([]string, []error) {
|
|||
|
||||
return warnings, errs
|
||||
}
|
||||
|
||||
func (c *ISOConfig) parseCheckSumFile(rd *bufio.Reader) error {
|
||||
for {
|
||||
line, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return fmt.Errorf("No checksum for \"%s\" found at: %s", filepath.Base(c.ISOUrls[0]), c.ISOChecksumURL)
|
||||
} else {
|
||||
return fmt.Errorf("Error getting checksum from url: %s , %s", c.ISOChecksumURL, err.Error())
|
||||
}
|
||||
}
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
if strings.ToLower(parts[0]) == c.ISOChecksumType {
|
||||
// BSD-style checksum
|
||||
if parts[1] == fmt.Sprintf("(%s)", filepath.Base(c.ISOUrls[0])) {
|
||||
c.ISOChecksum = parts[3]
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// Standard checksum
|
||||
if parts[1][0] == '*' {
|
||||
// Binary mode
|
||||
parts[1] = parts[1][1:]
|
||||
}
|
||||
if parts[1] == filepath.Base(c.ISOUrls[0]) {
|
||||
c.ISOChecksum = parts[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
@ -8,11 +10,22 @@ import (
|
|||
func testISOConfig() ISOConfig {
|
||||
return ISOConfig{
|
||||
ISOChecksum: "foo",
|
||||
ISOChecksumURL: "",
|
||||
ISOChecksumType: "md5",
|
||||
RawSingleISOUrl: "http://www.packer.io",
|
||||
RawSingleISOUrl: "http://www.packer.io/the-OS.iso",
|
||||
}
|
||||
}
|
||||
|
||||
var cs_bsd_style = `
|
||||
MD5 (other.iso) = bAr
|
||||
MD5 (the-OS.iso) = baZ
|
||||
`
|
||||
|
||||
var cs_gnu_style = `
|
||||
bAr0 *the-OS.iso
|
||||
baZ0 other.iso
|
||||
`
|
||||
|
||||
func TestISOConfigPrepare_ISOChecksum(t *testing.T) {
|
||||
i := testISOConfig()
|
||||
|
||||
|
@ -42,6 +55,53 @@ func TestISOConfigPrepare_ISOChecksum(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestISOConfigPrepare_ISOChecksumURL(t *testing.T) {
|
||||
i := testISOConfig()
|
||||
i.ISOChecksumURL = "file:///not_read"
|
||||
|
||||
// Test ISOChecksum overrides url
|
||||
warns, err := i.Prepare(nil)
|
||||
if len(warns) > 0 && len(err) > 0 {
|
||||
t.Fatalf("bad: %#v, %#v", warns, err)
|
||||
}
|
||||
|
||||
// Test good - ISOChecksumURL BSD style
|
||||
i = testISOConfig()
|
||||
i.ISOChecksum = ""
|
||||
cs_file, _ := ioutil.TempFile("", "packer-test-")
|
||||
ioutil.WriteFile(cs_file.Name(), []byte(cs_bsd_style), 0666)
|
||||
i.ISOChecksumURL = fmt.Sprintf("file://%s", cs_file.Name())
|
||||
warns, err = i.Prepare(nil)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if i.ISOChecksum != "baz" {
|
||||
t.Fatalf("should've found \"baz\" got: %s", i.ISOChecksum)
|
||||
}
|
||||
|
||||
// Test good - ISOChecksumURL GNU style
|
||||
i = testISOConfig()
|
||||
i.ISOChecksum = ""
|
||||
cs_file, _ = ioutil.TempFile("", "packer-test-")
|
||||
ioutil.WriteFile(cs_file.Name(), []byte(cs_gnu_style), 0666)
|
||||
i.ISOChecksumURL = fmt.Sprintf("file://%s", cs_file.Name())
|
||||
warns, err = i.Prepare(nil)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if i.ISOChecksum != "bar0" {
|
||||
t.Fatalf("should've found \"bar0\" got: %s", i.ISOChecksum)
|
||||
}
|
||||
}
|
||||
|
||||
func TestISOConfigPrepare_ISOChecksumType(t *testing.T) {
|
||||
i := testISOConfig()
|
||||
|
||||
|
@ -113,7 +173,7 @@ func TestISOConfigPrepare_ISOUrl(t *testing.T) {
|
|||
|
||||
// Test iso_url set
|
||||
i = testISOConfig()
|
||||
i.RawSingleISOUrl = "http://www.packer.io"
|
||||
i.RawSingleISOUrl = "http://www.packer.io/the-OS.iso"
|
||||
warns, err = i.Prepare(nil)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
|
@ -122,15 +182,15 @@ func TestISOConfigPrepare_ISOUrl(t *testing.T) {
|
|||
t.Errorf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
expected := []string{"http://www.packer.io"}
|
||||
expected := []string{"http://www.packer.io/the-OS.iso"}
|
||||
if !reflect.DeepEqual(i.ISOUrls, expected) {
|
||||
t.Fatalf("bad: %#v", i.ISOUrls)
|
||||
}
|
||||
|
||||
// Test both set
|
||||
i = testISOConfig()
|
||||
i.RawSingleISOUrl = "http://www.packer.io"
|
||||
i.ISOUrls = []string{"http://www.packer.io"}
|
||||
i.RawSingleISOUrl = "http://www.packer.io/the-OS.iso"
|
||||
i.ISOUrls = []string{"http://www.packer.io/the-OS.iso"}
|
||||
warns, err = i.Prepare(nil)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
|
@ -143,8 +203,8 @@ func TestISOConfigPrepare_ISOUrl(t *testing.T) {
|
|||
i = testISOConfig()
|
||||
i.RawSingleISOUrl = ""
|
||||
i.ISOUrls = []string{
|
||||
"http://www.packer.io",
|
||||
"http://www.hashicorp.com",
|
||||
"http://www.packer.io/the-OS.iso",
|
||||
"http://www.hashicorp.com/the-OS.iso",
|
||||
}
|
||||
|
||||
warns, err = i.Prepare(nil)
|
||||
|
@ -156,8 +216,8 @@ func TestISOConfigPrepare_ISOUrl(t *testing.T) {
|
|||
}
|
||||
|
||||
expected = []string{
|
||||
"http://www.packer.io",
|
||||
"http://www.hashicorp.com",
|
||||
"http://www.packer.io/the-OS.iso",
|
||||
"http://www.hashicorp.com/the-OS.iso",
|
||||
}
|
||||
if !reflect.DeepEqual(i.ISOUrls, expected) {
|
||||
t.Fatalf("bad: %#v", i.ISOUrls)
|
||||
|
|
|
@ -59,8 +59,9 @@ builder.
|
|||
- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
|
||||
files are so large, this is required and Packer will verify it prior to
|
||||
booting a virtual machine with the ISO attached. The type of the checksum is
|
||||
specified with `iso_checksum_type`, documented below. Also can be url that
|
||||
contains checksum file with `iso_checksum_type` type.
|
||||
specified with `iso_checksum_type`, documented below. At least one of
|
||||
`iso_checksum` and `iso_checksum_url` must be defined. This has precedence
|
||||
over `iso_checksum_url` type.
|
||||
|
||||
- `iso_checksum_type` (string) - The type of the checksum specified in
|
||||
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
|
||||
|
@ -68,6 +69,11 @@ builder.
|
|||
recommended since ISO files are generally large and corruption does happen
|
||||
from time to time.
|
||||
|
||||
- `iso_checksum_url` (string) - A URL to a GNU or BSD style checksum file
|
||||
containing a checksum for the OS ISO file. At least one of `iso_checksum`
|
||||
and `iso_checksum_url` must be defined. This will be ignored if
|
||||
`iso_checksum` is non empty.
|
||||
|
||||
- `iso_url` (string) - A URL to the ISO containing the installation image.
|
||||
This URL can be either an HTTP URL or a file URL (or path to a file). If
|
||||
this is an HTTP URL, Packer will download it and cache it between runs.
|
||||
|
|
|
@ -83,12 +83,20 @@ builder.
|
|||
- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
|
||||
files are so large, this is required and Packer will verify it prior to
|
||||
booting a virtual machine with the ISO attached. The type of the checksum is
|
||||
specified with `iso_checksum_type`, documented below. Also can be url that
|
||||
contains checksum file with `iso_checksum_type` type.
|
||||
specified with `iso_checksum_type`, documented below. At least one of
|
||||
`iso_checksum` and `iso_checksum_url` must be defined. This has precedence
|
||||
over `iso_checksum_url` type.
|
||||
|
||||
- `iso_checksum_type` (string) - The type of the checksum specified in
|
||||
`iso_checksum`. Valid values are "md5", "sha1", "sha256", or
|
||||
"sha512" currently.
|
||||
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
|
||||
"sha512" currently. While "none" will skip checksumming, this is not
|
||||
recommended since ISO files are generally large and corruption does happen
|
||||
from time to time.
|
||||
|
||||
- `iso_checksum_url` (string) - A URL to a GNU or BSD style checksum file
|
||||
containing a checksum for the OS ISO file. At least one of `iso_checksum`
|
||||
and `iso_checksum_url` must be defined. This will be ignored if
|
||||
`iso_checksum` is non empty.
|
||||
|
||||
- `iso_url` (string) - A URL to the ISO containing the installation image.
|
||||
This URL can be either an HTTP URL or a file URL (or path to a file). If
|
||||
|
|
|
@ -57,8 +57,9 @@ builder.
|
|||
- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
|
||||
files are so large, this is required and Packer will verify it prior to
|
||||
booting a virtual machine with the ISO attached. The type of the checksum is
|
||||
specified with `iso_checksum_type`, documented below. Also can be url that
|
||||
contains checksum file with `iso_checksum_type` type.
|
||||
specified with `iso_checksum_type`, documented below. At least one of
|
||||
`iso_checksum` and `iso_checksum_url` must be defined. This has precedence
|
||||
over `iso_checksum_url` type.
|
||||
|
||||
- `iso_checksum_type` (string) - The type of the checksum specified in
|
||||
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
|
||||
|
@ -66,6 +67,11 @@ builder.
|
|||
recommended since ISO files are generally large and corruption does happen
|
||||
from time to time.
|
||||
|
||||
- `iso_checksum_url` (string) - A URL to a GNU or BSD style checksum file
|
||||
containing a checksum for the OS ISO file. At least one of `iso_checksum`
|
||||
and `iso_checksum_url` must be defined. This will be ignored if
|
||||
`iso_checksum` is non empty.
|
||||
|
||||
- `iso_url` (string) - A URL to the ISO containing the installation image.
|
||||
This URL can be either an HTTP URL or a file URL (or path to a file). If
|
||||
this is an HTTP URL, Packer will download it and cache it between runs.
|
||||
|
|
|
@ -60,8 +60,9 @@ builder.
|
|||
- `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
|
||||
files are so large, this is required and Packer will verify it prior to
|
||||
booting a virtual machine with the ISO attached. The type of the checksum is
|
||||
specified with `iso_checksum_type`, documented below. Also can be url that
|
||||
contains checksum file with `iso_checksum_type` type.
|
||||
specified with `iso_checksum_type`, documented below. At least one of
|
||||
`iso_checksum` and `iso_checksum_url` must be defined. This has precedence
|
||||
over `iso_checksum_url` type.
|
||||
|
||||
- `iso_checksum_type` (string) - The type of the checksum specified in
|
||||
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
|
||||
|
@ -69,6 +70,11 @@ builder.
|
|||
recommended since ISO files are generally large and corruption does happen
|
||||
from time to time.
|
||||
|
||||
- `iso_checksum_url` (string) - A URL to a GNU or BSD style checksum file
|
||||
containing a checksum for the OS ISO file. At least one of `iso_checksum`
|
||||
and `iso_checksum_url` must be defined. This will be ignored if
|
||||
`iso_checksum` is non empty.
|
||||
|
||||
- `iso_url` (string) - A URL to the ISO containing the installation image.
|
||||
This URL can be either an HTTP URL or a file URL (or path to a file). If
|
||||
this is an HTTP URL, Packer will download it and cache it between runs.
|
||||
|
|
Loading…
Reference in New Issue