/
iso_config.go
176 lines (163 loc) · 5.68 KB
/
iso_config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//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
}